protobufjs 7.4.0 → 8.0.0-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.0-experimental (c) 2016, daniel wirtz
3
+ * compiled fri, 21 mar 2025 17:14:14 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
@@ -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,10 +3750,17 @@ 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
3756
  var Root; // cyclic
3659
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"};
3763
+
3660
3764
  /**
3661
3765
  * Constructs a new reflection object instance.
3662
3766
  * @classdesc Base class of all reflection objects.
@@ -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,65 @@ 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
+ if (this instanceof Root || this.parent && this.parent.resolved) {
3914
+ this._resolveFeatures();
3915
+ this.resolved = true;
3916
+ }
3801
3917
  return this;
3802
3918
  };
3803
3919
 
3920
+ /**
3921
+ * Resolves child features from parent features
3922
+ * @returns {undefined}
3923
+ */
3924
+ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures() {
3925
+ var defaults = {};
3926
+
3927
+ var edition = this.root.getOption("edition");
3928
+ if (this instanceof Root) {
3929
+ if (this.root.getOption("syntax") === "proto3") {
3930
+ defaults = Object.assign({}, proto3Defaults);
3931
+ } else if (edition === "2023") {
3932
+ defaults = Object.assign({}, editions2023Defaults);
3933
+ } else {
3934
+ defaults = Object.assign({}, proto2Defaults);
3935
+ }
3936
+ }
3937
+
3938
+ var protoFeatures = Object.assign(Object.assign({}, this._protoFeatures), this._inferLegacyProtoFeatures(edition));
3939
+
3940
+ if (this instanceof Root) {
3941
+ this._features = Object.assign(defaults, protoFeatures || {});
3942
+ // fields in Oneofs aren't actually children of them, so we have to
3943
+ // special-case it
3944
+ } else if (this.partOf instanceof OneOf) {
3945
+ var lexicalParentFeaturesCopy = Object.assign({}, this.partOf._features);
3946
+ this._features = Object.assign(lexicalParentFeaturesCopy, protoFeatures || {});
3947
+ } else if (this.declaringField) {
3948
+ // Skip feature resolution of sister fields.
3949
+ } else if (this.parent) {
3950
+ var parentFeaturesCopy = Object.assign({}, this.parent._features);
3951
+ this._features = Object.assign(parentFeaturesCopy, protoFeatures || {});
3952
+ } else {
3953
+ this._features = Object.assign({}, protoFeatures);
3954
+ }
3955
+ if (this.extensionField) {
3956
+ // Sister fields should have the same features as their extensions.
3957
+ this.extensionField._features = this._features;
3958
+ }
3959
+ };
3960
+
3961
+ /**
3962
+ * Infers features from legacy syntax that may have been specified differently.
3963
+ * in older editions.
3964
+ * @param {string|undefined} edition The edition this proto is on, or undefined if pre-editions
3965
+ * @returns {object} The feature values to override
3966
+ * @abstract
3967
+ */
3968
+ ReflectionObject.prototype._inferLegacyProtoFeatures = function _inferLegacyProtoFeatures(/*edition*/) {
3969
+ return {};
3970
+ };
3971
+
3804
3972
  /**
3805
3973
  * Gets an option value.
3806
3974
  * @param {string} name Option name
@@ -3836,6 +4004,7 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3836
4004
  if (!this.parsedOptions) {
3837
4005
  this.parsedOptions = [];
3838
4006
  }
4007
+ var isFeature = /^features$/.test(name);
3839
4008
  var parsedOptions = this.parsedOptions;
3840
4009
  if (propName) {
3841
4010
  // If setting a sub property of an option then try to merge it
@@ -3845,10 +4014,11 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3845
4014
  });
3846
4015
  if (opt) {
3847
4016
  // If we found an existing option - just merge the property value
4017
+ // (If it's a feature, will just write over)
3848
4018
  var newValue = opt[name];
3849
4019
  util.setProperty(newValue, propName, value);
3850
4020
  } else {
3851
- // otherwise, create a new option, set it's property and add it to the list
4021
+ // otherwise, create a new option, set its property and add it to the list
3852
4022
  opt = {};
3853
4023
  opt[name] = util.setProperty({}, propName, value);
3854
4024
  parsedOptions.push(opt);
@@ -3859,6 +4029,13 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3859
4029
  newOpt[name] = value;
3860
4030
  parsedOptions.push(newOpt);
3861
4031
  }
4032
+
4033
+
4034
+ if (isFeature) {
4035
+ var features = parsedOptions.find(x => {return Object.prototype.hasOwnProperty.call(x, "features");});
4036
+ this._protoFeatures = features.features || {};
4037
+ }
4038
+
3862
4039
  return this;
3863
4040
  };
3864
4041
 
@@ -3892,7 +4069,7 @@ ReflectionObject._configure = function(Root_) {
3892
4069
  Root = Root_;
3893
4070
  };
3894
4071
 
3895
- },{"37":37}],25:[function(require,module,exports){
4072
+ },{"25":25,"37":37}],25:[function(require,module,exports){
3896
4073
  "use strict";
3897
4074
  module.exports = OneOf;
3898
4075
 
@@ -4066,6 +4243,25 @@ OneOf.prototype.onRemove = function onRemove(parent) {
4066
4243
  ReflectionObject.prototype.onRemove.call(this, parent);
4067
4244
  };
4068
4245
 
4246
+ /**
4247
+ * Determines whether this field corresponds to a synthetic oneof created for
4248
+ * a proto3 optional field. No behavioral logic should depend on this, but it
4249
+ * can be relevant for reflection.
4250
+ * @name OneOf#isProto3Optional
4251
+ * @type {boolean}
4252
+ * @readonly
4253
+ */
4254
+ Object.defineProperty(OneOf.prototype, "isProto3Optional", {
4255
+ get: function() {
4256
+ if (this.fieldsArray == null || this.fieldsArray.length !== 1) {
4257
+ return false;
4258
+ }
4259
+
4260
+ var field = this.fieldsArray[0];
4261
+ return field.options != null && field.options["proto3_optional"] === true;
4262
+ }
4263
+ });
4264
+
4069
4265
  /**
4070
4266
  * Decorator function as returned by {@link OneOf.d} (TypeScript).
4071
4267
  * @typedef OneOfDecorator
@@ -4113,6 +4309,7 @@ var tokenize = require(34),
4113
4309
  Enum = require(15),
4114
4310
  Service = require(33),
4115
4311
  Method = require(22),
4312
+ ReflectionObject = require(24),
4116
4313
  types = require(36),
4117
4314
  util = require(37);
4118
4315
 
@@ -4124,8 +4321,7 @@ var base10Re = /^[1-9][0-9]*$/,
4124
4321
  base8NegRe = /^-?0[0-7]+$/,
4125
4322
  numberRe = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/,
4126
4323
  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]*)+$/;
4324
+ typeRefRe = /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/;
4129
4325
 
4130
4326
  /**
4131
4327
  * Result object returned from {@link parse}.
@@ -4182,6 +4378,7 @@ function parse(source, root, options) {
4182
4378
  imports,
4183
4379
  weakImports,
4184
4380
  syntax,
4381
+ edition = false,
4185
4382
  isProto3 = false;
4186
4383
 
4187
4384
  var ptr = root;
@@ -4226,7 +4423,6 @@ function parse(source, root, options) {
4226
4423
  try {
4227
4424
  return parseNumber(token, /* insideTryCatch */ true);
