@bufbuild/protobuf 2.0.0-alpha.1 → 2.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/cjs/codegenv1/embed.d.ts +2 -2
  2. package/dist/cjs/codegenv1/embed.js +25 -25
  3. package/dist/cjs/codegenv1/enum.js +2 -4
  4. package/dist/cjs/codegenv1/restore-json-names.d.ts +3 -0
  5. package/dist/cjs/codegenv1/restore-json-names.js +3 -0
  6. package/dist/cjs/codegenv1/symbols.d.ts +9 -0
  7. package/dist/cjs/codegenv1/symbols.js +9 -0
  8. package/dist/cjs/codegenv1/types.d.ts +55 -2
  9. package/dist/cjs/create.js +7 -18
  10. package/dist/cjs/desc-types.d.ts +27 -10
  11. package/dist/cjs/extensions.d.ts +21 -1
  12. package/dist/cjs/extensions.js +38 -7
  13. package/dist/cjs/fields.d.ts +17 -16
  14. package/dist/cjs/fields.js +17 -10
  15. package/dist/cjs/from-binary.js +9 -19
  16. package/dist/cjs/from-json.js +9 -13
  17. package/dist/cjs/index.d.ts +1 -1
  18. package/dist/cjs/index.js +3 -1
  19. package/dist/cjs/reflect/names.d.ts +0 -12
  20. package/dist/cjs/reflect/names.js +1 -39
  21. package/dist/cjs/reflect/nested-types.d.ts +11 -1
  22. package/dist/cjs/reflect/nested-types.js +34 -1
  23. package/dist/cjs/reflect/reflect-types.d.ts +158 -10
  24. package/dist/cjs/reflect/reflect.d.ts +11 -2
  25. package/dist/cjs/reflect/reflect.js +306 -281
  26. package/dist/cjs/reflect/registry.js +50 -41
  27. package/dist/cjs/reflect/unsafe.js +38 -43
  28. package/dist/cjs/to-binary.js +1 -3
  29. package/dist/cjs/to-json.js +7 -27
  30. package/dist/cjs/wire/base64-encoding.js +2 -2
  31. package/dist/cjs/wire/binary-encoding.d.ts +5 -3
  32. package/dist/cjs/wire/binary-encoding.js +16 -10
  33. package/dist/cjs/wkt/gen/google/protobuf/any_pb.d.ts +7 -0
  34. package/dist/cjs/wkt/gen/google/protobuf/any_pb.js +7 -2
  35. package/dist/cjs/wkt/gen/google/protobuf/api_pb.d.ts +15 -0
  36. package/dist/cjs/wkt/gen/google/protobuf/api_pb.js +15 -6
  37. package/dist/cjs/wkt/gen/google/protobuf/compiler/plugin_pb.d.ts +22 -0
  38. package/dist/cjs/wkt/gen/google/protobuf/compiler/plugin_pb.js +22 -9
  39. package/dist/cjs/wkt/gen/google/protobuf/descriptor_pb.d.ts +186 -0
  40. package/dist/cjs/wkt/gen/google/protobuf/descriptor_pb.js +186 -83
  41. package/dist/cjs/wkt/gen/google/protobuf/duration_pb.d.ts +7 -0
  42. package/dist/cjs/wkt/gen/google/protobuf/duration_pb.js +7 -2
  43. package/dist/cjs/wkt/gen/google/protobuf/empty_pb.d.ts +7 -0
  44. package/dist/cjs/wkt/gen/google/protobuf/empty_pb.js +7 -2
  45. package/dist/cjs/wkt/gen/google/protobuf/field_mask_pb.d.ts +7 -0
  46. package/dist/cjs/wkt/gen/google/protobuf/field_mask_pb.js +7 -2
  47. package/dist/cjs/wkt/gen/google/protobuf/source_context_pb.d.ts +7 -0
  48. package/dist/cjs/wkt/gen/google/protobuf/source_context_pb.js +7 -2
  49. package/dist/cjs/wkt/gen/google/protobuf/struct_pb.d.ts +18 -0
  50. package/dist/cjs/wkt/gen/google/protobuf/struct_pb.js +18 -7
  51. package/dist/cjs/wkt/gen/google/protobuf/timestamp_pb.d.ts +7 -0
  52. package/dist/cjs/wkt/gen/google/protobuf/timestamp_pb.js +7 -2
  53. package/dist/cjs/wkt/gen/google/protobuf/type_pb.d.ts +32 -0
  54. package/dist/cjs/wkt/gen/google/protobuf/type_pb.js +32 -13
  55. package/dist/cjs/wkt/gen/google/protobuf/wrappers_pb.d.ts +39 -0
  56. package/dist/cjs/wkt/gen/google/protobuf/wrappers_pb.js +39 -18
  57. package/dist/esm/codegenv1/embed.d.ts +2 -2
  58. package/dist/esm/codegenv1/embed.js +25 -25
  59. package/dist/esm/codegenv1/enum.js +2 -4
  60. package/dist/esm/codegenv1/restore-json-names.d.ts +3 -0
  61. package/dist/esm/codegenv1/restore-json-names.js +3 -0
  62. package/dist/esm/codegenv1/symbols.d.ts +9 -0
  63. package/dist/esm/codegenv1/symbols.js +9 -0
  64. package/dist/esm/codegenv1/types.d.ts +55 -2
  65. package/dist/esm/create.js +7 -18
  66. package/dist/esm/desc-types.d.ts +27 -10
  67. package/dist/esm/extensions.d.ts +21 -1
  68. package/dist/esm/extensions.js +35 -6
  69. package/dist/esm/fields.d.ts +17 -16
  70. package/dist/esm/fields.js +17 -10
  71. package/dist/esm/from-binary.js +9 -19
  72. package/dist/esm/from-json.js +11 -15
  73. package/dist/esm/index.d.ts +1 -1
  74. package/dist/esm/index.js +1 -1
  75. package/dist/esm/reflect/names.d.ts +0 -12
  76. package/dist/esm/reflect/names.js +0 -37
  77. package/dist/esm/reflect/nested-types.d.ts +11 -1
  78. package/dist/esm/reflect/nested-types.js +32 -0
  79. package/dist/esm/reflect/reflect-types.d.ts +158 -10
  80. package/dist/esm/reflect/reflect.d.ts +11 -2
  81. package/dist/esm/reflect/reflect.js +304 -279
  82. package/dist/esm/reflect/registry.js +50 -41
  83. package/dist/esm/reflect/unsafe.js +38 -43
  84. package/dist/esm/to-binary.js +1 -3
  85. package/dist/esm/to-json.js +7 -27
  86. package/dist/esm/wire/base64-encoding.js +2 -2
  87. package/dist/esm/wire/binary-encoding.d.ts +5 -3
  88. package/dist/esm/wire/binary-encoding.js +16 -10
  89. package/dist/esm/wkt/gen/google/protobuf/any_pb.d.ts +7 -0
  90. package/dist/esm/wkt/gen/google/protobuf/any_pb.js +7 -2
  91. package/dist/esm/wkt/gen/google/protobuf/api_pb.d.ts +15 -0
  92. package/dist/esm/wkt/gen/google/protobuf/api_pb.js +15 -6
  93. package/dist/esm/wkt/gen/google/protobuf/compiler/plugin_pb.d.ts +22 -0
  94. package/dist/esm/wkt/gen/google/protobuf/compiler/plugin_pb.js +22 -9
  95. package/dist/esm/wkt/gen/google/protobuf/descriptor_pb.d.ts +186 -0
  96. package/dist/esm/wkt/gen/google/protobuf/descriptor_pb.js +186 -83
  97. package/dist/esm/wkt/gen/google/protobuf/duration_pb.d.ts +7 -0
  98. package/dist/esm/wkt/gen/google/protobuf/duration_pb.js +7 -2
  99. package/dist/esm/wkt/gen/google/protobuf/empty_pb.d.ts +7 -0
  100. package/dist/esm/wkt/gen/google/protobuf/empty_pb.js +7 -2
  101. package/dist/esm/wkt/gen/google/protobuf/field_mask_pb.d.ts +7 -0
  102. package/dist/esm/wkt/gen/google/protobuf/field_mask_pb.js +7 -2
  103. package/dist/esm/wkt/gen/google/protobuf/source_context_pb.d.ts +7 -0
  104. package/dist/esm/wkt/gen/google/protobuf/source_context_pb.js +7 -2
  105. package/dist/esm/wkt/gen/google/protobuf/struct_pb.d.ts +18 -0
  106. package/dist/esm/wkt/gen/google/protobuf/struct_pb.js +18 -7
  107. package/dist/esm/wkt/gen/google/protobuf/timestamp_pb.d.ts +7 -0
  108. package/dist/esm/wkt/gen/google/protobuf/timestamp_pb.js +7 -2
  109. package/dist/esm/wkt/gen/google/protobuf/type_pb.d.ts +32 -0
  110. package/dist/esm/wkt/gen/google/protobuf/type_pb.js +32 -13
  111. package/dist/esm/wkt/gen/google/protobuf/wrappers_pb.d.ts +39 -0
  112. package/dist/esm/wkt/gen/google/protobuf/wrappers_pb.js +39 -18
  113. package/package.json +2 -2
