Skip to content

Commit 51a0d79

Browse files
authored
V2: Add DescEnum.value (#927)
1 parent 5899427 commit 51a0d79

File tree

9 files changed

+57
-34
lines changed

9 files changed

+57
-34
lines changed

packages/bundle-size/README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ usually do. We repeat this for an increasing number of files.
1616

1717
| code generator | files | bundle size | minified | compressed |
1818
| ------------------- | ----: | ----------: | --------: | ---------: |
19-
| protobuf-es | 1 | 125,855 b | 65,617 b | 15,259 b |
20-
| protobuf-es | 4 | 128,044 b | 67,125 b | 15,961 b |
21-
| protobuf-es | 8 | 130,806 b | 68,896 b | 16,416 b |
22-
| protobuf-es | 16 | 141,256 b | 76,877 b | 18,761 b |
23-
| protobuf-es | 32 | 169,047 b | 98,895 b | 24,239 b |
19+
| protobuf-es | 1 | 125,880 b | 65,631 b | 15,280 b |
20+
| protobuf-es | 4 | 128,069 b | 67,139 b | 15,961 b |
21+
| protobuf-es | 8 | 130,831 b | 68,910 b | 16,456 b |
22+
| protobuf-es | 16 | 141,281 b | 76,891 b | 18,790 b |
23+
| protobuf-es | 32 | 169,072 b | 98,909 b | 24,236 b |
2424
| protobuf-javascript | 1 | 334,193 b | 255,820 b | 42,481 b |
2525
| protobuf-javascript | 4 | 360,861 b | 271,092 b | 43,912 b |
2626
| protobuf-javascript | 8 | 382,904 b | 283,409 b | 45,038 b |

packages/bundle-size/chart.svg

+5-5
Loading

packages/protobuf-test/src/generate-code.test.ts

+11
Original file line numberDiff line numberDiff line change
@@ -290,3 +290,14 @@ describe("GenMessage.field", () => {
290290
proto3_ts.Proto3MessageSchema.field.foo;
291291
});
292292
});
293+
294+
describe("GenDescEnum.value", () => {
295+
test("is type safe", () => {
296+
const val = proto3_ts.Proto3EnumSchema.value[proto3_ts.Proto3Enum.YES];
297+
expect(val.number).toBe(1);
298+
expect(val.name).toBe("PROTO3_ENUM_YES");
299+
expect(val.localName).toBe("YES");
300+
// @ts-expect-error TS7053: Element implicitly has an any type because expression of type 77 can't be used to index type Record<Proto3Enum, DescEnumValue>
301+
proto3_ts.Proto3EnumSchema.value[77];
302+
});
303+
});

