protobufjs 6.8.8 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +941 -921
  2. package/LICENSE +39 -39
  3. package/README.md +901 -879
  4. package/cli/LICENSE +33 -33
  5. package/cli/README.md +11 -11
  6. package/cli/index.d.ts +3 -3
  7. package/cli/index.js +3 -3
  8. package/cli/lib/tsd-jsdoc/LICENSE +20 -20
  9. package/cli/lib/tsd-jsdoc/README.md +23 -23
  10. package/cli/lib/tsd-jsdoc/plugin.js +21 -21
  11. package/cli/lib/tsd-jsdoc/publish.js +705 -693
  12. package/cli/lib/tsd-jsdoc.json +18 -18
  13. package/cli/package.json +1 -1
  14. package/cli/package.standalone.json +32 -32
  15. package/cli/pbjs.d.ts +9 -9
  16. package/cli/pbjs.js +329 -329
  17. package/cli/pbts.d.ts +9 -9
  18. package/cli/pbts.js +197 -197
  19. package/cli/targets/json-module.js +38 -38
  20. package/cli/targets/json.js +8 -8
  21. package/cli/targets/proto.js +326 -326
  22. package/cli/targets/proto2.js +10 -10
  23. package/cli/targets/proto3.js +10 -10
  24. package/cli/targets/static-module.js +29 -29
  25. package/cli/targets/static.js +702 -702
  26. package/cli/util.js +183 -183
  27. package/cli/wrappers/amd.js +7 -7
  28. package/cli/wrappers/closure.js +7 -7
  29. package/cli/wrappers/commonjs.js +7 -7
  30. package/cli/wrappers/default.js +15 -15
  31. package/cli/wrappers/es6.js +5 -5
  32. package/dist/README.md +31 -31
  33. package/dist/light/README.md +31 -31
  34. package/dist/light/protobuf.js +6058 -6032
  35. package/dist/light/protobuf.js.map +1 -1
  36. package/dist/light/protobuf.min.js +3 -3
  37. package/dist/light/protobuf.min.js.map +1 -1
  38. package/dist/minimal/README.md +31 -31
  39. package/dist/minimal/protobuf.js +1900 -1877
  40. package/dist/minimal/protobuf.js.map +1 -1
  41. package/dist/minimal/protobuf.min.js +3 -3
  42. package/dist/minimal/protobuf.min.js.map +1 -1
  43. package/dist/protobuf.js +7625 -7596
  44. package/dist/protobuf.js.map +1 -1
  45. package/dist/protobuf.min.js +3 -3
  46. package/dist/protobuf.min.js.map +1 -1
  47. package/ext/debug/README.md +4 -4
  48. package/ext/debug/index.js +71 -71
  49. package/ext/descriptor/README.md +72 -72
  50. package/ext/descriptor/index.js +1052 -1052
  51. package/ext/descriptor/test.js +54 -54
  52. package/google/LICENSE +27 -27
  53. package/google/README.md +1 -1
  54. package/google/api/annotations.proto +10 -10
  55. package/google/protobuf/descriptor.proto +286 -286
  56. package/google/protobuf/source_context.proto +7 -7
  57. package/index.d.ts +6 -6
  58. package/index.js +4 -4
  59. package/light.d.ts +2 -2
  60. package/light.js +3 -3
  61. package/minimal.d.ts +2 -2
  62. package/minimal.js +4 -4
  63. package/package-lock.json +4223 -3171
  64. package/package.json +122 -122
  65. package/scripts/changelog.js +150 -150
  66. package/scripts/postinstall.js +35 -35
  67. package/src/common.js +399 -399
  68. package/src/converter.js +293 -293
  69. package/src/decoder.js +106 -106
  70. package/src/encoder.js +100 -100
  71. package/src/enum.js +181 -181
  72. package/src/field.js +371 -371
  73. package/src/index-light.js +104 -104
  74. package/src/index-minimal.js +36 -36
  75. package/src/index.js +12 -12
  76. package/src/mapfield.js +126 -126
  77. package/src/message.js +138 -138
  78. package/src/method.js +151 -151
  79. package/src/namespace.js +433 -433
  80. package/src/object.js +200 -200
  81. package/src/oneof.js +203 -203
  82. package/src/parse.js +761 -758
  83. package/src/reader.js +411 -405
  84. package/src/reader_buffer.js +51 -44
  85. package/src/root.js +353 -351
  86. package/src/roots.js +18 -18
  87. package/src/rpc/service.js +142 -142
  88. package/src/rpc.js +36 -36
  89. package/src/service.js +167 -167
  90. package/src/tokenize.js +397 -397
  91. package/src/type.js +589 -589
  92. package/src/types.js +196 -196
  93. package/src/typescript.jsdoc +15 -15
  94. package/src/util/longbits.js +200 -200
  95. package/src/util/minimal.js +414 -414
  96. package/src/util.js +178 -178
  97. package/src/verifier.js +176 -176
  98. package/src/wrappers.js +83 -83
  99. package/src/writer.js +465 -459
  100. package/src/writer_buffer.js +85 -81
  101. package/tsconfig.json +6 -6
  102. package/cli/node_modules/os-tmpdir/index.js +0 -25
  103. package/cli/node_modules/os-tmpdir/license +0 -21
  104. package/cli/node_modules/os-tmpdir/readme.md +0 -32
  105. package/cli/node_modules/tmp/LICENSE +0 -21
  106. package/cli/node_modules/tmp/README.md +0 -314
  107. package/cli/node_modules/tmp/lib/tmp.js +0 -611
  108. package/cli/package-lock.json +0 -20
