protobufjs 7.4.0 → 7.5.0

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.
@@ -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 v7.5.0 (c) 2016, daniel wirtz
3
+ * compiled tue, 15 apr 2025 17:05:18 utc
4
4
  * licensed under the bsd-3-clause license
5
5
  * see: https://github.com/dcodeio/protobuf.js for details
6
6
  */
@@ -1430,16 +1430,14 @@ function missing(field) {
1430
1430
  */
1431
1431
  function decoder(mtype) {
1432
1432
  /* eslint-disable no-unexpected-multiline */
1433
- var gen = util.codegen(["r", "l"], mtype.name + "$decode")
1433
+ var gen = util.codegen(["r", "l", "e"], mtype.name + "$decode")
1434
1434
  ("if(!(r instanceof Reader))")
1435
1435
  ("r=Reader.create(r)")
1436
1436
  ("var c=l===undefined?r.len:r.pos+l,m=new this.ctor" + (mtype.fieldsArray.filter(function(field) { return field.map; }).length ? ",k,value" : ""))
1437
1437
  ("while(r.pos<c){")
1438
- ("var t=r.uint32()");
1439
- if (mtype.group) gen
1440
- ("if((t&7)===4)")
1441
- ("break");
1442
- gen
1438
+ ("var t=r.uint32()")
1439
+ ("if(t===e)")
1440
+ ("break")
1443
1441
  ("switch(t>>>3){");
1444
1442
 
1445
1443
  var i = 0;
@@ -1505,15 +1503,15 @@ function decoder(mtype) {
1505
1503
  ("}else");
1506
1504
 
1507
1505
  // Non-packed
1508
- if (types.basic[type] === undefined) gen(field.resolvedType.group
1509
- ? "%s.push(types[%i].decode(r))"
1506
+ if (types.basic[type] === undefined) gen(field.delimited
1507
+ ? "%s.push(types[%i].decode(r,undefined,((t&~7)|4)))"
1510
1508
  : "%s.push(types[%i].decode(r,r.uint32()))", ref, i);
1511
1509
  else gen
1512
1510
  ("%s.push(r.%s())", ref, type);
1513
1511
 
1514
1512
  // Non-repeated
1515
- } else if (types.basic[type] === undefined) gen(field.resolvedType.group
1516
- ? "%s=types[%i].decode(r)"
1513
+ } else if (types.basic[type] === undefined) gen(field.delimited
1514
+ ? "%s=types[%i].decode(r,undefined,((t&~7)|4))"
1517
1515
  : "%s=types[%i].decode(r,r.uint32())", ref, i);
1518
1516
  else gen
1519
1517
  ("%s=r.%s()", ref, type);
@@ -1560,7 +1558,7 @@ var Enum = require(14),
1560
1558
  * @ignore
1561
1559
  */
1562
1560
  function genTypePartial(gen, field, fieldIndex, ref) {
1563
- return field.resolvedType.group
1561
+ return field.delimited
1564
1562
  ? gen("types[%i].encode(%s,w.uint32(%i)).uint32(%i)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0)
1565
1563
  : gen("types[%i].encode(%s,w.uint32(%i).fork()).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0);
1566
1564
  }
@@ -1703,6 +1701,12 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
1703
1701
  */
1704
1702
  this.valuesOptions = valuesOptions;
1705
1703
 
1704
+ /**
1705
+ * Resolved values features, if any
1706
+ * @type {Object<string, Object<string, *>>|undefined}
1707
+ */
1708
+ this._valuesFeatures = {};
1709
+
1706
1710
  /**
1707
1711
  * Reserved ranges, if any.
1708
1712
  * @type {Array.<number[]|string>}
@@ -1719,6 +1723,21 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
1719
1723
  this.valuesById[ this.values[keys[i]] = values[keys[i]] ] = keys[i];
1720
1724
  }
1721
1725
 
1726
+ /**
1727
+ * @override
1728
+ */
1729
+ Enum.prototype._resolveFeatures = function _resolveFeatures(edition) {
1730
+ edition = this._edition || edition;
1731
+ ReflectionObject.prototype._resolveFeatures.call(this, edition);
1732
+
1733
+ Object.keys(this.values).forEach(key => {
1734
+ var parentFeaturesCopy = Object.assign({}, this._features);
1735
+ this._valuesFeatures[key] = Object.assign(parentFeaturesCopy, this.valuesOptions && this.valuesOptions[key] && this.valuesOptions[key].features);
1736
+ });
1737
+
1738
+ return this;
1739
+ };
1740
+
1722
1741
  /**
1723
1742
  * Enum descriptor.
1724
1743
  * @interface IEnum
@@ -1736,6 +1755,9 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
1736
1755
  Enum.fromJSON = function fromJSON(name, json) {
1737
1756
  var enm = new Enum(name, json.values, json.options, json.comment, json.comments);
1738
1757
  enm.reserved = json.reserved;
1758
+ if (json.edition)
1759
+ enm._edition = json.edition;
1760
+ enm._defaultEdition = "proto3"; // For backwards-compatibility.
1739
1761
  return enm;
1740
1762
  };
1741
1763
 
@@ -1747,6 +1769,7 @@ Enum.fromJSON = function fromJSON(name, json) {
1747
1769
  Enum.prototype.toJSON = function toJSON(toJSONOptions) {
1748
1770
  var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
1749
1771
  return util.toObject([
1772
+ "edition" , this._editionToJSON(),
1750
1773
  "options" , this.options,
1751
1774
  "valuesOptions" , this.valuesOptions,
1752
1775
  "values" , this.values,
@@ -1882,7 +1905,11 @@ var ruleRe = /^required|optional|repeated$/;
1882
1905
  * @throws {TypeError} If arguments are invalid
1883
1906
  */
1884
1907
  Field.fromJSON = function fromJSON(name, json) {
1885
- return new Field(name, json.id, json.type, json.rule, json.extend, json.options, json.comment);
1908
+ var field = new Field(name, json.id, json.type, json.rule, json.extend, json.options, json.comment);
1909
+ if (json.edition)
1910
+ field._edition = json.edition;
1911
+ field._defaultEdition = "proto3"; // For backwards-compatibility.
1912
+ return field;
1886
1913
  };
1887
1914
 
1888
1915
  /**
@@ -1952,18 +1979,6 @@ function Field(name, id, type, rule, extend, options, comment) {
1952
1979
  */
1953
1980
  this.extend = extend || undefined; // toJSON
1954
1981
 
1955
- /**
1956
- * Whether this field is required.
1957
- * @type {boolean}
1958
- */
1959
- this.required = rule === "required";
1960
-
1961
- /**
1962
- * Whether this field is optional.
1963
- * @type {boolean}
1964
- */
1965
- this.optional = !this.required;
1966
-
1967
1982
  /**
1968
1983
  * Whether this field is repeated.
1969
1984
  * @type {boolean}
@@ -2030,13 +2045,6 @@ function Field(name, id, type, rule, extend, options, comment) {
2030
2045
  */
2031
2046
  this.declaringField = null;
2032
2047
 
2033
- /**
2034
- * Internally remembers whether this field is packed.
2035
- * @type {boolean|null}
2036
- * @private
2037
- */
2038
- this._packed = null;
2039
-
2040
2048
  /**
2041
2049
  * Comment for this field.
2042
2050
  * @type {string|null}
@@ -2045,17 +2053,69 @@ function Field(name, id, type, rule, extend, options, comment) {
2045
2053
  }
2046
2054
 
2047
2055
  /**
2048
- * Determines whether this field is packed. Only relevant when repeated and working with proto2.
2056
+ * Determines whether this field is required.
2057
+ * @name Field#required
2058
+ * @type {boolean}
2059
+ * @readonly
2060
+ */
2061
+ Object.defineProperty(Field.prototype, "required", {
2062
+ get: function() {
2063
+ return this._features.field_presence === "LEGACY_REQUIRED";
2064
+ }
2065
+ });
2066
+
2067
+ /**
2068
+ * Determines whether this field is not required.
2069
+ * @name Field#optional
2070
+ * @type {boolean}
2071
+ * @readonly
2072
+ */
2073
+ Object.defineProperty(Field.prototype, "optional", {
2074
+ get: function() {
2075
+ return !this.required;
2076
+ }
2077
+ });
2078
+
2079
+ /**
2080
+ * Determines whether this field uses tag-delimited encoding. In proto2 this
2081
+ * corresponded to group syntax.
2082
+ * @name Field#delimited
2083
+ * @type {boolean}
2084
+ * @readonly
2085
+ */
2086
+ Object.defineProperty(Field.prototype, "delimited", {
2087
+ get: function() {
2088
+ return this.resolvedType instanceof Type &&
2089
+ this._features.message_encoding === "DELIMITED";
2090
+ }
2091
+ });
2092
+
2093
+ /**
2094
+ * Determines whether this field is packed. Only relevant when repeated.
2049
2095
  * @name Field#packed
2050
2096
  * @type {boolean}
2051
2097
  * @readonly
2052
2098
  */
2053
2099
  Object.defineProperty(Field.prototype, "packed", {
2054
2100
  get: function() {
2055
- // defaults to packed=true if not explicity set to false
2056
- if (this._packed === null)
2057
- this._packed = this.getOption("packed") !== false;
2058
- return this._packed;
2101
+ return this._features.repeated_field_encoding === "PACKED";
2102
+ }
2103
+ });
2104
+
2105
+ /**
2106
+ * Determines whether this field tracks presence.
2107
+ * @name Field#hasPresence
2108
+ * @type {boolean}
2109
+ * @readonly
2110
+ */
2111
+ Object.defineProperty(Field.prototype, "hasPresence", {
2112
+ get: function() {
2113
+ if (this.repeated || this.map) {
2114
+ return false;
2115
+ }
2116
+ return this.partOf || // oneofs
2117
+ this.declaringField || this.extensionField || // extensions
2118
+ this._features.field_presence !== "IMPLICIT";
2059
2119
  }
2060
2120
  });
2061
2121
 
@@ -2063,8 +2123,6 @@ Object.defineProperty(Field.prototype, "packed", {
2063
2123
  * @override
2064
2124
  */
2065
2125
  Field.prototype.setOption = function setOption(name, value, ifNotSet) {
2066
- if (name === "packed") // clear cached before setting
2067
- this._packed = null;
2068
2126
  return ReflectionObject.prototype.setOption.call(this, name, value, ifNotSet);
2069
2127
  };
2070
2128
 
@@ -2092,6 +2150,7 @@ Field.prototype.setOption = function setOption(name, value, ifNotSet) {
2092
2150
  Field.prototype.toJSON = function toJSON(toJSONOptions) {
2093
2151
  var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
2094
2152
  return util.toObject([
2153
+ "edition" , this._editionToJSON(),
2095
2154
  "rule" , this.rule !== "optional" && this.rule || undefined,
2096
2155
  "type" , this.type,
2097
2156
  "id" , this.id,
@@ -2131,7 +2190,7 @@ Field.prototype.resolve = function resolve() {
2131
2190
 
2132
2191
  // remove unnecessary options
2133
2192
  if (this.options) {
2134
- if (this.options.packed === true || this.options.packed !== undefined && this.resolvedType && !(this.resolvedType instanceof Enum))
2193
+ if (this.options.packed !== undefined && this.resolvedType && !(this.resolvedType instanceof Enum))
2135
2194
  delete this.options.packed;
2136
2195
  if (!Object.keys(this.options).length)
2137
2196
  this.options = undefined;
@@ -2169,6 +2228,40 @@ Field.prototype.resolve = function resolve() {
2169
2228
  return ReflectionObject.prototype.resolve.call(this);
2170
2229
  };
2171
2230
 
2231
+ /**
2232
+ * Infers field features from legacy syntax that may have been specified differently.
2233
+ * in older editions.
2234
+ * @param {string|undefined} edition The edition this proto is on, or undefined if pre-editions
2235
+ * @returns {object} The feature values to override
2236
+ */
2237
+ Field.prototype._inferLegacyProtoFeatures = function _inferLegacyProtoFeatures(edition) {
2238
+ if (edition !== "proto2" && edition !== "proto3") {
2239
+ return {};
2240
+ }
2241
+
2242
+ var features = {};
2243
+ this.resolve();
2244
+ if (this.rule === "required") {
2245
+ features.field_presence = "LEGACY_REQUIRED";
2246
+ }
2247
+ if (this.resolvedType instanceof Type && this.resolvedType.group) {
2248
+ features.message_encoding = "DELIMITED";
2249
+ }
2250
+ if (this.getOption("packed") === true) {
2251
+ features.repeated_field_encoding = "PACKED";
2252
+ } else if (this.getOption("packed") === false) {
2253
+ features.repeated_field_encoding = "EXPANDED";
2254
+ }
2255
+ return features;
2256
+ };
2257
+
2258
+ /**
2259
+ * @override
2260
+ */
2261
+ Field.prototype._resolveFeatures = function _resolveFeatures(edition) {
2262
+ return ReflectionObject.prototype._resolveFeatures.call(this, this._edition || edition);
2263
+ };
2264
+
2172
2265
  /**
2173
2266
  * Decorator function as returned by {@link Field.d} and {@link MapField.d} (TypeScript).
2174
2267
  * @typedef FieldDecorator
@@ -3040,6 +3133,15 @@ Namespace.prototype.add = function add(object) {
3040
3133
  }
3041
3134
  }
3042
3135
  this.nested[object.name] = object;
3136
+
3137
+ if (!(this instanceof Type || this instanceof Service || this instanceof Enum || this instanceof Field)) {
3138
+ // This is a package or a root namespace.
3139
+ if (!object._edition) {
3140
+ // Make sure that some edition is set if it hasn't already been specified.
3141
+ object._edition = object._defaultEdition;
3142
+ }
3143
+ }
3144
+
3043
3145
  object.onAdd(this);
3044
3146
  return clearCache(this);
3045
3147
  };
@@ -3102,12 +3204,26 @@ Namespace.prototype.define = function define(path, json) {
3102
3204
  */
3103
3205
  Namespace.prototype.resolveAll = function resolveAll() {
3104
3206
  var nested = this.nestedArray, i = 0;
3207
+ this.resolve();
3105
3208
  while (i < nested.length)
3106
3209
  if (nested[i] instanceof Namespace)
3107
3210
  nested[i++].resolveAll();
3108
3211
  else
3109
3212
  nested[i++].resolve();
3110
- return this.resolve();
3213
+ return this;
3214
+ };
3215
+
3216
+ /**
3217
+ * @override
3218
+ */
3219
+ Namespace.prototype._resolveFeaturesRecursive = function _resolveFeaturesRecursive(edition) {
3220
+ edition = this._edition || edition;
3221
+
3222
+ ReflectionObject.prototype._resolveFeaturesRecursive.call(this, edition);
3223
+ this.nestedArray.forEach(nested => {
3224
+ nested._resolveFeaturesRecursive(edition);
3225
+ });
3226
+ return this;
3111
3227
  };
3112
3228
 
3113
3229
  /**
@@ -3238,10 +3354,17 @@ module.exports = ReflectionObject;
3238
3354
 
3239
3355
  ReflectionObject.className = "ReflectionObject";
3240
3356
 
3357
+ const OneOf = require(23);
3241
3358
  var util = require(33);
3242
3359
 
3243
3360
  var Root; // cyclic
3244
3361
 
3362
+ /* eslint-disable no-warning-comments */
3363
+ // TODO: Replace with embedded proto.
3364
+ var editions2023Defaults = {enum_type: "OPEN", field_presence: "EXPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY"};
3365
+ var proto2Defaults = {enum_type: "CLOSED", field_presence: "EXPLICIT", json_format: "LEGACY_BEST_EFFORT", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "EXPANDED", utf8_validation: "NONE"};
3366
+ var proto3Defaults = {enum_type: "OPEN", field_presence: "IMPLICIT", json_format: "ALLOW", message_encoding: "LENGTH_PREFIXED", repeated_field_encoding: "PACKED", utf8_validation: "VERIFY"};
3367
+
3245
3368
  /**
3246
3369
  * Constructs a new reflection object instance.
3247
3370
  * @classdesc Base class of all reflection objects.
@@ -3276,6 +3399,25 @@ function ReflectionObject(name, options) {
3276
3399
  */
3277
3400
  this.name = name;
3278
3401
 
3402
+ /**
3403
+ * The edition specified for this object. Only relevant for top-level objects.
3404
+ * @type {string}
3405
+ */
3406
+ this._edition = null;
3407
+
3408
+ /**
3409
+ * The default edition to use for this object if none is specified. For legacy reasons,
3410
+ * this is proto2 except in the JSON parsing case where it was proto3.
3411
+ * @type {string}
3412
+ */
3413
+ this._defaultEdition = "proto2";
3414
+
3415
+ /**
3416
+ * Resolved Features.
3417
+ * @type {object}
3418
+ */
3419
+ this._features = {};
3420
+
3279
3421
  /**
3280
3422
  * Parent namespace.
3281
3423
  * @type {Namespace|null}
@@ -3381,11 +3523,84 @@ ReflectionObject.prototype.onRemove = function onRemove(parent) {
3381
3523
  ReflectionObject.prototype.resolve = function resolve() {
3382
3524
  if (this.resolved)
3383
3525
  return this;
3384
- if (this.root instanceof Root)
3385
- this.resolved = true; // only if part of a root
3526
+ if (this instanceof Root) {
3527
+ this._resolveFeaturesRecursive(this._edition);
3528
+ this.resolved = true;
3529
+ }
3386
3530
  return this;
3387
3531
  };
3388
3532
 
3533
+ /**
3534
+ * Resolves this objects editions features.
3535
+ * @param {string} edition The edition we're currently resolving for.
3536
+ * @returns {ReflectionObject} `this`
3537
+ */
3538
+ ReflectionObject.prototype._resolveFeaturesRecursive = function _resolveFeaturesRecursive(edition) {
3539
+ return this._resolveFeatures(this._edition || edition);
3540
+ };
3541
+
3542
+ /**
3543
+ * Resolves child features from parent features
3544
+ * @param {string} edition The edition we're currently resolving for.
3545
+ * @returns {undefined}
3546
+ */
3547
+ ReflectionObject.prototype._resolveFeatures = function _resolveFeatures(edition) {
3548
+ var defaults = {};
3549
+
3550
+ /* istanbul ignore if */
3551
+ if (!edition) {
3552
+ throw new Error("Unknown edition for " + this.fullName);
3553
+ }
3554
+
3555
+ var protoFeatures = Object.assign(this.options ? Object.assign({}, this.options.features) : {},
3556
+ this._inferLegacyProtoFeatures(edition));
3557
+
3558
+ if (this._edition) {
3559
+ // For a namespace marked with a specific edition, reset defaults.
3560
+ /* istanbul ignore else */
3561
+ if (edition === "proto2") {
3562
+ defaults = Object.assign({}, proto2Defaults);
3563
+ } else if (edition === "proto3") {
3564
+ defaults = Object.assign({}, proto3Defaults);
3565
+ } else if (edition === "2023") {
3566
+ defaults = Object.assign({}, editions2023Defaults);
3567
+ } else {
3568
+ throw new Error("Unknown edition: " + edition);
3569
+ }
3570
+ this._features = Object.assign(defaults, protoFeatures || {});
3571
+ return;
3572
+ }
3573
+
3574
+ // fields in Oneofs aren't actually children of them, so we have to
3575
+ // special-case it
3576
+ /* istanbul ignore else */
3577
+ if (this.partOf instanceof OneOf) {
3578
+ var lexicalParentFeaturesCopy = Object.assign({}, this.partOf._features);
3579
+ this._features = Object.assign(lexicalParentFeaturesCopy, protoFeatures || {});
3580
+ } else if (this.declaringField) {
3581
+ // Skip feature resolution of sister fields.
3582
+ } else if (this.parent) {
3583
+ var parentFeaturesCopy = Object.assign({}, this.parent._features);
3584
+ this._features = Object.assign(parentFeaturesCopy, protoFeatures || {});
3585
+ } else {
3586
+ throw new Error("Unable to find a parent for " + this.fullName);
3587
+ }
3588
+ if (this.extensionField) {
3589
+ // Sister fields should have the same features as their extensions.
3590
+ this.extensionField._features = this._features;
3591
+ }
3592
+ };
3593
+
3594
+ /**
3595
+ * Infers features from legacy syntax that may have been specified differently.
3596
+ * in older editions.
3597
+ * @param {string|undefined} edition The edition this proto is on, or undefined if pre-editions
3598
+ * @returns {object} The feature values to override
3599
+ */
3600
+ ReflectionObject.prototype._inferLegacyProtoFeatures = function _inferLegacyProtoFeatures(/*edition*/) {
3601
+ return {};
3602
+ };
3603
+
3389
3604
  /**
3390
3605
  * Gets an option value.
3391
3606
  * @param {string} name Option name
@@ -3401,12 +3616,19 @@ ReflectionObject.prototype.getOption = function getOption(name) {
3401
3616
  * Sets an option.
3402
3617
  * @param {string} name Option name
3403
3618
  * @param {*} value Option value
3404
- * @param {boolean} [ifNotSet] Sets the option only if it isn't currently set
3619
+ * @param {boolean|undefined} [ifNotSet] Sets the option only if it isn't currently set
3405
3620
  * @returns {ReflectionObject} `this`
3406
3621
  */
3407
3622
  ReflectionObject.prototype.setOption = function setOption(name, value, ifNotSet) {
3408
- if (!ifNotSet || !this.options || this.options[name] === undefined)
3409
- (this.options || (this.options = {}))[name] = value;
3623
+ if (!this.options)
3624
+ this.options = {};
3625
+ if (/^features\./.test(name)) {
3626
+ util.setProperty(this.options, name, value, ifNotSet);
3627
+ } else if (!ifNotSet || this.options[name] === undefined) {
3628
+ if (this.getOption(name) !== value) this.resolved = false;
3629
+ this.options[name] = value;
3630
+ }
3631
+
3410
3632
  return this;
3411
3633
  };
3412
3634
 
@@ -3430,10 +3652,11 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3430
3652
  });
3431
3653
  if (opt) {
3432
3654
  // If we found an existing option - just merge the property value
3655
+ // (If it's a feature, will just write over)
3433
3656
  var newValue = opt[name];
3434
3657
  util.setProperty(newValue, propName, value);
3435
3658
  } else {
3436
- // otherwise, create a new option, set it's property and add it to the list
3659
+ // otherwise, create a new option, set its property and add it to the list
3437
3660
  opt = {};
3438
3661
  opt[name] = util.setProperty({}, propName, value);
3439
3662
  parsedOptions.push(opt);
@@ -3444,6 +3667,7 @@ ReflectionObject.prototype.setParsedOption = function setParsedOption(name, valu
3444
3667
  newOpt[name] = value;
3445
3668
  parsedOptions.push(newOpt);
3446
3669
  }
3670
+
3447
3671
  return this;
3448
3672
  };
3449
3673
 
@@ -3472,12 +3696,25 @@ ReflectionObject.prototype.toString = function toString() {
3472
3696
  return className;
3473
3697
  };
3474
3698
 
3699
+ /**
3700
+ * Converts the edition this object is pinned to for JSON format.
3701
+ * @returns {string|undefined} The edition string for JSON representation
3702
+ */
3703
+ ReflectionObject.prototype._editionToJSON = function _editionToJSON() {
3704
+ if (!this._edition || this._edition === "proto3") {
3705
+ // Avoid emitting proto3 since we need to default to it for backwards
3706
+ // compatibility anyway.
3707
+ return undefined;
3708
+ }
3709
+ return this._edition;
3710
+ };
3711
+
3475
3712
  // Sets up cyclic dependencies (called in index-light)
3476
3713
  ReflectionObject._configure = function(Root_) {
3477
3714
  Root = Root_;
3478
3715
  };
3479
3716
 
3480
- },{"33":33}],23:[function(require,module,exports){
3717
+ },{"23":23,"33":33}],23:[function(require,module,exports){
3481
3718
  "use strict";
3482
3719
  module.exports = OneOf;
3483
3720
 
@@ -3651,6 +3888,25 @@ OneOf.prototype.onRemove = function onRemove(parent) {
3651
3888
  ReflectionObject.prototype.onRemove.call(this, parent);
3652
3889
  };
3653
3890
 
3891
+ /**
3892
+ * Determines whether this field corresponds to a synthetic oneof created for
3893
+ * a proto3 optional field. No behavioral logic should depend on this, but it
3894
+ * can be relevant for reflection.
3895
+ * @name OneOf#isProto3Optional
3896
+ * @type {boolean}
3897
+ * @readonly
3898
+ */
3899
+ Object.defineProperty(OneOf.prototype, "isProto3Optional", {
3900
+ get: function() {
3901
+ if (this.fieldsArray == null || this.fieldsArray.length !== 1) {
3902
+ return false;
3903
+ }
3904
+
3905
+ var field = this.fieldsArray[0];
3906
+ return field.options != null && field.options["proto3_optional"] === true;
3907
+ }
3908
+ });
3909
+
3654
3910
  /**
3655
3911
  * Decorator function as returned by {@link OneOf.d} (TypeScript).
3656
3912
  * @typedef OneOfDecorator
@@ -4191,11 +4447,14 @@ function Root(options) {
4191
4447
  * @type {string[]}
4192
4448
  */
4193
4449
  this.files = [];
4450
+
4451
+ // Default to proto2 if unspecified.
4452
+ this._edition = "proto2";
4194
4453
  }
4195
4454
 
4196
4455
  /**
4197
4456
  * Loads a namespace descriptor into a root namespace.
4198
- * @param {INamespace} json Nameespace descriptor
4457
+ * @param {INamespace} json Namespace descriptor
4199
4458
  * @param {Root} [root] Root namespace, defaults to create a new one if omitted
4200
4459
  * @returns {Root} Root namespace
4201
4460
  */
@@ -4204,7 +4463,7 @@ Root.fromJSON = function fromJSON(json, root) {
4204
4463
  root = new Root();
4205
4464
  if (json.options)
4206
4465
  root.setOptions(json.options);
4207
- return root.addJSON(json.nested);
4466
+ return root.addJSON(json.nested).resolveAll();
4208
4467
  };
4209
4468
 
4210
4469
  /**
@@ -4244,20 +4503,26 @@ Root.prototype.load = function load(filename, options, callback) {
4244
4503
  options = undefined;
4245
4504
  }
4246
4505
  var self = this;
4247
- if (!callback)
4506
+ if (!callback) {
4248
4507
  return util.asPromise(load, self, filename, options);
4508
+ }
4249
4509
 
4250
4510
  var sync = callback === SYNC; // undocumented
4251
4511
 
4252
4512
  // Finishes loading by calling the callback (exactly once)
4253
4513
  function finish(err, root) {
4254
4514
  /* istanbul ignore if */
4255
- if (!callback)
4515
+ if (!callback) {
4256
4516
  return;
4257
- if (sync)
4517
+ }
4518
+ if (sync) {
4258
4519
  throw err;
4520
+ }
4259
4521
  var cb = callback;
4260
4522
  callback = null;
4523
+ if (root) {
4524
+ root.resolveAll();
4525
+ }
4261
4526
  cb(err, root);
4262
4527
  }
4263
4528
 
@@ -4295,8 +4560,9 @@ Root.prototype.load = function load(filename, options, callback) {
4295
4560
  } catch (err) {
4296
4561
  finish(err);
4297
4562
  }
4298
- if (!sync && !queued)
4563
+ if (!sync && !queued) {
4299
4564
  finish(null, self); // only once anyway
4565
+ }
4300
4566
  }
4301
4567
 
4302
4568
  // Fetches a single file
@@ -4304,15 +4570,16 @@ Root.prototype.load = function load(filename, options, callback) {
4304
4570
  filename = getBundledFileName(filename) || filename;
4305
4571
 
4306
4572
  // Skip if already loaded / attempted
4307
- if (self.files.indexOf(filename) > -1)
4573
+ if (self.files.indexOf(filename) > -1) {
4308
4574
  return;
4575
+ }
4309
4576
  self.files.push(filename);
4310
4577
 
4311
4578
  // Shortcut bundled definitions
4312
4579
  if (filename in common) {
4313
- if (sync)
4580
+ if (sync) {
4314
4581
  process(filename, common[filename]);
4315
- else {
4582
+ } else {
4316
4583
  ++queued;
4317
4584
  setTimeout(function() {
4318
4585
  --queued;
@@ -4338,8 +4605,9 @@ Root.prototype.load = function load(filename, options, callback) {
4338
4605
  self.fetch(filename, function(err, source) {
4339
4606
  --queued;
4340
4607
  /* istanbul ignore if */
4341
- if (!callback)
4608
+ if (!callback) {
4342
4609
  return; // terminated meanwhile
4610
+ }
4343
4611
  if (err) {
4344
4612
  /* istanbul ignore else */
4345
4613
  if (!weak)
@@ -4356,17 +4624,21 @@ Root.prototype.load = function load(filename, options, callback) {
4356
4624
 
4357
4625
  // Assembling the root namespace doesn't require working type
4358
4626
  // references anymore, so we can load everything in parallel
4359
- if (util.isString(filename))
4627
+ if (util.isString(filename)) {
4360
4628
  filename = [ filename ];
4629
+ }
4361
4630
  for (var i = 0, resolved; i < filename.length; ++i)
4362
4631
  if (resolved = self.resolvePath("", filename[i]))
4363
4632
  fetch(resolved);
4364
-
4365
- if (sync)
4633
+ self.resolveAll();
4634
+ if (sync) {
4366
4635
  return self;
4367
- if (!queued)
4636
+ }
4637
+ if (!queued) {
4368
4638
  finish(null, self);
4369
- return undefined;
4639
+ }
4640
+
4641
+ return self;
4370
4642
  };
4371
4643
  // function load(filename:string, options:IParseOptions, callback:LoadCallback):undefined
4372
4644
 
@@ -4785,7 +5057,10 @@ Service.fromJSON = function fromJSON(name, json) {
4785
5057
  service.add(Method.fromJSON(names[i], json.methods[names[i]]));
4786
5058
  if (json.nested)
4787
5059
  service.addJSON(json.nested);
5060
+ if (json.edition)
5061
+ service._edition = json.edition;
4788
5062
  service.comment = json.comment;
5063
+ service._defaultEdition = "proto3"; // For backwards-compatibility.
4789
5064
  return service;
4790
5065
  };
4791
5066
 
@@ -4798,6 +5073,7 @@ Service.prototype.toJSON = function toJSON(toJSONOptions) {
4798
5073
  var inherited = Namespace.prototype.toJSON.call(this, toJSONOptions);
4799
5074
  var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
4800
5075
  return util.toObject([
5076
+ "edition" , this._editionToJSON(),
4801
5077
  "options" , inherited && inherited.options || undefined,
4802
5078
  "methods" , Namespace.arrayToJSON(this.methodsArray, toJSONOptions) || /* istanbul ignore next */ {},
4803
5079
  "nested" , inherited && inherited.nested || undefined,
@@ -4834,10 +5110,24 @@ Service.prototype.get = function get(name) {
4834
5110
  * @override
4835
5111
  */
4836
5112
  Service.prototype.resolveAll = function resolveAll() {
5113
+ Namespace.prototype.resolve.call(this);
4837
5114
  var methods = this.methodsArray;
4838
5115
  for (var i = 0; i < methods.length; ++i)
4839
5116
  methods[i].resolve();
4840
- return Namespace.prototype.resolve.call(this);
5117
+ return this;
5118
+ };
5119
+
5120
+ /**
5121
+ * @override
5122
+ */
5123
+ Service.prototype._resolveFeaturesRecursive = function _resolveFeaturesRecursive(edition) {
5124
+ edition = this._edition || edition;
5125
+
5126
+ Namespace.prototype._resolveFeaturesRecursive.call(this, edition);
5127
+ this.methodsArray.forEach(method => {
5128
+ method._resolveFeaturesRecursive(edition);
5129
+ });
5130
+ return this;
4841
5131
  };
4842
5132
 
4843
5133
  /**
@@ -5169,6 +5459,9 @@ Type.fromJSON = function fromJSON(name, json) {
5169
5459
  type.group = true;
5170
5460
  if (json.comment)
5171
5461
  type.comment = json.comment;
5462
+ if (json.edition)
5463
+ type._edition = json.edition;
5464
+ type._defaultEdition = "proto3"; // For backwards-compatibility.
5172
5465
  return type;
5173
5466
  };
5174
5467
 
@@ -5181,6 +5474,7 @@ Type.prototype.toJSON = function toJSON(toJSONOptions) {
5181
5474
  var inherited = Namespace.prototype.toJSON.call(this, toJSONOptions);
5182
5475
  var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
5183
5476
  return util.toObject([
5477
+ "edition" , this._editionToJSON(),
5184
5478
  "options" , inherited && inherited.options || undefined,
5185
5479
  "oneofs" , Namespace.arrayToJSON(this.oneofsArray, toJSONOptions),
5186
5480
  "fields" , Namespace.arrayToJSON(this.fieldsArray.filter(function(obj) { return !obj.declaringField; }), toJSONOptions) || {},
@@ -5196,13 +5490,30 @@ Type.prototype.toJSON = function toJSON(toJSONOptions) {
5196
5490
  * @override
5197
5491
  */
5198
5492
  Type.prototype.resolveAll = function resolveAll() {
5199
- var fields = this.fieldsArray, i = 0;
5200
- while (i < fields.length)
5201
- fields[i++].resolve();
5493
+ Namespace.prototype.resolveAll.call(this);
5202
5494
  var oneofs = this.oneofsArray; i = 0;
5203
5495
  while (i < oneofs.length)
5204
5496
  oneofs[i++].resolve();
5205
- return Namespace.prototype.resolveAll.call(this);
5497
+ var fields = this.fieldsArray, i = 0;
5498
+ while (i < fields.length)
5499
+ fields[i++].resolve();
5500
+ return this;
5501
+ };
5502
+
5503
+ /**
5504
+ * @override
5505
+ */
5506
+ Type.prototype._resolveFeaturesRecursive = function _resolveFeaturesRecursive(edition) {
5507
+ edition = this._edition || edition;
5508
+
5509
+ Namespace.prototype._resolveFeaturesRecursive.call(this, edition);
5510
+ this.oneofsArray.forEach(oneof => {
5511
+ oneof._resolveFeatures(edition);
5512
+ });
5513
+ this.fieldsArray.forEach(field => {
5514
+ field._resolveFeatures(edition);
5515
+ });
5516
+ return this;
5206
5517
  };
5207
5518
 
5208
5519
  /**
@@ -5857,9 +6168,10 @@ util.decorateEnum = function decorateEnum(object) {
5857
6168
  * @param {Object.<string,*>} dst Destination object
5858
6169
  * @param {string} path dot '.' delimited path of the property to set
5859
6170
  * @param {Object} value the value to set
6171
+ * @param {boolean|undefined} [ifNotSet] Sets the option only if it isn't currently set
5860
6172
  * @returns {Object.<string,*>} Destination object
5861
6173
  */
5862
- util.setProperty = function setProperty(dst, path, value) {
6174
+ util.setProperty = function setProperty(dst, path, value, ifNotSet) {
5863
6175
  function setProp(dst, path, value) {
5864
6176
  var part = path.shift();
5865
6177
  if (part === "__proto__" || part === "prototype") {
@@ -5869,6 +6181,8 @@ util.setProperty = function setProperty(dst, path, value) {
5869
6181
  dst[part] = setProp(dst[part] || {}, path, value);
5870
6182
  } else {
5871
6183
  var prevValue = dst[part];
6184
+ if (prevValue && ifNotSet)
6185
+ return dst;
5872
6186
  if (prevValue)
5873
6187
  value = [].concat(prevValue).concat(value);
5874
6188
  dst[part] = value;