protobufjs 7.4.0 → 7.5.1
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/light/protobuf.js +471 -80
- package/dist/light/protobuf.js.map +1 -1
- package/dist/light/protobuf.min.js +3 -3
- package/dist/light/protobuf.min.js.map +1 -1
- package/dist/minimal/protobuf.js +2 -2
- package/dist/minimal/protobuf.min.js +2 -2
- package/dist/protobuf.js +611 -144
- package/dist/protobuf.js.map +1 -1
- package/dist/protobuf.min.js +3 -3
- package/dist/protobuf.min.js.map +1 -1
- package/index.d.ts +83 -13
- package/package.json +4 -2
- package/src/decoder.js +8 -10
- package/src/encoder.js +1 -1
- package/src/enum.js +25 -0
- package/src/field.js +104 -28
- package/src/namespace.js +92 -13
- package/src/object.js +135 -4
- package/src/oneof.js +19 -0
- package/src/parse.js +139 -63
- package/src/root.js +32 -15
- package/src/service.js +21 -1
- package/src/type.js +27 -4
- package/src/util.js +4 -1
package/index.d.ts
CHANGED
|
@@ -179,6 +179,9 @@ export class Enum extends ReflectionObject {
|
|
|
179
179
|
/** Values options, if any */
|
|
180
180
|
public valuesOptions?: { [k: string]: { [k: string]: any } };
|
|
181
181
|
|
|
182
|
+
/** Resolved values features, if any */
|
|
183
|
+
public _valuesFeatures?: { [k: string]: { [k: string]: any } };
|
|
184
|
+
|
|
182
185
|
/** Reserved ranges, if any. */
|
|
183
186
|
public reserved: (number[]|string)[];
|
|
184
187
|
|
|
@@ -267,9 +270,24 @@ export class Field extends FieldBase {
|
|
|
267
270
|
*/
|
|
268
271
|
public static fromJSON(name: string, json: IField): Field;
|
|
269
272
|
|
|
270
|
-
/** Determines whether this field is
|
|
273
|
+
/** Determines whether this field is required. */
|
|
274
|
+
public readonly required: boolean;
|
|
275
|
+
|
|
276
|
+
/** Determines whether this field is not required. */
|
|
277
|
+
public readonly optional: boolean;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Determines whether this field uses tag-delimited encoding. In proto2 this
|
|
281
|
+
* corresponded to group syntax.
|
|
282
|
+
*/
|
|
283
|
+
public readonly delimited: boolean;
|
|
284
|
+
|
|
285
|
+
/** Determines whether this field is packed. Only relevant when repeated. */
|
|
271
286
|
public readonly packed: boolean;
|
|
272
287
|
|
|
288
|
+
/** Determines whether this field tracks presence. */
|
|
289
|
+
public readonly hasPresence: boolean;
|
|
290
|
+
|
|
273
291
|
/**
|
|
274
292
|
* Field decorator (TypeScript).
|
|
275
293
|
* @param fieldId Field id
|
|
@@ -314,12 +332,6 @@ export class FieldBase extends ReflectionObject {
|
|
|
314
332
|
/** Extended type if different from parent. */
|
|
315
333
|
public extend?: string;
|
|
316
334
|
|
|
317
|
-
/** Whether this field is required. */
|
|
318
|
-
public required: boolean;
|
|
319
|
-
|
|
320
|
-
/** Whether this field is optional. */
|
|
321
|
-
public optional: boolean;
|
|
322
|
-
|
|
323
335
|
/** Whether this field is repeated. */
|
|
324
336
|
public repeated: boolean;
|
|
325
337
|
|
|
@@ -369,6 +381,14 @@ export class FieldBase extends ReflectionObject {
|
|
|
369
381
|
* @throws {Error} If any reference cannot be resolved
|
|
370
382
|
*/
|
|
371
383
|
public resolve(): Field;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Infers field features from legacy syntax that may have been specified differently.
|
|
387
|
+
* in older editions.
|
|
388
|
+
* @param edition The edition this proto is on, or undefined if pre-editions
|
|
389
|
+
* @returns The feature values to override
|
|
390
|
+
*/
|
|
391
|
+
public _inferLegacyProtoFeatures(edition: (string|undefined)): object;
|
|
372
392
|
}
|
|
373
393
|
|
|
374
394
|
/** Field descriptor. */
|
|
@@ -730,6 +750,9 @@ export abstract class NamespaceBase extends ReflectionObject {
|
|
|
730
750
|
/** Nested objects by name. */
|
|
731
751
|
public nested?: { [k: string]: ReflectionObject };
|
|
732
752
|
|
|
753
|
+
/** Whether or not objects contained in this namespace need feature resolution. */
|
|
754
|
+
protected _needsRecursiveFeatureResolution: boolean;
|
|
755
|
+
|
|
733
756
|
/** Nested objects of this namespace as an array for iteration. */
|
|
734
757
|
public readonly nestedArray: ReflectionObject[];
|
|
735
758
|
|
|
@@ -877,6 +900,21 @@ export abstract class ReflectionObject {
|
|
|
877
900
|
/** Unique name within its namespace. */
|
|
878
901
|
public name: string;
|
|
879
902
|
|
|
903
|
+
/** The edition specified for this object. Only relevant for top-level objects. */
|
|
904
|
+
public _edition: string;
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* The default edition to use for this object if none is specified. For legacy reasons,
|
|
908
|
+
* this is proto2 except in the JSON parsing case where it was proto3.
|
|
909
|
+
*/
|
|
910
|
+
public _defaultEdition: string;
|
|
911
|
+
|
|
912
|
+
/** Resolved Features. */
|
|
913
|
+
public _features: object;
|
|
914
|
+
|
|
915
|
+
/** Whether or not features have been resolved. */
|
|
916
|
+
public _featuresResolved: boolean;
|
|
917
|
+
|
|
880
918
|
/** Parent namespace. */
|
|
881
919
|
public parent: (Namespace|null);
|
|
882
920
|
|
|
@@ -919,6 +957,27 @@ export abstract class ReflectionObject {
|
|
|
919
957
|
*/
|
|
920
958
|
public resolve(): ReflectionObject;
|
|
921
959
|
|
|
960
|
+
/**
|
|
961
|
+
* Resolves this objects editions features.
|
|
962
|
+
* @param edition The edition we're currently resolving for.
|
|
963
|
+
* @returns `this`
|
|
964
|
+
*/
|
|
965
|
+
public _resolveFeaturesRecursive(edition: string): ReflectionObject;
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Resolves child features from parent features
|
|
969
|
+
* @param edition The edition we're currently resolving for.
|
|
970
|
+
*/
|
|
971
|
+
public _resolveFeatures(edition: string): void;
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* Infers features from legacy syntax that may have been specified differently.
|
|
975
|
+
* in older editions.
|
|
976
|
+
* @param edition The edition this proto is on, or undefined if pre-editions
|
|
977
|
+
* @returns The feature values to override
|
|
978
|
+
*/
|
|
979
|
+
public _inferLegacyProtoFeatures(edition: (string|undefined)): object;
|
|
980
|
+
|
|
922
981
|
/**
|
|
923
982
|
* Gets an option value.
|
|
924
983
|
* @param name Option name
|
|
@@ -933,7 +992,7 @@ export abstract class ReflectionObject {
|
|
|
933
992
|
* @param [ifNotSet] Sets the option only if it isn't currently set
|
|
934
993
|
* @returns `this`
|
|
935
994
|
*/
|
|
936
|
-
public setOption(name: string, value: any, ifNotSet?: boolean): ReflectionObject;
|
|
995
|
+
public setOption(name: string, value: any, ifNotSet?: (boolean|undefined)): ReflectionObject;
|
|
937
996
|
|
|
938
997
|
/**
|
|
939
998
|
* Sets a parsed option.
|
|
@@ -957,6 +1016,12 @@ export abstract class ReflectionObject {
|
|
|
957
1016
|
* @returns Class name[, space, full name]
|
|
958
1017
|
*/
|
|
959
1018
|
public toString(): string;
|
|
1019
|
+
|
|
1020
|
+
/**
|
|
1021
|
+
* Converts the edition this object is pinned to for JSON format.
|
|
1022
|
+
* @returns The edition string for JSON representation
|
|
1023
|
+
*/
|
|
1024
|
+
public _editionToJSON(): (string|undefined);
|
|
960
1025
|
}
|
|
961
1026
|
|
|
962
1027
|
/** Reflected oneof. */
|
|
@@ -1010,6 +1075,13 @@ export class OneOf extends ReflectionObject {
|
|
|
1010
1075
|
*/
|
|
1011
1076
|
public remove(field: Field): OneOf;
|
|
1012
1077
|
|
|
1078
|
+
/**
|
|
1079
|
+
* Determines whether this field corresponds to a synthetic oneof created for
|
|
1080
|
+
* a proto3 optional field. No behavioral logic should depend on this, but it
|
|
1081
|
+
* can be relevant for reflection.
|
|
1082
|
+
*/
|
|
1083
|
+
public readonly isProto3Optional: boolean;
|
|
1084
|
+
|
|
1013
1085
|
/**
|
|
1014
1086
|
* OneOf decorator (TypeScript).
|
|
1015
1087
|
* @param fieldNames Field names
|
|
@@ -1055,9 +1127,6 @@ export interface IParserResult {
|
|
|
1055
1127
|
/** Weak imports, if any */
|
|
1056
1128
|
weakImports: (string[]|undefined);
|
|
1057
1129
|
|
|
1058
|
-
/** Syntax, if specified (either `"proto2"` or `"proto3"`) */
|
|
1059
|
-
syntax: (string|undefined);
|
|
1060
|
-
|
|
1061
1130
|
/** Populated root instance */
|
|
1062
1131
|
root: Root;
|
|
1063
1132
|
}
|
|
@@ -1255,7 +1324,7 @@ export class Root extends NamespaceBase {
|
|
|
1255
1324
|
|
|
1256
1325
|
/**
|
|
1257
1326
|
* Loads a namespace descriptor into a root namespace.
|
|
1258
|
-
* @param json
|
|
1327
|
+
* @param json Namespace descriptor
|
|
1259
1328
|
* @param [root] Root namespace, defaults to create a new one if omitted
|
|
1260
1329
|
* @returns Root namespace
|
|
1261
1330
|
*/
|
|
@@ -2194,9 +2263,10 @@ export namespace util {
|
|
|
2194
2263
|
* @param dst Destination object
|
|
2195
2264
|
* @param path dot '.' delimited path of the property to set
|
|
2196
2265
|
* @param value the value to set
|
|
2266
|
+
* @param [ifNotSet] Sets the option only if it isn't currently set
|
|
2197
2267
|
* @returns Destination object
|
|
2198
2268
|
*/
|
|
2199
|
-
function setProperty(dst: { [k: string]: any }, path: string, value: object): { [k: string]: any };
|
|
2269
|
+
function setProperty(dst: { [k: string]: any }, path: string, value: object, ifNotSet?: (boolean|undefined)): { [k: string]: any };
|
|
2200
2270
|
|
|
2201
2271
|
/** Decorator root (TypeScript). */
|
|
2202
2272
|
let decorateRoot: Root;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "protobufjs",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.1",
|
|
4
4
|
"versionScheme": "~",
|
|
5
5
|
"description": "Protocol Buffers for JavaScript (& TypeScript).",
|
|
6
6
|
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
|
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
"build:bundle": "gulp --gulpfile scripts/gulpfile.js",
|
|
34
34
|
"build:types": "node cli/bin/pbts --main --global protobuf --out index.d.ts src/ lib/aspromise/index.js lib/base64/index.js lib/codegen/index.js lib/eventemitter/index.js lib/float/index.js lib/fetch/index.js lib/inquire/index.js lib/path/index.js lib/pool/index.js lib/utf8/index.js",
|
|
35
35
|
"changelog": "node scripts/changelog -w",
|
|
36
|
-
"coverage": "
|
|
36
|
+
"coverage": "npm run coverage:test && npm run coverage:report",
|
|
37
|
+
"coverage:test": "nyc --silent tape -r ./lib/tape-adapter tests/*.js tests/node/*.js",
|
|
38
|
+
"coverage:report": "nyc report --reporter=lcov --reporter=text",
|
|
37
39
|
"docs": "jsdoc -c config/jsdoc.json -R README.md --verbose --pedantic",
|
|
38
40
|
"lint": "npm run lint:sources && npm run lint:types",
|
|
39
41
|
"lint:sources": "eslint \"**/*.js\" -c config/eslint.json",
|
package/src/decoder.js
CHANGED
|
@@ -16,16 +16,14 @@ function missing(field) {
|
|
|
16
16
|
*/
|
|
17
17
|
function decoder(mtype) {
|
|
18
18
|
/* eslint-disable no-unexpected-multiline */
|
|
19
|
-
var gen = util.codegen(["r", "l"], mtype.name + "$decode")
|
|
19
|
+
var gen = util.codegen(["r", "l", "e"], mtype.name + "$decode")
|
|
20
20
|
("if(!(r instanceof Reader))")
|
|
21
21
|
("r=Reader.create(r)")
|
|
22
22
|
("var c=l===undefined?r.len:r.pos+l,m=new this.ctor" + (mtype.fieldsArray.filter(function(field) { return field.map; }).length ? ",k,value" : ""))
|
|
23
23
|
("while(r.pos<c){")
|
|
24
|
-
("var t=r.uint32()")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
("break");
|
|
28
|
-
gen
|
|
24
|
+
("var t=r.uint32()")
|
|
25
|
+
("if(t===e)")
|
|
26
|
+
("break")
|
|
29
27
|
("switch(t>>>3){");
|
|
30
28
|
|
|
31
29
|
var i = 0;
|
|
@@ -91,15 +89,15 @@ function decoder(mtype) {
|
|
|
91
89
|
("}else");
|
|
92
90
|
|
|
93
91
|
// Non-packed
|
|
94
|
-
if (types.basic[type] === undefined) gen(field.
|
|
95
|
-
? "%s.push(types[%i].decode(r))"
|
|
92
|
+
if (types.basic[type] === undefined) gen(field.delimited
|
|
93
|
+
? "%s.push(types[%i].decode(r,undefined,((t&~7)|4)))"
|
|
96
94
|
: "%s.push(types[%i].decode(r,r.uint32()))", ref, i);
|
|
97
95
|
else gen
|
|
98
96
|
("%s.push(r.%s())", ref, type);
|
|
99
97
|
|
|
100
98
|
// Non-repeated
|
|
101
|
-
} else if (types.basic[type] === undefined) gen(field.
|
|
102
|
-
? "%s=types[%i].decode(r)"
|
|
99
|
+
} else if (types.basic[type] === undefined) gen(field.delimited
|
|
100
|
+
? "%s=types[%i].decode(r,undefined,((t&~7)|4))"
|
|
103
101
|
: "%s=types[%i].decode(r,r.uint32())", ref, i);
|
|
104
102
|
else gen
|
|
105
103
|
("%s=r.%s()", ref, type);
|
package/src/encoder.js
CHANGED
|
@@ -15,7 +15,7 @@ var Enum = require("./enum"),
|
|
|
15
15
|
* @ignore
|
|
16
16
|
*/
|
|
17
17
|
function genTypePartial(gen, field, fieldIndex, ref) {
|
|
18
|
-
return field.
|
|
18
|
+
return field.delimited
|
|
19
19
|
? gen("types[%i].encode(%s,w.uint32(%i)).uint32(%i)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0)
|
|
20
20
|
: gen("types[%i].encode(%s,w.uint32(%i).fork()).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0);
|
|
21
21
|
}
|
package/src/enum.js
CHANGED
|
@@ -56,6 +56,12 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
|
|
|
56
56
|
*/
|
|
57
57
|
this.valuesOptions = valuesOptions;
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Resolved values features, if any
|
|
61
|
+
* @type {Object<string, Object<string, *>>|undefined}
|
|
62
|
+
*/
|
|
63
|
+
this._valuesFeatures = {};
|
|
64
|
+
|
|
59
65
|
/**
|
|
60
66
|
* Reserved ranges, if any.
|
|
61
67
|
* @type {Array.<number[]|string>}
|
|
@@ -72,6 +78,21 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
|
|
|
72
78
|
this.valuesById[ this.values[keys[i]] = values[keys[i]] ] = keys[i];
|
|
73
79
|
}
|
|
74
80
|
|
|
81
|
+
/**
|
|
82
|
+
* @override
|
|
83
|
+
*/
|
|
84
|
+
Enum.prototype._resolveFeatures = function _resolveFeatures(edition) {
|
|
85
|
+
edition = this._edition || edition;
|
|
86
|
+
ReflectionObject.prototype._resolveFeatures.call(this, edition);
|
|
87
|
+
|
|
88
|
+
Object.keys(this.values).forEach(key => {
|
|
89
|
+
var parentFeaturesCopy = Object.assign({}, this._features);
|
|
90
|
+
this._valuesFeatures[key] = Object.assign(parentFeaturesCopy, this.valuesOptions && this.valuesOptions[key] && this.valuesOptions[key].features);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return this;
|
|
94
|
+
};
|
|
95
|
+
|
|
75
96
|
/**
|
|
76
97
|
* Enum descriptor.
|
|
77
98
|
* @interface IEnum
|
|
@@ -89,6 +110,9 @@ function Enum(name, values, options, comment, comments, valuesOptions) {
|
|
|
89
110
|
Enum.fromJSON = function fromJSON(name, json) {
|
|
90
111
|
var enm = new Enum(name, json.values, json.options, json.comment, json.comments);
|
|
91
112
|
enm.reserved = json.reserved;
|
|
113
|
+
if (json.edition)
|
|
114
|
+
enm._edition = json.edition;
|
|
115
|
+
enm._defaultEdition = "proto3"; // For backwards-compatibility.
|
|
92
116
|
return enm;
|
|
93
117
|
};
|
|
94
118
|
|
|
@@ -100,6 +124,7 @@ Enum.fromJSON = function fromJSON(name, json) {
|
|
|
100
124
|
Enum.prototype.toJSON = function toJSON(toJSONOptions) {
|
|
101
125
|
var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
|
|
102
126
|
return util.toObject([
|
|
127
|
+
"edition" , this._editionToJSON(),
|
|
103
128
|
"options" , this.options,
|
|
104
129
|
"valuesOptions" , this.valuesOptions,
|
|
105
130
|
"values" , this.values,
|
package/src/field.js
CHANGED
|
@@ -35,7 +35,11 @@ var ruleRe = /^required|optional|repeated$/;
|
|
|
35
35
|
* @throws {TypeError} If arguments are invalid
|
|
36
36
|
*/
|
|
37
37
|
Field.fromJSON = function fromJSON(name, json) {
|
|
38
|
-
|
|
38
|
+
var field = new Field(name, json.id, json.type, json.rule, json.extend, json.options, json.comment);
|
|
39
|
+
if (json.edition)
|
|
40
|
+
field._edition = json.edition;
|
|
41
|
+
field._defaultEdition = "proto3"; // For backwards-compatibility.
|
|
42
|
+
return field;
|
|
39
43
|
};
|
|
40
44
|
|
|
41
45
|
/**
|
|
@@ -105,18 +109,6 @@ function Field(name, id, type, rule, extend, options, comment) {
|
|
|
105
109
|
*/
|
|
106
110
|
this.extend = extend || undefined; // toJSON
|
|
107
111
|
|
|
108
|
-
/**
|
|
109
|
-
* Whether this field is required.
|
|
110
|
-
* @type {boolean}
|
|
111
|
-
*/
|
|
112
|
-
this.required = rule === "required";
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Whether this field is optional.
|
|
116
|
-
* @type {boolean}
|
|
117
|
-
*/
|
|
118
|
-
this.optional = !this.required;
|
|
119
|
-
|
|
120
112
|
/**
|
|
121
113
|
* Whether this field is repeated.
|
|
122
114
|
* @type {boolean}
|
|
@@ -183,13 +175,6 @@ function Field(name, id, type, rule, extend, options, comment) {
|
|
|
183
175
|
*/
|
|
184
176
|
this.declaringField = null;
|
|
185
177
|
|
|
186
|
-
/**
|
|
187
|
-
* Internally remembers whether this field is packed.
|
|
188
|
-
* @type {boolean|null}
|
|
189
|
-
* @private
|
|
190
|
-
*/
|
|
191
|
-
this._packed = null;
|
|
192
|
-
|
|
193
178
|
/**
|
|
194
179
|
* Comment for this field.
|
|
195
180
|
* @type {string|null}
|
|
@@ -198,17 +183,69 @@ function Field(name, id, type, rule, extend, options, comment) {
|
|
|
198
183
|
}
|
|
199
184
|
|
|
200
185
|
/**
|
|
201
|
-
* Determines whether this field is
|
|
186
|
+
* Determines whether this field is required.
|
|
187
|
+
* @name Field#required
|
|
188
|
+
* @type {boolean}
|
|
189
|
+
* @readonly
|
|
190
|
+
*/
|
|
191
|
+
Object.defineProperty(Field.prototype, "required", {
|
|
192
|
+
get: function() {
|
|
193
|
+
return this._features.field_presence === "LEGACY_REQUIRED";
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Determines whether this field is not required.
|
|
199
|
+
* @name Field#optional
|
|
200
|
+
* @type {boolean}
|
|
201
|
+
* @readonly
|
|
202
|
+
*/
|
|
203
|
+
Object.defineProperty(Field.prototype, "optional", {
|
|
204
|
+
get: function() {
|
|
205
|
+
return !this.required;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Determines whether this field uses tag-delimited encoding. In proto2 this
|
|
211
|
+
* corresponded to group syntax.
|
|
212
|
+
* @name Field#delimited
|
|
213
|
+
* @type {boolean}
|
|
214
|
+
* @readonly
|
|
215
|
+
*/
|
|
216
|
+
Object.defineProperty(Field.prototype, "delimited", {
|
|
217
|
+
get: function() {
|
|
218
|
+
return this.resolvedType instanceof Type &&
|
|
219
|
+
this._features.message_encoding === "DELIMITED";
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Determines whether this field is packed. Only relevant when repeated.
|
|
202
225
|
* @name Field#packed
|
|
203
226
|
* @type {boolean}
|
|
204
227
|
* @readonly
|
|
205
228
|
*/
|
|
206
229
|
Object.defineProperty(Field.prototype, "packed", {
|
|
207
230
|
get: function() {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
231
|
+
return this._features.repeated_field_encoding === "PACKED";
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Determines whether this field tracks presence.
|
|
237
|
+
* @name Field#hasPresence
|
|
238
|
+
* @type {boolean}
|
|
239
|
+
* @readonly
|
|
240
|
+
*/
|
|
241
|
+
Object.defineProperty(Field.prototype, "hasPresence", {
|
|
242
|
+
get: function() {
|
|
243
|
+
if (this.repeated || this.map) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
return this.partOf || // oneofs
|
|
247
|
+
this.declaringField || this.extensionField || // extensions
|
|
248
|
+
this._features.field_presence !== "IMPLICIT";
|
|
212
249
|
}
|
|
213
250
|
});
|
|
214
251
|
|
|
@@ -216,8 +253,6 @@ Object.defineProperty(Field.prototype, "packed", {
|
|
|
216
253
|
* @override
|
|
217
254
|
*/
|
|
218
255
|
Field.prototype.setOption = function setOption(name, value, ifNotSet) {
|
|
219
|
-
if (name === "packed") // clear cached before setting
|
|
220
|
-
this._packed = null;
|
|
221
256
|
return ReflectionObject.prototype.setOption.call(this, name, value, ifNotSet);
|
|
222
257
|
};
|
|
223
258
|
|
|
@@ -245,6 +280,7 @@ Field.prototype.setOption = function setOption(name, value, ifNotSet) {
|
|
|
245
280
|
Field.prototype.toJSON = function toJSON(toJSONOptions) {
|
|
246
281
|
var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
|
|
247
282
|
return util.toObject([
|
|
283
|
+
"edition" , this._editionToJSON(),
|
|
248
284
|
"rule" , this.rule !== "optional" && this.rule || undefined,
|
|
249
285
|
"type" , this.type,
|
|
250
286
|
"id" , this.id,
|
|
@@ -284,7 +320,7 @@ Field.prototype.resolve = function resolve() {
|
|
|
284
320
|
|
|
285
321
|
// remove unnecessary options
|
|
286
322
|
if (this.options) {
|
|
287
|
-
if (this.options.packed
|
|
323
|
+
if (this.options.packed !== undefined && this.resolvedType && !(this.resolvedType instanceof Enum))
|
|
288
324
|
delete this.options.packed;
|
|
289
325
|
if (!Object.keys(this.options).length)
|
|
290
326
|
this.options = undefined;
|
|
@@ -322,6 +358,46 @@ Field.prototype.resolve = function resolve() {
|
|
|
322
358
|
return ReflectionObject.prototype.resolve.call(this);
|
|
323
359
|
};
|
|
324
360
|
|
|
361
|
+
/**
|
|
362
|
+
* Infers field features from legacy syntax that may have been specified differently.
|
|
363
|
+
* in older editions.
|
|
364
|
+
* @param {string|undefined} edition The edition this proto is on, or undefined if pre-editions
|
|
365
|
+
* @returns {object} The feature values to override
|
|
366
|
+
*/
|
|
367
|
+
Field.prototype._inferLegacyProtoFeatures = function _inferLegacyProtoFeatures(edition) {
|
|
368
|
+
if (edition !== "proto2" && edition !== "proto3") {
|
|
369
|
+
return {};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
var features = {};
|
|
373
|
+
|
|
374
|
+
if (this.rule === "required") {
|
|
375
|
+
features.field_presence = "LEGACY_REQUIRED";
|
|
376
|
+
}
|
|
377
|
+
if (this.parent && types.defaults[this.type] === undefined) {
|
|
378
|
+
// We can't use resolvedType because types may not have been resolved yet. However,
|
|
379
|
+
// legacy groups are always in the same scope as the field so we don't have to do a
|
|
380
|
+
// full scan of the tree.
|
|
381
|
+
var type = this.parent.get(this.type.split(".").pop());
|
|
382
|
+
if (type && type instanceof Type && type.group) {
|
|
383
|
+
features.message_encoding = "DELIMITED";
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (this.getOption("packed") === true) {
|
|
387
|
+
features.repeated_field_encoding = "PACKED";
|
|
388
|
+
} else if (this.getOption("packed") === false) {
|
|
389
|
+
features.repeated_field_encoding = "EXPANDED";
|
|
390
|
+
}
|
|
391
|
+
return features;
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* @override
|
|
396
|
+
*/
|
|
397
|
+
Field.prototype._resolveFeatures = function _resolveFeatures(edition) {
|
|
398
|
+
return ReflectionObject.prototype._resolveFeatures.call(this, this._edition || edition);
|
|
399
|
+
};
|
|
400
|
+
|
|
325
401
|
/**
|
|
326
402
|
* Decorator function as returned by {@link Field.d} and {@link MapField.d} (TypeScript).
|
|
327
403
|
* @typedef FieldDecorator
|
package/src/namespace.js
CHANGED
|
@@ -108,10 +108,33 @@ function Namespace(name, options) {
|
|
|
108
108
|
* @private
|
|
109
109
|
*/
|
|
110
110
|
this._nestedArray = null;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Cache lookup calls for any objects contains anywhere under this namespace.
|
|
114
|
+
* This drastically speeds up resolve for large cross-linked protos where the same
|
|
115
|
+
* types are looked up repeatedly.
|
|
116
|
+
* @type {Object.<string,ReflectionObject|null>}
|
|
117
|
+
* @private
|
|
118
|
+
*/
|
|
119
|
+
this._lookupCache = {};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Whether or not objects contained in this namespace need feature resolution.
|
|
123
|
+
* @type {boolean}
|
|
124
|
+
* @protected
|
|
125
|
+
*/
|
|
126
|
+
this._needsRecursiveFeatureResolution = true;
|
|
111
127
|
}
|
|
112
128
|
|
|
113
129
|
function clearCache(namespace) {
|
|
114
130
|
namespace._nestedArray = null;
|
|
131
|
+
namespace._lookupCache = {};
|
|
132
|
+
|
|
133
|
+
// Also clear parent caches, since they include nested lookups.
|
|
134
|
+
var parent = namespace;
|
|
135
|
+
while(parent = parent.parent) {
|
|
136
|
+
parent._lookupCache = {};
|
|
137
|
+
}
|
|
115
138
|
return namespace;
|
|
116
139
|
}
|
|
117
140
|
|
|
@@ -240,6 +263,23 @@ Namespace.prototype.add = function add(object) {
|
|
|
240
263
|
}
|
|
241
264
|
}
|
|
242
265
|
this.nested[object.name] = object;
|
|
266
|
+
|
|
267
|
+
if (!(this instanceof Type || this instanceof Service || this instanceof Enum || this instanceof Field)) {
|
|
268
|
+
// This is a package or a root namespace.
|
|
269
|
+
if (!object._edition) {
|
|
270
|
+
// Make sure that some edition is set if it hasn't already been specified.
|
|
271
|
+
object._edition = object._defaultEdition;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
this._needsRecursiveFeatureResolution = true;
|
|
276
|
+
|
|
277
|
+
// Also clear parent caches, since they need to recurse down.
|
|
278
|
+
var parent = this;
|
|
279
|
+
while(parent = parent.parent) {
|
|
280
|
+
parent._needsRecursiveFeatureResolution = true;
|
|
281
|
+
}
|
|
282
|
+
|
|
243
283
|
object.onAdd(this);
|
|
244
284
|
return clearCache(this);
|
|
245
285
|
};
|
|
@@ -302,12 +342,29 @@ Namespace.prototype.define = function define(path, json) {
|
|
|
302
342
|
*/
|
|
303
343
|
Namespace.prototype.resolveAll = function resolveAll() {
|
|
304
344
|
var nested = this.nestedArray, i = 0;
|
|
345
|
+
this.resolve();
|
|
305
346
|
while (i < nested.length)
|
|
306
347
|
if (nested[i] instanceof Namespace)
|
|
307
348
|
nested[i++].resolveAll();
|
|
308
349
|
else
|
|
309
350
|
nested[i++].resolve();
|
|
310
|
-
return this
|
|
351
|
+
return this;
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* @override
|
|
356
|
+
*/
|
|
357
|
+
Namespace.prototype._resolveFeaturesRecursive = function _resolveFeaturesRecursive(edition) {
|
|
358
|
+
if (!this._needsRecursiveFeatureResolution) return this;
|
|
359
|
+
this._needsRecursiveFeatureResolution = false;
|
|
360
|
+
|
|
361
|
+
edition = this._edition || edition;
|
|
362
|
+
|
|
363
|
+
ReflectionObject.prototype._resolveFeaturesRecursive.call(this, edition);
|
|
364
|
+
this.nestedArray.forEach(nested => {
|
|
365
|
+
nested._resolveFeaturesRecursive(edition);
|
|
366
|
+
});
|
|
367
|
+
return this;
|
|
311
368
|
};
|
|
312
369
|
|
|
313
370
|
/**
|
|
@@ -318,7 +375,6 @@ Namespace.prototype.resolveAll = function resolveAll() {
|
|
|
318
375
|
* @returns {ReflectionObject|null} Looked up object or `null` if none could be found
|
|
319
376
|
*/
|
|
320
377
|
Namespace.prototype.lookup = function lookup(path, filterTypes, parentAlreadyChecked) {
|
|
321
|
-
|
|
322
378
|
/* istanbul ignore next */
|
|
323
379
|
if (typeof filterTypes === "boolean") {
|
|
324
380
|
parentAlreadyChecked = filterTypes;
|
|
@@ -337,25 +393,48 @@ Namespace.prototype.lookup = function lookup(path, filterTypes, parentAlreadyChe
|
|
|
337
393
|
if (path[0] === "")
|
|
338
394
|
return this.root.lookup(path.slice(1), filterTypes);
|
|
339
395
|
|
|
396
|
+
var found = this._lookupImpl(path);
|
|
397
|
+
if (found && (!filterTypes || filterTypes.indexOf(found.constructor) > -1)) {
|
|
398
|
+
return found;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// If there hasn't been a match, try again at the parent
|
|
402
|
+
if (this.parent === null || parentAlreadyChecked)
|
|
403
|
+
return null;
|
|
404
|
+
return this.parent.lookup(path, filterTypes);
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Internal helper for lookup that handles searching just at this namespace and below along with caching.
|
|
409
|
+
* @param {string[]} path Path to look up
|
|
410
|
+
* @returns {ReflectionObject|null} Looked up object or `null` if none could be found
|
|
411
|
+
* @private
|
|
412
|
+
*/
|
|
413
|
+
Namespace.prototype._lookupImpl = function lookup(path) {
|
|
414
|
+
var flatPath = path.join(".");
|
|
415
|
+
if(Object.prototype.hasOwnProperty.call(this._lookupCache, flatPath)) {
|
|
416
|
+
return this._lookupCache[flatPath];
|
|
417
|
+
}
|
|
418
|
+
|
|
340
419
|
// Test if the first part matches any nested object, and if so, traverse if path contains more
|
|
341
420
|
var found = this.get(path[0]);
|
|
421
|
+
var exact = null;
|
|
342
422
|
if (found) {
|
|
343
423
|
if (path.length === 1) {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
return found;
|
|
424
|
+
exact = found;
|
|
425
|
+
} else if (found instanceof Namespace && (found = found._lookupImpl(path.slice(1))))
|
|
426
|
+
exact = found;
|
|
348
427
|
|
|
349
428
|
// Otherwise try each nested namespace
|
|
350
|
-
} else
|
|
429
|
+
} else {
|
|
351
430
|
for (var i = 0; i < this.nestedArray.length; ++i)
|
|
352
|
-
if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i].
|
|
353
|
-
|
|
431
|
+
if (this._nestedArray[i] instanceof Namespace && (found = this._nestedArray[i]._lookupImpl(path)))
|
|
432
|
+
exact = found;
|
|
433
|
+
}
|
|
354
434
|
|
|
355
|
-
//
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
return this.parent.lookup(path, filterTypes);
|
|
435
|
+
// Set this even when null, so that when we walk up the tree we can quickly bail on repeated checks back down.
|
|
436
|
+
this._lookupCache[flatPath] = exact;
|
|
437
|
+
return exact;
|
|
359
438
|
};
|
|
360
439
|
|
|
361
440
|
/**
|