protobufjs 8.6.4 → 8.6.6

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/ext/descriptor.js CHANGED
@@ -251,7 +251,7 @@ function Type_fromDescriptor(descriptor, ctx, nested, depth) {
251
251
 
252
252
  var type = new Type(descriptor.name.length ? descriptor.name : "Type" + unnamedMessageIndex++, fromDescriptorOptions(descriptor.options, exports.MessageOptions)),
253
253
  i,
254
- mapEntries = {};
254
+ mapEntries = Object.create(null);
255
255
 
256
256
  if (!nested) {
257
257
  type._edition = ctx.edition;
@@ -704,6 +704,8 @@ function Enum_fromDescriptor(descriptor, ctx, nested) {
704
704
  valueName = name && name.length ? name : "NAME" + (descriptor.value[i].number || 0),
705
705
  value = descriptor.value[i].number || 0,
706
706
  options = fromDescriptorOptions(descriptor.value[i].options, exports.EnumValueOptions);
707
+ if (valueName === "__proto__")
708
+ continue;
707
709
  values[valueName] = value;
708
710
  if (options)
709
711
  (valuesOptions || (valuesOptions = {}))[valueName] = options;
@@ -1006,7 +1008,7 @@ function fromDescriptorType(type) {
1006
1008
  }
1007
1009
 
1008
1010
  function groupTypeNames() {
1009
- var names = {};
1011
+ var names = Object.create(null);
1010
1012
  for (var a = 0; a < arguments.length; ++a) {
1011
1013
  var fields = arguments[a];
1012
1014
  if (!fields)
package/ext/protojson.js CHANGED
@@ -241,8 +241,10 @@ function readEnum(enm, value, name, options) {
241
241
  throw invalid(name, value, "unknown enum value");
242
242
  }
243
243
  if (typeof value === "number") {
244
- if (!isFinite(value) || Math.floor(value) !== value)
244
+ if ((value | 0) !== value)
245
245
  throw invalid(name, value, "invalid enum number");
246
+ if (enm._features.enum_type === "CLOSED" && enm.valuesById[value] === undefined)
247
+ throw invalid(name, value, "unknown enum value");
246
248
  return value;
247
249
  }
248
250
  if (value === null && enm.fullName === ".google.protobuf.NullValue")
package/ext/textformat.js CHANGED
@@ -464,17 +464,16 @@ Parser.prototype.parseAny = function parseAny(type, typeUrl, object, seen, depth
464
464
  };
465
465
 
466
466
  Parser.prototype.parseMapField = function parseMapField(field, object, depth) {
467
- if (!object[field.name])
468
- object[field.name] = {};
467
+ var map = getField(object, field, {});
469
468
  if (this.tn.skip("[")) {
470
469
  if (!this.tn.skip("]")) {
471
470
  do {
472
- addMapEntry(field, object[field.name], this.parseMapEntry(field, depth + 1));
471
+ addMapEntry(field, map, this.parseMapEntry(field, depth + 1));
473
472
  } while (this.tn.skip(","));
474
473
  this.tn.expect("]");
475
474
  }
476
475
  } else
477
- addMapEntry(field, object[field.name], this.parseMapEntry(field, depth + 1));
476
+ addMapEntry(field, map, this.parseMapEntry(field, depth + 1));
478
477
  };
479
478
 
480
479
  Parser.prototype.parseMessageFieldDelimiter = function parseMessageFieldDelimiter() {
@@ -637,7 +636,7 @@ Parser.prototype.skipBalanced = function skipBalanced(open, close, depth) {
637
636
 
638
637
  function addField(object, seen, field, value) {
639
638
  if (field.repeated) {
640
- (object[field.name] || (object[field.name] = [])).push(value);
639
+ getField(object, field, []).push(value);
641
640
  return;
642
641
  }
643
642
  if (Object.prototype.hasOwnProperty.call(seen, field.name))
@@ -649,6 +648,18 @@ function addField(object, seen, field, value) {
649
648
  seen[oneofName] = true;
650
649
  }
651
650
  seen[field.name] = true;
651
+ setField(object, field, value);
652
+ }
653
+
654
+ function getField(object, field, value) {
655
+ if (!Object.prototype.hasOwnProperty.call(object, field.name))
656
+ setField(object, field, value);
657
+ return object[field.name];
658
+ }
659
+
660
+ function setField(object, field, value) {
661
+ if (field.name === "__proto__")
662
+ util.makeProp(object, field.name);
652
663
  object[field.name] = value;
653
664
  }
654
665
 
@@ -661,7 +672,10 @@ function addMapEntry(field, map, entry) {
661
672
  value = Object.prototype.hasOwnProperty.call(entry, "value")
662
673
  ? entry.value
663
674
  : defaultMapValue(valueField);
664
- map[mapKey(keyField, key)] = value;
675
+ var outKey = mapKey(keyField, key);
676
+ if (outKey === "__proto__")
677
+ util.makeProp(map, outKey);
678
+ map[outKey] = value;
665
679
  }
666
680
 
667
681
  function defaultMapValue(field) {
@@ -832,6 +846,12 @@ function parseInteger(token, sign, unsigned, bits) {
832
846
  return parseIntegerBigInt(digits, radix, sign, unsigned, bits);
833
847
 
834
848
  var value = parseInt(digits, radix) * sign;
849
+ if (bits === 32) {
850
+ var min = unsigned ? 0 : -2147483648,
851
+ max = unsigned ? 4294967295 : 2147483647;
852
+ if (value < min || value > max)
853
+ throw Error((unsigned ? "unsigned " : "") + "integer value out of range");
854
+ }
835
855
  if (bits === 64 && util.Long)
836
856
  return util.Long.fromString(String(value), unsigned);
837
857
  return value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "protobufjs",
3
- "version": "8.6.4",
3
+ "version": "8.6.6",
4
4
  "description": "Protocol Buffers for JavaScript & TypeScript.",
5
5
  "author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
6
6
  "license": "BSD-3-Clause",
@@ -55,7 +55,7 @@
55
55
  "bundle-collapser": "^1.3.0",
56
56
  "escodegen": "^1.13.0",
57
57
  "eslint": "^10.0.0",
58
- "eslint-plugin-jsdoc": "^62.9.0",
58
+ "eslint-plugin-jsdoc": "^63.0.0",
59
59
  "espree": "^9.0.0",
60
60
  "estraverse": "^5.1.0",
61
61
  "gh-pages": "^6.0.0",
package/src/converter.js CHANGED
@@ -15,31 +15,33 @@ var Enum = require("./enum"),
15
15
  * @param {Field} field Reflected field
16
16
  * @param {number} fieldIndex Field index
17
17
  * @param {string} prop Property reference
18
+ * @param {string} [dstProp] Repeated destination property reference
18
19
  * @returns {Codegen} Codegen instance
19
20
  * @ignore
20
21
  */
21
- function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
22
- var defaultAlreadyEmitted = false;
22
+ function genValuePartial_fromObject(gen, field, fieldIndex, prop, dstProp) {
23
23
  /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
24
24
  if (field.resolvedType) {
25
- if (field.resolvedType instanceof Enum) { gen
25
+ if (field.resolvedType instanceof Enum) {
26
+ var dst = dstProp
27
+ ? "m" + dstProp + "[m" + dstProp + ".length]"
28
+ : "m" + prop;
29
+ gen
26
30
  ("switch(d%s){", prop);
27
- for (var values = field.resolvedType.values, keys = Object.keys(values), i = 0; i < keys.length; ++i) {
28
- // enum unknown values passthrough
29
- if (values[keys[i]] === field.typeDefault && !defaultAlreadyEmitted) { gen
30
- ("default:")
31
- ("if(typeof d%s===\"number\"){m%s=d%s;break}", prop, prop, prop);
32
- if (!field.repeated) gen // fallback to default value only for
33
- // arrays, to avoid leaving holes.
34
- ("break"); // for non-repeated fields, just ignore
35
- defaultAlreadyEmitted = true;
36
- }
37
- gen
31
+ for (var values = field.resolvedType.values, keys = Object.keys(values), i = 0; i < keys.length; ++i) { gen
38
32
  ("case%j:", keys[i])
39
33
  ("case %i:", values[keys[i]])
40
- ("m%s=%j", prop, values[keys[i]])
34
+ ("%s=%j", dst, values[keys[i]])
41
35
  ("break");
42
- } gen
36
+ }
37
+ gen
38
+ ("default:");
39
+ if (field.resolvedType._features.enum_type !== "CLOSED") {
40
+ gen
41
+ ("if(typeof d%s===\"number\"&&(d%s|0)===d%s)", prop, prop, prop)
42
+ ("%s=d%s", dst, prop);
43
+ }
44
+ gen
43
45
  ("}");
44
46
  } else gen
45
47
  ("if(!util.isObject(d%s))", prop)
@@ -142,10 +144,14 @@ converter.fromObject = function fromObject(mtype) {
142
144
  } else if (field.repeated) { gen
143
145
  ("if(d%s){", prop)
144
146
  ("if(!Array.isArray(d%s))", prop)
145
- ("throw TypeError(%j)", field.fullName + ": array expected")
146
- ("m%s=Array(d%s.length)", prop, prop)
147
+ ("throw TypeError(%j)", field.fullName + ": array expected");
148
+ if (field.resolvedType instanceof Enum) gen
149
+ ("m%s=[]", prop);
150
+ else gen
151
+ ("m%s=Array(d%s.length)", prop, prop);
152
+ gen
147
153
  ("for(var i=0;i<d%s.length;++i){", prop);
148
- genValuePartial_fromObject(gen, field, /* not sorted */ i, prop + "[i]")
154
+ genValuePartial_fromObject(gen, field, /* not sorted */ i, prop + "[i]", field.resolvedType instanceof Enum ? prop : undefined)
149
155
  ("}")
150
156
  ("}");
151
157
 
@@ -162,6 +168,8 @@ converter.fromObject = function fromObject(mtype) {
162
168
  ("if(d%s.length){", prop);
163
169
  else if (field.type === "bool") gen
164
170
  ("if(d%s){", prop);
171
+ else if (field.type === "double" || field.type === "float") gen
172
+ ("if(!Object.is(Number(d%s),0)){", prop);
165
173
  else if (types.long[field.type] !== undefined) gen
166
174
  ("if(typeof d%s===\"object\"?d%s.low||d%s.high:Number(d%s)!==0){", prop, prop, prop, prop);
167
175
  else gen
package/src/decoder.js CHANGED
@@ -13,6 +13,16 @@ function stringMethod(field) {
13
13
  return field._features.utf8_validation === "VERIFY" ? "stringVerify" : "string";
14
14
  }
15
15
 
16
+ function genPreserveUnknown(gen, ref) {
17
+ /* eslint-disable no-unexpected-multiline */
18
+ return gen
19
+ ("if(!r.discardUnknown){")
20
+ ("util.makeProp(m,\"$unknowns\",false);")
21
+ ("(m.$unknowns||(m.$unknowns=[])).push(%s)", ref)
22
+ ("}");
23
+ /* eslint-enable no-unexpected-multiline */
24
+ }
25
+
16
26
  /**
17
27
  * Generates a decoder specific to the specified message type.
18
28
  * @param {Type} mtype Message type
@@ -21,14 +31,14 @@ function stringMethod(field) {
21
31
  function decoder(mtype) {
22
32
  /* eslint-disable no-unexpected-multiline */
23
33
  var hasMapField = false,
24
- hasImplicitPresenceField = false,
34
+ needsValueVar = false,
25
35
  i = 0;
26
36
  for (; i < mtype.fieldsArray.length; ++i) {
27
37
  var pfield = mtype._fieldsArray[i];
28
38
  if (pfield.map)
29
39
  hasMapField = true;
30
- if (!pfield.repeated && !pfield.map && !pfield.hasPresence)
31
- hasImplicitPresenceField = true;
40
+ if (pfield.resolvedType instanceof Enum || !pfield.repeated && !pfield.map && !pfield.hasPresence)
41
+ needsValueVar = true;
32
42
  }
33
43
  var gen = util.codegen(["r", "l", "z", "q", "g"])
34
44
  ("if(!(r instanceof Reader))")
@@ -36,7 +46,7 @@ function decoder(mtype) {
36
46
  ("if(q===undefined)q=0")
37
47
  ("if(q>Reader.recursionLimit)")
38
48
  ("throw Error(\"max depth exceeded\")")
39
- ("var c=l===undefined?r.len:r.pos+l,m=g||new C" + (hasMapField ? ",k,v" : hasImplicitPresenceField ? ",v" : ""))
49
+ ("var c=l===undefined?r.len:r.pos+l,m=g||new C" + (hasMapField ? ",k,v" : needsValueVar ? ",v" : ""))
40
50
  ("while(r.pos<c){")
41
51
  ("var s=r.pos")
42
52
  ("var t=r.tag()")
@@ -48,18 +58,21 @@ function decoder(mtype) {
48
58
  ("var u=t&7")
49
59
  ("switch(t>>>=3){");
50
60
  for (i = 0; i < /* initializes */ mtype.fieldsArray.length; ++i) {
51
- var field = mtype._fieldsArray[i].resolve(),
52
- type = field.resolvedType instanceof Enum ? "int32" : field.type,
53
- ref = "m" + util.safeProp(field.name);
61
+ var field = mtype._fieldsArray[i].resolve(),
62
+ type = field.resolvedType instanceof Enum ? "int32" : field.type,
63
+ ref = "m" + util.safeProp(field.name),
64
+ closed = field.resolvedType instanceof Enum && field.resolvedType._features.enum_type === "CLOSED";
54
65
 
55
66
  // Map fields
56
67
  if (field.map) {
57
68
  gen
58
69
  ("case %i:{", field.id)
59
70
  ("if(u!==2)")
60
- ("break")
71
+ ("break");
72
+ if (!closed) gen
61
73
  ("if(%s===util.emptyObject)", ref)
62
- ("%s={}", ref)
74
+ ("%s={}", ref);
75
+ gen
63
76
  ("var c2=r.uint32()+r.pos");
64
77
 
65
78
  if (types.defaults[field.keyType] !== undefined) gen
@@ -99,6 +112,15 @@ function decoder(mtype) {
99
112
  ("r.skipType(u,q,t2)")
100
113
  ("}");
101
114
 
115
+ if (closed) { gen
116
+ ("if(types[%i].valuesById[v]===undefined){", i);
117
+ genPreserveUnknown(gen, "r.raw(s,r.pos)")
118
+ ("continue")
119
+ ("}")
120
+ ("if(%s===util.emptyObject)", ref)
121
+ ("%s={}", ref);
122
+ }
123
+
102
124
  var val = types.basic[type] === undefined ? "v||new types[" + i + "].ctor" : "v";
103
125
  if (types.long[field.keyType] !== undefined) gen
104
126
  ("%s[typeof k===\"object\"?util.longToHash(k):k]=%s", ref, val);
@@ -116,20 +138,39 @@ function decoder(mtype) {
116
138
  ("{");
117
139
 
118
140
  // Packable (always check for forward and backward compatiblity)
119
- if (types.packed[type] !== undefined) gen
120
- ("if(u===2){")
141
+ if (types.packed[type] !== undefined) {
142
+ gen
143
+ ("if(u===2){");
144
+ if (!closed) gen
121
145
  ("if(!(%s&&%s.length))", ref, ref)
122
- ("%s=[]", ref)
123
- ("var c2=r.uint32()+r.pos")
146
+ ("%s=[]", ref);
147
+ gen
148
+ ("var c2=r.uint32()+r.pos");
149
+ if (closed) {
150
+ gen
151
+ ("while(r.pos<c2){")
152
+ ("s=r.pos")
153
+ ("v=r.%s()", type)
154
+ ("if(types[%i].valuesById[v]!==undefined){", i)
155
+ ("if(!(%s&&%s.length))", ref, ref)
156
+ ("%s=[]", ref)
157
+ ("%s.push(v)", ref)
158
+ ("}else");
159
+ genPreserveUnknown(gen, "util.rawField(" + field.id + ",0,r.raw(s,r.pos))")
160
+ ("}");
161
+ } else gen
124
162
  ("while(r.pos<c2)")
125
- ("%s.push(r.%s())", ref, type)
163
+ ("%s.push(r.%s())", ref, type);
164
+ gen
126
165
  ("continue")
127
166
  ("}");
167
+ }
128
168
 
129
169
  // Non-packed
130
170
  gen
131
171
  ("if(u!==%i)", types.basic[type] === undefined ? field.delimited ? 3 : 2 : types.basic[type])
132
- ("break")
172
+ ("break");
173
+ if (!closed) gen
133
174
  ("if(!(%s&&%s.length))", ref, ref)
134
175
  ("%s=[]", ref);
135
176
  if (types.basic[type] === undefined) {
@@ -137,6 +178,14 @@ function decoder(mtype) {
137
178
  ("%s.push(types[%i].decode(r,undefined,%i,q+1))", ref, i, field.id * 8 + 4);
138
179
  else gen
139
180
  ("%s.push(types[%i].decode(r,r.uint32(),undefined,q+1))", ref, i);
181
+ } else if (closed) { gen
182
+ ("v=r.%s()", type)
183
+ ("if(types[%i].valuesById[v]!==undefined){", i)
184
+ ("if(!(%s&&%s.length))", ref, ref)
185
+ ("%s=[]", ref)
186
+ ("%s.push(v)", ref)
187
+ ("}else");
188
+ genPreserveUnknown(gen, "r.raw(s,r.pos)");
140
189
  } else gen
141
190
  ("%s.push(r.%s())", ref, type === "string" ? stringMethod(field) : type);
142
191
 
@@ -155,33 +204,55 @@ function decoder(mtype) {
155
204
  gen
156
205
  ("case %i:{", field.id)
157
206
  ("if(u!==%i)", types.basic[type])
158
- ("break")
207
+ ("break");
208
+ if (closed) { gen
209
+ ("v=r.%s()", type)
210
+ ("if(types[%i].valuesById[v]!==undefined){", i)
211
+ ("%s=v", ref);
212
+ if (field.partOf) gen
213
+ ("m%s=%j", util.safeProp(field.partOf.name), field.name);
214
+ gen
215
+ ("}else");
216
+ genPreserveUnknown(gen, "r.raw(s,r.pos)");
217
+ } else gen
159
218
  ("%s=r.%s()", ref, type === "string" ? stringMethod(field) : type);
160
219
  } else {
161
220
  gen
162
221
  ("case %i:{", field.id)
163
222
  ("if(u!==%i)", types.basic[type])
164
223
  ("break");
165
- if (field.resolvedType instanceof Enum && field.typeDefault !== 0) gen
166
- // TODO: Protoc rejects open enums whose first value is not zero.
167
- // We should do the same, but for v8 this would be a regression.
168
- ("if((v=r.%s())!==%j)", type, field.typeDefault);
169
- else if (type === "string") gen
170
- ("if((v=r.%s()).length)", stringMethod(field));
171
- else if (type === "bytes") gen
172
- ("if((v=r.%s()).length)", type);
173
- else if (types.long[type] !== undefined) gen
174
- ("if(typeof(v=r.%s())===\"object\"?v.low||v.high:v!==0)", type);
175
- else if (type === "double" || type === "float") gen
176
- ("if((v=r.%s())!==0)", type);
177
- else gen
178
- ("if(v=r.%s())", type);
179
- gen
180
- ("%s=v", ref)
181
- ("else")
182
- ("delete %s", ref); // rare/odd case: later default clears earlier non-default
224
+ if (closed) { gen
225
+ ("v=r.%s()", type)
226
+ ("if(types[%i].valuesById[v]!==undefined){", i)
227
+ ("if(v!==%j)", field.typeDefault)
228
+ ("%s=v", ref)
229
+ ("else")
230
+ ("delete %s", ref)
231
+ ("}else{");
232
+ genPreserveUnknown(gen, "r.raw(s,r.pos)")
233
+ ("}");
234
+ } else {
235
+ if (field.resolvedType instanceof Enum && field.typeDefault !== 0) gen
236
+ // TODO: Protoc rejects open enums whose first value is not zero.
237
+ // We should do the same, but for v8 this would be a regression.
238
+ ("if((v=r.%s())!==%j)", type, field.typeDefault);
239
+ else if (type === "string") gen
240
+ ("if((v=r.%s()).length)", stringMethod(field));
241
+ else if (type === "bytes") gen
242
+ ("if((v=r.%s()).length)", type);
243
+ else if (types.long[type] !== undefined) gen
244
+ ("if(typeof(v=r.%s())===\"object\"?v.low||v.high:v!==0)", type);
245
+ else if (type === "double" || type === "float") gen
246
+ ("if(!Object.is(v=r.%s(),0))", type);
247
+ else gen
248
+ ("if(v=r.%s())", type);
249
+ gen
250
+ ("%s=v", ref)
251
+ ("else")
252
+ ("delete %s", ref); // rare/odd case: later default clears earlier non-default
253
+ }
183
254
  }
184
- if (field.partOf) gen
255
+ if (field.partOf && !closed) gen
185
256
  ("m%s=%j", util.safeProp(field.partOf.name), field.name);
186
257
  gen
187
258
  ("continue")
@@ -191,11 +262,8 @@ function decoder(mtype) {
191
262
  ("}");
192
263
  // Unknown fields
193
264
  gen
194
- ("r.skipType(%s,q,t)", i ? "u" : "t&7")
195
- ("if(!r.discardUnknown){")
196
- ("util.makeProp(m,\"$unknowns\",false);")
197
- ("(m.$unknowns||(m.$unknowns=[])).push(r.raw(s,r.pos))")
198
- ("}")
265
+ ("r.skipType(%s,q,t)", i ? "u" : "t&7");
266
+ genPreserveUnknown(gen, "r.raw(s,r.pos)")
199
267
  ("}")
200
268
  ("if(z!==undefined)")
201
269
  ("throw Error(\"missing end group\")");
package/src/encoder.js CHANGED
@@ -91,8 +91,23 @@ function encoder(mtype) {
91
91
 
92
92
  // Non-repeated
93
93
  } else {
94
- if (!field.required) gen
94
+ if (!field.required)
95
+ if (field.hasPresence || !(field.resolvedType instanceof Enum || types.basic[type] !== undefined)) gen
95
96
  ("if(%s!=null&&Object.hasOwnProperty.call(m,%j))", ref, field.name); // !== undefined && !== null
97
+ else if (field.resolvedType instanceof Enum) gen
98
+ ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)&&%s!==%j)", ref, field.name, ref, field.typeDefault);
99
+ else if (type === "bool") gen
100
+ ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)&&%s!==false)", ref, field.name, ref);
101
+ else if (type === "string") gen
102
+ ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)&&%s!==\"\")", ref, field.name, ref);
103
+ else if (type === "bytes") gen
104
+ ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)&&%s.length)", ref, field.name, ref);
105
+ else if (type === "double" || type === "float") gen
106
+ ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)&&!Object.is(%s,0))", ref, field.name, ref);
107
+ else if (types.long[type] !== undefined) gen
108
+ ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)&&(typeof %s===\"object\"?%s.low||%s.high:%s!==0))", ref, field.name, ref, ref, ref, ref);
109
+ else gen
110
+ ("if(%s!=null&&Object.hasOwnProperty.call(m,%j)&&%s!==0)", ref, field.name, ref);
96
111
 
97
112
  if (wireType === undefined)
98
113
  genTypePartial(gen, field, index, ref);
package/src/enum.js CHANGED
@@ -3,7 +3,15 @@ module.exports = Enum;
3
3
 
4
4
  // extends ReflectionObject
5
5
  var ReflectionObject = require("./object");
6
- ((Enum.prototype = Object.create(ReflectionObject.prototype)).constructor = Enum).className = "Enum";
6
+ Enum.prototype = Object.create(ReflectionObject.prototype, {
7
+ constructor: {
8
+ value: Enum,
9
+ writable: true,
10
+ enumerable: false,
11
+ configurable: true
12
+ }
13
+ });
14
+ Enum.className = "Enum";
7
15
 
8
16
  var Namespace = require("./namespace"),
9
17
  util = require("./util");
@@ -30,7 +38,7 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
30
38
  * Enum values by id.
31
39
  * @type {Object.<number,string>}
32
40
  */
33
- this.valuesById = {};
41
+ this.valuesById = Object.create(null);
34
42
 
35
43
  /**
36
44
  * Enum values by name.
package/src/field.js CHANGED
@@ -3,7 +3,15 @@ module.exports = Field;
3
3
 
4
4
  // extends ReflectionObject
5
5
  var ReflectionObject = require("./object");
6
- ((Field.prototype = Object.create(ReflectionObject.prototype)).constructor = Field).className = "Field";
6
+ Field.prototype = Object.create(ReflectionObject.prototype, {
7
+ constructor: {
8
+ value: Field,
9
+ writable: true,
10
+ enumerable: false,
11
+ configurable: true
12
+ }
13
+ });
14
+ Field.className = "Field";
7
15
 
8
16
  var Enum = require("./enum"),
9
17
  types = require("./types"),
package/src/mapfield.js CHANGED
@@ -3,7 +3,15 @@ module.exports = MapField;
3
3
 
4
4
  // extends Field
5
5
  var Field = require("./field");
6
- ((MapField.prototype = Object.create(Field.prototype)).constructor = MapField).className = "MapField";
6
+ MapField.prototype = Object.create(Field.prototype, {
7
+ constructor: {
8
+ value: MapField,
9
+ writable: true,
10
+ enumerable: false,
11
+ configurable: true
12
+ }
13
+ });
14
+ MapField.className = "MapField";
7
15
 
8
16
  var types = require("./types"),
9
17
  util = require("./util");
package/src/method.js CHANGED
@@ -3,7 +3,15 @@ module.exports = Method;
3
3
 
4
4
  // extends ReflectionObject
5
5
  var ReflectionObject = require("./object");
6
- ((Method.prototype = Object.create(ReflectionObject.prototype)).constructor = Method).className = "Method";
6
+ Method.prototype = Object.create(ReflectionObject.prototype, {
7
+ constructor: {
8
+ value: Method,
9
+ writable: true,
10
+ enumerable: false,
11
+ configurable: true
12
+ }
13
+ });
14
+ Method.className = "Method";
7
15
 
8
16
  var util = require("./util");
9
17
 
package/src/namespace.js CHANGED
@@ -3,7 +3,15 @@ module.exports = Namespace;
3
3
 
4
4
  // extends ReflectionObject
5
5
  var ReflectionObject = require("./object");
6
- ((Namespace.prototype = Object.create(ReflectionObject.prototype)).constructor = Namespace).className = "Namespace";
6
+ Namespace.prototype = Object.create(ReflectionObject.prototype, {
7
+ constructor: {
8
+ value: Namespace,
9
+ writable: true,
10
+ enumerable: false,
11
+ configurable: true
12
+ }
13
+ });
14
+ Namespace.className = "Namespace";
7
15
 
8
16
  var Field = require("./field"),
9
17
  util = require("./util"),
package/src/object.js CHANGED
@@ -270,7 +270,7 @@ ReflectionObject.prototype._inferLegacyProtoFeatures = function _inferLegacyProt
270
270
  * @returns {*} Option value or `undefined` if not set
271
271
  */
272
272
  ReflectionObject.prototype.getOption = function getOption(name) {
273
- if (this.options)
273
+ if (this.options && Object.prototype.hasOwnProperty.call(this.options, name))
274
274
  return this.options[name];
275
275
  return undefined;
276
276
  };
@@ -289,9 +289,12 @@ ReflectionObject.prototype.setOption = function setOption(name, value, ifNotSet)
289
289
  this.options = {};
290
290
  if (/^features\./.test(name)) {
291
291
  util.setProperty(this.options, name, value, ifNotSet);
292
- } else if (!ifNotSet || this.options[name] === undefined) {
293
- if (this.getOption(name) !== value) this.resolved = false;
294
- this.options[name] = value;
292
+ } else {
293
+ var prev = this.getOption(name);
294
+ if (!ifNotSet || prev === undefined) {
295
+ if (prev !== value) this.resolved = false;
296
+ this.options[name] = value;
297
+ }
295
298
  }
296
299
 
297
300
  return this;
@@ -353,15 +356,22 @@ ReflectionObject.prototype.setOptions = function setOptions(options, ifNotSet) {
353
356
 
354
357
  /**
355
358
  * Converts this instance to its string representation.
359
+ * @name ReflectionObject#toString
360
+ * @function
356
361
  * @returns {string} Class name[, space, full name]
357
362
  */
358
- ReflectionObject.prototype.toString = function toString() {
359
- var className = this.constructor.className,
360
- fullName = this.fullName;
361
- if (fullName.length)
362
- return className + " " + fullName;
363
- return className;
364
- };
363
+ Object.defineProperty(ReflectionObject.prototype, "toString", {
364
+ value: function toString() {
365
+ var className = this.constructor.className,
366
+ fullName = this.fullName;
367
+ if (fullName.length)
368
+ return className + " " + fullName;
369
+ return className;
370
+ },
371
+ writable: true,
372
+ enumerable: false,
373
+ configurable: true
374
+ });
365
375
 
366
376
  /**
367
377
  * Converts the edition this object is pinned to for JSON format.
package/src/oneof.js CHANGED
@@ -3,7 +3,15 @@ module.exports = OneOf;
3
3
 
4
4
  // extends ReflectionObject
5
5
  var ReflectionObject = require("./object");
6
- ((OneOf.prototype = Object.create(ReflectionObject.prototype)).constructor = OneOf).className = "OneOf";
6
+ OneOf.prototype = Object.create(ReflectionObject.prototype, {
7
+ constructor: {
8
+ value: OneOf,
9
+ writable: true,
10
+ enumerable: false,
11
+ configurable: true
12
+ }
13
+ });
14
+ OneOf.className = "OneOf";
7
15
 
8
16
  var Field = require("./field"),
9
17
  util = require("./util");