packages/protobuf/src/codegenv1/enum.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ import type { JsonValue } from "../json-value.js";
2121
*
2222
* @private
2323
*/
24-
export function enumDesc<Shape, JsonType extends JsonValue = JsonValue>(
25-
file: DescFile,
26-
path: number,
27-
...paths: number[]
28-
): GenEnum<Shape, JsonType> {
24+
export function enumDesc<
25+
Shape extends number,
26+
JsonType extends JsonValue = JsonValue,
27+
>(file: DescFile, path: number, ...paths: number[]): GenEnum<Shape, JsonType> {
2928
if (paths.length == 0) {
3029
return file.enums[path] as GenEnum<Shape, JsonType>;
3130
}

packages/protobuf/src/codegenv1/types.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import type { Message } from "../types.js";
1616
import type {
1717
DescEnum,
18+
DescEnumValue,
1819
DescExtension,
1920
DescField,
2021
DescFile,
@@ -54,9 +55,11 @@ export type GenMessage<RuntimeShape extends Message, JsonType = JsonValue> =
5455
* @private
5556
*/
5657
export type GenEnum<
57-
RuntimeShape,
58+
RuntimeShape extends number,
5859
JsonType extends JsonValue = JsonValue,
59-
> = DescEnum & brandv1<RuntimeShape, JsonType>;
60+
> = Omit<DescEnum, "value"> & {
61+
value: Record<RuntimeShape, DescEnumValue>;
62+
} & brandv1<RuntimeShape, JsonType>;
6063

6164
/**
6265
* Describes an extension in a protobuf source file.

packages/protobuf/src/descriptors.ts

+4
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ export interface DescEnum {
171171
* Values declared for this enumeration.
172172
*/
173173
readonly values: DescEnumValue[];
174+
/**
175+
* All values of this enum by their number.
176+
*/
177+
readonly value: Record<number, DescEnumValue>;
174178
/**
175179
* A prefix shared by all enum values.
176180
* For example, `my_enum_` for `enum MyEnum {MY_ENUM_A=0; MY_ENUM_B=1;}`

packages/protobuf/src/registry.ts

+19-14
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ function addEnum(
599599
open: true,
600600
name: proto.name,
601601
typeName: makeTypeName(proto, parent, file),
602+
value: {},
602603
values: [],
603604
sharedPrefix,
604605
toString(): string {
@@ -609,20 +610,24 @@ function addEnum(
609610
reg.add(desc);
610611
proto.value.forEach((proto) => {
611612
const name = proto.name;
612-
desc.values.push({
613-
kind: "enum_value",
614-
proto,
615-
deprecated: proto.options?.deprecated ?? false,
616-
parent: desc,
617-
name: proto.name,
618-
localName: safeObjectProperty(
619-
sharedPrefix == undefined ? name : name.substring(sharedPrefix.length),
620-
),
621-
number: proto.number,
622-
toString() {
623-
return `enum value ${desc.typeName}.${this.name}`;
624-
},
625-
});
613+
desc.values.push(
614+
(desc.value[proto.number] = {
615+
kind: "enum_value" as const,
616+
proto,
617+
deprecated: proto.options?.deprecated ?? false,
618+
parent: desc,
619+
name,
620+
localName: safeObjectProperty(
621+
sharedPrefix == undefined
622+
? name
623+
: name.substring(sharedPrefix.length),
624+
),
625+
number: proto.number,
626+
toString() {
627+
return `enum value ${desc.typeName}.${name}`;
628+
},
629+
}),
630+
);
626631
});
627632
(parent?.nestedEnums ?? file.enums).push(desc);
628633
}

packages/protobuf/src/to-json.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import {
1616
type DescEnum,
17+
type DescEnumValue,
1718
type DescField,
1819
type DescMessage,
1920
ScalarType,
@@ -169,7 +170,7 @@ export function enumToJson<Desc extends DescEnum>(
169170
if (descEnum.typeName == "google.protobuf.NullValue") {
170171
return null as EnumJsonType<Desc>;
171172
}
172-
const name = descEnum.values.find((v) => v.number === value)?.name;
173+
const name = (descEnum.value[value] as DescEnumValue | undefined)?.name;
173174
if (name === undefined) {
174175
throw new Error(
175176
`${String(value)} is not a value in ${descEnum.toString()}`,
@@ -308,7 +309,7 @@ function enumToJsonInternal(
308309
if (enumAsInteger) {
309310
return value;
310311
}
311-
const val = desc.values.find((v) => v.number == value);
312+
const val = desc.value[value] as DescEnumValue | undefined;
312313
return val?.name ?? value; // if we don't know the enum value, just return the number
313314
}
314315

packages/protobuf/src/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export type EnumShape<Desc extends DescEnum> =
6363
* Extract the enum JSON type from a enum descriptor.
6464
*/
6565
export type EnumJsonType<Desc extends DescEnum> =
66-
Desc extends GenEnum<unknown, infer JsonType> ? JsonType : string | null;
66+
Desc extends GenEnum<number, infer JsonType> ? JsonType : string | null;
6767

6868
/**
6969
* Extract the value type from an extension descriptor.

0 commit comments

Comments
 (0)