protobufjs 7.4.0 → 8.0.1-experimental

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.
package/dist/protobuf.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * protobuf.js v7.4.0 (c) 2016, daniel wirtz
3
- * compiled thu, 22 aug 2024 20:30:39 utc
2
+ * protobuf.js v8.0.1-experimental (c) 2016, daniel wirtz
3
+ * compiled mon, 24 mar 2025 19:22:52 utc
4
4
  * licensed under the bsd-3-clause license
5
5
  * see: https://github.com/dcodeio/protobuf.js for details
6
6
  */
@@ -1831,16 +1831,14 @@ function missing(field) {
1831
1831
  */
1832
1832
  function decoder(mtype) {
1833
1833
  /* eslint-disable no-unexpected-multiline */
1834
- var gen = util.codegen(["r", "l"], mtype.name + "$decode")
1834
+ var gen = util.codegen(["r", "l", "e"], mtype.name + "$decode")
1835
1835
  ("if(!(r instanceof Reader))")
1836
1836
  ("r=Reader.create(r)")
1837
1837
  ("var c=l===undefined?r.len:r.pos+l,m=new this.ctor" + (mtype.fieldsArray.filter(function(field) { return field.map; }).length ? ",k,value" : ""))
1838
1838
  ("while(r.pos<c){")
1839
- ("var t=r.uint32()");
1840
- if (mtype.group) gen
1841
- ("if((t&7)===4)")
1842
- ("break");
1843
- gen
1839
+ ("var t=r.uint32()")
1840
+ ("if(t===e)")
1841
+ ("break")
1844
1842
  ("switch(t>>>3){");
1845
1843
 
1846
1844
  var i = 0;
@@ -1906,15 +1904,15 @@ function decoder(mtype) {
1906
1904
  ("}else");
1907
1905
 
1908
1906
  // Non-packed
1909
- if (types.basic[type] === undefined) gen(field.resolvedType.group
1910
- ? "%s.push(types[%i].decode(r))"
1907
+ if (types.basic[type] === undefined) gen(field.delimited
1908
+ ? "%s.push(types[%i].decode(r,undefined,((t&~7)|4)))"
1911
1909
  : "%s.push(types[%i].decode(r,r.uint32()))", ref, i);
1912
1910
  else gen
1913
1911
  ("%s.push(r.%s())", ref, type);
1914
1912
 
1915
1913
  // Non-repeated
1916
- } else if (types.basic[type] === undefined) gen(field.resolvedType.group
1917
- ? "%s=types[%i].decode(r)"
1914
+ } else if (types.basic[type] === undefined) gen(field.delimited
1915
+ ? "%s=types[%i].decode(r,undefined,((t&~7)|4))"
1918
1916
  : "%s=types[%i].decode(r,r.uint32())", ref, i);
1919
1917
  else gen
1920
1918
  ("%s=r.%s()", ref, type);
@@ -1961,7 +1959,7 @@ var Enum = require(15),
1961
1959
  * @ignore
1962
1960
  */
1963
1961
  function genTypePartial(gen, field, fieldIndex, ref) {
1964
- return field.resolvedType.group
1962
+ return field.delimited
1965
1963
  ? gen("types[%i].encode(%s,w.uint32(%i)).uint32(%i)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0)
1966
1964
  : gen("types[%i].encode(%s,w.uint32(%i).fork()).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0);
1967
1965
  }
@@ -2104,6 +2102,18 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
2104
2102
  */
2105
2103
  this.valuesOptions = valuesOptions;
2106
2104
 
2105
+ /**
2106
+ * Resolved values features, if any
2107
+ * @type {Object<string, Object<string, *>>|undefined}
2108
+ */
2109
+ this._valuesFeatures = {};
2110
+
2111
+ /**
2112
+ * Unresolved values features, if any
2113
+ * @type {Object<string, Object<string, *>>|undefined}
2114
+ */
2115
+ this._valuesProtoFeatures = {};
2116
+
2107
2117
  /**
2108
2118
  * Reserved ranges, if any.
2109
2119
  * @type {Array.<number[]|string>}
@@ -2120,6 +2130,22 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
2120
2130
  this.valuesById[ this.values[keys[i]] = values[keys[i]] ] = keys[i];
2121
2131
  }
2122
2132
 
2133
+ /**
2134
+ * Resolves value features
2135
+ * @returns {Enum} `this`
2136
+ */
2137
+ Enum.prototype.resolve = function resolve() {
2138
+ ReflectionObject.prototype.resolve.call(this);
2139
+
2140
+ for (var key of Object.keys(this._valuesProtoFeatures)) {
2141
+ var parentFeaturesCopy = Object.assign({}, this._features);
2142
+ this._valuesFeatures[key] = Object.assign(parentFeaturesCopy, this._valuesProtoFeatures[key] || {});
2143
+ }
2144
+
2145
+ return this;
2146
+ };
2147
+
2148
+
2123
2149
  /**
2124
2150
  * Enum descriptor.
2125
2151
  * @interface IEnum
@@ -2196,6 +2222,21 @@ Enum.prototype.add = function add(name, id, comment, options) {
2196
2222
  if (this.valuesOptions === undefined)
2197
2223
  this.valuesOptions = {};
2198
2224
  this.valuesOptions[name] = options || null;
2225
+
2226
+ for (var key of Object.keys(this.valuesOptions)) {
2227
+ var features = Array.isArray(this.valuesOptions[key]) ? this.valuesOptions[key].find(x => {return Object.prototype.hasOwnProperty.call(x, "features");}) : this.valuesOptions[key] === "features";
2228
+ if (features) {
2229
+ this._valuesProtoFeatures[key] = features.features;
2230
+ } else {
2231
+ this._valuesProtoFeatures[key] = {};
2232
+ }
2233
+ }
2234
+ }
2235
+
2236
+ for (var enumValue of Object.keys(this.values)) {
2237
+ if (!this._valuesProtoFeatures[enumValue]) {
2238
+ this._valuesProtoFeatures[enumValue] = {};
2239
+ }
2199
2240
  }
2200
2241
 
2201
2242
  this.comments[name] = comment || null;
@@ -2353,18 +2394,6 @@ function Field(name, id, type, rule, extend, options, comment) {
2353
2394
  */
2354
2395
  this.extend = extend || undefined; // toJSON
2355
2396
 
2356
- /**
2357
- * Whether this field is required.
2358
- * @type {boolean}
2359
- */
2360
- this.required = rule === "required";
2361
-
2362
- /**
2363
- * Whether this field is optional.
2364
- * @type {boolean}
2365
- */
2366
- this.optional = !this.required;
2367
-
2368
2397
  /**
2369
2398
  * Whether this field is repeated.
2370
2399
  * @type {boolean}
@@ -2431,13 +2460,6 @@ function Field(name, id, type, rule, extend, options, comment) {
2431
2460
  */
2432
2461
  this.declaringField = null;
2433
2462
 
2434
- /**
2435
- * Internally remembers whether this field is packed.
2436
- * @type {boolean|null}
2437
- * @private
2438
- */
2439
- this._packed = null;
2440
-
2441
2463
  /**
2442
2464
  * Comment for this field.
2443
2465
  * @type {string|null}
@@ -2446,17 +2468,69 @@ function Field(name, id, type, rule, extend, options, comment) {
2446
2468
  }
2447
2469
 
2448
2470
  /**
2449
- * Determines whether this field is packed. Only relevant when repeated and working with proto2.
2471
+ * Determines whether this field is required.
2472
+ * @name Field#required
2473
+ * @type {boolean}
2474
+ * @readonly
2475
+ */
2476
+ Object.defineProperty(Field.prototype, "required", {
2477
+ get: function() {
2478
+ return this._features.field_presence === "LEGACY_REQUIRED";
2479
+ }
2480
+ });
2481
+
2482
+ /**
2483
+ * Determines whether this field is not required.
2484
+ * @name Field#optional
2485
+ * @type {boolean}
2486
+ * @readonly
2487
+ */
2488
+ Object.defineProperty(Field.prototype, "optional", {
2489
+ get: function() {
2490
+ return !this.required;
2491
+ }
2492
+ });
2493
+
2494
+ /**
2495
+ * Determines whether this field uses tag-delimited encoding. In proto2 this
2496
+ * corresponded to group syntax.
2497
+ * @name Field#delimited
2498
+ * @type {boolean}
2499
+ * @readonly
2500
+ */
2501
+ Object.defineProperty(Field.prototype, "delimited", {
2502
+ get: function() {
2503
+ return this.resolvedType instanceof Type &&
2504
+ this._features.message_encoding === "DELIMITED";
2505
+ }
2506
+ });
2507
+
2508
+ /**
2509
+ * Determines whether this field is packed. Only relevant when repeated.
2450
2510
  * @name Field#packed
2451
2511
  * @type {boolean}
2452
2512
  * @readonly
2453
2513
  */
2454
2514
  Object.defineProperty(Field.prototype, "packed", {
2455
2515
  get: function() {
2456
- // defaults to packed=true if not explicity set to false
2457
- if (this._packed === null)
2458
- this._packed = this.getOption("packed") !== false;
2459
- return this._packed;
2516
+ return this._features.repeated_field_encoding === "PACKED";
2517
+ }
2518
+ });
2519
+
2520
+ /**
2521
+ * Determines whether this field tracks presence.
2522
+ * @name Field#hasPresence
2523
+ * @type {boolean}
2524
+ * @readonly
2525
+ */
2526
+ Object.defineProperty(Field.prototype, "hasPresence", {
2527
+ get: function() {
2528
+ if (this.repeated || this.map) {
2529
+ return false;
2530
+ }
2531
+ return this.partOf || // oneofs
2532
+ this.declaringField || this.extensionField || // extensions
2533
+ this._features.field_presence !== "IMPLICIT";
2460
2534
  }
2461
2535
  });
2462
2536
 
@@ -2464,8 +2538,6 @@ Object.defineProperty(Field.prototype, "packed", {
2464
2538
  * @override
2465
2539
  */
2466
2540
  Field.prototype.setOption = function setOption(name, value, ifNotSet) {
2467
- if (name === "packed") // clear cached before setting
2468
- this._packed = null;
2469
2541
  return ReflectionObject.prototype.setOption.call(this, name, value, ifNotSet);
2470
2542
  };
2471
2543
 
@@ -2532,7 +2604,7 @@ Field.prototype.resolve = function resolve() {
2532
2604
 
2533
2605
  // remove unnecessary options
2534
2606
  if (this.options) {
2535
- if (this.options.packed === true || this.options.packed !== undefined && this.resolvedType && !(this.resolvedType instanceof Enum))
2607
+ if (this.options.packed !== undefined && this.resolvedType && !(this.resolvedType instanceof Enum))
2536
2608
  delete this.options.packed;
2537
2609
  if (!Object.keys(this.options).length)
2538
2610
  this.options = undefined;
@@ -2570,6 +2642,30 @@ Field.prototype.resolve = function resolve() {
2570
2642
  return ReflectionObject.prototype.resolve.call(this);
2571
2643
  };
2572
2644
 
2645
+ /**
2646
+ * Infers field features from legacy syntax that may have been specified differently.
2647
+ * in older editions.
2648
+ * @param {string|undefined} edition The edition this proto is on, or undefined if pre-editions
2649
+ * @returns {object} The feature values to override
2650
+ */
2651
+ Field.prototype._inferLegacyProtoFeatures = function _inferLegacyProtoFeatures(edition) {
2652
+ if (edition) return {};
2653
+
2654
+ var features = {};
2655
+ if (this.rule === "required") {
2656
+ features.field_presence = "LEGACY_REQUIRED";
2657
+ }
2658
+ if (this.resolvedType instanceof Type && this.resolvedType.group) {
2659
+ features.message_encoding = "DELIMITED";
2660
+ }
2661
+ if (this.getOption("packed") === true) {
2662
+ features.repeated_field_encoding = "PACKED";
2663
+ } else if (this.getOption("packed") === false) {
2664
+ features.repeated_field_encoding = "EXPANDED";
2665
+ }
2666
+ return features;
2667
+ };
2668
+
2573
2669
  /**
2574
2670
  * Decorator function as returned by {@link Field.d} and {@link MapField.d} (TypeScript).
2575
2671
  * @typedef FieldDecorator
@@ -2725,7 +2821,7 @@ protobuf.types = require(36);
2725
2821
  protobuf.util = require(37);
2726
2822
 
2727
2823
  // Set up possibly cyclic reflection dependencies
2728
- protobuf.ReflectionObject._configure(protobuf.Root);
2824
+ protobuf.ReflectionObject._configure(protobuf.Root, protobuf.Namespace);
2729
2825
  protobuf.Namespace._configure(protobuf.Type, protobuf.Service, protobuf.Enum);
2730
2826
  protobuf.Root._configure(protobuf.Type);
2731
2827
  protobuf.Field._configure(protobuf.Type);
@@ -3517,12 +3613,13 @@ Namespace.prototype.define = function define(path, json) {
3517
3613
  */
3518
3614
  Namespace.prototype.resolveAll = function resolveAll() {
3519
3615
  var nested = this.nestedArray, i = 0;
3616
+ this.resolve();
3520
3617
  while (i < nested.length)
3521
3618
  if (nested[i] instanceof Namespace)
3522
3619
  nested[i++].resolveAll();
3523
3620
  else
3524
3621
  nested[i++].resolve();
3525
- return this.resolve();
3622
+ return this;
3526
3623
  };
3527
3624
 
3528
3625
  /**
@@ -3653,9 +3750,16 @@ module.exports = ReflectionObject;
3653
3750
 
3654
3751
  ReflectionObject.className = "ReflectionObject";
3655
3752
 
3753
+ const OneOf = require(25);
3656
3754
  var util = require(37);
3657
3755
 
3658
- var Root; // cyclic
3756
+ var Root, Namespace; // cyclic
3757
+
3758
+ /* eslint-disable no-warning-comments */
3759
+ // TODO: Replace with embedded proto.
3760
+ var editions2023Defaults = {enum_type: "OPEN", field_presence: "EXPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY"};
3761
+ var proto2Defaults = {enum_type: "CLOSED", field_presence: "EXPLICIT", json_format: "LEGACY_BEST_EFFORT", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "EXPANDED", utf8_validation: "NONE"};
3762
+ var proto3Defaults = {enum_type: "OPEN", field_presence: "IMPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY"};
3659
3763
 
3660
3764
  /**
3661
3765
  * Constructs a new reflection object instance.
@@ -3691,6 +3795,16 @@ function ReflectionObject(name, options) {
3691
3795
  */
3692
3796
  this.name = name;
3693
3797
 
3798
+ /**
3799
+ * Resolved Features.
3800
+ */
3801
+ this._features = {};
3802
+
3803
+ /**
3804
+ * Unresolved Features.
3805
+ */
3806
+ this._protoFeatures = null;
3807
+
3694
3808
  /**
3695
3809
  * Parent namespace.
3696
3810
  * @type {Namespace|null}
@@ -3796,11 +3910,69 @@ ReflectionObject.prototype.onRemove = function onRemove(parent) {
3796
3910
  ReflectionObject.prototype.resolve = function resolve() {
3797
3911
  if (this.resolved)
3798
3912
  return this;
3799
- if (this.root instanceof Root)
3800
- this.resolved = true; // only if part of a root
3913
+ var edition = this.getOption("edition");
3914
+ if ((this instanceof Namespace && edition) || (this.parent && this.parent.resolved)) {
3915
+ this._resolveFeatures();
3916
+ this.resolved = true;
3917
+ }
3801
3918
  return this;
3802
3919
  };
3803
3920
 
3921
+ /**
3922
+ * Resolves child features from parent features
3923
+ * @returns {undefined}
3924
+ */
3925
+ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures() {
3926
+ var defaults = {};
3927
+
3928
+ var protoFeatures = Object.assign(Object.assign({}, this._protoFeatures), this._inferLegacyProtoFeatures(edition));
3929
+
3930
+ var edition = this.getOption("edition");
3931
+ if (this instanceof Namespace && edition) {
3932
+ // For a namespace marked with a specific edition, reset defaults.
3933
+ if (edition === "proto2") {
3934
+ defaults = Object.assign({}, proto2Defaults);
3935
+ } else if (edition === "proto3") {
3936
+ defaults = Object.assign({}, proto3Defaults);
3937
+ } else if (edition === "2023") {
3938
+ defaults = Object.assign({}, editions2023Defaults);
3939
+ } else {
3940
+ throw new Error("Unknown edition: " + edition);
3941
+ }
3942
+ this._features = Object.assign(defaults, protoFeatures || {});
3943
+ return;
3944
+ }
3945
+
3946
+ // fields in Oneofs aren't actually children of them, so we have to
3947
+ // special-case it
3948
+ if (this.partOf instanceof OneOf) {
3949
+ var lexicalParentFeaturesCopy = Object.assign({}, this.partOf._features);
3950
+ this._features = Object.assign(lexicalParentFeaturesCopy, protoFeatures || {});
3951
+ } else if (this.declaringField) {
3952
+ // Skip feature resolution of sister fields.
3953
+ } else if (this.parent) {
3954
+ var parentFeaturesCopy = Object.assign({}, this.parent._features);
3955
+ this._features = Object.assign(parentFeaturesCopy, protoFeatures || {});
3956
+ } else {
3957
+ this._features = Object.assign({}, protoFeatures);
3958
+ }
3959
+ if (this.extensionField) {
3960
+ // Sister fields should have the same features as their extensions.
3961
+ this.extensionField._features = this._features;
3962
+ }
3963
+ };
3964
+
3965
+ /**
3966
+ * Infers features from legacy syntax that may have been specified differently.
3967
+ * in older editions.
3968
+ * @param {string|undefined} edition The edition this proto is on, or undefined if pre-editions
3969
+ * @returns {object} The feature values to override
3970
+ * @abstract
3971
+ */
3972
+ ReflectionObject.prototype._inferLegacyProtoFeatures = function _inferLegacyProtoFeatures(/*edition*/) {
3973
+ return {};
3974
+ };
3975
+
3804
3976
  /**
3805
3977
  * Gets an option value.
3806
3978
  * @param {string} name Option name
@@ -3820,8 +3992,10 @@ ReflectionObject.prototype.getOption = function getOption(name) {
3820
3992
  * @returns {ReflectionObject} `this`
3821
3993
  */
3822
3994
  ReflectionObject.prototype.setOption = function setOption(name, value, ifNotSet) {
3823
- if (!ifNotSet || !this.options || this.options[name] === undefined)
3995
+ if (!ifNotSet || !this.options || this.options[name] === undefined) {
3996
+ if (this.getOption(name) !== value) this.resolved = false;
3824
3997
  (this.options || (this.options = {}))[name] = value;
3998
+ }
3825
3999
  return this;
3826
4000
  };
3827
4001
 
@@ -3836,6 +4010,7 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3836
4010
  if (!this.parsedOptions) {
3837
4011
  this.parsedOptions = [];
3838
4012
  }
4013
+ var isFeature = /^features$/.test(name);
3839
4014
  var parsedOptions = this.parsedOptions;
3840
4015
  if (propName) {
3841
4016
  // If setting a sub property of an option then try to merge it
@@ -3845,10 +4020,11 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3845
4020
  });
3846
4021
  if (opt) {
3847
4022
  // If we found an existing option - just merge the property value
4023
+ // (If it's a feature, will just write over)
3848
4024
  var newValue = opt[name];
3849
4025
  util.setProperty(newValue, propName, value);
3850
4026
  } else {
3851
- // otherwise, create a new option, set it's property and add it to the list
4027
+ // otherwise, create a new option, set its property and add it to the list
3852
4028
  opt = {};
3853
4029
  opt[name] = util.setProperty({}, propName, value);
3854
4030
  parsedOptions.push(opt);
@@ -3859,6 +4035,13 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3859
4035
  newOpt[name] = value;
3860
4036
  parsedOptions.push(newOpt);
3861
4037
  }
4038
+
4039
+
4040
+ if (isFeature) {
4041
+ var features = parsedOptions.find(x => {return Object.prototype.hasOwnProperty.call(x, "features");});
4042
+ this._protoFeatures = features.features || {};
4043
+ }
4044
+
3862
4045
  return this;
3863
4046
  };
3864
4047
 
@@ -3888,11 +4071,12 @@ ReflectionObject.prototype.toString = function toString() {
3888
4071
  };
3889
4072
 
3890
4073
  // Sets up cyclic dependencies (called in index-light)
3891
- ReflectionObject._configure = function(Root_) {
4074
+ ReflectionObject._configure = function(Root_, Namespace_) {
3892
4075
  Root = Root_;
4076
+ Namespace = Namespace_;
3893
4077
  };
3894
4078
 
3895
- },{"37":37}],25:[function(require,module,exports){
4079
+ },{"25":25,"37":37}],25:[function(require,module,exports){
3896
4080
  "use strict";
3897
4081
  module.exports = OneOf;
3898
4082
 
@@ -4066,6 +4250,25 @@ OneOf.prototype.onRemove = function onRemove(parent) {
4066
4250
  ReflectionObject.prototype.onRemove.call(this, parent);
4067
4251
  };
4068
4252
 
4253
+ /**
4254
+ * Determines whether this field corresponds to a synthetic oneof created for
4255
+ * a proto3 optional field. No behavioral logic should depend on this, but it
4256
+ * can be relevant for reflection.
4257
+ * @name OneOf#isProto3Optional
4258
+ * @type {boolean}
4259
+ * @readonly
4260
+ */
4261
+ Object.defineProperty(OneOf.prototype, "isProto3Optional", {
4262
+ get: function() {
4263
+ if (this.fieldsArray == null || this.fieldsArray.length !== 1) {
4264
+ return false;
4265
+ }
4266
+
4267
+ var field = this.fieldsArray[0];
4268
+ return field.options != null && field.options["proto3_optional"] === true;
4269
+ }
4270
+ });
4271
+
4069
4272
  /**
4070
4273
  * Decorator function as returned by {@link OneOf.d} (TypeScript).
4071
4274
  * @typedef OneOfDecorator
@@ -4113,6 +4316,7 @@ var tokenize = require(34),
4113
4316
  Enum = require(15),
4114
4317
  Service = require(33),
4115
4318
  Method = require(22),
4319
+ ReflectionObject = require(24),
4116
4320
  types = require(36),
4117
4321
  util = require(37);
4118
4322
 
@@ -4124,8 +4328,7 @@ var base10Re = /^[1-9][0-9]*$/,
4124
4328
  base8NegRe = /^-?0[0-7]+$/,
4125
4329
  numberRe = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/,
4126
4330
  nameRe = /^[a-zA-Z_][a-zA-Z_0-9]*$/,
4127
- typeRefRe = /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
4128
- fqTypeRefRe = /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/;
4331
+ typeRefRe = /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/;
4129
4332
 
4130
4333
  /**
4131
4334
  * Result object returned from {@link parse}.
@@ -4133,7 +4336,6 @@ var base10Re = /^[1-9][0-9]*$/,
4133
4336
  * @property {string|undefined} package Package name, if declared
4134
4337
  * @property {string[]|undefined} imports Imports, if any
4135
4338
  * @property {string[]|undefined} weakImports Weak imports, if any
4136
- * @property {string|undefined} syntax Syntax, if specified (either `"proto2"` or `"proto3"`)
4137
4339
  * @property {Root} root Populated root instance
4138
4340
  */
4139
4341
 
@@ -4181,8 +4383,9 @@ function parse(source, root, options) {
4181
4383
  pkg,
4182
4384
  imports,
4183
4385
  weakImports,
4184
- syntax,
4185
- isProto3 = false;
4386
+ edition = "proto2",
4387
+ isProto3 = false,
4388
+ isProto2 = true;
4186
4389
 
4187
4390
  var ptr = root;
4188
4391
 
@@ -4226,7 +4429,6 @@ function parse(source, root, options) {
4226
4429
  try {
4227
4430
  return parseNumber(token, /* insideTryCatch */ true);
4228
4431
  } catch (e) {
4229
-
4230
4432
  /* istanbul ignore else */
4231
4433
  if (acceptTypeRef && typeRefRe.test(token))
4232
4434
  return token;
@@ -4241,8 +4443,17 @@ function parse(source, root, options) {
4241
4443
  do {
4242
4444
  if (acceptStrings && ((token = peek()) === "\"" || token === "'"))
4243
4445
  target.push(readString());
4244
- else
4245
- target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]);
4446
+ else {
4447
+ try {
4448
+ target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]);
4449
+ } catch (err) {
4450
+ if (typeRefRe.test(token) && (!isProto2 && !isProto3)) {
4451
+ target.push(token);
4452
+ } else {
4453
+ throw err;
4454
+ }
4455
+ }
4456
+ }
4246
4457
  } while (skip(",", true));
4247
4458
  var dummy = {options: undefined};
4248
4459
  dummy.setOption = function(name, value) {
@@ -4319,7 +4530,6 @@ function parse(source, root, options) {
4319
4530
  }
4320
4531
 
4321
4532
  function parsePackage() {
4322
-
4323
4533
  /* istanbul ignore if */
4324
4534
  if (pkg !== undefined)
4325
4535
  throw illegal("package");
@@ -4331,6 +4541,12 @@ function parse(source, root, options) {
4331
4541
  throw illegal(pkg, "name");
4332
4542
 
4333
4543
  ptr = ptr.define(pkg);
4544
+
4545
+ var oldEdition = ptr.getOption("edition");
4546
+ if (oldEdition && oldEdition !== edition) {
4547
+ throw new Error("incompatible editions detected in package " + pkg + ": " + edition + " vs " + oldEdition);
4548
+ }
4549
+ ptr.setOption("edition", edition);
4334
4550
  skip(";");
4335
4551
  }
4336
4552
 
@@ -4356,20 +4572,38 @@ function parse(source, root, options) {
4356
4572
 
4357
4573
  function parseSyntax() {
4358
4574
  skip("=");
4359
- syntax = readString();
4360
- isProto3 = syntax === "proto3";
4575
+ edition = readString();
4576
+ isProto3 = edition === "proto3";
4577
+ isProto2 = edition === "proto2";
4361
4578
 
4362
4579
  /* istanbul ignore if */
4363
- if (!isProto3 && syntax !== "proto2")
4364
- throw illegal(syntax, "syntax");
4580
+ if (!isProto3 && !isProto2)
4581
+ throw illegal(edition, "syntax");
4365
4582
 
4366
4583
  // Syntax is needed to understand the meaning of the optional field rule
4367
4584
  // Otherwise the meaning is ambiguous between proto2 and proto3
4368
- root.setOption("syntax", syntax);
4585
+ root.setOption("edition", edition);
4586
+
4587
+ skip(";");
4588
+ }
4589
+
4590
+ function parseEdition() {
4591
+ skip("=");
4592
+ edition = readString();
4593
+ isProto3 = false;
4594
+ isProto2 = false;
4595
+ const supportedEditions = ["2023"];
4596
+
4597
+ /* istanbul ignore if */
4598
+ if (!supportedEditions.includes(edition))
4599
+ throw illegal(edition, "edition");
4600
+
4601
+ root.setOption("edition", edition);
4369
4602
 
4370
4603
  skip(";");
4371
4604
  }
4372
4605
 
4606
+
4373
4607
  function parseCommon(parent, token) {
4374
4608
  switch (token) {
4375
4609
 
@@ -4437,6 +4671,9 @@ function parse(source, root, options) {
4437
4671
  break;
4438
4672
 
4439
4673
  case "required":
4674
+ if (!isProto2)
4675
+ throw illegal(token);
4676
+ /* eslint-disable no-fallthrough */
4440
4677
  case "repeated":
4441
4678
  parseField(type, token);
4442
4679
  break;
@@ -4445,6 +4682,8 @@ function parse(source, root, options) {
4445
4682
  /* istanbul ignore if */
4446
4683
  if (isProto3) {
4447
4684
  parseField(type, "proto3_optional");
4685
+ } else if (!isProto2) {
4686
+ throw illegal(token);
4448
4687
  } else {
4449
4688
  parseField(type, "optional");
4450
4689
  }
@@ -4464,8 +4703,9 @@ function parse(source, root, options) {
4464
4703
 
4465
4704
  default:
4466
4705
  /* istanbul ignore if */
4467
- if (!isProto3 || !typeRefRe.test(token))
4706
+ if (isProto2 || !typeRefRe.test(token)) {
4468
4707
  throw illegal(token);
4708
+ }
4469
4709
 
4470
4710
  push(token);
4471
4711
  parseField(type, "optional");
@@ -4499,6 +4739,7 @@ function parse(source, root, options) {
4499
4739
  var name = next();
4500
4740
 
4501
4741
  /* istanbul ignore if */
4742
+
4502
4743
  if (!nameRe.test(name))
4503
4744
  throw illegal(name, "name");
4504
4745
 
@@ -4506,6 +4747,7 @@ function parse(source, root, options) {
4506
4747
  skip("=");
4507
4748
 
4508
4749
  var field = new Field(name, parseId(next()), type, rule, extend);
4750
+
4509
4751
  ifBlock(field, function parseField_block(token) {
4510
4752
 
4511
4753
  /* istanbul ignore else */
@@ -4528,12 +4770,6 @@ function parse(source, root, options) {
4528
4770
  } else {
4529
4771
  parent.add(field);
4530
4772
  }
4531
-
4532
- // JSON defaults to packed=true if not set so we have to set packed=false explicity when
4533
- // parsing proto2 descriptors without the option, where applicable. This must be done for
4534
- // all known packable types and anything that could be an enum (= is not a basic type).
4535
- if (!isProto3 && field.repeated && (types.packed[type] !== undefined || types.basic[type] === undefined))
4536
- field.setOption("packed", false, /* ifNotSet */ true);
4537
4773
  }
4538
4774
 
4539
4775
  function parseGroup(parent, rule) {
@@ -4559,7 +4795,6 @@ function parse(source, root, options) {
4559
4795
  parseOption(type, token);
4560
4796
  skip(";");
4561
4797
  break;
4562
-
4563
4798
  case "required":
4564
4799
  case "repeated":
4565
4800
  parseField(type, token);
@@ -4688,8 +4923,17 @@ function parse(source, root, options) {
4688
4923
  dummy.setOption = function(name, value) {
4689
4924
  if (this.options === undefined)
4690
4925
  this.options = {};
4926
+
4691
4927
  this.options[name] = value;
4692
4928
  };
4929
+ dummy.setParsedOption = function(name, value, propName) {
4930
+ // In order to not change existing behavior, only calling
4931
+ // this for features
4932
+ if (/^features$/.test(name)) {
4933
+ return ReflectionObject.prototype.setParsedOption.call(dummy, name, value, propName);
4934
+ }
4935
+ return undefined;
4936
+ };
4693
4937
  ifBlock(dummy, function parseEnumValue_block(token) {
4694
4938
 
4695
4939
  /* istanbul ignore else */
@@ -4702,34 +4946,42 @@ function parse(source, root, options) {
4702
4946
  }, function parseEnumValue_line() {
4703
4947
  parseInlineOptions(dummy); // skip
4704
4948
  });
4705
- parent.add(token, value, dummy.comment, dummy.options);
4949
+ parent.add(token, value, dummy.comment, dummy.parsedOptions || dummy.options);
4706
4950
  }
4707
4951
 
4708
4952
  function parseOption(parent, token) {
4709
- var isCustom = skip("(", true);
4710
-
4711
- /* istanbul ignore if */
4712
- if (!typeRefRe.test(token = next()))
4713
- throw illegal(token, "name");
4714
-
4715
- var name = token;
4716
- var option = name;
4717
- var propName;
4953
+ var option;
4954
+ var propName;
4955
+ var isOption = true;
4956
+ if (token === "option") {
4957
+ token = next();
4958
+ }
4718
4959
 
4719
- if (isCustom) {
4720
- skip(")");
4721
- name = "(" + name + ")";
4722
- option = name;
4723
- token = peek();
4724
- if (fqTypeRefRe.test(token)) {
4725
- propName = token.slice(1); //remove '.' before property name
4726
- name += token;
4727
- next();
4960
+ while (token !== "=") {
4961
+ if (token === "(") {
4962
+ var parensValue = next();
4963
+ skip(")");
4964
+ token = "(" + parensValue + ")";
4965
+ }
4966
+ if (isOption) {
4967
+ isOption = false;
4968
+ if (token.includes(".") && !token.includes("(")) {
4969
+ var tokens = token.split(".");
4970
+ option = tokens[0] + ".";
4971
+ token = tokens[1];
4972
+ continue;
4973
+ }
4974
+ option = token;
4975
+ } else {
4976
+ propName = propName ? propName += token : token;
4977
+ }
4978
+ token = next();
4728
4979
  }
4729
- }
4730
- skip("=");
4731
- var optionValue = parseOptionValue(parent, name);
4732
- setParsedOption(parent, option, optionValue, propName);
4980
+ var name = propName ? option.concat(propName) : option;
4981
+ var optionValue = parseOptionValue(parent, name);
4982
+ propName = propName && propName[0] === "." ? propName.slice(1) : propName;
4983
+ option = option && option[option.length - 1] === "." ? option.slice(0, -1) : option;
4984
+ setParsedOption(parent, option, optionValue, propName);
4733
4985
  }
4734
4986
 
4735
4987
  function parseOptionValue(parent, name) {
@@ -4751,12 +5003,12 @@ function parse(source, root, options) {
4751
5003
 
4752
5004
  skip(":", true);
4753
5005
 
4754
- if (peek() === "{")
4755
- value = parseOptionValue(parent, name + "." + token);
4756
- else if (peek() === "[") {
5006
+ if (peek() === "{") {
4757
5007
  // option (my_option) = {
4758
5008
  // repeated_value: [ "foo", "bar" ]
4759
5009
  // };
5010
+ value = parseOptionValue(parent, name + "." + token);
5011
+ } else if (peek() === "[") {
4760
5012
  value = [];
4761
5013
  var lastValue;
4762
5014
  if (skip("[", true)) {
@@ -4823,8 +5075,9 @@ function parse(source, root, options) {
4823
5075
 
4824
5076
  var service = new Service(token);
4825
5077
  ifBlock(service, function parseService_block(token) {
4826
- if (parseCommon(service, token))
5078
+ if (parseCommon(service, token)) {
4827
5079
  return;
5080
+ }
4828
5081
 
4829
5082
  /* istanbul ignore else */
4830
5083
  if (token === "rpc")
@@ -4911,7 +5164,7 @@ function parse(source, root, options) {
4911
5164
 
4912
5165
  default:
4913
5166
  /* istanbul ignore if */
4914
- if (!isProto3 || !typeRefRe.test(token))
5167
+ if (isProto2 || !typeRefRe.test(token))
4915
5168
  throw illegal(token);
4916
5169
  push(token);
4917
5170
  parseField(parent, "optional", reference);
@@ -4951,10 +5204,16 @@ function parse(source, root, options) {
4951
5204
  parseSyntax();
4952
5205
  break;
4953
5206
 
4954
- case "option":
5207
+ case "edition":
5208
+ /* istanbul ignore if */
5209
+ if (!head)
5210
+ throw illegal(token);
5211
+ parseEdition();
5212
+ break;
4955
5213
 
5214
+ case "option":
4956
5215
  parseOption(ptr, token);
4957
- skip(";");
5216
+ skip(";", true);
4958
5217
  break;
4959
5218
 
4960
5219
  default:
@@ -4975,7 +5234,6 @@ function parse(source, root, options) {
4975
5234
  "package" : pkg,
4976
5235
  "imports" : imports,
4977
5236
  weakImports : weakImports,
4978
- syntax : syntax,
4979
5237
  root : root
4980
5238
  };
4981
5239
  }
@@ -4992,7 +5250,7 @@ function parse(source, root, options) {
4992
5250
  * @variation 2
4993
5251
  */
4994
5252
 
4995
- },{"15":15,"16":16,"20":20,"22":22,"25":25,"29":29,"33":33,"34":34,"35":35,"36":36,"37":37}],27:[function(require,module,exports){
5253
+ },{"15":15,"16":16,"20":20,"22":22,"24":24,"25":25,"29":29,"33":33,"34":34,"35":35,"36":36,"37":37}],27:[function(require,module,exports){
4996
5254
  "use strict";
4997
5255
  module.exports = Reader;
4998
5256
 
@@ -5501,11 +5759,14 @@ function Root(options) {
5501
5759
  * @type {string[]}
5502
5760
  */
5503
5761
  this.files = [];
5762
+
5763
+ // Default to proto2 if not specified.
5764
+ this.setOption("edition", "proto2", true);
5504
5765
  }
5505
5766
 
5506
5767
  /**
5507
5768
  * Loads a namespace descriptor into a root namespace.
5508
- * @param {INamespace} json Nameespace descriptor
5769
+ * @param {INamespace} json Namespace descriptor
5509
5770
  * @param {Root} [root] Root namespace, defaults to create a new one if omitted
5510
5771
  * @returns {Root} Root namespace
5511
5772
  */
@@ -5554,20 +5815,26 @@ Root.prototype.load = function load(filename, options, callback) {
5554
5815
  options = undefined;
5555
5816
  }
5556
5817
  var self = this;
5557
- if (!callback)
5818
+ if (!callback) {
5558
5819
  return util.asPromise(load, self, filename, options);
5820
+ }
5559
5821
 
5560
5822
  var sync = callback === SYNC; // undocumented
5561
5823
 
5562
5824
  // Finishes loading by calling the callback (exactly once)
5563
5825
  function finish(err, root) {
5564
5826
  /* istanbul ignore if */
5565
- if (!callback)
5827
+ if (!callback) {
5566
5828
  return;
5567
- if (sync)
5829
+ }
5830
+ if (sync) {
5568
5831
  throw err;
5832
+ }
5569
5833
  var cb = callback;
5570
5834
  callback = null;
5835
+ if (root) {
5836
+ root.resolveAll();
5837
+ }
5571
5838
  cb(err, root);
5572
5839
  }
5573
5840
 
@@ -5605,8 +5872,9 @@ Root.prototype.load = function load(filename, options, callback) {
5605
5872
  } catch (err) {
5606
5873
  finish(err);
5607
5874
  }
5608
- if (!sync && !queued)
5875
+ if (!sync && !queued) {
5609
5876
  finish(null, self); // only once anyway
5877
+ }
5610
5878
  }
5611
5879
 
5612
5880
  // Fetches a single file
@@ -5614,15 +5882,16 @@ Root.prototype.load = function load(filename, options, callback) {
5614
5882
  filename = getBundledFileName(filename) || filename;
5615
5883
 
5616
5884
  // Skip if already loaded / attempted
5617
- if (self.files.indexOf(filename) > -1)
5885
+ if (self.files.indexOf(filename) > -1) {
5618
5886
  return;
5887
+ }
5619
5888
  self.files.push(filename);
5620
5889
 
5621
5890
  // Shortcut bundled definitions
5622
5891
  if (filename in common) {
5623
- if (sync)
5892
+ if (sync) {
5624
5893
  process(filename, common[filename]);
5625
- else {
5894
+ } else {
5626
5895
  ++queued;
5627
5896
  setTimeout(function() {
5628
5897
  --queued;
@@ -5648,8 +5917,9 @@ Root.prototype.load = function load(filename, options, callback) {
5648
5917
  self.fetch(filename, function(err, source) {
5649
5918
  --queued;
5650
5919
  /* istanbul ignore if */
5651
- if (!callback)
5920
+ if (!callback) {
5652
5921
  return; // terminated meanwhile
5922
+ }
5653
5923
  if (err) {
5654
5924
  /* istanbul ignore else */
5655
5925
  if (!weak)
@@ -5666,17 +5936,21 @@ Root.prototype.load = function load(filename, options, callback) {
5666
5936
 
5667
5937
  // Assembling the root namespace doesn't require working type
5668
5938
  // references anymore, so we can load everything in parallel
5669
- if (util.isString(filename))
5939
+ if (util.isString(filename)) {
5670
5940
  filename = [ filename ];
5941
+ }
5671
5942
  for (var i = 0, resolved; i < filename.length; ++i)
5672
5943
  if (resolved = self.resolvePath("", filename[i]))
5673
5944
  fetch(resolved);
5674
-
5675
- if (sync)
5945
+ self.resolveAll();
5946
+ if (sync) {
5676
5947
  return self;
5677
- if (!queued)
5948
+ }
5949
+ if (!queued) {
5678
5950
  finish(null, self);
5679
- return undefined;
5951
+ }
5952
+
5953
+ return self;
5680
5954
  };
5681
5955
  // function load(filename:string, options:IParseOptions, callback:LoadCallback):undefined
5682
5956
 
@@ -6144,10 +6418,11 @@ Service.prototype.get = function get(name) {
6144
6418
  * @override
6145
6419
  */
6146
6420
  Service.prototype.resolveAll = function resolveAll() {
6421
+ Namespace.prototype.resolve.call(this);
6147
6422
  var methods = this.methodsArray;
6148
6423
  for (var i = 0; i < methods.length; ++i)
6149
6424
  methods[i].resolve();
6150
- return Namespace.prototype.resolve.call(this);
6425
+ return this;
6151
6426
  };
6152
6427
 
6153
6428
  /**
@@ -6924,13 +7199,14 @@ Type.prototype.toJSON = function toJSON(toJSONOptions) {
6924
7199
  * @override
6925
7200
  */
6926
7201
  Type.prototype.resolveAll = function resolveAll() {
6927
- var fields = this.fieldsArray, i = 0;
6928
- while (i < fields.length)
6929
- fields[i++].resolve();
7202
+ Namespace.prototype.resolveAll.call(this);
6930
7203
  var oneofs = this.oneofsArray; i = 0;
6931
7204
  while (i < oneofs.length)
6932
7205
  oneofs[i++].resolve();
6933
- return Namespace.prototype.resolveAll.call(this);
7206
+ var fields = this.fieldsArray, i = 0;
7207
+ while (i < fields.length)
7208
+ fields[i++].resolve();
7209
+ return this;
6934
7210
  };
6935
7211
 
6936
7212
  /**
@@ -7585,6 +7861,7 @@ util.decorateEnum = function decorateEnum(object) {
7585
7861
  * @param {Object.<string,*>} dst Destination object
7586
7862
  * @param {string} path dot '.' delimited path of the property to set
7587
7863
  * @param {Object} value the value to set
7864
+ * @param {boolean} overWrite whether or not to concatenate the values into an array or overwrite; defaults to false.
7588
7865
  * @returns {Object.<string,*>} Destination object
7589
7866
  */
7590
7867
  util.setProperty = function setProperty(dst, path, value) {