protobufjs 8.0.1 → 8.0.2

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.
Files changed (98) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +727 -727
  3. package/dist/light/protobuf.js +7724 -7591
  4. package/dist/light/protobuf.js.map +1 -1
  5. package/dist/light/protobuf.min.js +3 -3
  6. package/dist/light/protobuf.min.js.map +1 -1
  7. package/dist/minimal/protobuf.js +2606 -2546
  8. package/dist/minimal/protobuf.js.map +1 -1
  9. package/dist/minimal/protobuf.min.js +3 -3
  10. package/dist/minimal/protobuf.min.js.map +1 -1
  11. package/dist/protobuf.js +9593 -9436
  12. package/dist/protobuf.js.map +1 -1
  13. package/dist/protobuf.min.js +3 -3
  14. package/dist/protobuf.min.js.map +1 -1
  15. package/ext/debug/README.md +4 -4
  16. package/ext/debug/index.js +71 -71
  17. package/ext/descriptor/README.md +72 -72
  18. package/ext/descriptor/index.d.ts +195 -191
  19. package/ext/descriptor/index.js +1181 -1163
  20. package/ext/descriptor/test.js +54 -54
  21. package/google/LICENSE +27 -27
  22. package/google/README.md +1 -1
  23. package/google/api/annotations.json +82 -82
  24. package/google/api/annotations.proto +10 -10
  25. package/google/api/http.json +85 -85
  26. package/google/api/http.proto +30 -30
  27. package/google/protobuf/api.json +117 -117
  28. package/google/protobuf/api.proto +33 -33
  29. package/google/protobuf/descriptor.json +1381 -1381
  30. package/google/protobuf/descriptor.proto +534 -534
  31. package/google/protobuf/source_context.json +19 -19
  32. package/google/protobuf/source_context.proto +7 -7
  33. package/google/protobuf/type.json +201 -201
  34. package/google/protobuf/type.proto +89 -89
  35. package/index.d.ts +2817 -2799
  36. package/index.js +4 -4
  37. package/light.d.ts +2 -2
  38. package/light.js +3 -3
  39. package/minimal.d.ts +2 -2
  40. package/minimal.js +4 -4
  41. package/package.json +96 -114
  42. package/scripts/postinstall.js +32 -32
  43. package/src/common.js +399 -399
  44. package/src/converter.js +310 -301
  45. package/src/decoder.js +135 -127
  46. package/src/encoder.js +100 -100
  47. package/src/enum.js +226 -223
  48. package/src/field.js +453 -453
  49. package/src/index-light.js +104 -104
  50. package/src/index-minimal.js +36 -36
  51. package/src/index.js +12 -12
  52. package/src/mapfield.js +126 -126
  53. package/src/message.js +139 -143
  54. package/src/method.js +160 -160
  55. package/src/namespace.js +550 -546
  56. package/src/object.js +385 -381
  57. package/src/oneof.js +222 -222
  58. package/src/parse.js +1032 -1013
  59. package/src/reader.js +426 -416
  60. package/src/reader_buffer.js +51 -51
  61. package/src/root.js +403 -403
  62. package/src/roots.js +17 -17
  63. package/src/rpc/service.js +142 -142
  64. package/src/rpc.js +36 -36
  65. package/src/service.js +193 -189
  66. package/src/tokenize.js +421 -416
  67. package/src/type.js +625 -615
  68. package/src/types.js +196 -196
  69. package/src/typescript.jsdoc +15 -15
  70. package/src/util/aspromise.d.ts +13 -0
  71. package/src/util/aspromise.js +52 -0
  72. package/src/util/base64.d.ts +32 -0
  73. package/src/util/base64.js +139 -0
  74. package/src/util/codegen.d.ts +31 -0
  75. package/src/util/codegen.js +113 -0
  76. package/src/util/eventemitter.d.ts +45 -0
  77. package/src/util/eventemitter.js +84 -0
  78. package/src/util/fetch.d.ts +56 -0
  79. package/src/util/fetch.js +114 -0
  80. package/src/util/float.d.ts +83 -0
  81. package/src/util/float.js +335 -0
  82. package/src/util/inquire.d.ts +9 -0
  83. package/src/util/inquire.js +37 -0
  84. package/src/util/longbits.js +200 -200
  85. package/src/util/minimal.js +461 -438
  86. package/src/util/path.d.ts +22 -0
  87. package/src/util/path.js +72 -0
  88. package/src/util/patterns.js +8 -0
  89. package/src/util/pool.d.ts +32 -0
  90. package/src/util/pool.js +48 -0
  91. package/src/util/utf8.d.ts +24 -0
  92. package/src/util/utf8.js +104 -0
  93. package/src/util.js +215 -215
  94. package/src/verifier.js +180 -177
  95. package/src/wrappers.js +103 -102
  96. package/src/writer.js +465 -465
  97. package/src/writer_buffer.js +85 -85
  98. package/tsconfig.json +8 -8