@@ -16,6 +16,7 @@ import { parseTextFormatEnumValue, parseTextFormatScalarValue, } from "../wire/t
16
16
  import { LongType, ScalarType } from "./scalar.js";
17
17
  import { nestedTypes } from "./nested-types.js";
18
18
  import { unsafeIsSetExplicit } from "./unsafe.js";
19
+ import { protoCamelCase, safeObjectProperty } from "./names.js";
19
20
  /**
20
21
  * Create a registry from the given inputs.
21
22
  *
@@ -200,8 +201,6 @@ const TYPE_BYTES = 12;
200
201
  const TYPE_ENUM = 14;
201
202
  // bootstrap-inject google.protobuf.FieldDescriptorProto.Label.LABEL_REPEATED: const $name: FieldDescriptorProto_Label.$localName = $number;
202
203
  const LABEL_REPEATED = 3;
203
- // bootstrap-inject google.protobuf.FieldDescriptorProto.Label.LABEL_OPTIONAL: const $name: FieldDescriptorProto_Label.$localName = $number;
204
- const LABEL_OPTIONAL = 1;
205
204
  // bootstrap-inject google.protobuf.FieldDescriptorProto.Label.LABEL_REQUIRED: const $name: FieldDescriptorProto_Label.$localName = $number;
206
205
  const LABEL_REQUIRED = 2;
207
206
  // bootstrap-inject google.protobuf.FieldOptions.JSType.JS_STRING: const $name: FieldOptions_JSType.$localName = $number;
@@ -210,6 +209,8 @@ const JS_STRING = 1;
210
209
  const IDEMPOTENCY_UNKNOWN = 0;
211
210
  // bootstrap-inject google.protobuf.FeatureSet.FieldPresence.EXPLICIT: const $name: FeatureSet_FieldPresence.$localName = $number;
212
211
  const EXPLICIT = 1;
212
+ // bootstrap-inject google.protobuf.FeatureSet.FieldPresence.IMPLICIT: const $name: FeatureSet_FieldPresence.$localName = $number;
213
+ const IMPLICIT = 2;
213
214
  // bootstrap-inject google.protobuf.FeatureSet.FieldPresence.LEGACY_REQUIRED: const $name: FeatureSet_FieldPresence.$localName = $number;
214
215
  const LEGACY_REQUIRED = 3;
215
216
  // bootstrap-inject google.protobuf.FeatureSet.RepeatedFieldEncoding.PACKED: const $name: FeatureSet_RepeatedFieldEncoding.$localName = $number;
@@ -220,7 +221,7 @@ const DELIMITED = 2;
220
221
  const OPEN = 1;
221
222
  // prettier-ignore
222
223
  // bootstrap-inject defaults: EDITION_PROTO2 to EDITION_2023: export const minimumEdition: SupportedEdition = $minimumEdition, maximumEdition: SupportedEdition = $maximumEdition;
223
- // generated from protoc v27.0-rc1
224
+ // generated from protoc v27.0-rc2
224
225
  export const minimumEdition = 998, maximumEdition = 1000;
225
226
  const featureDefaults = {
226
227
  // EDITION_PROTO2
@@ -261,7 +262,7 @@ function addFile(proto, reg) {
261
262
  proto,
262
263
  deprecated: (_b = (_a = proto.options) === null || _a === void 0 ? void 0 : _a.deprecated) !== null && _b !== void 0 ? _b : false,
263
264
  edition: getFileEdition(proto),
264
- name: proto.name.replace(/\.proto/, ""),
265
+ name: proto.name.replace(/\.proto$/, ""),
265
266
  dependencies: findFileDependencies(proto, reg),
266
267
  enums: [],
267
268
  messages: [],
@@ -269,7 +270,7 @@ function addFile(proto, reg) {
269
270
  services: [],
270
271
  toString() {
271
272
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- we asserted above
272
- return `file ${this.proto.name}`;
273
+ return `file ${proto.name}`;
273
274
  },
274
275
  };
275
276
  const mapEntriesStore = new Map();
@@ -340,6 +341,7 @@ function addFields(message, reg, mapEntries) {
340
341
  const oneof = findOneof(proto, allOneofs);
341
342
  const field = newField(proto, message, reg, oneof, mapEntries);
342
343
  message.fields.push(field);
344
+ message.field[field.localName] = field;
343
345
  if (oneof === undefined) {
344
346
  message.members.push(field);
345
347
  }
@@ -364,6 +366,7 @@ function addFields(message, reg, mapEntries) {
364
366
  */