package/src/parse.js CHANGED
@@ -1,758 +1,761 @@
1
- "use strict";
2
- module.exports = parse;
3
-
4
- parse.filename = null;
5
- parse.defaults = { keepCase: false };
6
-
7
- var tokenize = require("./tokenize"),
8
- Root = require("./root"),
9
- Type = require("./type"),
10
- Field = require("./field"),
11
- MapField = require("./mapfield"),
12
- OneOf = require("./oneof"),
13
- Enum = require("./enum"),
14
- Service = require("./service"),
15
- Method = require("./method"),
16
- types = require("./types"),
17
- util = require("./util");
18
-
19
- var base10Re = /^[1-9][0-9]*$/,
20
- base10NegRe = /^-?[1-9][0-9]*$/,
21
- base16Re = /^0[x][0-9a-fA-F]+$/,
22
- base16NegRe = /^-?0[x][0-9a-fA-F]+$/,
23
- base8Re = /^0[0-7]+$/,
24
- base8NegRe = /^-?0[0-7]+$/,
25
- numberRe = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/,
26
- nameRe = /^[a-zA-Z_][a-zA-Z_0-9]*$/,
27
- typeRefRe = /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
28
- fqTypeRefRe = /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/;
29
-
30
- /**
31
- * Result object returned from {@link parse}.
32
- * @interface IParserResult
33
- * @property {string|undefined} package Package name, if declared
34
- * @property {string[]|undefined} imports Imports, if any
35
- * @property {string[]|undefined} weakImports Weak imports, if any
36
- * @property {string|undefined} syntax Syntax, if specified (either `"proto2"` or `"proto3"`)
37
- * @property {Root} root Populated root instance
38
- */
39
-
40
- /**
41
- * Options modifying the behavior of {@link parse}.
42
- * @interface IParseOptions
43
- * @property {boolean} [keepCase=false] Keeps field casing instead of converting to camel case
44
- * @property {boolean} [alternateCommentMode=false] Recognize double-slash comments in addition to doc-block comments.
45
- */
46
-
47
- /**
48
- * Options modifying the behavior of JSON serialization.
49
- * @interface IToJSONOptions
50
- * @property {boolean} [keepComments=false] Serializes comments.
51
- */
52
-
53
- /**
54
- * Parses the given .proto source and returns an object with the parsed contents.
55
- * @param {string} source Source contents
56
- * @param {Root} root Root to populate
57
- * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
58
- * @returns {IParserResult} Parser result
59
- * @property {string} filename=null Currently processing file name for error reporting, if known
60
- * @property {IParseOptions} defaults Default {@link IParseOptions}
61
- */
62
- function parse(source, root, options) {
63
- /* eslint-disable callback-return */
64
- if (!(root instanceof Root)) {
65
- options = root;
66
- root = new Root();
67
- }
68
- if (!options)
69
- options = parse.defaults;
70
-
71
- var tn = tokenize(source, options.alternateCommentMode || false),
72
- next = tn.next,
73
- push = tn.push,
74
- peek = tn.peek,
75
- skip = tn.skip,
76
- cmnt = tn.cmnt;
77
-
78
- var head = true,
79
- pkg,
80
- imports,
81
- weakImports,
82
- syntax,
83
- isProto3 = false;
84
-
85
- var ptr = root;
86
-
87
- var applyCase = options.keepCase ? function(name) { return name; } : util.camelCase;
88
-
89
- /* istanbul ignore next */
90
- function illegal(token, name, insideTryCatch) {
91
- var filename = parse.filename;
92
- if (!insideTryCatch)
93
- parse.filename = null;
94
- return Error("illegal " + (name || "token") + " '" + token + "' (" + (filename ? filename + ", " : "") + "line " + tn.line + ")");
95
- }
96
-
97
- function readString() {
98
- var values = [],
99
- token;
100
- do {
101
- /* istanbul ignore if */
102
- if ((token = next()) !== "\"" && token !== "'")
103
- throw illegal(token);
104
-
105
- values.push(next());
106
- skip(token);
107
- token = peek();
108
- } while (token === "\"" || token === "'");
109
- return values.join("");
110
- }
111
-
112
- function readValue(acceptTypeRef) {
113
- var token = next();
114
- switch (token) {
115
- case "'":
116
- case "\"":
117
- push(token);
118
- return readString();
119
- case "true": case "TRUE":
120
- return true;
121
- case "false": case "FALSE":
122
- return false;
123
- }
124
- try {
125
- return parseNumber(token, /* insideTryCatch */ true);
126
- } catch (e) {
127
-
128
- /* istanbul ignore else */
129
- if (acceptTypeRef && typeRefRe.test(token))
130
- return token;
131
-
132
- /* istanbul ignore next */
133
- throw illegal(token, "value");
134
- }
135
- }
136
-
137
- function readRanges(target, acceptStrings) {
138
- var token, start;
139
- do {
140
- if (acceptStrings && ((token = peek()) === "\"" || token === "'"))
141
- target.push(readString());
142
- else
143
- target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]);
144
- } while (skip(",", true));
145
- skip(";");
146
- }
147
-
148
- function parseNumber(token, insideTryCatch) {
149
- var sign = 1;
150
- if (token.charAt(0) === "-") {
151
- sign = -1;
152
- token = token.substring(1);
153
- }
154
- switch (token) {
155
- case "inf": case "INF": case "Inf":
156
- return sign * Infinity;
157
- case "nan": case "NAN": case "Nan": case "NaN":
158
- return NaN;
159
- case "0":
160
- return 0;
161
- }
162
- if (base10Re.test(token))
163
- return sign * parseInt(token, 10);
164
- if (base16Re.test(token))
165
- return sign * parseInt(token, 16);
166
- if (base8Re.test(token))
167
- return sign * parseInt(token, 8);
168
-
169
- /* istanbul ignore else */
170
- if (numberRe.test(token))
171
- return sign * parseFloat(token);
172
-
173
- /* istanbul ignore next */
174
- throw illegal(token, "number", insideTryCatch);
175
- }
176
-
177
- function parseId(token, acceptNegative) {
178
- switch (token) {
179
- case "max": case "MAX": case "Max":
180
- return 536870911;
181
- case "0":
182
- return 0;
183
- }
184
-
185
- /* istanbul ignore if */
186
- if (!acceptNegative && token.charAt(0) === "-")
187
- throw illegal(token, "id");
188
-
189
- if (base10NegRe.test(token))
190
- return parseInt(token, 10);
191
- if (base16NegRe.test(token))
192
- return parseInt(token, 16);
193
-
194
- /* istanbul ignore else */
195
- if (base8NegRe.test(token))
196
- return parseInt(token, 8);
197
-
198
- /* istanbul ignore next */
199
- throw illegal(token, "id");
200
- }
201
-
202
- function parsePackage() {
203
-
204
- /* istanbul ignore if */
205
- if (pkg !== undefined)
206
- throw illegal("package");
207
-
208
- pkg = next();
209
-
210
- /* istanbul ignore if */
211
- if (!typeRefRe.test(pkg))
212
- throw illegal(pkg, "name");
213
-
214
- ptr = ptr.define(pkg);
215
- skip(";");
216
- }
217
-
218
- function parseImport() {
219
- var token = peek();
220
- var whichImports;
221
- switch (token) {
222
- case "weak":
223
- whichImports = weakImports || (weakImports = []);
224
- next();
225
- break;
226
- case "public":
227
- next();
228
- // eslint-disable-line no-fallthrough
229
- default:
230
- whichImports = imports || (imports = []);
231
- break;
232
- }
233
- token = readString();
234
- skip(";");
235
- whichImports.push(token);
236
- }
237
-
238
- function parseSyntax() {
239
- skip("=");
240
- syntax = readString();
241
- isProto3 = syntax === "proto3";
242
-
243
- /* istanbul ignore if */
244
- if (!isProto3 && syntax !== "proto2")
245
- throw illegal(syntax, "syntax");
246
-
247
- skip(";");
248
- }
249
-
250
- function parseCommon(parent, token) {
251
- switch (token) {
252
-
253
- case "option":
254
- parseOption(parent, token);
255
- skip(";");
256
- return true;
257
-
258
- case "message":
259
- parseType(parent, token);
260
- return true;
261
-
262
- case "enum":
263
- parseEnum(parent, token);
264
- return true;
265
-
266
- case "service":
267
- parseService(parent, token);
268
- return true;
269
-
270
- case "extend":
271
- parseExtension(parent, token);
272
- return true;
273
- }
274
- return false;
275
- }
276
-
277
- function ifBlock(obj, fnIf, fnElse) {
278
- var trailingLine = tn.line;
279
- if (obj) {
280
- obj.comment = cmnt(); // try block-type comment
281
- obj.filename = parse.filename;
282
- }
283
- if (skip("{", true)) {
284
- var token;
285
- while ((token = next()) !== "}")
286
- fnIf(token);
287
- skip(";", true);
288
- } else {
289
- if (fnElse)
290
- fnElse();
291
- skip(";");
292
- if (obj && typeof obj.comment !== "string")
293
- obj.comment = cmnt(trailingLine); // try line-type comment if no block
294
- }
295
- }
296
-
297
- function parseType(parent, token) {
298
-
299
- /* istanbul ignore if */
300
- if (!nameRe.test(token = next()))
301
- throw illegal(token, "type name");
302
-
303
- var type = new Type(token);
304
- ifBlock(type, function parseType_block(token) {
305
- if (parseCommon(type, token))
306
- return;
307
-
308
- switch (token) {
309
-
310
- case "map":
311
- parseMapField(type, token);
312
- break;
313
-
314
- case "required":
315
- case "optional":
316
- case "repeated":
317
- parseField(type, token);
318
- break;
319
-
320
- case "oneof":
321
- parseOneOf(type, token);
322
- break;
323
-
324
- case "extensions":
325
- readRanges(type.extensions || (type.extensions = []));
326
- break;
327
-
328
- case "reserved":
329
- readRanges(type.reserved || (type.reserved = []), true);
330
- break;
331
-
332
- default:
333
- /* istanbul ignore if */
334
- if (!isProto3 || !typeRefRe.test(token))
335
- throw illegal(token);
336
-
337
- push(token);
338
- parseField(type, "optional");
339
- break;
340
- }
341
- });
342
- parent.add(type);
343
- }
344
-
345
- function parseField(parent, rule, extend) {
346
- var type = next();
347
- if (type === "group") {
348
- parseGroup(parent, rule);
349
- return;
350
- }
351
-
352
- /* istanbul ignore if */
353
- if (!typeRefRe.test(type))
354
- throw illegal(type, "type");
355
-
356
- var name = next();
357
-
358
- /* istanbul ignore if */
359
- if (!nameRe.test(name))
360
- throw illegal(name, "name");
361
-
362
- name = applyCase(name);
363
- skip("=");
364
-
365
- var field = new Field(name, parseId(next()), type, rule, extend);
366
- ifBlock(field, function parseField_block(token) {
367
-
368
- /* istanbul ignore else */
369
- if (token === "option") {
370
- parseOption(field, token);
371
- skip(";");
372
- } else
373
- throw illegal(token);
374
-
375
- }, function parseField_line() {
376
- parseInlineOptions(field);
377
- });
378
- parent.add(field);
379
-
380
- // JSON defaults to packed=true if not set so we have to set packed=false explicity when
381
- // parsing proto2 descriptors without the option, where applicable. This must be done for
382
- // all known packable types and anything that could be an enum (= is not a basic type).
383
- if (!isProto3 && field.repeated && (types.packed[type] !== undefined || types.basic[type] === undefined))
384
- field.setOption("packed", false, /* ifNotSet */ true);
385
- }
386
-
387
- function parseGroup(parent, rule) {
388
- var name = next();
389
-
390
- /* istanbul ignore if */
391
- if (!nameRe.test(name))
392
- throw illegal(name, "name");
393
-
394
- var fieldName = util.lcFirst(name);
395
- if (name === fieldName)
396
- name = util.ucFirst(name);
397
- skip("=");
398
- var id = parseId(next());
399
- var type = new Type(name);
400
- type.group = true;
401
- var field = new Field(fieldName, id, name, rule);
402
- field.filename = parse.filename;
403
- ifBlock(type, function parseGroup_block(token) {
404
- switch (token) {
405
-
406
- case "option":
407
- parseOption(type, token);
408
- skip(";");
409
- break;
410
-
411
- case "required":
412
- case "optional":
413
- case "repeated":
414
- parseField(type, token);
415
- break;
416
-
417
- /* istanbul ignore next */
418
- default:
419
- throw illegal(token); // there are no groups with proto3 semantics
420
- }
421
- });
422
- parent.add(type)
423
- .add(field);
424
- }
425
-
426
- function parseMapField(parent) {
427
- skip("<");
428
- var keyType = next();
429
-
430
- /* istanbul ignore if */
431
- if (types.mapKey[keyType] === undefined)
432
- throw illegal(keyType, "type");
433
-
434
- skip(",");
435
- var valueType = next();
436
-
437
- /* istanbul ignore if */
438
- if (!typeRefRe.test(valueType))
439
- throw illegal(valueType, "type");
440
-
441
- skip(">");
442
- var name = next();
443
-
444
- /* istanbul ignore if */
445
- if (!nameRe.test(name))
446
- throw illegal(name, "name");
447
-
448
- skip("=");
449
- var field = new MapField(applyCase(name), parseId(next()), keyType, valueType);
450
- ifBlock(field, function parseMapField_block(token) {
451
-
452
- /* istanbul ignore else */
453
- if (token === "option") {
454
- parseOption(field, token);
455
- skip(";");
456
- } else
457
- throw illegal(token);
458
-
459
- }, function parseMapField_line() {
460
- parseInlineOptions(field);
461
- });
462
- parent.add(field);
463
- }
464
-
465
- function parseOneOf(parent, token) {
466
-
467
- /* istanbul ignore if */
468
- if (!nameRe.test(token = next()))
469
- throw illegal(token, "name");
470
-
471
- var oneof = new OneOf(applyCase(token));
472
- ifBlock(oneof, function parseOneOf_block(token) {
473
- if (token === "option") {
474
- parseOption(oneof, token);
475
- skip(";");
476
- } else {
477
- push(token);
478
- parseField(oneof, "optional");
479
- }
480
- });
481
- parent.add(oneof);
482
- }
483
-
484
- function parseEnum(parent, token) {
485
-
486
- /* istanbul ignore if */
487
- if (!nameRe.test(token = next()))
488
- throw illegal(token, "name");
489
-
490
- var enm = new Enum(token);
491
- ifBlock(enm, function parseEnum_block(token) {
492
- switch(token) {
493
- case "option":
494
- parseOption(enm, token);
495
- skip(";");
496
- break;
497
-
498
- case "reserved":
499
- readRanges(enm.reserved || (enm.reserved = []), true);
500
- break;
501
-
502
- default:
503
- parseEnumValue(enm, token);
504
- }
505
- });
506
- parent.add(enm);
507
- }
508
-
509
- function parseEnumValue(parent, token) {
510
-
511
- /* istanbul ignore if */
512
- if (!nameRe.test(token))
513
- throw illegal(token, "name");
514
-
515
- skip("=");
516
- var value = parseId(next(), true),
517
- dummy = {};
518
- ifBlock(dummy, function parseEnumValue_block(token) {
519
-
520
- /* istanbul ignore else */
521
- if (token === "option") {
522
- parseOption(dummy, token); // skip
523
- skip(";");
524
- } else
525
- throw illegal(token);
526
-
527
- }, function parseEnumValue_line() {
528
- parseInlineOptions(dummy); // skip
529
- });
530
- parent.add(token, value, dummy.comment);
531
- }
532
-
533
- function parseOption(parent, token) {
534
- var isCustom = skip("(", true);
535
-
536
- /* istanbul ignore if */
537
- if (!typeRefRe.test(token = next()))
538
- throw illegal(token, "name");
539
-
540
- var name = token;
541
- if (isCustom) {
542
- skip(")");
543
- name = "(" + name + ")";
544
- token = peek();
545
- if (fqTypeRefRe.test(token)) {
546
- name += token;
547
- next();
548
- }
549
- }
550
- skip("=");
551
- parseOptionValue(parent, name);
552
- }
553
-
554
- function parseOptionValue(parent, name) {
555
- if (skip("{", true)) { // { a: "foo" b { c: "bar" } }
556
- do {
557
- /* istanbul ignore if */
558
- if (!nameRe.test(token = next()))
559
- throw illegal(token, "name");
560
-
561
- if (peek() === "{")
562
- parseOptionValue(parent, name + "." + token);
563
- else {
564
- skip(":");
565
- if (peek() === "{")
566
- parseOptionValue(parent, name + "." + token);
567
- else
568
- setOption(parent, name + "." + token, readValue(true));
569
- }
570
- skip(",", true);
571
- } while (!skip("}", true));
572
- } else
573
- setOption(parent, name, readValue(true));
574
- // Does not enforce a delimiter to be universal
575
- }
576
-
577
- function setOption(parent, name, value) {
578
- if (parent.setOption)
579
- parent.setOption(name, value);
580
- }
581
-
582
- function parseInlineOptions(parent) {
583
- if (skip("[", true)) {
584
- do {
585
- parseOption(parent, "option");
586
- } while (skip(",", true));
587
- skip("]");
588
- }
589
- return parent;
590
- }
591
-
592
- function parseService(parent, token) {
593
-
594
- /* istanbul ignore if */
595
- if (!nameRe.test(token = next()))
596
- throw illegal(token, "service name");
597
-
598
- var service = new Service(token);
599
- ifBlock(service, function parseService_block(token) {
600
- if (parseCommon(service, token))
601
- return;
602
-
603
- /* istanbul ignore else */
604
- if (token === "rpc")
605
- parseMethod(service, token);
606
- else
607
- throw illegal(token);
608
- });
609
- parent.add(service);
610
- }
611
-
612
- function parseMethod(parent, token) {
613
- var type = token;
614
-
615
- /* istanbul ignore if */
616
- if (!nameRe.test(token = next()))
617
- throw illegal(token, "name");
618
-
619
- var name = token,
620
- requestType, requestStream,
621
- responseType, responseStream;
622
-
623
- skip("(");
624
- if (skip("stream", true))
625
- requestStream = true;
626
-
627
- /* istanbul ignore if */
628
- if (!typeRefRe.test(token = next()))
629
- throw illegal(token);
630
-
631
- requestType = token;
632
- skip(")"); skip("returns"); skip("(");
633
- if (skip("stream", true))
634
- responseStream = true;
635
-
636
- /* istanbul ignore if */
637
- if (!typeRefRe.test(token = next()))
638
- throw illegal(token);
639
-
640
- responseType = token;
641
- skip(")");
642
-
643
- var method = new Method(name, type, requestType, responseType, requestStream, responseStream);
644
- ifBlock(method, function parseMethod_block(token) {
645
-
646
- /* istanbul ignore else */
647
- if (token === "option") {
648
- parseOption(method, token);
649
- skip(";");
650
- } else
651
- throw illegal(token);
652
-
653
- });
654
- parent.add(method);
655
- }
656
-
657
- function parseExtension(parent, token) {
658
-
659
- /* istanbul ignore if */
660
- if (!typeRefRe.test(token = next()))
661
- throw illegal(token, "reference");
662
-
663
- var reference = token;
664
- ifBlock(null, function parseExtension_block(token) {
665
- switch (token) {
666
-
667
- case "required":
668
- case "repeated":
669
- case "optional":
670
- parseField(parent, token, reference);
671
- break;
672
-
673
- default:
674
- /* istanbul ignore if */
675
- if (!isProto3 || !typeRefRe.test(token))
676
- throw illegal(token);
677
- push(token);
678
- parseField(parent, "optional", reference);
679
- break;
680
- }
681
- });
682
- }
683
-
684
- var token;
685
- while ((token = next()) !== null) {
686
- switch (token) {
687
-
688
- case "package":
689
-
690
- /* istanbul ignore if */
691
- if (!head)
692
- throw illegal(token);
693
-
694
- parsePackage();
695
- break;
696
-
697
- case "import":
698
-
699
- /* istanbul ignore if */
700
- if (!head)
701
- throw illegal(token);
702
-
703
- parseImport();
704
- break;
705
-
706
- case "syntax":
707
-
708
- /* istanbul ignore if */
709
- if (!head)
710
- throw illegal(token);
711
-
712
- parseSyntax();
713
- break;
714
-
715
- case "option":
716
-
717
- /* istanbul ignore if */
718
- if (!head)
719
- throw illegal(token);
720
-
721
- parseOption(ptr, token);
722
- skip(";");
723
- break;
724
-
725
- default:
726
-
727
- /* istanbul ignore else */
728
- if (parseCommon(ptr, token)) {
729
- head = false;
730
- continue;
731
- }
732
-
733
- /* istanbul ignore next */
734
- throw illegal(token);
735
- }
736
- }
737
-
738
- parse.filename = null;
739
- return {
740
- "package" : pkg,
741
- "imports" : imports,
742
- weakImports : weakImports,
743
- syntax : syntax,
744
- root : root
745
- };
746
- }
747
-
748
- /**
749
- * Parses the given .proto source and returns an object with the parsed contents.
750
- * @name parse
751
- * @function
752
- * @param {string} source Source contents
753
- * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
754
- * @returns {IParserResult} Parser result
755
- * @property {string} filename=null Currently processing file name for error reporting, if known
756
- * @property {IParseOptions} defaults Default {@link IParseOptions}
757
- * @variation 2
758
- */
1
+ "use strict";
2
+ module.exports = parse;
3
+
4
+ parse.filename = null;
5
+ parse.defaults = { keepCase: false };
6
+
7
+ var tokenize = require("./tokenize"),
8
+ Root = require("./root"),
9
+ Type = require("./type"),
10
+ Field = require("./field"),
11
+ MapField = require("./mapfield"),
12
+ OneOf = require("./oneof"),
13
+ Enum = require("./enum"),
14
+ Service = require("./service"),
15
+ Method = require("./method"),
16
+ types = require("./types"),
17
+ util = require("./util");
18
+
19
+ var base10Re = /^[1-9][0-9]*$/,
20
+ base10NegRe = /^-?[1-9][0-9]*$/,
21
+ base16Re = /^0[x][0-9a-fA-F]+$/,
22
+ base16NegRe = /^-?0[x][0-9a-fA-F]+$/,
23
+ base8Re = /^0[0-7]+$/,
24
+ base8NegRe = /^-?0[0-7]+$/,
25
+ numberRe = /^(?![eE])[0-9]*(?:\.[0-9]*)?(?:[eE][+-]?[0-9]+)?$/,
26
+ nameRe = /^[a-zA-Z_][a-zA-Z_0-9]*$/,
27
+ typeRefRe = /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
28
+ fqTypeRefRe = /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/;
29
+
30
+ /**
31
+ * Result object returned from {@link parse}.
32
+ * @interface IParserResult
33
+ * @property {string|undefined} package Package name, if declared
34
+ * @property {string[]|undefined} imports Imports, if any
35
+ * @property {string[]|undefined} weakImports Weak imports, if any
36
+ * @property {string|undefined} syntax Syntax, if specified (either `"proto2"` or `"proto3"`)
37
+ * @property {Root} root Populated root instance
38
+ */
39
+
40
+ /**
41
+ * Options modifying the behavior of {@link parse}.
42
+ * @interface IParseOptions
43
+ * @property {boolean} [keepCase=false] Keeps field casing instead of converting to camel case
44
+ * @property {boolean} [alternateCommentMode=false] Recognize double-slash comments in addition to doc-block comments.
45
+ */
46
+
47
+ /**
48
+ * Options modifying the behavior of JSON serialization.
49
+ * @interface IToJSONOptions
50
+ * @property {boolean} [keepComments=false] Serializes comments.
51
+ */
52
+
53
+ /**
54
+ * Parses the given .proto source and returns an object with the parsed contents.
55
+ * @param {string} source Source contents
56
+ * @param {Root} root Root to populate
57
+ * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
58
+ * @returns {IParserResult} Parser result
59
+ * @property {string} filename=null Currently processing file name for error reporting, if known
60
+ * @property {IParseOptions} defaults Default {@link IParseOptions}
61
+ */
62
+ function parse(source, root, options) {
63
+ /* eslint-disable callback-return */
64
+ if (!(root instanceof Root)) {
65
+ options = root;
66
+ root = new Root();
67
+ }
68
+ if (!options)
69
+ options = parse.defaults;
70
+
71
+ var tn = tokenize(source, options.alternateCommentMode || false),
72
+ next = tn.next,
73
+ push = tn.push,
74
+ peek = tn.peek,
75
+ skip = tn.skip,
76
+ cmnt = tn.cmnt;
77
+
78
+ var head = true,
79
+ pkg,
80
+ imports,
81
+ weakImports,
82
+ syntax,
83
+ isProto3 = false;
84
+
85
+ var ptr = root;
86
+
87
+ var applyCase = options.keepCase ? function(name) { return name; } : util.camelCase;
88
+
89
+ /* istanbul ignore next */
90
+ function illegal(token, name, insideTryCatch) {
91
+ var filename = parse.filename;
92
+ if (!insideTryCatch)
93
+ parse.filename = null;
94
+ return Error("illegal " + (name || "token") + " '" + token + "' (" + (filename ? filename + ", " : "") + "line " + tn.line + ")");
95
+ }
96
+
97
+ function readString() {
98
+ var values = [],
99
+ token;
100
+ do {
101
+ /* istanbul ignore if */
102
+ if ((token = next()) !== "\"" && token !== "'")
103
+ throw illegal(token);
104
+
105
+ values.push(next());
106
+ skip(token);
107
+ token = peek();
108
+ } while (token === "\"" || token === "'");
109
+ return values.join("");
110
+ }
111
+
112
+ function readValue(acceptTypeRef) {
113
+ var token = next();
114
+ switch (token) {
115
+ case "'":
116
+ case "\"":
117
+ push(token);
118
+ return readString();
119
+ case "true": case "TRUE":
120
+ return true;
121
+ case "false": case "FALSE":
122
+ return false;
123
+ }
124
+ try {
125
+ return parseNumber(token, /* insideTryCatch */ true);
126
+ } catch (e) {
127
+
128
+ /* istanbul ignore else */
129
+ if (acceptTypeRef && typeRefRe.test(token))
130
+ return token;
131
+
132
+ /* istanbul ignore next */
133
+ throw illegal(token, "value");
134
+ }
135
+ }
136
+
137
+ function readRanges(target, acceptStrings) {
138
+ var token, start;
139
+ do {
140
+ if (acceptStrings && ((token = peek()) === "\"" || token === "'"))
141
+ target.push(readString());
142
+ else
143
+ target.push([ start = parseId(next()), skip("to", true) ? parseId(next()) : start ]);
144
+ } while (skip(",", true));
145
+ skip(";");
146
+ }
147
+
148
+ function parseNumber(token, insideTryCatch) {
149
+ var sign = 1;
150
+ if (token.charAt(0) === "-") {
151
+ sign = -1;
152
+ token = token.substring(1);
153
+ }
154
+ switch (token) {
155
+ case "inf": case "INF": case "Inf":
156
+ return sign * Infinity;
157
+ case "nan": case "NAN": case "Nan": case "NaN":
158
+ return NaN;
159
+ case "0":
160
+ return 0;
161
+ }
162
+ if (base10Re.test(token))
163
+ return sign * parseInt(token, 10);
164
+ if (base16Re.test(token))
165
+ return sign * parseInt(token, 16);
166
+ if (base8Re.test(token))
167
+ return sign * parseInt(token, 8);
168
+
169
+ /* istanbul ignore else */
170
+ if (numberRe.test(token))
171
+ return sign * parseFloat(token);
172
+
173
+ /* istanbul ignore next */
174
+ throw illegal(token, "number", insideTryCatch);
175
+ }
176
+
177
+ function parseId(token, acceptNegative) {
178
+ switch (token) {
179
+ case "max": case "MAX": case "Max":
180
+ return 536870911;
181
+ case "0":
182
+ return 0;
183
+ }
184
+
185
+ /* istanbul ignore if */
186
+ if (!acceptNegative && token.charAt(0) === "-")
187
+ throw illegal(token, "id");
188
+
189
+ if (base10NegRe.test(token))
190
+ return parseInt(token, 10);
191
+ if (base16NegRe.test(token))
192
+ return parseInt(token, 16);
193
+
194
+ /* istanbul ignore else */
195
+ if (base8NegRe.test(token))
196
+ return parseInt(token, 8);
197
+
198
+ /* istanbul ignore next */
199
+ throw illegal(token, "id");
200
+ }
201
+
202
+ function parsePackage() {
203
+
204
+ /* istanbul ignore if */
205
+ if (pkg !== undefined)
206
+ throw illegal("package");
207
+
208
+ pkg = next();
209
+
210
+ /* istanbul ignore if */
211
+ if (!typeRefRe.test(pkg))
212
+ throw illegal(pkg, "name");
213
+
214
+ ptr = ptr.define(pkg);
215
+ skip(";");
216
+ }
217
+
218
+ function parseImport() {
219
+ var token = peek();
220
+ var whichImports;
221
+ switch (token) {
222
+ case "weak":
223
+ whichImports = weakImports || (weakImports = []);
224
+ next();
225
+ break;
226
+ case "public":
227
+ next();
228
+ // eslint-disable-line no-fallthrough
229
+ default:
230
+ whichImports = imports || (imports = []);
231
+ break;
232
+ }
233
+ token = readString();
234
+ skip(";");
235
+ whichImports.push(token);
236
+ }
237
+
238
+ function parseSyntax() {
239
+ skip("=");
240
+ syntax = readString();
241
+ isProto3 = syntax === "proto3";
242
+
243
+ /* istanbul ignore if */
244
+ if (!isProto3 && syntax !== "proto2")
245
+ throw illegal(syntax, "syntax");
246
+
247
+ skip(";");
248
+ }
249
+
250
+ function parseCommon(parent, token) {
251
+ switch (token) {
252
+
253
+ case "option":
254
+ parseOption(parent, token);
255
+ skip(";");
256
+ return true;
257
+
258
+ case "message":
259
+ parseType(parent, token);
260
+ return true;
261
+
262
+ case "enum":
263
+ parseEnum(parent, token);
264
+ return true;
265
+
266
+ case "service":
267
+ parseService(parent, token);
268
+ return true;
269
+
270
+ case "extend":
271
+ parseExtension(parent, token);
272
+ return true;
273
+ }
274
+ return false;
275
+ }
276
+
277
+ function ifBlock(obj, fnIf, fnElse) {
278
+ var trailingLine = tn.line;
279
+ if (obj) {
280
+ if(typeof obj.comment !== "string") {
281
+ obj.comment = cmnt(); // try block-type comment
282
+ }
283
+ obj.filename = parse.filename;
284
+ }
285
+ if (skip("{", true)) {
286
+ var token;
287
+ while ((token = next()) !== "}")
288
+ fnIf(token);
289
+ skip(";", true);
290
+ } else {
291
+ if (fnElse)
292
+ fnElse();
293
+ skip(";");
294
+ if (obj && typeof obj.comment !== "string")
295
+ obj.comment = cmnt(trailingLine); // try line-type comment if no block
296
+ }
297
+ }
298
+
299
+ function parseType(parent, token) {
300
+
301
+ /* istanbul ignore if */
302
+ if (!nameRe.test(token = next()))
303
+ throw illegal(token, "type name");
304
+
305
+ var type = new Type(token);
306
+ ifBlock(type, function parseType_block(token) {
307
+ if (parseCommon(type, token))
308
+ return;
309
+
310
+ switch (token) {
311
+
312
+ case "map":
313
+ parseMapField(type, token);
314
+ break;
315
+
316
+ case "required":
317
+ case "optional":
318
+ case "repeated":
319
+ parseField(type, token);
320
+ break;
321
+
322
+ case "oneof":
323
+ parseOneOf(type, token);
324
+ break;
325
+
326
+ case "extensions":
327
+ readRanges(type.extensions || (type.extensions = []));
328
+ break;
329
+
330
+ case "reserved":
331
+ readRanges(type.reserved || (type.reserved = []), true);
332
+ break;
333
+
334
+ default:
335
+ /* istanbul ignore if */
336
+ if (!isProto3 || !typeRefRe.test(token))
337
+ throw illegal(token);
338
+
339
+ push(token);
340
+ parseField(type, "optional");
341
+ break;
342
+ }
343
+ });
344
+ parent.add(type);
345
+ }
346
+
347
+ function parseField(parent, rule, extend) {
348
+ var type = next();
349
+ if (type === "group") {
350
+ parseGroup(parent, rule);
351
+ return;
352
+ }
353
+
354
+ /* istanbul ignore if */
355
+ if (!typeRefRe.test(type))
356
+ throw illegal(type, "type");
357
+
358
+ var name = next();
359
+
360
+ /* istanbul ignore if */
361
+ if (!nameRe.test(name))
362
+ throw illegal(name, "name");
363
+
364
+ name = applyCase(name);
365
+ skip("=");
366
+
367
+ var field = new Field(name, parseId(next()), type, rule, extend);
368
+ ifBlock(field, function parseField_block(token) {
369
+
370
+ /* istanbul ignore else */
371
+ if (token === "option") {
372
+ parseOption(field, token);
373
+ skip(";");
374
+ } else
375
+ throw illegal(token);
376
+
377
+ }, function parseField_line() {
378
+ parseInlineOptions(field);
379
+ });
380
+ parent.add(field);
381
+
382
+ // JSON defaults to packed=true if not set so we have to set packed=false explicity when
383
+ // parsing proto2 descriptors without the option, where applicable. This must be done for
384
+ // all known packable types and anything that could be an enum (= is not a basic type).
385
+ if (!isProto3 && field.repeated && (types.packed[type] !== undefined || types.basic[type] === undefined))
386
+ field.setOption("packed", false, /* ifNotSet */ true);
387
+ }
388
+
389
+ function parseGroup(parent, rule) {
390
+ var name = next();
391
+
392
+ /* istanbul ignore if */
393
+ if (!nameRe.test(name))
394
+ throw illegal(name, "name");
395
+
396
+ var fieldName = util.lcFirst(name);
397
+ if (name === fieldName)
398
+ name = util.ucFirst(name);
399
+ skip("=");
400
+ var id = parseId(next());
401
+ var type = new Type(name);
402
+ type.group = true;
403
+ var field = new Field(fieldName, id, name, rule);
404
+ field.filename = parse.filename;
405
+ ifBlock(type, function parseGroup_block(token) {
406
+ switch (token) {
407
+
408
+ case "option":
409
+ parseOption(type, token);
410
+ skip(";");
411
+ break;
412
+
413
+ case "required":
414
+ case "optional":
415
+ case "repeated":
416
+ parseField(type, token);
417
+ break;
418
+
419
+ /* istanbul ignore next */
420
+ default:
421
+ throw illegal(token); // there are no groups with proto3 semantics
422
+ }
423
+ });
424
+ parent.add(type)
425
+ .add(field);
426
+ }
427
+
428
+ function parseMapField(parent) {
429
+ skip("<");
430
+ var keyType = next();
431
+
432
+ /* istanbul ignore if */
433
+ if (types.mapKey[keyType] === undefined)
434
+ throw illegal(keyType, "type");
435
+
436
+ skip(",");
437
+ var valueType = next();
438
+
439
+ /* istanbul ignore if */
440
+ if (!typeRefRe.test(valueType))
441
+ throw illegal(valueType, "type");
442
+
443
+ skip(">");
444
+ var name = next();
445
+
446
+ /* istanbul ignore if */
447
+ if (!nameRe.test(name))
448
+ throw illegal(name, "name");
449
+
450
+ skip("=");
451
+ var field = new MapField(applyCase(name), parseId(next()), keyType, valueType);
452
+ ifBlock(field, function parseMapField_block(token) {
453
+
454
+ /* istanbul ignore else */
455
+ if (token === "option") {
456
+ parseOption(field, token);
457
+ skip(";");
458
+ } else
459
+ throw illegal(token);
460
+
461
+ }, function parseMapField_line() {
462
+ parseInlineOptions(field);
463
+ });
464
+ parent.add(field);
465
+ }
466
+
467
+ function parseOneOf(parent, token) {
468
+
469
+ /* istanbul ignore if */
470
+ if (!nameRe.test(token = next()))
471
+ throw illegal(token, "name");
472
+
473
+ var oneof = new OneOf(applyCase(token));
474
+ ifBlock(oneof, function parseOneOf_block(token) {
475
+ if (token === "option") {
476
+ parseOption(oneof, token);
477
+ skip(";");
478
+ } else {
479
+ push(token);
480
+ parseField(oneof, "optional");
481
+ }
482
+ });
483
+ parent.add(oneof);
484
+ }
485
+
486
+ function parseEnum(parent, token) {
487
+
488
+ /* istanbul ignore if */
489
+ if (!nameRe.test(token = next()))
490
+ throw illegal(token, "name");
491
+
492
+ var enm = new Enum(token);
493
+ ifBlock(enm, function parseEnum_block(token) {
494
+ switch(token) {
495
+ case "option":
496
+ parseOption(enm, token);
497
+ skip(";");
498
+ break;
499
+
500
+ case "reserved":
501
+ readRanges(enm.reserved || (enm.reserved = []), true);
502
+ break;
503
+
504
+ default:
505
+ parseEnumValue(enm, token);
506
+ }
507
+ });
508
+ parent.add(enm);
509
+ }
510
+
511
+ function parseEnumValue(parent, token) {
512
+
513
+ /* istanbul ignore if */
514
+ if (!nameRe.test(token))
515
+ throw illegal(token, "name");
516
+
517
+ skip("=");
518
+ var value = parseId(next(), true),
519
+ dummy = {};
520
+ ifBlock(dummy, function parseEnumValue_block(token) {
521
+
522
+ /* istanbul ignore else */
523
+ if (token === "option") {
524
+ parseOption(dummy, token); // skip
525
+ skip(";");
526
+ } else
527
+ throw illegal(token);
528
+
529
+ }, function parseEnumValue_line() {
530
+ parseInlineOptions(dummy); // skip
531
+ });
532
+ parent.add(token, value, dummy.comment);
533
+ }
534
+
535
+ function parseOption(parent, token) {
536
+ var isCustom = skip("(", true);
537
+
538
+ /* istanbul ignore if */
539
+ if (!typeRefRe.test(token = next()))
540
+ throw illegal(token, "name");
541
+
542
+ var name = token;
543
+ if (isCustom) {
544
+ skip(")");
545
+ name = "(" + name + ")";
546
+ token = peek();
547
+ if (fqTypeRefRe.test(token)) {
548
+ name += token;
549
+ next();
550
+ }
551
+ }
552
+ skip("=");
553
+ parseOptionValue(parent, name);
554
+ }
555
+
556
+ function parseOptionValue(parent, name) {
557
+ if (skip("{", true)) { // { a: "foo" b { c: "bar" } }
558
+ do {
559
+ /* istanbul ignore if */
560
+ if (!nameRe.test(token = next()))
561
+ throw illegal(token, "name");
562
+
563
+ if (peek() === "{")
564
+ parseOptionValue(parent, name + "." + token);
565
+ else {
566
+ skip(":");
567
+ if (peek() === "{")
568
+ parseOptionValue(parent, name + "." + token);
569
+ else
570
+ setOption(parent, name + "." + token, readValue(true));
571
+ }
572
+ skip(",", true);
573
+ } while (!skip("}", true));
574
+ } else
575
+ setOption(parent, name, readValue(true));
576
+ // Does not enforce a delimiter to be universal
577
+ }
578
+
579
+ function setOption(parent, name, value) {
580
+ if (parent.setOption)
581
+ parent.setOption(name, value);
582
+ }
583
+
584
+ function parseInlineOptions(parent) {
585
+ if (skip("[", true)) {
586
+ do {
587
+ parseOption(parent, "option");
588
+ } while (skip(",", true));
589
+ skip("]");
590
+ }
591
+ return parent;
592
+ }
593
+
594
+ function parseService(parent, token) {
595
+
596
+ /* istanbul ignore if */
597
+ if (!nameRe.test(token = next()))
598
+ throw illegal(token, "service name");
599
+
600
+ var service = new Service(token);
601
+ ifBlock(service, function parseService_block(token) {
602
+ if (parseCommon(service, token))
603
+ return;
604
+
605
+ /* istanbul ignore else */
606
+ if (token === "rpc")
607
+ parseMethod(service, token);
608
+ else
609
+ throw illegal(token);
610
+ });
611
+ parent.add(service);
612
+ }
613
+
614
+ function parseMethod(parent, token) {
615
+ // Get the comment of the preceding line now (if one exists) in case the
616
+ // method is defined across multiple lines.
617
+ var commentText = cmnt();
618
+
619
+ var type = token;
620
+
621
+ /* istanbul ignore if */
622
+ if (!nameRe.test(token = next()))
623
+ throw illegal(token, "name");
624
+
625
+ var name = token,
626
+ requestType, requestStream,
627
+ responseType, responseStream;
628
+
629
+ skip("(");
630
+ if (skip("stream", true))
631
+ requestStream = true;
632
+
633
+ /* istanbul ignore if */
634
+ if (!typeRefRe.test(token = next()))
635
+ throw illegal(token);
636
+
637
+ requestType = token;
638
+ skip(")"); skip("returns"); skip("(");
639
+ if (skip("stream", true))
640
+ responseStream = true;
641
+
642
+ /* istanbul ignore if */
643
+ if (!typeRefRe.test(token = next()))
644
+ throw illegal(token);
645
+
646
+ responseType = token;
647
+ skip(")");
648
+
649
+ var method = new Method(name, type, requestType, responseType, requestStream, responseStream);
650
+ method.comment = commentText;
651
+ ifBlock(method, function parseMethod_block(token) {
652
+
653
+ /* istanbul ignore else */
654
+ if (token === "option") {
655
+ parseOption(method, token);
656
+ skip(";");
657
+ } else
658
+ throw illegal(token);
659
+
660
+ });
661
+ parent.add(method);
662
+ }
663
+
664
+ function parseExtension(parent, token) {
665
+
666
+ /* istanbul ignore if */
667
+ if (!typeRefRe.test(token = next()))
668
+ throw illegal(token, "reference");
669
+
670
+ var reference = token;
671
+ ifBlock(null, function parseExtension_block(token) {
672
+ switch (token) {
673
+
674
+ case "required":
675
+ case "repeated":
676
+ case "optional":
677
+ parseField(parent, token, reference);
678
+ break;
679
+
680
+ default:
681
+ /* istanbul ignore if */
682
+ if (!isProto3 || !typeRefRe.test(token))
683
+ throw illegal(token);
684
+ push(token);
685
+ parseField(parent, "optional", reference);
686
+ break;
687
+ }
688
+ });
689
+ }
690
+
691
+ var token;
692
+ while ((token = next()) !== null) {
693
+ switch (token) {
694
+
695
+ case "package":
696
+
697
+ /* istanbul ignore if */
698
+ if (!head)
699
+ throw illegal(token);
700
+
701
+ parsePackage();
702
+ break;
703
+
704
+ case "import":
705
+
706
+ /* istanbul ignore if */
707
+ if (!head)
708
+ throw illegal(token);
709
+
710
+ parseImport();
711
+ break;
712
+
713
+ case "syntax":
714
+
715
+ /* istanbul ignore if */
716
+ if (!head)
717
+ throw illegal(token);
718
+
719
+ parseSyntax();
720
+ break;
721
+
722
+ case "option":
723
+
724
+ parseOption(ptr, token);
725
+ skip(";");
726
+ break;
727
+
728
+ default:
729
+
730
+ /* istanbul ignore else */
731
+ if (parseCommon(ptr, token)) {
732
+ head = false;
733
+ continue;
734
+ }
735
+
736
+ /* istanbul ignore next */
737
+ throw illegal(token);
738
+ }
739
+ }
740
+
741
+ parse.filename = null;
742
+ return {
743
+ "package" : pkg,
744
+ "imports" : imports,
745
+ weakImports : weakImports,
746
+ syntax : syntax,
747
+ root : root
748
+ };
749
+ }
750
+
751
+ /**
752
+ * Parses the given .proto source and returns an object with the parsed contents.
753
+ * @name parse
754
+ * @function
755
+ * @param {string} source Source contents
756
+ * @param {IParseOptions} [options] Parse options. Defaults to {@link parse.defaults} when omitted.
757
+ * @returns {IParserResult} Parser result
758
+ * @property {string} filename=null Currently processing file name for error reporting, if known
759
+ * @property {IParseOptions} defaults Default {@link IParseOptions}
760
+ * @variation 2
761
+ */