package/src/root.js CHANGED
@@ -1,404 +1,404 @@
1
- "use strict";
2
- module.exports = Root;
3
-
4
- // extends Namespace
5
- var Namespace = require("./namespace");
6
- ((Root.prototype = Object.create(Namespace.prototype)).constructor = Root).className = "Root";
7
-
8
- var Field = require("./field"),
9
- Enum = require("./enum"),
10
- OneOf = require("./oneof"),
11
- util = require("./util");
12
-
13
- var Type, // cyclic
14
- parse, // might be excluded
15
- common; // "
16
-
17
- /**
18
- * Constructs a new root namespace instance.
19
- * @classdesc Root namespace wrapping all types, enums, services, sub-namespaces etc. that belong together.
20
- * @extends NamespaceBase
21
- * @constructor
22
- * @param {Object.<string,*>} [options] Top level options
23
- */
24
- function Root(options) {
25
- Namespace.call(this, "", options);
26
-
27
- /**
28
- * Deferred extension fields.
29
- * @type {Field[]}
30
- */
31
- this.deferred = [];
32
-
33
- /**
34
- * Resolved file names of loaded files.
35
- * @type {string[]}
36
- */
37
- this.files = [];
38
-
39
- /**
40
- * Edition, defaults to proto2 if unspecified.
41
- * @type {string}
42
- * @private
43
- */
44
- this._edition = "proto2";
45
-
46
- /**
47
- * Global lookup cache of fully qualified names.
48
- * @type {Object.<string,ReflectionObject>}
49
- * @private
50
- */
1
+ "use strict";
2
+ module.exports = Root;
3
+
4
+ // extends Namespace
5
+ var Namespace = require("./namespace");
6
+ ((Root.prototype = Object.create(Namespace.prototype)).constructor = Root).className = "Root";
7
+
8
+ var Field = require("./field"),
9
+ Enum = require("./enum"),
10
+ OneOf = require("./oneof"),
11
+ util = require("./util");
12
+
13
+ var Type, // cyclic
14
+ parse, // might be excluded
15
+ common; // "
16
+
17
+ /**
18
+ * Constructs a new root namespace instance.
19
+ * @classdesc Root namespace wrapping all types, enums, services, sub-namespaces etc. that belong together.
20
+ * @extends NamespaceBase
21
+ * @constructor
22
+ * @param {Object.<string,*>} [options] Top level options
23
+ */
24
+ function Root(options) {
25
+ Namespace.call(this, "", options);
26
+
27
+ /**
28
+ * Deferred extension fields.
29
+ * @type {Field[]}
30
+ */
31
+ this.deferred = [];
32
+
33
+ /**
34
+ * Resolved file names of loaded files.
35
+ * @type {string[]}
36
+ */
37
+ this.files = [];
38
+
39
+ /**
40
+ * Edition, defaults to proto2 if unspecified.
41
+ * @type {string}
42
+ * @private
43
+ */
44
+ this._edition = "proto2";
45
+
46
+ /**
47
+ * Global lookup cache of fully qualified names.
48
+ * @type {Object.<string,ReflectionObject>}
49
+ * @private
50
+ */
51
51
  this._fullyQualifiedObjects = {};
52
- }
53
-
54
- /**
55
- * Loads a namespace descriptor into a root namespace.
56
- * @param {INamespace} json Namespace descriptor
57
- * @param {Root} [root] Root namespace, defaults to create a new one if omitted
58
- * @returns {Root} Root namespace
59
- */
60
- Root.fromJSON = function fromJSON(json, root) {
61
- if (!root)
62
- root = new Root();
63
- if (json.options)
64
- root.setOptions(json.options);
65
- return root.addJSON(json.nested).resolveAll();
66
- };
67
-
68
- /**
69
- * Resolves the path of an imported file, relative to the importing origin.
70
- * This method exists so you can override it with your own logic in case your imports are scattered over multiple directories.
71
- * @function
72
- * @param {string} origin The file name of the importing file
73
- * @param {string} target The file name being imported
74
- * @returns {string|null} Resolved path to `target` or `null` to skip the file
75
- */
76
- Root.prototype.resolvePath = util.path.resolve;
77
-
78
- /**
79
- * Fetch content from file path or url
80
- * This method exists so you can override it with your own logic.
81
- * @function
82
- * @param {string} path File path or url
83
- * @param {FetchCallback} callback Callback function
84
- * @returns {undefined}
85
- */
86
- Root.prototype.fetch = util.fetch;
87
-
88
- // A symbol-like function to safely signal synchronous loading
89
- /* istanbul ignore next */
90
- function SYNC() {} // eslint-disable-line no-empty-function
91
-
92
- /**
93
- * Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
94
- * @param {string|string[]} filename Names of one or multiple files to load
95
- * @param {IParseOptions} options Parse options
96
- * @param {LoadCallback} callback Callback function
97
- * @returns {undefined}
98
- */
99
- Root.prototype.load = function load(filename, options, callback) {
100
- if (typeof options === "function") {
101
- callback = options;
102
- options = undefined;
103
- }
104
- var self = this;
105
- if (!callback) {
106
- return util.asPromise(load, self, filename, options);
107
- }
108
-
109
- var sync = callback === SYNC; // undocumented
110
-
111
- // Finishes loading by calling the callback (exactly once)
112
- function finish(err, root) {
113
- /* istanbul ignore if */
114
- if (!callback) {
115
- return;
116
- }
117
- if (sync) {
118
- throw err;
119
- }
120
- if (root) {
121
- root.resolveAll();
122
- }
123
- var cb = callback;
124
- callback = null;
125
- cb(err, root);
126
- }
127
-
128
- // Bundled definition existence checking
129
- function getBundledFileName(filename) {
130
- var idx = filename.lastIndexOf("google/protobuf/");
131
- if (idx > -1) {
132
- var altname = filename.substring(idx);
133
- if (altname in common) return altname;
134
- }
135
- return null;
136
- }
137
-
138
- // Processes a single file
139
- function process(filename, source) {
140
- try {
141
- if (util.isString(source) && source.charAt(0) === "{")
142
- source = JSON.parse(source);
143
- if (!util.isString(source))
144
- self.setOptions(source.options).addJSON(source.nested);
145
- else {
146
- parse.filename = filename;
147
- var parsed = parse(source, self, options),
148
- resolved,
149
- i = 0;
150
- if (parsed.imports)
151
- for (; i < parsed.imports.length; ++i)
152
- if (resolved = getBundledFileName(parsed.imports[i]) || self.resolvePath(filename, parsed.imports[i]))
153
- fetch(resolved);
154
- if (parsed.weakImports)
155
- for (i = 0; i < parsed.weakImports.length; ++i)
156
- if (resolved = getBundledFileName(parsed.weakImports[i]) || self.resolvePath(filename, parsed.weakImports[i]))
157
- fetch(resolved, true);
158
- }
159
- } catch (err) {
160
- finish(err);
161
- }
162
- if (!sync && !queued) {
163
- finish(null, self); // only once anyway
164
- }
165
- }
166
-
167
- // Fetches a single file
168
- function fetch(filename, weak) {
169
- filename = getBundledFileName(filename) || filename;
170
-
171
- // Skip if already loaded / attempted
172
- if (self.files.indexOf(filename) > -1) {
173
- return;
174
- }
175
- self.files.push(filename);
176
-
177
- // Shortcut bundled definitions
178
- if (filename in common) {
179
- if (sync) {
180
- process(filename, common[filename]);
181
- } else {
182
- ++queued;
183
- setTimeout(function() {
184
- --queued;
185
- process(filename, common[filename]);
186
- });
187
- }
188
- return;
189
- }
190
-
191
- // Otherwise fetch from disk or network
192
- if (sync) {
193
- var source;
194
- try {
195
- source = util.fs.readFileSync(filename).toString("utf8");
196
- } catch (err) {
197
- if (!weak)
198
- finish(err);
199
- return;
200
- }
201
- process(filename, source);
202
- } else {
203
- ++queued;
204
- self.fetch(filename, function(err, source) {
205
- --queued;
206
- /* istanbul ignore if */
207
- if (!callback) {
208
- return; // terminated meanwhile
209
- }
210
- if (err) {
211
- /* istanbul ignore else */
212
- if (!weak)
213
- finish(err);
214
- else if (!queued) // can't be covered reliably
215
- finish(null, self);
216
- return;
217
- }
218
- process(filename, source);
219
- });
220
- }
221
- }
222
- var queued = 0;
223
-
224
- // Assembling the root namespace doesn't require working type
225
- // references anymore, so we can load everything in parallel
226
- if (util.isString(filename)) {
227
- filename = [ filename ];
228
- }
229
- for (var i = 0, resolved; i < filename.length; ++i)
230
- if (resolved = self.resolvePath("", filename[i]))
231
- fetch(resolved);
232
- if (sync) {
233
- self.resolveAll();
234
- return self;
235
- }
236
- if (!queued) {
237
- finish(null, self);
238
- }
239
-
240
- return self;
241
- };
242
- // function load(filename:string, options:IParseOptions, callback:LoadCallback):undefined
243
-
244
- /**
245
- * Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
246
- * @function Root#load
247
- * @param {string|string[]} filename Names of one or multiple files to load
248
- * @param {LoadCallback} callback Callback function
249
- * @returns {undefined}
250
- * @variation 2
251
- */
252
- // function load(filename:string, callback:LoadCallback):undefined
253
-
254
- /**
255
- * Loads one or multiple .proto or preprocessed .json files into this root namespace and returns a promise.
256
- * @function Root#load
257
- * @param {string|string[]} filename Names of one or multiple files to load
258
- * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
259
- * @returns {Promise<Root>} Promise
260
- * @variation 3
261
- */
262
- // function load(filename:string, [options:IParseOptions]):Promise<Root>
263
-
264
- /**
265
- * Synchronously loads one or multiple .proto or preprocessed .json files into this root namespace (node only).
266
- * @function Root#loadSync
267
- * @param {string|string[]} filename Names of one or multiple files to load
268
- * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
269
- * @returns {Root} Root namespace
270
- * @throws {Error} If synchronous fetching is not supported (i.e. in browsers) or if a file's syntax is invalid
271
- */
272
- Root.prototype.loadSync = function loadSync(filename, options) {
273
- if (!util.isNode)
274
- throw Error("not supported");
275
- return this.load(filename, options, SYNC);
276
- };
277
-
278
- /**
279
- * @override
280
- */
281
- Root.prototype.resolveAll = function resolveAll() {
282
- if (!this._needsRecursiveResolve) return this;
283
-
284
- if (this.deferred.length)
285
- throw Error("unresolvable extensions: " + this.deferred.map(function(field) {
286
- return "'extend " + field.extend + "' in " + field.parent.fullName;
287
- }).join(", "));
288
- return Namespace.prototype.resolveAll.call(this);
289
- };
290
-
291
- // only uppercased (and thus conflict-free) children are exposed, see below
292
- var exposeRe = /^[A-Z]/;
293
-
294
- /**
295
- * Handles a deferred declaring extension field by creating a sister field to represent it within its extended type.
296
- * @param {Root} root Root instance
297
- * @param {Field} field Declaring extension field witin the declaring type
298
- * @returns {boolean} `true` if successfully added to the extended type, `false` otherwise
299
- * @inner
300
- * @ignore
301
- */
302
- function tryHandleExtension(root, field) {
303
- var extendedType = field.parent.lookup(field.extend);
304
- if (extendedType) {
305
- var sisterField = new Field(field.fullName, field.id, field.type, field.rule, undefined, field.options);
306
- //do not allow to extend same field twice to prevent the error
307
- if (extendedType.get(sisterField.name)) {
308
- return true;
309
- }
310
- sisterField.declaringField = field;
311
- field.extensionField = sisterField;
312
- extendedType.add(sisterField);
313
- return true;
314
- }
315
- return false;
316
- }
317
-
318
- /**
319
- * Called when any object is added to this root or its sub-namespaces.
320
- * @param {ReflectionObject} object Object added
321
- * @returns {undefined}
322
- * @private
323
- */
324
- Root.prototype._handleAdd = function _handleAdd(object) {
325
- if (object instanceof Field) {
326
-
327
- if (/* an extension field (implies not part of a oneof) */ object.extend !== undefined && /* not already handled */ !object.extensionField)
328
- if (!tryHandleExtension(this, object))
329
- this.deferred.push(object);
330
-
331
- } else if (object instanceof Enum) {
332
-
333
- if (exposeRe.test(object.name))
334
- object.parent[object.name] = object.values; // expose enum values as property of its parent
335
-
336
- } else if (!(object instanceof OneOf)) /* everything else is a namespace */ {
337
-
338
- if (object instanceof Type) // Try to handle any deferred extensions
339
- for (var i = 0; i < this.deferred.length;)
340
- if (tryHandleExtension(this, this.deferred[i]))
341
- this.deferred.splice(i, 1);
342
- else
343
- ++i;
344
- for (var j = 0; j < /* initializes */ object.nestedArray.length; ++j) // recurse into the namespace
345
- this._handleAdd(object._nestedArray[j]);
346
- if (exposeRe.test(object.name))
347
- object.parent[object.name] = object; // expose namespace as property of its parent
348
- }
349
-
350
- if (object instanceof Type || object instanceof Enum || object instanceof Field) {
351
- // Only store types and enums for quick lookup during resolve.
352
- this._fullyQualifiedObjects[object.fullName] = object;
353
- }
354
-
355
- // The above also adds uppercased (and thus conflict-free) nested types, services and enums as
356
- // properties of namespaces just like static code does. This allows using a .d.ts generated for
357
- // a static module with reflection-based solutions where the condition is met.
358
- };
359
-
360
- /**
361
- * Called when any object is removed from this root or its sub-namespaces.
362
- * @param {ReflectionObject} object Object removed
363
- * @returns {undefined}
364
- * @private
365
- */
366
- Root.prototype._handleRemove = function _handleRemove(object) {
367
- if (object instanceof Field) {
368
-
369
- if (/* an extension field */ object.extend !== undefined) {
370
- if (/* already handled */ object.extensionField) { // remove its sister field
371
- object.extensionField.parent.remove(object.extensionField);
372
- object.extensionField = null;
373
- } else { // cancel the extension
374
- var index = this.deferred.indexOf(object);
375
- /* istanbul ignore else */
376
- if (index > -1)
377
- this.deferred.splice(index, 1);
378
- }
379
- }
380
-
381
- } else if (object instanceof Enum) {
382
-
383
- if (exposeRe.test(object.name))
384
- delete object.parent[object.name]; // unexpose enum values
385
-
386
- } else if (object instanceof Namespace) {
387
-
388
- for (var i = 0; i < /* initializes */ object.nestedArray.length; ++i) // recurse into the namespace
389
- this._handleRemove(object._nestedArray[i]);
390
-
391
- if (exposeRe.test(object.name))
392
- delete object.parent[object.name]; // unexpose namespaces
393
-
394
- }
395
-
396
- delete this._fullyQualifiedObjects[object.fullName];
397
- };
398
-
399
- // Sets up cyclic dependencies (called in index-light)
400
- Root._configure = function(Type_, parse_, common_) {
401
- Type = Type_;
402
- parse = parse_;
403
- common = common_;
404
- };
52
+ }
53
+
54
+ /**
55
+ * Loads a namespace descriptor into a root namespace.
56
+ * @param {INamespace} json Namespace descriptor
57
+ * @param {Root} [root] Root namespace, defaults to create a new one if omitted
58
+ * @returns {Root} Root namespace
59
+ */
60
+ Root.fromJSON = function fromJSON(json, root) {
61
+ if (!root)
62
+ root = new Root();
63
+ if (json.options)
64
+ root.setOptions(json.options);
65
+ return root.addJSON(json.nested).resolveAll();
66
+ };
67
+
68
+ /**
69
+ * Resolves the path of an imported file, relative to the importing origin.
70
+ * This method exists so you can override it with your own logic in case your imports are scattered over multiple directories.
71
+ * @function
72
+ * @param {string} origin The file name of the importing file
73
+ * @param {string} target The file name being imported
74
+ * @returns {string|null} Resolved path to `target` or `null` to skip the file
75
+ */
76
+ Root.prototype.resolvePath = util.path.resolve;
77
+
78
+ /**
79
+ * Fetch content from file path or url
80
+ * This method exists so you can override it with your own logic.
81
+ * @function
82
+ * @param {string} path File path or url
83
+ * @param {FetchCallback} callback Callback function
84
+ * @returns {undefined}
85
+ */
86
+ Root.prototype.fetch = util.fetch;
87
+
88
+ // A symbol-like function to safely signal synchronous loading
89
+ /* istanbul ignore next */
90
+ function SYNC() {} // eslint-disable-line no-empty-function
91
+
92
+ /**
93
+ * Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
94
+ * @param {string|string[]} filename Names of one or multiple files to load
95
+ * @param {IParseOptions} options Parse options
96
+ * @param {LoadCallback} callback Callback function
97
+ * @returns {undefined}
98
+ */
99
+ Root.prototype.load = function load(filename, options, callback) {
100
+ if (typeof options === "function") {
101
+ callback = options;
102
+ options = undefined;
103
+ }
104
+ var self = this;
105
+ if (!callback) {
106
+ return util.asPromise(load, self, filename, options);
107
+ }
108
+
109
+ var sync = callback === SYNC; // undocumented
110
+
111
+ // Finishes loading by calling the callback (exactly once)
112
+ function finish(err, root) {
113
+ /* istanbul ignore if */
114
+ if (!callback) {
115
+ return;
116
+ }
117
+ if (sync) {
118
+ throw err;
119
+ }
120
+ if (root) {
121
+ root.resolveAll();
122
+ }
123
+ var cb = callback;
124
+ callback = null;
125
+ cb(err, root);
126
+ }
127
+
128
+ // Bundled definition existence checking
129
+ function getBundledFileName(filename) {
130
+ var idx = filename.lastIndexOf("google/protobuf/");
131
+ if (idx > -1) {
132
+ var altname = filename.substring(idx);
133
+ if (altname in common) return altname;
134
+ }
135
+ return null;
136
+ }
137
+
138
+ // Processes a single file
139
+ function process(filename, source) {
140
+ try {
141
+ if (util.isString(source) && source.charAt(0) === "{")
142
+ source = JSON.parse(source);
143
+ if (!util.isString(source))
144
+ self.setOptions(source.options).addJSON(source.nested);
145
+ else {
146
+ parse.filename = filename;
147
+ var parsed = parse(source, self, options),
148
+ resolved,
149
+ i = 0;
150
+ if (parsed.imports)
151
+ for (; i < parsed.imports.length; ++i)
152
+ if (resolved = getBundledFileName(parsed.imports[i]) || self.resolvePath(filename, parsed.imports[i]))
153
+ fetch(resolved);
154
+ if (parsed.weakImports)
155
+ for (i = 0; i < parsed.weakImports.length; ++i)
156
+ if (resolved = getBundledFileName(parsed.weakImports[i]) || self.resolvePath(filename, parsed.weakImports[i]))
157
+ fetch(resolved, true);
158
+ }
159
+ } catch (err) {
160
+ finish(err);
161
+ }
162
+ if (!sync && !queued) {
163
+ finish(null, self); // only once anyway
164
+ }
165
+ }
166
+
167
+ // Fetches a single file
168
+ function fetch(filename, weak) {
169
+ filename = getBundledFileName(filename) || filename;
170
+
171
+ // Skip if already loaded / attempted
172
+ if (self.files.indexOf(filename) > -1) {
173
+ return;
174
+ }
175
+ self.files.push(filename);
176
+
177
+ // Shortcut bundled definitions
178
+ if (filename in common) {
179
+ if (sync) {
180
+ process(filename, common[filename]);
181
+ } else {
182
+ ++queued;
183
+ setTimeout(function() {
184
+ --queued;
185
+ process(filename, common[filename]);
186
+ });
187
+ }
188
+ return;
189
+ }
190
+
191
+ // Otherwise fetch from disk or network
192
+ if (sync) {
193
+ var source;
194
+ try {
195
+ source = util.fs.readFileSync(filename).toString("utf8");
196
+ } catch (err) {
197
+ if (!weak)
198
+ finish(err);
199
+ return;
200
+ }
201
+ process(filename, source);
202
+ } else {
203
+ ++queued;
204
+ self.fetch(filename, function(err, source) {
205
+ --queued;
206
+ /* istanbul ignore if */
207
+ if (!callback) {
208
+ return; // terminated meanwhile
209
+ }
210
+ if (err) {
211
+ /* istanbul ignore else */
212
+ if (!weak)
213
+ finish(err);
214
+ else if (!queued) // can't be covered reliably
215
+ finish(null, self);
216
+ return;
217
+ }
218
+ process(filename, source);
219
+ });
220
+ }
221
+ }
222
+ var queued = 0;
223
+
224
+ // Assembling the root namespace doesn't require working type
225
+ // references anymore, so we can load everything in parallel
226
+ if (util.isString(filename)) {
227
+ filename = [ filename ];
228
+ }
229
+ for (var i = 0, resolved; i < filename.length; ++i)
230
+ if (resolved = self.resolvePath("", filename[i]))
231
+ fetch(resolved);
232
+ if (sync) {
233
+ self.resolveAll();
234
+ return self;
235
+ }
236
+ if (!queued) {
237
+ finish(null, self);
238
+ }
239
+
240
+ return self;
241
+ };
242
+ // function load(filename:string, options:IParseOptions, callback:LoadCallback):undefined
243
+
244
+ /**
245
+ * Loads one or multiple .proto or preprocessed .json files into this root namespace and calls the callback.
246
+ * @function Root#load
247
+ * @param {string|string[]} filename Names of one or multiple files to load
248
+ * @param {LoadCallback} callback Callback function
249
+ * @returns {undefined}
250
+ * @variation 2
251
+ */
252
+ // function load(filename:string, callback:LoadCallback):undefined
253
+
254
+ /**
255
+ * Loads one or multiple .proto or preprocessed .json files into this root namespace and returns a promise.
256
+ * @function Root#load
257
+ * @param {string|string[]} filename Names of one or multiple files to load
258
+ * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
259
+ * @returns {Promise<Root>} Promise
260
+ * @variation 3
261
+ */
262
+ // function load(filename:string, [options:IParseOptions]):Promise<Root>
263
+
264
+ /**
265
+ * Synchronously loads one or multiple .proto or preprocessed .json files into this root namespace (node only).
266
+ * @function Root#loadSync
267
+ * @param {string|string[]} filename Names of one or multiple files to load
268
+ * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
269
+ * @returns {Root} Root namespace
270
+ * @throws {Error} If synchronous fetching is not supported (i.e. in browsers) or if a file's syntax is invalid
271
+ */
272
+ Root.prototype.loadSync = function loadSync(filename, options) {
273
+ if (!util.isNode)
274
+ throw Error("not supported");
275
+ return this.load(filename, options, SYNC);
276
+ };
277
+
278
+ /**
279
+ * @override
280
+ */
281
+ Root.prototype.resolveAll = function resolveAll() {
282
+ if (!this._needsRecursiveResolve) return this;
283
+
284
+ if (this.deferred.length)
285
+ throw Error("unresolvable extensions: " + this.deferred.map(function(field) {
286
+ return "'extend " + field.extend + "' in " + field.parent.fullName;
287
+ }).join(", "));
288
+ return Namespace.prototype.resolveAll.call(this);
289
+ };
290
+
291
+ // only uppercased (and thus conflict-free) children are exposed, see below
292
+ var exposeRe = /^[A-Z]/;
293
+
294
+ /**
295
+ * Handles a deferred declaring extension field by creating a sister field to represent it within its extended type.
296
+ * @param {Root} root Root instance
297
+ * @param {Field} field Declaring extension field witin the declaring type
298
+ * @returns {boolean} `true` if successfully added to the extended type, `false` otherwise
299
+ * @inner
300
+ * @ignore
301
+ */
302
+ function tryHandleExtension(root, field) {
303
+ var extendedType = field.parent.lookup(field.extend);
304
+ if (extendedType) {
305
+ var sisterField = new Field(field.fullName, field.id, field.type, field.rule, undefined, field.options);
306
+ //do not allow to extend same field twice to prevent the error
307
+ if (extendedType.get(sisterField.name)) {
308
+ return true;
309
+ }
310
+ sisterField.declaringField = field;
311
+ field.extensionField = sisterField;
312
+ extendedType.add(sisterField);
313
+ return true;
314
+ }
315
+ return false;
316
+ }
317
+
318
+ /**
319
+ * Called when any object is added to this root or its sub-namespaces.
320
+ * @param {ReflectionObject} object Object added
321
+ * @returns {undefined}
322
+ * @private
323
+ */
324
+ Root.prototype._handleAdd = function _handleAdd(object) {
325
+ if (object instanceof Field) {
326
+
327
+ if (/* an extension field (implies not part of a oneof) */ object.extend !== undefined && /* not already handled */ !object.extensionField)
328
+ if (!tryHandleExtension(this, object))
329
+ this.deferred.push(object);
330
+
331
+ } else if (object instanceof Enum) {
332
+
333
+ if (exposeRe.test(object.name))
334
+ object.parent[object.name] = object.values; // expose enum values as property of its parent
335
+
336
+ } else if (!(object instanceof OneOf)) /* everything else is a namespace */ {
337
+
338
+ if (object instanceof Type) // Try to handle any deferred extensions
339
+ for (var i = 0; i < this.deferred.length;)
340
+ if (tryHandleExtension(this, this.deferred[i]))
341
+ this.deferred.splice(i, 1);
342
+ else
343
+ ++i;
344
+ for (var j = 0; j < /* initializes */ object.nestedArray.length; ++j) // recurse into the namespace
345
+ this._handleAdd(object._nestedArray[j]);
346
+ if (exposeRe.test(object.name))
347
+ object.parent[object.name] = object; // expose namespace as property of its parent
348
+ }
349
+
350
+ if (object instanceof Type || object instanceof Enum || object instanceof Field) {
351
+ // Only store types and enums for quick lookup during resolve.
352
+ this._fullyQualifiedObjects[object.fullName] = object;
353
+ }
354
+
355
+ // The above also adds uppercased (and thus conflict-free) nested types, services and enums as
356
+ // properties of namespaces just like static code does. This allows using a .d.ts generated for
357
+ // a static module with reflection-based solutions where the condition is met.
358
+ };
359
+
360
+ /**
361
+ * Called when any object is removed from this root or its sub-namespaces.
362
+ * @param {ReflectionObject} object Object removed
363
+ * @returns {undefined}
364
+ * @private
365
+ */
366
+ Root.prototype._handleRemove = function _handleRemove(object) {
367
+ if (object instanceof Field) {
368
+
369
+ if (/* an extension field */ object.extend !== undefined) {
370
+ if (/* already handled */ object.extensionField) { // remove its sister field
371
+ object.extensionField.parent.remove(object.extensionField);
372
+ object.extensionField = null;
373
+ } else { // cancel the extension
374
+ var index = this.deferred.indexOf(object);
375
+ /* istanbul ignore else */
376
+ if (index > -1)
377
+ this.deferred.splice(index, 1);
378
+ }
379
+ }
380
+
381
+ } else if (object instanceof Enum) {
382
+
383
+ if (exposeRe.test(object.name))
384
+ delete object.parent[object.name]; // unexpose enum values
385
+
386
+ } else if (object instanceof Namespace) {
387
+
388
+ for (var i = 0; i < /* initializes */ object.nestedArray.length; ++i) // recurse into the namespace
389
+ this._handleRemove(object._nestedArray[i]);
390
+
391
+ if (exposeRe.test(object.name))
392
+ delete object.parent[object.name]; // unexpose namespaces
393
+
394
+ }
395
+
396
+ delete this._fullyQualifiedObjects[object.fullName];
397
+ };
398
+
399
+ // Sets up cyclic dependencies (called in index-light)
400
+ Root._configure = function(Type_, parse_, common_) {
401
+ Type = Type_;
402
+ parse = parse_;
403
+ common = common_;
404
+ };