protobufjs 8.0.3-experimental → 8.0.3

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