365
367
  function addEnum(proto, file, parent, reg) {
366
368
  var _a, _b, _c;
369
+ const sharedPrefix = findEnumSharedPrefix(proto.name, proto.value);
367
370
  const desc = {
368
371
  kind: "enum",
369
372
  proto,
@@ -374,7 +377,7 @@ function addEnum(proto, file, parent, reg) {
374
377
  name: proto.name,
375
378
  typeName: makeTypeName(proto, parent, file),
376
379
  values: [],
377
- sharedPrefix: findEnumSharedPrefix(proto.name, proto.value.map((v) => v.name)),
380
+ sharedPrefix,
378
381
  toString() {
379
382
  return `enum ${this.typeName}`;
380
383
  },
@@ -383,12 +386,14 @@ function addEnum(proto, file, parent, reg) {
383
386
  reg.add(desc);
384
387
  proto.value.forEach((proto) => {
385
388
  var _a, _b;
389
+ const name = proto.name;
386
390
  desc.values.push({
387
391
  kind: "enum_value",
388
392
  proto,
389
393
  deprecated: (_b = (_a = proto.options) === null || _a === void 0 ? void 0 : _a.deprecated) !== null && _b !== void 0 ? _b : false,
390
394
  parent: desc,
391
395
  name: proto.name,
396
+ localName: safeObjectProperty(sharedPrefix == undefined ? name : name.substring(sharedPrefix.length)),
392
397
  number: proto.number,
393
398
  toString() {
394
399
  return `enum value ${desc.typeName}.${this.name}`;
@@ -412,6 +417,7 @@ function addMessage(proto, file, parent, reg, mapEntries) {
412
417
  name: proto.name,
413
418
  typeName: makeTypeName(proto, parent, file),
414
419
  fields: [],
420
+ field: {},
415
421
  oneofs: [],
416
422
  members: [],
417
423
  nestedEnums: [],
@@ -488,6 +494,9 @@ function newMethod(proto, parent, reg) {
488
494
  deprecated: (_b = (_a = proto.options) === null || _a === void 0 ? void 0 : _a.deprecated) !== null && _b !== void 0 ? _b : false,
489
495
  parent,
490
496
  name,
497
+ localName: safeObjectProperty(name.length
498
+ ? safeObjectProperty(name[0].toLowerCase() + name.substring(1))
499
+ : name),
491
500
  methodKind,
492
501
  input,
493
502
  output,
@@ -508,6 +517,7 @@ function newOneof(proto, parent) {
508
517
  parent,
509
518
  fields: [],
510
519
  name: proto.name,
520
+ localName: safeObjectProperty(protoCamelCase(proto.name)),
511
521
  toString() {
512
522
  return `oneof ${parent.typeName}.${this.name}`;
513
523
  },
@@ -515,7 +525,9 @@ function newOneof(proto, parent) {
515
525
  }
516
526
  function newField(proto, parentOrFile, reg, oneof, mapEntries) {
517
527
  var _a, _b, _c;
528
+ const isExtension = mapEntries === undefined;
518
529
  const field = {
530
+ kind: "field",
519
531
  proto,
520
532
  deprecated: (_b = (_a = proto.options) === null || _a === void 0 ? void 0 : _a.deprecated) !== null && _b !== void 0 ? _b : false,
521
533
  name: proto.name,
@@ -523,8 +535,16 @@ function newField(proto, parentOrFile, reg, oneof, mapEntries) {
523
535
  scalar: undefined,
524
536
  message: undefined,
525
537
  enum: undefined,
538
+ presence: getFieldPresence(proto, oneof, isExtension, parentOrFile),
539
+ listKind: undefined,
540
+ mapKind: undefined,
541
+ mapKey: undefined,
542
+ delimitedEncoding: undefined,
543
+ packed: undefined,
544
+ longType: undefined,
545
+ getDefaultValue: undefined,
526
546
  };
527
- if (mapEntries === undefined) {
547
+ if (isExtension) {
528
548
  // extension field
529
549
  const file = parentOrFile.kind == "file" ? parentOrFile : parentOrFile.file;
530
550
  const parent = parentOrFile.kind == "file" ? undefined : parentOrFile;
@@ -544,9 +564,11 @@ function newField(proto, parentOrFile, reg, oneof, mapEntries) {
544
564
  // regular field
545
565
  const parent = parentOrFile;
546
566
  assert(parent.kind == "message");
547
- field.kind = "field";
548
567
  field.parent = parent;
549
568
  field.oneof = oneof;
569
+ field.localName = oneof
570
+ ? protoCamelCase(proto.name)
571
+ : safeObjectProperty(protoCamelCase(proto.name));
550
572
  field.jsonName = proto.jsonName;
551
573
  field.toString = () => `field ${parent.typeName}.${proto.name}`;
552
574
  }
@@ -567,7 +589,7 @@ function newField(proto, parentOrFile, reg, oneof, mapEntries) {
567
589
  assert(keyField.scalar != ScalarType.BYTES &&
568
590
  keyField.scalar != ScalarType.FLOAT &&
569
591
  keyField.scalar != ScalarType.DOUBLE);
570
- const valueField = mapEntry.fields.find((f) => f.proto.number === 2);
592
+ const valueField = mapEntry.fields.find((f) => f.number === 2);
571
593
  assert(valueField);
572
594
  assert(valueField.fieldKind != "list" && valueField.fieldKind != "map");
573
595
  field.mapKey = keyField.scalar;
@@ -637,8 +659,6 @@ function newField(proto, parentOrFile, reg, oneof, mapEntries) {
637
659
  break;
638
660
  }
639
661
  }
640
- field.presence = getFieldPresence(proto, oneof, parentOrFile);
641
- field.optional = isOptionalField(field);
642
662
  return field;
643
663
  }
644
664
  /**
@@ -677,13 +697,13 @@ function findFileDependencies(proto, reg) {
677
697
  * Finds a prefix shared by enum values, for example `my_enum_` for
678
698
  * `enum MyEnum {MY_ENUM_A=0; MY_ENUM_B=1;}`.
679
699
  */
680
- function findEnumSharedPrefix(enumName, valueNames) {
700
+ function findEnumSharedPrefix(enumName, values) {
681
701
  const prefix = camelToSnakeCase(enumName) + "_";
682
- for (const name of valueNames) {
683
- if (!name.toLowerCase().startsWith(prefix)) {
702
+ for (const value of values) {
703
+ if (!value.name.toLowerCase().startsWith(prefix)) {
684
704
  return undefined;
685
705
  }
686
- const shortName = name.substring(prefix.length);
706
+ const shortName = value.name.substring(prefix.length);
687
707
  if (shortName.length == 0) {
688
708
  return undefined;
689
709
  }
@@ -755,39 +775,28 @@ function findOneof(proto, allOneofs) {
755
775
  * Presence of the field.
756
776
  * See https://protobuf.dev/programming-guides/field_presence/
757
777
  */
758
- function getFieldPresence(proto, oneof, parent) {
778
+ function getFieldPresence(proto, oneof, isExtension, parent) {
759
779
  if (proto.label == LABEL_REQUIRED) {
760
780
  // proto2 required is LEGACY_REQUIRED
761
781
  return LEGACY_REQUIRED;
762
782
  }
763
- const { edition } = parent.kind == "message" ? parent.file : parent;
764
- if (edition == EDITION_PROTO3) {
765
- // proto3 oneof and optional are explicit
766
- if (oneof != undefined || proto.proto3Optional) {
767
- return EXPLICIT;
768
- }
769
- // proto3 singular message is explicit
770
- const singularMessage = proto.label != LABEL_REPEATED && proto.type == TYPE_MESSAGE;
771
- if (singularMessage) {
772
- return EXPLICIT;
773
- }
783
+ if (proto.label == LABEL_REPEATED) {
784
+ // repeated fields (including maps) do not track presence
785
+ return IMPLICIT;
774
786
  }
775
- // also resolves proto2/proto3 defaults
776
- return resolveFeature("fieldPresence", { proto, parent });
777
- }
778
- /**
779
- * Did the user use the `optional` keyword?
780
- */
781
- function isOptionalField(field) {
782
- const edition = (field.kind == "extension" ? field.file : field.parent.file)
783
- .edition;
784
- if (edition == EDITION_PROTO2) {
785
- return !field.oneof && field.proto.label == LABEL_OPTIONAL;
787
+ if (!!oneof || proto.proto3Optional) {
788
+ // oneof is always explicit
789
+ return EXPLICIT;
786
790
  }
787
- if (edition == EDITION_PROTO3) {
788
- return field.proto.proto3Optional;
791
+ if (proto.type == TYPE_MESSAGE) {
792
+ // singular message field cannot be implicit
793
+ return EXPLICIT;
789
794
  }
790
- return false;
795
+ if (isExtension) {
796
+ // extensions always track presence
797
+ return EXPLICIT;
798
+ }
799
+ return resolveFeature("fieldPresence", { proto, parent });
791
800
  }
792
801
  /**
793
802
  * Pack this repeated field?
@@ -11,7 +11,6 @@
11
11
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
- import { localName } from "./names.js";
15
14
  import { isScalarZeroValue, scalarZeroValue } from "./scalar.js";
16
15
  // bootstrap-inject google.protobuf.FeatureSet.FieldPresence.IMPLICIT: const $name: FeatureSet_FieldPresence.$localName = $number;
17
16
  const IMPLICIT = 2;
@@ -23,11 +22,11 @@ export const unsafeLocal = Symbol.for("reflect unsafe local");
23
22
  */
24
23
  export function unsafeOneofCase(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
25
24
  oneof) {
26
- const c = target[localName(oneof)].case;
25
+ const c = target[oneof.localName].case;
27
26
  if (c === undefined) {
28
27
  return c;
29
28
  }
30
- return oneof.fields.find((f) => localName(f) === c);
29
+ return oneof.fields.find((f) => f.localName === c);
31
30
  }
32
31
  /**
33
32
  * Returns true if the field is set.
@@ -36,28 +35,28 @@ oneof) {
36
35
  */
37
36
  export function unsafeIsSet(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
38
37
  field) {
39
- const name = localName(field);
38
+ const name = field.localName;
40
39
  if (field.oneof) {
41
- return target[localName(field.oneof)].case === name; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
40
+ return target[field.oneof.localName].case === name; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
42
41
  }
42
+ if (field.presence != IMPLICIT) {
43
+ // Fields with explicit presence have properties on the prototype chain
44
+ // for default / zero values (except for proto3).
45
+ return (target[name] !== undefined &&
46
+ Object.prototype.hasOwnProperty.call(target, name));
47
+ }
48
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
43
49
  switch (field.fieldKind) {
44
- case "message":
45
- return target[name] !== undefined;
46
50
  case "list":
47
51
  return target[name].length > 0;
48
52
  case "map":
49
53
  return Object.keys(target[name]).length > 0; // eslint-disable-line @typescript-eslint/no-unsafe-argument
50
- default:
51
- if (field.presence == IMPLICIT) {
52
- if (field.fieldKind == "enum") {
53
- return target[name] !== field.enum.values[0].number;
54
- }
55
- return !isScalarZeroValue(field.scalar, target[name]);
56
- }
57
- // EXPLICIT and LEGACY_REQUIRED
58
- return (target[name] !== undefined &&
59
- Object.prototype.hasOwnProperty.call(target, name));
54
+ case "scalar":
55
+ return !isScalarZeroValue(field.scalar, target[name]);
56
+ case "enum":
57
+ return target[name] !== field.enum.values[0].number;
60
58
  }
59
+ throw new Error("message field with implicit presence");
61
60
  }
62
61
  /**
63
62
  * Returns true if the field is set, but only for singular fields with explicit
@@ -75,15 +74,14 @@ export function unsafeIsSetExplicit(target, localName) {
75
74
  * @private
76
75
  */
77
76
  export function unsafeGet(target, field) {
78
- const name = localName(field);
79
77
  if (field.oneof) {
80
- const oneof = target[localName(field.oneof)];
81
- if (oneof.case === name) {
78
+ const oneof = target[field.oneof.localName];
79
+ if (oneof.case === field.localName) {
82
80
  return oneof.value;
83
81
  }
84
82
  return undefined;
85
83
  }
86
- return target[name];
84
+ return target[field.localName];
87
85
  }
88
86
  /**
89
87
  * Set a field value, respecting oneof groups.
@@ -91,15 +89,14 @@ export function unsafeGet(target, field) {
91
89
  * @private
92
90
  */
93
91
  export function unsafeSet(target, field, value) {
94
- const name = localName(field);
95
92
  if (field.oneof) {
96
- target[localName(field.oneof)] = {
97
- case: name,
93
+ target[field.oneof.localName] = {
94
+ case: field.localName,
98
95
  value: value,
99
96
  };
100
97
  }
101
98
  else {
102
- target[name] = value;
99
+ target[field.localName] = value;
103
100
  }
104
101
  }
105
102
  /**
@@ -109,14 +106,21 @@ export function unsafeSet(target, field, value) {
109
106
  */
110
107
  export function unsafeClear(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
111
108
  field) {
112
- const name = localName(field);
109
+ const name = field.localName;
113
110
  if (field.oneof) {
114
- const oneofLocalName = localName(field.oneof);
111
+ const oneofLocalName = field.oneof.localName;
115
112
  if (target[oneofLocalName].case === name) {
116
113
  target[oneofLocalName] = { case: undefined };
117
114
  }
118
115
  }
116
+ else if (field.presence != IMPLICIT) {
117
+ // Fields with explicit presence have properties on the prototype chain
118
+ // for default / zero values (except for proto3). By deleting their own
119
+ // property, the field is reset.
120
+ delete target[name];
121
+ }
119
122
  else {
123
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
120
124
  switch (field.fieldKind) {
121
125
  case "map":
122
126
  target[name] = {};
@@ -124,19 +128,12 @@ field) {
124
128
  case "list":
125
129
  target[name] = [];
126
130
  break;
127
- case "message":
128
- delete target[name];
131
+ case "enum":
132
+ target[name] = field.enum.values[0].number;
133
+ break;
134
+ case "scalar":
135
+ target[name] = scalarZeroValue(field.scalar, field.longType);
129
136
  break;
130
- default:
131
- if (field.presence == IMPLICIT) {
132
- target[name] =
133
- field.fieldKind == "enum"
134
- ? field.enum.values[0].number
135
- : scalarZeroValue(field.scalar, field.longType);
136
- }
137
- else {
138
- delete target[name];
139
- }
140
137
  }
141
138
  }
142
139
  }
@@ -146,8 +143,7 @@ field) {
146
143
  * @private
147
144
  */
148
145
  export function unsafeAddListItem(target, field, value) {
149
- const name = localName(field);
150
- target[name].push(value);
146
+ target[field.localName].push(value);
151
147
  }
152
148
  /**
153
149
  * Set a map entry.
@@ -155,6 +151,5 @@ export function unsafeAddListItem(target, field, value) {
155
151
  * @private
156
152
  */
157
153
  export function unsafeSetMapEntry(target, field, key, value) {
158
- const name = localName(field);
159
- target[name][key] = value;
154
+ target[field.localName][key] = value;
160
155
  }
@@ -30,9 +30,7 @@ function writeFields(writer, opts, msg) {
30
30
  var _a;
31
31
  for (const f of msg.sortedFields) {
32
32
  if (!msg.isSet(f)) {
33
- if (f.fieldKind != "map" &&
34
- f.fieldKind != "list" &&
35
- f.presence == LEGACY_REQUIRED) {
33
+ if (f.presence == LEGACY_REQUIRED) {
36
34
  throw new Error(`cannot encode field ${msg.desc.typeName}.${f.name} to binary: required field not set`);
37
35
  }
38
36
  continue;
@@ -21,8 +21,8 @@ import { base64Encode } from "./wire/index.js";
21
21
  import { createExtensionContainer, getExtension } from "./extensions.js";
22
22
  // bootstrap-inject google.protobuf.FeatureSet.FieldPresence.LEGACY_REQUIRED: const $name: FeatureSet_FieldPresence.$localName = $number;
23
23
  const LEGACY_REQUIRED = 3;
24
- // bootstrap-inject google.protobuf.FieldDescriptorProto.Label.LABEL_OPTIONAL: const $name: FieldDescriptorProto_Label.$localName = $number;
25
- const LABEL_OPTIONAL = 1;
24
+ // bootstrap-inject google.protobuf.FeatureSet.FieldPresence.IMPLICIT: const $name: FeatureSet_FieldPresence.$localName = $number;
25
+ const IMPLICIT = 2;
26
26
  // Default options for serializing to JSON.
27
27
  const jsonWriteDefaults = {
28
28
  emitDefaultValues: false,
@@ -55,15 +55,11 @@ function reflectToJson(msg, opts) {
55
55
  const json = {};
56
56
  for (const f of msg.sortedFields) {
57
57
  if (!msg.isSet(f)) {
58
- if (f.fieldKind != "map" &&
59
- f.fieldKind != "list" &&
60
- f.presence == LEGACY_REQUIRED) {
58
+ if (f.presence == LEGACY_REQUIRED) {
61
59
  throw new Error(`cannot encode field ${msg.desc.typeName}.${f.name} to binary: required field not set`);
62
60
  }
63
- if (!opts.emitDefaultValues) {
64
- continue;
65
- }
66
- if (!canEmitFieldDefaultValue(f)) {
61
+ if (!opts.emitDefaultValues || f.presence !== IMPLICIT) {
62
+ // Fields with implicit presence omit zero values (e.g. empty string) by default
67
63
  continue;
68
64
  }
69
65
  }
@@ -85,8 +81,8 @@ function reflectToJson(msg, opts) {
85
81
  continue;
86
82
  }
87
83
  const value = getExtension(msg.message, extension);
88
- const [, field] = createExtensionContainer(extension);
89
- const jsonValue = fieldToJson(field, value, opts);
84
+ const [container, field] = createExtensionContainer(extension, value);
85
+ const jsonValue = fieldToJson(field, container.get(field), opts);
90
86
  if (jsonValue !== undefined) {
91
87
  json[extension.jsonName] = jsonValue;
92
88
  }
@@ -214,22 +210,6 @@ function scalarToJson(type, value) {
214
210
  return base64Encode(value);
215
211
  }
216
212
  }
217
- // Decide whether an unset field should be emitted with JSON write option `emitDefaultValues`
218
- function canEmitFieldDefaultValue(field) {
219
- switch (true) {
220
- // oneof fields are never emitted
221
- case field.oneof !== undefined:
222
- // singular message field are allowed to emit JSON null, but we do not
223
- // eslint-disable-next-line no-fallthrough
224
- case field.fieldKind === "message":
225
- // the field uses explicit presence, so we cannot emit a zero value
226
- // eslint-disable-next-line no-fallthrough
227
- case field.proto.label === LABEL_OPTIONAL:
228
- return false;
229
- default:
230
- return true;
231
- }
232
- }
233
213
  function jsonName(f, opts) {
234
214
  return opts.useProtoFieldName ? f.name : f.jsonName;
235
215
  }
@@ -39,10 +39,10 @@ export function base64Decode(base64Str) {
39
39
  b = table[base64Str.charCodeAt(i)];
40
40
  if (b === undefined) {
41
41
  switch (base64Str[i]) {
42
- // @ts-ignore TS7029: Fallthrough case in switch
42
+ // @ts-expect-error TS7029: Fallthrough case in switch
43
43
  case "=":
44
44
  groupPos = 0; // reset state when padding found
45
- // @ts-ignore TS7029: Fallthrough case in switch
45
+ // eslint-disable-next-line no-fallthrough
46
46
  case "\n":
47
47
  case "\r":
48
48
  case "\t":
@@ -170,10 +170,12 @@ export declare class BinaryReader {
170
170
  */
171
171
  tag(): [number, WireType];
172
172
  /**
173
- * Skip one element on the wire and return the skipped data.
174
- * Supports WireType.StartGroup since v2.0.0-alpha.23.
173
+ * Skip one element and return the skipped data.
174
+ *
175
+ * When skipping StartGroup, provide the tags field number to check for
176
+ * matching field number in the EndGroup tag.
175
177
  */
176
- skip(wireType: WireType): Uint8Array;
178
+ skip(wireType: WireType, fieldNo?: number): Uint8Array;
177
179
  protected varint64: () => [number, number];
178
180
  /**
179
181
  * Throws error if position in byte array is out of range.
@@ -291,10 +291,12 @@ export class BinaryReader {
291
291
  return [fieldNo, wireType];
292
292
  }
293
293
  /**
294
- * Skip one element on the wire and return the skipped data.
295
- * Supports WireType.StartGroup since v2.0.0-alpha.23.
294
+ * Skip one element and return the skipped data.
295
+ *
296
+ * When skipping StartGroup, provide the tags field number to check for
297
+ * matching field number in the EndGroup tag.
296
298
  */
297
- skip(wireType) {
299
+ skip(wireType, fieldNo) {
298
300
  let start = this.pos;
299
301
  switch (wireType) {
300
302
  case WireType.Varint:
@@ -303,11 +305,10 @@ export class BinaryReader {
303
305
  }
304
306
  break;
305
307
  // eslint-disable-next-line
306
- // @ts-ignore TS7029: Fallthrough case in switch
308
+ // @ts-expect-error TS7029: Fallthrough case in switch
307
309
  case WireType.Bit64:
308
310
  this.pos += 4;
309
- // eslint-disable-next-line
310
- // @ts-ignore TS7029: Fallthrough case in switch
311
+ // eslint-disable-next-line no-fallthrough
311
312
  case WireType.Bit32:
312
313
  this.pos += 4;
313
314
  break;
@@ -316,10 +317,15 @@ export class BinaryReader {
316
317
  this.pos += len;
317
318
  break;
318
319
  case WireType.StartGroup:
319
- // TODO check for matching field numbers in StartGroup / EndGroup tags
320
- let t;
321
- while ((t = this.tag()[1]) !== WireType.EndGroup) {
322
- this.skip(t);
320
+ for (;;) {
321
+ const [fn, wt] = this.tag();
322
+ if (wt === WireType.EndGroup) {
323
+ if (fieldNo !== undefined && fn !== fieldNo) {
324
+ throw new Error("invalid end group tag");
325
+ }
326
+ break;
327
+ }
328
+ this.skip(wt, fn);
323
329
  }
324
330
  break;
325
331
  default:
@@ -1,5 +1,8 @@
1
1
  import type { GenDescFile, GenDescMessage } from "../../../../codegenv1/types.js";
2
2
  import type { Message } from "../../../../types.js";
3
+ /**
4
+ * Describes the file google/protobuf/any.proto.
5
+ */
3
6
  export declare const fileDesc_google_protobuf_any: GenDescFile;
4
7
  /**
5
8
  * `Any` contains an arbitrary serialized protocol buffer message along with a
@@ -133,4 +136,8 @@ export type Any = Message<"google.protobuf.Any"> & {
133
136
  */
134
137
  value: Uint8Array;
135
138
  };
139
+ /**
140
+ * Describes the message google.protobuf.Any.
141
+ * Use `create(AnyDesc)` to create a new message.
142
+ */
136
143
  export declare const AnyDesc: GenDescMessage<Any>;
@@ -13,7 +13,12 @@
13
13
  // limitations under the License.
14
14
  import { fileDesc } from "../../../../codegenv1/file.js";
15
15
  import { messageDesc } from "../../../../codegenv1/message.js";
16
+ /**
17
+ * Describes the file google/protobuf/any.proto.
18
+ */
16
19
  export const fileDesc_google_protobuf_any = /*@__PURE__*/ fileDesc("Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYiJgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnYKE2NvbS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaLGdvb2dsZS5nb2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2tub3duL2FueXBiogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM");
17
- // Describes the message google.protobuf.Any.
18
- // Use `create(AnyDesc)` to create a new Any.
20
+ /**
21
+ * Describes the message google.protobuf.Any.
22
+ * Use `create(AnyDesc)` to create a new message.
23
+ */
19
24
  export const AnyDesc = /*@__PURE__*/ messageDesc(fileDesc_google_protobuf_any, 0);
@@ -2,6 +2,9 @@ import type { GenDescFile, GenDescMessage } from "../../../../codegenv1/types.js
2
2
  import type { SourceContext } from "./source_context_pb.js";
3
3
  import type { Option, Syntax } from "./type_pb.js";
4
4
  import type { Message } from "../../../../types.js";
5
+ /**
6
+ * Describes the file google/protobuf/api.proto.
7
+ */
5
8
  export declare const fileDesc_google_protobuf_api: GenDescFile;
6
9
  /**
7
10
  * Api is a light-weight descriptor for an API Interface.
@@ -81,6 +84,10 @@ export type Api = Message<"google.protobuf.Api"> & {
81
84
  */
82
85
  syntax: Syntax;
83
86
  };
87
+ /**
88
+ * Describes the message google.protobuf.Api.
89
+ * Use `create(ApiDesc)` to create a new message.
90
+ */
84
91
  export declare const ApiDesc: GenDescMessage<Api>;
85
92
  /**
86
93
  * Method represents a method of an API interface.
@@ -131,6 +138,10 @@ export type Method = Message<"google.protobuf.Method"> & {
131
138
  */
132
139
  syntax: Syntax;
133
140
  };
141
+ /**
142
+ * Describes the message google.protobuf.Method.
143
+ * Use `create(MethodDesc)` to create a new message.
144
+ */
134
145
  export declare const MethodDesc: GenDescMessage<Method>;
135
146
  /**
136
147
  * Declares an API Interface to be included in this interface. The including
@@ -229,4 +240,8 @@ export type Mixin = Message<"google.protobuf.Mixin"> & {
229
240
  */
230
241
  root: string;
231
242
  };
243
+ /**
244
+ * Describes the message google.protobuf.Mixin.
245
+ * Use `create(MixinDesc)` to create a new message.
246
+ */
232
247
  export declare const MixinDesc: GenDescMessage<Mixin>;