4228
4425
  } catch (e) {
4229
-
4230
4426
  /* istanbul ignore else */
4231
4427
  if (acceptTypeRef && typeRefRe.test(token))
4232
4428
  return token;
@@ -4241,8 +4437,17 @@ function parse(source, root, options) {
4241
4437
  do {
4242
4438
  if (acceptStrings && ((token = peek()) === "\"" || token === "'"))
4243
4439
  target.push(readString());
4244
- else
4245
- target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]);
4440
+ else {
4441
+ try {
4442
+ target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]);
4443
+ } catch (err) {
4444
+ if (typeRefRe.test(token) && edition) {
4445
+ target.push(token);
4446
+ } else {
4447
+ throw err;
4448
+ }
4449
+ }
4450
+ }
4246
4451
  } while (skip(",", true));
4247
4452
  var dummy = {options: undefined};
4248
4453
  dummy.setOption = function(name, value) {
@@ -4370,6 +4575,21 @@ function parse(source, root, options) {
4370
4575
  skip(";");
4371
4576
  }
4372
4577
 
4578
+ function parseEdition() {
4579
+ skip("=");
4580
+ edition = readString();
4581
+ const supportedEditions = ["2023"];
4582
+
4583
+ /* istanbul ignore if */
4584
+ if (!supportedEditions.includes(edition))
4585
+ throw illegal(edition, "edition");
4586
+
4587
+ root.setOption("edition", edition);
4588
+
4589
+ skip(";");
4590
+ }
4591
+
4592
+
4373
4593
  function parseCommon(parent, token) {
4374
4594
  switch (token) {
4375
4595
 
@@ -4437,6 +4657,9 @@ function parse(source, root, options) {
4437
4657
  break;
4438
4658
 
4439
4659
  case "required":
4660
+ if (edition)
4661
+ throw illegal(token);
4662
+ /* eslint-disable no-fallthrough */
4440
4663
  case "repeated":
4441
4664
  parseField(type, token);
4442
4665
  break;
@@ -4445,6 +4668,8 @@ function parse(source, root, options) {
4445
4668
  /* istanbul ignore if */
4446
4669
  if (isProto3) {
4447
4670
  parseField(type, "proto3_optional");
4671
+ } else if (edition) {
4672
+ throw illegal(token);
4448
4673
  } else {
4449
4674
  parseField(type, "optional");
4450
4675
  }
@@ -4464,8 +4689,9 @@ function parse(source, root, options) {
4464
4689
 
4465
4690
  default:
4466
4691
  /* istanbul ignore if */
4467
- if (!isProto3 || !typeRefRe.test(token))
4692
+ if (!isProto3 && !edition || !typeRefRe.test(token)) {
4468
4693
  throw illegal(token);
4694
+ }
4469
4695
 
4470
4696
  push(token);
4471
4697
  parseField(type, "optional");
@@ -4499,6 +4725,7 @@ function parse(source, root, options) {
4499
4725
  var name = next();
4500
4726
 
4501
4727
  /* istanbul ignore if */
4728
+
4502
4729
  if (!nameRe.test(name))
4503
4730
  throw illegal(name, "name");
4504
4731
 
@@ -4506,6 +4733,7 @@ function parse(source, root, options) {
4506
4733
  skip("=");
4507
4734
 
4508
4735
  var field = new Field(name, parseId(next()), type, rule, extend);
4736
+
4509
4737
  ifBlock(field, function parseField_block(token) {
4510
4738
 
4511
4739
  /* istanbul ignore else */
@@ -4528,12 +4756,6 @@ function parse(source, root, options) {
4528
4756
  } else {
4529
4757
  parent.add(field);
4530
4758
  }
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
4759
  }
4538
4760
 
4539
4761
  function parseGroup(parent, rule) {
@@ -4559,7 +4781,6 @@ function parse(source, root, options) {
4559
4781
  parseOption(type, token);
4560
4782
  skip(";");
4561
4783
  break;
4562
-
4563
4784
  case "required":
4564
4785
  case "repeated":
4565
4786
  parseField(type, token);
@@ -4688,8 +4909,17 @@ function parse(source, root, options) {
4688
4909
  dummy.setOption = function(name, value) {
4689
4910
  if (this.options === undefined)
4690
4911
  this.options = {};
4912
+
4691
4913
  this.options[name] = value;
4692
4914
  };
4915
+ dummy.setParsedOption = function(name, value, propName) {
4916
+ // In order to not change existing behavior, only calling
4917
+ // this for features
4918
+ if (/^features$/.test(name)) {
4919
+ return ReflectionObject.prototype.setParsedOption.call(dummy, name, value, propName);
4920
+ }
4921
+ return undefined;
4922
+ };
4693
4923
  ifBlock(dummy, function parseEnumValue_block(token) {
4694
4924
 
4695
4925
  /* istanbul ignore else */
@@ -4702,34 +4932,42 @@ function parse(source, root, options) {
4702
4932
  }, function parseEnumValue_line() {
4703
4933
  parseInlineOptions(dummy); // skip
4704
4934
  });
4705
- parent.add(token, value, dummy.comment, dummy.options);
4935
+ parent.add(token, value, dummy.comment, dummy.parsedOptions || dummy.options);
4706
4936
  }
4707
4937
 
4708
4938
  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;
4939
+ var option;
4940
+ var propName;
4941
+ var isOption = true;
4942
+ if (token === "option") {
4943
+ token = next();
4944
+ }
4718
4945
 
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();
4946
+ while (token !== "=") {
4947
+ if (token === "(") {
4948
+ var parensValue = next();
4949
+ skip(")");
4950
+ token = "(" + parensValue + ")";
4951
+ }
4952
+ if (isOption) {
4953
+ isOption = false;
4954
+ if (token.includes(".") && !token.includes("(")) {
4955
+ var tokens = token.split(".");
4956
+ option = tokens[0] + ".";
4957
+ token = tokens[1];
4958
+ continue;
4959
+ }
4960
+ option = token;
4961
+ } else {
4962
+ propName = propName ? propName += token : token;
4963
+ }
4964
+ token = next();
4728
4965
  }
4729
- }
4730
- skip("=");
4731
- var optionValue = parseOptionValue(parent, name);
4732
- setParsedOption(parent, option, optionValue, propName);
4966
+ var name = propName ? option.concat(propName) : option;
4967
+ var optionValue = parseOptionValue(parent, name);
4968
+ propName = propName && propName[0] === "." ? propName.slice(1) : propName;
4969
+ option = option && option[option.length - 1] === "." ? option.slice(0, -1) : option;
4970
+ setParsedOption(parent, option, optionValue, propName);
4733
4971
  }
4734
4972
 
4735
4973
  function parseOptionValue(parent, name) {
@@ -4751,12 +4989,12 @@ function parse(source, root, options) {
4751
4989
 
4752
4990
  skip(":", true);
4753
4991
 
4754
- if (peek() === "{")
4755
- value = parseOptionValue(parent, name + "." + token);
4756
- else if (peek() === "[") {
4992
+ if (peek() === "{") {
4757
4993
  // option (my_option) = {
4758
4994
  // repeated_value: [ "foo", "bar" ]
4759
4995
  // };
4996
+ value = parseOptionValue(parent, name + "." + token);
4997
+ } else if (peek() === "[") {
4760
4998
  value = [];
4761
4999
  var lastValue;
4762
5000
  if (skip("[", true)) {
@@ -4823,8 +5061,9 @@ function parse(source, root, options) {
4823
5061
 
4824
5062
  var service = new Service(token);
4825
5063
  ifBlock(service, function parseService_block(token) {
4826
- if (parseCommon(service, token))
5064
+ if (parseCommon(service, token)) {
4827
5065
  return;
5066
+ }
4828
5067
 
4829
5068
  /* istanbul ignore else */
4830
5069
  if (token === "rpc")
@@ -4911,7 +5150,7 @@ function parse(source, root, options) {
4911
5150
 
4912
5151
  default:
4913
5152
  /* istanbul ignore if */
4914
- if (!isProto3 || !typeRefRe.test(token))
5153
+ if (!isProto3 && !edition || !typeRefRe.test(token))
4915
5154
  throw illegal(token);
4916
5155
  push(token);
4917
5156
  parseField(parent, "optional", reference);
@@ -4951,10 +5190,16 @@ function parse(source, root, options) {
4951
5190
  parseSyntax();
4952
5191
  break;
4953
5192
 
4954
- case "option":
5193
+ case "edition":
5194
+ /* istanbul ignore if */
5195
+ if (!head)
5196
+ throw illegal(token);
5197
+ parseEdition();
5198
+ break;
4955
5199
 
5200
+ case "option":
4956
5201
  parseOption(ptr, token);
4957
- skip(";");
5202
+ skip(";", true);
4958
5203
  break;
4959
5204
 
4960
5205
  default:
@@ -4992,7 +5237,7 @@ function parse(source, root, options) {
4992
5237
  * @variation 2
4993
5238
  */
4994
5239
 
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){
5240
+ },{"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
5241
  "use strict";
4997
5242
  module.exports = Reader;
4998
5243
 
@@ -5505,7 +5750,7 @@ function Root(options) {
5505
5750
 
5506
5751
  /**
5507
5752
  * Loads a namespace descriptor into a root namespace.
5508
- * @param {INamespace} json Nameespace descriptor
5753
+ * @param {INamespace} json Namespace descriptor
5509
5754
  * @param {Root} [root] Root namespace, defaults to create a new one if omitted
5510
5755
  * @returns {Root} Root namespace
5511
5756
  */
@@ -5554,20 +5799,26 @@ Root.prototype.load = function load(filename, options, callback) {
5554
5799
  options = undefined;
5555
5800
  }
5556
5801
  var self = this;
5557
- if (!callback)
5802
+ if (!callback) {
5558
5803
  return util.asPromise(load, self, filename, options);
5804
+ }
5559
5805
 
5560
5806
  var sync = callback === SYNC; // undocumented
5561
5807
 
5562
5808
  // Finishes loading by calling the callback (exactly once)
5563
5809
  function finish(err, root) {
5564
5810
  /* istanbul ignore if */
5565
- if (!callback)
5811
+ if (!callback) {
5566
5812
  return;
5567
- if (sync)
5813
+ }
5814
+ if (sync) {
5568
5815
  throw err;
5816
+ }
5569
5817
  var cb = callback;
5570
5818
  callback = null;
5819
+ if (root) {
5820
+ root.resolveAll();
5821
+ }
5571
5822
  cb(err, root);
5572
5823
  }
5573
5824
 
@@ -5605,8 +5856,9 @@ Root.prototype.load = function load(filename, options, callback) {
5605
5856
  } catch (err) {
5606
5857
  finish(err);
5607
5858
  }
5608
- if (!sync && !queued)
5859
+ if (!sync && !queued) {
5609
5860
  finish(null, self); // only once anyway
5861
+ }
5610
5862
  }
5611
5863
 
5612
5864
  // Fetches a single file
@@ -5614,15 +5866,16 @@ Root.prototype.load = function load(filename, options, callback) {
5614
5866
  filename = getBundledFileName(filename) || filename;
5615
5867
 
5616
5868
  // Skip if already loaded / attempted
5617
- if (self.files.indexOf(filename) > -1)
5869
+ if (self.files.indexOf(filename) > -1) {
5618
5870
  return;
5871
+ }
5619
5872
  self.files.push(filename);
5620
5873
 
5621
5874
  // Shortcut bundled definitions
5622
5875
  if (filename in common) {
5623
- if (sync)
5876
+ if (sync) {
5624
5877
  process(filename, common[filename]);
5625
- else {
5878
+ } else {
5626
5879
  ++queued;
5627
5880
  setTimeout(function() {
5628
5881
  --queued;
@@ -5648,8 +5901,9 @@ Root.prototype.load = function load(filename, options, callback) {
5648
5901
  self.fetch(filename, function(err, source) {
5649
5902
  --queued;
5650
5903
  /* istanbul ignore if */
5651
- if (!callback)
5904
+ if (!callback) {
5652
5905
  return; // terminated meanwhile
5906
+ }
5653
5907
  if (err) {
5654
5908
  /* istanbul ignore else */
5655
5909
  if (!weak)
@@ -5666,17 +5920,21 @@ Root.prototype.load = function load(filename, options, callback) {
5666
5920
 
5667
5921
  // Assembling the root namespace doesn't require working type
5668
5922
  // references anymore, so we can load everything in parallel
5669
- if (util.isString(filename))
5923
+ if (util.isString(filename)) {
5670
5924
  filename = [ filename ];
5925
+ }
5671
5926
  for (var i = 0, resolved; i < filename.length; ++i)
5672
5927
  if (resolved = self.resolvePath("", filename[i]))
5673
5928
  fetch(resolved);
5674
-
5675
- if (sync)
5929
+ self.resolveAll();
5930
+ if (sync) {
5676
5931
  return self;
5677
- if (!queued)
5932
+ }
5933
+ if (!queued) {
5678
5934
  finish(null, self);
5679
- return undefined;
5935
+ }
5936
+
5937
+ return self;
5680
5938
  };
5681
5939
  // function load(filename:string, options:IParseOptions, callback:LoadCallback):undefined
5682
5940
 
@@ -6144,10 +6402,11 @@ Service.prototype.get = function get(name) {
6144
6402
  * @override
6145
6403
  */
6146
6404
  Service.prototype.resolveAll = function resolveAll() {
6405
+ Namespace.prototype.resolve.call(this);
6147
6406
  var methods = this.methodsArray;
6148
6407
  for (var i = 0; i < methods.length; ++i)
6149
6408
  methods[i].resolve();
6150
- return Namespace.prototype.resolve.call(this);
6409
+ return this;
6151
6410
  };
6152
6411
 
6153
6412
  /**
@@ -6924,13 +7183,14 @@ Type.prototype.toJSON = function toJSON(toJSONOptions) {
6924
7183
  * @override
6925
7184
  */
6926
7185
  Type.prototype.resolveAll = function resolveAll() {
6927
- var fields = this.fieldsArray, i = 0;
6928
- while (i < fields.length)
6929
- fields[i++].resolve();
7186
+ Namespace.prototype.resolveAll.call(this);
6930
7187
  var oneofs = this.oneofsArray; i = 0;
6931
7188
  while (i < oneofs.length)
6932
7189
  oneofs[i++].resolve();
6933
- return Namespace.prototype.resolveAll.call(this);
7190
+ var fields = this.fieldsArray, i = 0;
7191
+ while (i < fields.length)
7192
+ fields[i++].resolve();
7193
+ return this;
6934
7194
  };
6935
7195
 
6936
7196
  /**
@@ -7585,6 +7845,7 @@ util.decorateEnum = function decorateEnum(object) {
7585
7845
  * @param {Object.<string,*>} dst Destination object
7586
7846
  * @param {string} path dot '.' delimited path of the property to set
7587
7847
  * @param {Object} value the value to set
7848
+ * @param {boolean} overWrite whether or not to concatenate the values into an array or overwrite; defaults to false.
7588
7849
  * @returns {Object.<string,*>} Destination object
7589
7850
  */
7590
7851
  util.setProperty = function setProperty(dst, path, value) {