protobufjs 3.6.0 → 3.8.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 (99) hide show
  1. package/bin/proto2js +16 -4
  2. package/bower.json +1 -1
  3. package/dist/ProtoBuf.js +645 -441
  4. package/dist/ProtoBuf.min.js +96 -96
  5. package/dist/ProtoBuf.min.js.gz +0 -0
  6. package/dist/ProtoBuf.min.map +2 -2
  7. package/dist/ProtoBuf.noparse.js +520 -357
  8. package/dist/ProtoBuf.noparse.min.js +68 -66
  9. package/dist/ProtoBuf.noparse.min.js.gz +0 -0
  10. package/dist/ProtoBuf.noparse.min.map +3 -3
  11. package/docs/ProtoBuf.Builder.Message.html +673 -135
  12. package/docs/ProtoBuf.Builder.Service.html +58 -19
  13. package/docs/ProtoBuf.Builder.html +374 -46
  14. package/docs/ProtoBuf.DotProto.Parser.html +58 -19
  15. package/docs/ProtoBuf.DotProto.Tokenizer.html +104 -19
  16. package/docs/ProtoBuf.DotProto.html +16 -10
  17. package/docs/ProtoBuf.Reflect.Enum.Value.html +207 -33
  18. package/docs/ProtoBuf.Reflect.Enum.html +318 -56
  19. package/docs/ProtoBuf.Reflect.Extension.html +53 -13
  20. package/docs/ProtoBuf.Reflect.Message.ExtensionField.html +450 -68
  21. package/docs/ProtoBuf.Reflect.Message.Field.html +454 -51
  22. package/docs/ProtoBuf.Reflect.Message.OneOf.html +1044 -0
  23. package/docs/ProtoBuf.Reflect.Message.html +378 -64
  24. package/docs/ProtoBuf.Reflect.Namespace.html +333 -51
  25. package/docs/ProtoBuf.Reflect.Service.Method.html +228 -35
  26. package/docs/ProtoBuf.Reflect.Service.RPCMethod.html +262 -41
  27. package/docs/ProtoBuf.Reflect.Service.html +318 -56
  28. package/docs/ProtoBuf.Reflect.T.html +210 -25
  29. package/docs/ProtoBuf.Reflect.html +17 -11
  30. package/docs/ProtoBuf.Util.html +59 -13
  31. package/docs/ProtoBuf.html +235 -67
  32. package/docs/ProtoBuf.js.html +648 -443
  33. package/docs/index.html +4 -2
  34. package/docs/styles/jsdoc-default.css +2 -2
  35. package/examples/protoify/.npmignore +2 -0
  36. package/examples/protoify/README.md +28 -0
  37. package/examples/protoify/index.js +147 -0
  38. package/examples/protoify/json.js +123 -0
  39. package/examples/protoify/json.json +123 -0
  40. package/examples/protoify/json.proto +30 -0
  41. package/examples/protoify/package.json +15 -0
  42. package/examples/protoify/test.js +56 -0
  43. package/examples/websocket/README.md +1 -0
  44. package/examples/websocket/package.json +1 -1
  45. package/externs/ProtoBuf.js +922 -922
  46. package/package.json +3 -3
  47. package/scripts/build.js +58 -58
  48. package/src/ProtoBuf/Builder/Message.js +107 -77
  49. package/src/ProtoBuf/Builder/Service.js +8 -5
  50. package/src/ProtoBuf/Builder.js +71 -37
  51. package/src/ProtoBuf/DotProto/Parser.js +108 -72
  52. package/src/ProtoBuf/DotProto/Tokenizer.js +17 -11
  53. package/src/ProtoBuf/Lang.js +1 -1
  54. package/src/ProtoBuf/Reflect/Enum/Value.js +3 -2
  55. package/src/ProtoBuf/Reflect/Enum.js +9 -5
  56. package/src/ProtoBuf/Reflect/Extension.js +4 -3
  57. package/src/ProtoBuf/Reflect/Message/ExtensionField.js +4 -3
  58. package/src/ProtoBuf/Reflect/Message/Field.js +45 -26
  59. package/src/ProtoBuf/Reflect/Message/OneOf.js +19 -0
  60. package/src/ProtoBuf/Reflect/Message.js +36 -19
  61. package/src/ProtoBuf/Reflect/Namespace.js +19 -15
  62. package/src/ProtoBuf/Reflect/Service/Method.js +9 -5
  63. package/src/ProtoBuf/Reflect/Service/RPCMethod.js +3 -2
  64. package/src/ProtoBuf/Reflect/Service.js +9 -5
  65. package/src/ProtoBuf/Reflect/T.js +20 -6
  66. package/src/ProtoBuf/Reflect.js +9 -0
  67. package/src/ProtoBuf/Util.js +132 -132
  68. package/src/ProtoBuf.js +15 -17
  69. package/src/google/protobuf/descriptor.json +33 -13
  70. package/tests/bench.txt +373 -373
  71. package/tests/complex.json +8 -4
  72. package/tests/custom-options.json +169 -169
  73. package/tests/extend.json +71 -71
  74. package/tests/nodeunit-browser/nodeunit.css +70 -70
  75. package/tests/nodeunit-browser/nodeunit.js +2108 -2108
  76. package/tests/oneof.proto +6 -0
  77. package/tests/options.json +32 -32
  78. package/tests/options.proto +2 -0
  79. package/tests/proto2js/Bar.json +46 -46
  80. package/tests/suite.js +83 -12
  81. package/.idea/.name +0 -1
  82. package/.idea/ProtoBuf.iml +0 -9
  83. package/.idea/dictionaries/Daniel.xml +0 -7
  84. package/.idea/encodings.xml +0 -5
  85. package/.idea/misc.xml +0 -5
  86. package/.idea/modules.xml +0 -9
  87. package/.idea/scopes/scope_settings.xml +0 -5
  88. package/.idea/vcs.xml +0 -7
  89. package/.idea/workspace.xml +0 -551
  90. package/NOTICE +0 -2
  91. package/sandbox/issue146/MyOptions.proto +0 -28
  92. package/sandbox/issue146/Sample.proto +0 -21
  93. package/sandbox/issue146/main.js +0 -3
  94. package/sandbox/issue147/enum.proto +0 -8
  95. package/sandbox/issue147/main.js +0 -3
  96. package/sandbox/issue42/innerextend.proto +0 -18
  97. package/sandbox/issue42/main.js +0 -8
  98. package/sandbox/issue42/outerextend.proto +0 -17
  99. package/v8.log +0 -3828
@@ -22,6 +22,7 @@
22
22
 
23
23
 
24
24
 
25
+
25
26
 
26
27
  <section>
27
28
  <article>
@@ -65,7 +66,7 @@
65
66
  * @const
66
67
  * @expose
67
68
  */
68
- ProtoBuf.VERSION = "3.6.0";
69
+ ProtoBuf.VERSION = "3.8.2";
69
70
 
70
71
  /**
71
72
  * Wire types.
@@ -261,138 +262,138 @@
261
262
  */
262
263
  ProtoBuf.populateAccessors = true;
263
264
 
264
- /**
265
- * @alias ProtoBuf.Util
266
- * @expose
267
- */
268
- ProtoBuf.Util = (function() {
269
- "use strict";
270
-
271
- // Object.create polyfill
272
- // ref: https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
273
- if (!Object.create)
274
- /** @expose */
275
- Object.create = function (o) {
276
- if (arguments.length > 1)
277
- throw Error('Object.create polyfill only accepts the first parameter.');
278
- function F() {}
279
- F.prototype = o;
280
- return new F();
281
- };
282
-
283
- /**
284
- * ProtoBuf utilities.
285
- * @exports ProtoBuf.Util
286
- * @namespace
287
- */
288
- var Util = {};
289
-
290
- /**
291
- * Flag if running in node (fs is available) or not.
292
- * @type {boolean}
293
- * @const
294
- * @expose
295
- */
296
- Util.IS_NODE = false;
297
- try {
298
- // There is no reliable way to detect node.js as an environment, so our
299
- // best bet is to feature-detect what we actually need.
300
- Util.IS_NODE =
301
- typeof require === 'function' &amp;&amp;
302
- typeof require("fs").readFileSync === 'function' &amp;&amp;
303
- typeof require("path").resolve === 'function';
304
- } catch (e) {}
305
-
306
- /**
307
- * Constructs a XMLHttpRequest object.
308
- * @return {XMLHttpRequest}
309
- * @throws {Error} If XMLHttpRequest is not supported
310
- * @expose
311
- */
312
- Util.XHR = function() {
313
- // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
314
- var XMLHttpFactories = [
315
- function () {return new XMLHttpRequest()},
316
- function () {return new ActiveXObject("Msxml2.XMLHTTP")},
317
- function () {return new ActiveXObject("Msxml3.XMLHTTP")},
318
- function () {return new ActiveXObject("Microsoft.XMLHTTP")}
319
- ];
320
- /** @type {?XMLHttpRequest} */
321
- var xhr = null;
322
- for (var i=0;i&lt;XMLHttpFactories.length;i++) {
323
- try { xhr = XMLHttpFactories[i](); }
324
- catch (e) { continue; }
325
- break;
326
- }
327
- if (!xhr)
328
- throw Error("XMLHttpRequest is not supported");
329
- return xhr;
330
- };
331
-
332
- /**
333
- * Fetches a resource.
334
- * @param {string} path Resource path
335
- * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
336
- * be fetched synchronously. If the request failed, contents will be null.
337
- * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
338
- * @expose
339
- */
340
- Util.fetch = function(path, callback) {
341
- if (callback &amp;&amp; typeof callback != 'function')
342
- callback = null;
343
- if (Util.IS_NODE) {
344
- if (callback) {
345
- require("fs").readFile(path, function(err, data) {
346
- if (err)
347
- callback(null);
348
- else
349
- callback(""+data);
350
- });
351
- } else
352
- try {
353
- return require("fs").readFileSync(path);
354
- } catch (e) {
355
- return null;
356
- }
357
- } else {
358
- var xhr = Util.XHR();
359
- xhr.open('GET', path, callback ? true : false);
360
- // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
361
- xhr.setRequestHeader('Accept', 'text/plain');
362
- if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
363
- if (callback) {
364
- xhr.onreadystatechange = function() {
365
- if (xhr.readyState != 4) return;
366
- if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 &amp;&amp; typeof xhr.responseText === 'string'))
367
- callback(xhr.responseText);
368
- else
369
- callback(null);
370
- };
371
- if (xhr.readyState == 4)
372
- return;
373
- xhr.send(null);
374
- } else {
375
- xhr.send(null);
376
- if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 &amp;&amp; typeof xhr.responseText === 'string'))
377
- return xhr.responseText;
378
- return null;
379
- }
380
- }
381
- };
382
-
383
- /**
384
- * Tests if an object is an array.
385
- * @function
386
- * @param {*} obj Object to test
387
- * @returns {boolean} true if it is an array, else false
388
- * @expose
389
- */
390
- Util.isArray = Array.isArray || function(obj) {
391
- return Object.prototype.toString.call(obj) === "[object Array]";
392
- };
393
-
394
- return Util;
395
- })();
265
+ /**
266
+ * @alias ProtoBuf.Util
267
+ * @expose
268
+ */
269
+ ProtoBuf.Util = (function() {
270
+ "use strict";
271
+
272
+ // Object.create polyfill
273
+ // ref: https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
274
+ if (!Object.create)
275
+ /** @expose */
276
+ Object.create = function (o) {
277
+ if (arguments.length > 1)
278
+ throw Error('Object.create polyfill only accepts the first parameter.');
279
+ function F() {}
280
+ F.prototype = o;
281
+ return new F();
282
+ };
283
+
284
+ /**
285
+ * ProtoBuf utilities.
286
+ * @exports ProtoBuf.Util
287
+ * @namespace
288
+ */
289
+ var Util = {};
290
+
291
+ /**
292
+ * Flag if running in node (fs is available) or not.
293
+ * @type {boolean}
294
+ * @const
295
+ * @expose
296
+ */
297
+ Util.IS_NODE = false;
298
+ try {
299
+ // There is no reliable way to detect node.js as an environment, so our
300
+ // best bet is to feature-detect what we actually need.
301
+ Util.IS_NODE =
302
+ typeof require === 'function' &amp;&amp;
303
+ typeof require("fs").readFileSync === 'function' &amp;&amp;
304
+ typeof require("path").resolve === 'function';
305
+ } catch (e) {}
306
+
307
+ /**
308
+ * Constructs a XMLHttpRequest object.
309
+ * @return {XMLHttpRequest}
310
+ * @throws {Error} If XMLHttpRequest is not supported
311
+ * @expose
312
+ */
313
+ Util.XHR = function() {
314
+ // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
315
+ var XMLHttpFactories = [
316
+ function () {return new XMLHttpRequest()},
317
+ function () {return new ActiveXObject("Msxml2.XMLHTTP")},
318
+ function () {return new ActiveXObject("Msxml3.XMLHTTP")},
319
+ function () {return new ActiveXObject("Microsoft.XMLHTTP")}
320
+ ];
321
+ /** @type {?XMLHttpRequest} */
322
+ var xhr = null;
323
+ for (var i=0;i&lt;XMLHttpFactories.length;i++) {
324
+ try { xhr = XMLHttpFactories[i](); }
325
+ catch (e) { continue; }
326
+ break;
327
+ }
328
+ if (!xhr)
329
+ throw Error("XMLHttpRequest is not supported");
330
+ return xhr;
331
+ };
332
+
333
+ /**
334
+ * Fetches a resource.
335
+ * @param {string} path Resource path
336
+ * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
337
+ * be fetched synchronously. If the request failed, contents will be null.
338
+ * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
339
+ * @expose
340
+ */
341
+ Util.fetch = function(path, callback) {
342
+ if (callback &amp;&amp; typeof callback != 'function')
343
+ callback = null;
344
+ if (Util.IS_NODE) {
345
+ if (callback) {
346
+ require("fs").readFile(path, function(err, data) {
347
+ if (err)
348
+ callback(null);
349
+ else
350
+ callback(""+data);
351
+ });
352
+ } else
353
+ try {
354
+ return require("fs").readFileSync(path);
355
+ } catch (e) {
356
+ return null;
357
+ }
358
+ } else {
359
+ var xhr = Util.XHR();
360
+ xhr.open('GET', path, callback ? true : false);
361
+ // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
362
+ xhr.setRequestHeader('Accept', 'text/plain');
363
+ if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
364
+ if (callback) {
365
+ xhr.onreadystatechange = function() {
366
+ if (xhr.readyState != 4) return;
367
+ if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 &amp;&amp; typeof xhr.responseText === 'string'))
368
+ callback(xhr.responseText);
369
+ else
370
+ callback(null);
371
+ };
372
+ if (xhr.readyState == 4)
373
+ return;
374
+ xhr.send(null);
375
+ } else {
376
+ xhr.send(null);
377
+ if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 &amp;&amp; typeof xhr.responseText === 'string'))
378
+ return xhr.responseText;
379
+ return null;
380
+ }
381
+ }
382
+ };
383
+
384
+ /**
385
+ * Tests if an object is an array.
386
+ * @function
387
+ * @param {*} obj Object to test
388
+ * @returns {boolean} true if it is an array, else false
389
+ * @expose
390
+ */
391
+ Util.isArray = Array.isArray || function(obj) {
392
+ return Object.prototype.toString.call(obj) === "[object Array]";
393
+ };
394
+
395
+ return Util;
396
+ })();
396
397
 
397
398
  /**
398
399
  * Language expressions.
@@ -429,7 +430,7 @@
429
430
  ID: /^(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
430
431
  NEGID: /^\-?(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
431
432
  WHITESPACE: /\s/,
432
- STRING: /['"]([^'"\\]*(\\.[^"\\]*)*)['"]/g,
433
+ STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
433
434
  BOOL: /^(?:true|false)$/i
434
435
  };
435
436
 
@@ -450,7 +451,7 @@
450
451
  /**
451
452
  * Constructs a new Tokenizer.
452
453
  * @exports ProtoBuf.DotProto.Tokenizer
453
- * @class proto tokenizer
454
+ * @class prototype tokenizer
454
455
  * @param {string} proto Proto to tokenize
455
456
  * @constructor
456
457
  */
@@ -499,22 +500,28 @@
499
500
  this.stringEndsWith = Lang.STRINGCLOSE;
500
501
  };
501
502
 
503
+ /**
504
+ * @alias ProtoBuf.DotProto.Tokenizer.prototype
505
+ * @inner
506
+ */
507
+ var TokenizerPrototype = Tokenizer.prototype;
508
+
502
509
  /**
503
510
  * Reads a string beginning at the current index.
504
511
  * @return {string} The string
505
512
  * @throws {Error} If it's not a valid string
506
513
  * @private
507
514
  */
508
- Tokenizer.prototype._readString = function() {
515
+ TokenizerPrototype._readString = function() {
509
516
  Lang.STRING.lastIndex = this.index-1; // Include the open quote
510
517
  var match;
511
518
  if ((match = Lang.STRING.exec(this.source)) !== null) {
512
- var s = match[1];
519
+ var s = typeof match[1] !== 'undefined' ? match[1] : match[2];
513
520
  this.index = Lang.STRING.lastIndex;
514
521
  this.stack.push(this.stringEndsWith);
515
522
  return s;
516
523
  }
517
- throw Error("Illegal string value at line "+this.line+", index "+this.index);
524
+ throw Error("Unterminated string at line "+this.line+", index "+this.index);
518
525
  };
519
526
 
520
527
  /**
@@ -523,7 +530,7 @@
523
530
  * @throws {Error} If it's not a valid proto file
524
531
  * @expose
525
532
  */
526
- Tokenizer.prototype.next = function() {
533
+ TokenizerPrototype.next = function() {
527
534
  if (this.stack.length > 0)
528
535
  return this.stack.shift();
529
536
  if (this.index >= this.source.length)
@@ -566,7 +573,7 @@
566
573
  this.index++;
567
574
  repeat = true;
568
575
  } else
569
- throw Error("Invalid comment at line "+this.line+": /"+this.source.charAt(this.index)+" ('/' or '*' expected)");
576
+ throw Error("Unterminated comment at line "+this.line+": /"+this.source.charAt(this.index));
570
577
  }
571
578
  } while (repeat);
572
579
  if (this.index === this.source.length) return null;
@@ -597,7 +604,7 @@
597
604
  * @throws {Error} If it's not a valid proto file
598
605
  * @expose
599
606
  */
600
- Tokenizer.prototype.peek = function() {
607
+ TokenizerPrototype.peek = function() {
601
608
  if (this.stack.length === 0) {
602
609
  var token = this.next();
603
610
  if (token === null)
@@ -612,7 +619,7 @@
612
619
  * @return {string} String representation as of "Tokenizer(index/length)"
613
620
  * @expose
614
621
  */
615
- Tokenizer.prototype.toString = function() {
622
+ TokenizerPrototype.toString = function() {
616
623
  return "Tokenizer("+this.index+"/"+this.source.length+" at line "+this.line+")";
617
624
  };
618
625
 
@@ -625,7 +632,7 @@
625
632
  /**
626
633
  * Constructs a new Parser.
627
634
  * @exports ProtoBuf.DotProto.Parser
628
- * @class proto parser
635
+ * @class prototype parser
629
636
  * @param {string} proto Protocol source
630
637
  * @constructor
631
638
  */
@@ -639,13 +646,19 @@
639
646
  this.tn = new Tokenizer(proto);
640
647
  };
641
648
 
649
+ /**
650
+ * @alias ProtoBuf.DotProto.Parser.prototype
651
+ * @inner
652
+ */
653
+ var ParserPrototype = Parser.prototype;
654
+
642
655
  /**
643
656
  * Runs the parser.
644
657
  * @return {{package: string|null, messages: Array.&lt;object>, enums: Array.&lt;object>, imports: Array.&lt;string>, options: object&lt;string,*>}}
645
658
  * @throws {Error} If the source cannot be parsed
646
659
  * @expose
647
660
  */
648
- Parser.prototype.parse = function() {
661
+ ParserPrototype.parse = function() {
649
662
  var topLevel = {
650
663
  "name": "[ROOT]", // temporary
651
664
  "package": null,
@@ -660,12 +673,12 @@
660
673
  switch (token) {
661
674
  case 'package':
662
675
  if (!head || topLevel["package"] !== null)
663
- throw Error("Illegal package at line "+this.tn.line);
676
+ throw Error("Unexpected package at line "+this.tn.line);
664
677
  topLevel["package"] = this._parsePackage(token);
665
678
  break;
666
679
  case 'import':
667
680
  if (!head)
668
- throw Error("Illegal import at line "+this.tn.line);
681
+ throw Error("Unexpected import at line "+this.tn.line);
669
682
  topLevel.imports.push(this._parseImport(token));
670
683
  break;
671
684
  case 'message':
@@ -678,7 +691,7 @@
678
691
  break;
679
692
  case 'option':
680
693
  if (!head)
681
- throw Error("Illegal option at line "+this.tn.line);
694
+ throw Error("Unexpected option at line "+this.tn.line);
682
695
  this._parseOption(topLevel, token);
683
696
  break;
684
697
  case 'service':
@@ -691,7 +704,7 @@
691
704
  this._parseIgnoredStatement(topLevel, token);
692
705
  break;
693
706
  default:
694
- throw Error("Illegal token at line "+this.tn.line+": "+token);
707
+ throw Error("Unexpected token at line "+this.tn.line+": "+token);
695
708
  }
696
709
  }
697
710
  delete topLevel["name"];
@@ -705,7 +718,7 @@
705
718
  * @throws {Error} If the number value is invalid
706
719
  * @private
707
720
  */
708
- Parser.prototype._parseNumber = function(val) {
721
+ ParserPrototype._parseNumber = function(val) {
709
722
  var sign = 1;
710
723
  if (val.charAt(0) == '-')
711
724
  sign = -1,
@@ -723,18 +736,17 @@
723
736
 
724
737
  /**
725
738
  * Parses a (possibly multiline) string.
726
- * @param {string} context Context description
727
739
  * @returns {string}
728
740
  * @private
729
741
  */
730
- Parser.prototype._parseString = function(context) {
742
+ ParserPrototype._parseString = function() {
731
743
  var value = "", token;
732
744
  do {
733
745
  token = this.tn.next(); // Known to be = this.tn.stringEndsWith
734
746
  value += this.tn.next();
735
747
  token = this.tn.next();
736
748
  if (token !== this.tn.stringEndsWith)
737
- throw Error("Illegal end of string in "+context+" at line "+this.tn.line+": "+token+" ('"+this.tn.stringEndsWith+"' expected)");
749
+ throw Error("Illegal end of string at line "+this.tn.line+": "+token);
738
750
  token = this.tn.peek();
739
751
  } while (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ);
740
752
  return value;
@@ -748,7 +760,7 @@
748
760
  * @throws {Error} If the ID value is invalid
749
761
  * @private
750
762
  */
751
- Parser.prototype._parseId = function(val, neg) {
763
+ ParserPrototype._parseId = function(val, neg) {
752
764
  var id = -1;
753
765
  var sign = 1;
754
766
  if (val.charAt(0) == '-')
@@ -761,10 +773,10 @@
761
773
  else if (Lang.NUMBER_OCT.test(val))
762
774
  id = parseInt(val.substring(1), 8);
763
775
  else
764
- throw Error("Illegal ID at line "+this.tn.line+": "+(sign &lt; 0 ? '-' : '')+val);
776
+ throw Error("Illegal id at line "+this.tn.line+": "+(sign &lt; 0 ? '-' : '')+val);
765
777
  id = (sign*id)|0; // Force to 32bit
766
778
  if (!neg &amp;&amp; id &lt; 0)
767
- throw Error("Illegal ID at line "+this.tn.line+": "+(sign &lt; 0 ? '-' : '')+val);
779
+ throw Error("Illegal id at line "+this.tn.line+": "+(sign &lt; 0 ? '-' : '')+val);
768
780
  return id;
769
781
  };
770
782
 
@@ -775,14 +787,14 @@
775
787
  * @throws {Error} If the package definition cannot be parsed
776
788
  * @private
777
789
  */
778
- Parser.prototype._parsePackage = function(token) {
790
+ ParserPrototype._parsePackage = function(token) {
779
791
  token = this.tn.next();
780
792
  if (!Lang.TYPEREF.test(token))
781
- throw Error("Illegal package at line "+this.tn.line+": "+token);
793
+ throw Error("Illegal package name at line "+this.tn.line+": "+token);
782
794
  var pkg = token;
783
795
  token = this.tn.next();
784
796
  if (token != Lang.END)
785
- throw Error("Illegal end of package at line "+this.tn.line+": "+token+" ('"+Lang.END+"' expected)");
797
+ throw Error("Illegal end of package at line "+this.tn.line+": "+token);
786
798
  return pkg;
787
799
  };
788
800
 
@@ -793,17 +805,17 @@
793
805
  * @throws {Error} If the import definition cannot be parsed
794
806
  * @private
795
807
  */
796
- Parser.prototype._parseImport = function(token) {
808
+ ParserPrototype._parseImport = function(token) {
797
809
  token = this.tn.peek();
798
810
  if (token === "public")
799
811
  this.tn.next(),
800
812
  token = this.tn.peek();
801
813
  if (token !== Lang.STRINGOPEN &amp;&amp; token !== Lang.STRINGOPEN_SQ)
802
- throw Error("Illegal import at line "+this.tn.line+": "+token+" ('"+Lang.STRINGOPEN+"' or '"+Lang.STRINGOPEN_SQ+"' expected)");
803
- var imported = this._parseString("root");
814
+ throw Error("Illegal start of import at line "+this.tn.line+": "+token);
815
+ var imported = this._parseString();
804
816
  token = this.tn.next();
805
817
  if (token !== Lang.END)
806
- throw Error("Illegal import at line "+this.tn.line+": "+token+" ('"+Lang.END+"' expected)");
818
+ throw Error("Illegal end of import at line "+this.tn.line+": "+token);
807
819
  return imported;
808
820
  };
809
821
 
@@ -814,7 +826,7 @@
814
826
  * @throws {Error} If the option cannot be parsed
815
827
  * @private
816
828
  */
817
- Parser.prototype._parseOption = function(parent, token) {
829
+ ParserPrototype._parseOption = function(parent, token) {
818
830
  token = this.tn.next();
819
831
  var custom = false;
820
832
  if (token == Lang.COPTOPEN)
@@ -823,12 +835,12 @@
823
835
  if (!Lang.TYPEREF.test(token))
824
836
  // we can allow options of the form google.protobuf.* since they will just get ignored anyways
825
837
  if (!/google\.protobuf\./.test(token))
826
- throw Error("Illegal option in message "+parent.name+" at line "+this.tn.line+": "+token);
838
+ throw Error("Illegal option name in message "+parent.name+" at line "+this.tn.line+": "+token);
827
839
  var name = token;
828
840
  token = this.tn.next();
829
841
  if (custom) { // (my_method_option).foo, (my_method_option), some_method_option, (foo.my_option).bar
830
842
  if (token !== Lang.COPTCLOSE)
831
- throw Error("Illegal option in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token+" ('"+Lang.COPTCLOSE+"' expected)");
843
+ throw Error("Illegal end in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
832
844
  name = '('+name+')';
833
845
  token = this.tn.next();
834
846
  if (Lang.FQTYPEREF.test(token))
@@ -836,11 +848,11 @@
836
848
  token = this.tn.next();
837
849
  }
838
850
  if (token !== Lang.EQUAL)
839
- throw Error("Illegal option operator in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token+" ('"+Lang.EQUAL+"' expected)");
851
+ throw Error("Illegal operator in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
840
852
  var value;
841
853
  token = this.tn.peek();
842
854
  if (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ)
843
- value = this._parseString("message "+parent.name+", option "+name);
855
+ value = this._parseString();
844
856
  else {
845
857
  this.tn.next();
846
858
  if (Lang.NUMBER.test(token))
@@ -854,7 +866,7 @@
854
866
  }
855
867
  token = this.tn.next();
856
868
  if (token !== Lang.END)
857
- throw Error("Illegal end of option in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token+" ('"+Lang.END+"' expected)");
869
+ throw Error("Illegal end of option in message "+parent.name+", option "+name+" at line "+this.tn.line+": "+token);
858
870
  parent["options"][name] = value;
859
871
  };
860
872
 
@@ -865,12 +877,12 @@
865
877
  * @throws {Error} If the directive cannot be parsed
866
878
  * @private
867
879
  */
868
- Parser.prototype._parseIgnoredStatement = function(parent, keyword) {
880
+ ParserPrototype._parseIgnoredStatement = function(parent, keyword) {
869
881
  var token;
870
882
  do {
871
883
  token = this.tn.next();
872
884
  if (token === null)
873
- throw Error("Unexpected EOF in "+parent.name+", "+keyword+" (ignored) at line "+this.tn.line);
885
+ throw Error("Unexpected EOF in "+parent.name+", "+keyword+" at line "+this.tn.line);
874
886
  if (token === Lang.END)
875
887
  break;
876
888
  } while (true);
@@ -883,7 +895,7 @@
883
895
  * @throws {Error} If the service cannot be parsed
884
896
  * @private
885
897
  */
886
- Parser.prototype._parseService = function(parent, token) {
898
+ ParserPrototype._parseService = function(parent, token) {
887
899
  token = this.tn.next();
888
900
  if (!Lang.NAME.test(token))
889
901
  throw Error("Illegal service name at line "+this.tn.line+": "+token);
@@ -895,7 +907,7 @@
895
907
  };
896
908
  token = this.tn.next();
897
909
  if (token !== Lang.OPEN)
898
- throw Error("Illegal OPEN after service "+name+" at line "+this.tn.line+": "+token+" ('"+Lang.OPEN+"' expected)");
910
+ throw Error("Illegal start of service "+name+" at line "+this.tn.line+": "+token);
899
911
  do {
900
912
  token = this.tn.next();
901
913
  if (token === "option")
@@ -903,7 +915,7 @@
903
915
  else if (token === 'rpc')
904
916
  this._parseServiceRPC(svc, token);
905
917
  else if (token !== Lang.CLOSE)
906
- throw Error("Illegal type for service "+name+" at line "+this.tn.line+": "+token);
918
+ throw Error("Illegal type of service "+name+" at line "+this.tn.line+": "+token);
907
919
  } while (token !== Lang.CLOSE);
908
920
  parent["services"].push(svc);
909
921
  };
@@ -914,11 +926,11 @@
914
926
  * @param {string} token Initial token
915
927
  * @private
916
928
  */
917
- Parser.prototype._parseServiceRPC = function(svc, token) {
929
+ ParserPrototype._parseServiceRPC = function(svc, token) {
918
930
  var type = token;
919
931
  token = this.tn.next();
920
932
  if (!Lang.NAME.test(token))
921
- throw Error("Illegal RPC method name in service "+svc["name"]+" at line "+this.tn.line+": "+token);
933
+ throw Error("Illegal method name in service "+svc["name"]+" at line "+this.tn.line+": "+token);
922
934
  var name = token;
923
935
  var method = {
924
936
  "request": null,
@@ -927,25 +939,25 @@
927
939
  };
928
940
  token = this.tn.next();
929
941
  if (token !== Lang.COPTOPEN)
930
- throw Error("Illegal start of request type in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token+" ('"+Lang.COPTOPEN+"' expected)");
942
+ throw Error("Illegal start of request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
931
943
  token = this.tn.next();
932
944
  if (!Lang.TYPEREF.test(token))
933
- throw Error("Illegal request type in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
945
+ throw Error("Illegal request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
934
946
  method["request"] = token;
935
947
  token = this.tn.next();
936
948
  if (token != Lang.COPTCLOSE)
937
- throw Error("Illegal end of request type in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token+" ('"+Lang.COPTCLOSE+"' expected)");
949
+ throw Error("Illegal end of request type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
938
950
  token = this.tn.next();
939
951
  if (token.toLowerCase() !== "returns")
940
- throw Error("Illegal request/response delimiter in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token+" ('returns' expected)");
952
+ throw Error("Illegal delimiter in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
941
953
  token = this.tn.next();
942
954
  if (token != Lang.COPTOPEN)
943
- throw Error("Illegal start of response type in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token+" ('"+Lang.COPTOPEN+"' expected)");
955
+ throw Error("Illegal start of response type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
944
956
  token = this.tn.next();
945
957
  method["response"] = token;
946
958
  token = this.tn.next();
947
959
  if (token !== Lang.COPTCLOSE)
948
- throw Error("Illegal end of response type in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token+" ('"+Lang.COPTCLOSE+"' expected)");
960
+ throw Error("Illegal end of response type in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
949
961
  token = this.tn.next();
950
962
  if (token === Lang.OPEN) {
951
963
  do {
@@ -953,12 +965,12 @@
953
965
  if (token === 'option')
954
966
  this._parseOption(method, token); // &lt;- will fail for the custom-options example
955
967
  else if (token !== Lang.CLOSE)
956
- throw Error("Illegal start of option in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token+" ('option' expected)");
968
+ throw Error("Illegal start of option inservice "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
957
969
  } while (token !== Lang.CLOSE);
958
970
  if (this.tn.peek() === Lang.END)
959
971
  this.tn.next();
960
972
  } else if (token !== Lang.END)
961
- throw Error("Illegal method delimiter in RPC service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token+" ('"+Lang.END+"' or '"+Lang.OPEN+"' expected)");
973
+ throw Error("Illegal delimiter in service "+svc["name"]+"#"+name+" at line "+this.tn.line+": "+token);
962
974
  if (typeof svc[type] === 'undefined')
963
975
  svc[type] = {};
964
976
  svc[type][name] = method;
@@ -973,7 +985,7 @@
973
985
  * @throws {Error} If the message cannot be parsed
974
986
  * @private
975
987
  */
976
- Parser.prototype._parseMessage = function(parent, fld, token) {
988
+ ParserPrototype._parseMessage = function(parent, fld, token) {
977
989
  /** @dict */
978
990
  var msg = {}; // Note: At some point we might want to exclude the parser, so we need a dict.
979
991
  var isGroup = token === "group";
@@ -984,7 +996,7 @@
984
996
  if (isGroup) {
985
997
  token = this.tn.next();
986
998
  if (token !== Lang.EQUAL)
987
- throw Error("Illegal id assignment after group "+msg.name+" at line "+this.tn.line+": "+token+" ('"+Lang.EQUAL+"' expected)");
999
+ throw Error("Illegal id assignment after group "+msg.name+" at line "+this.tn.line+": "+token);
988
1000
  token = this.tn.next();
989
1001
  try {
990
1002
  fld["id"] = this._parseId(token);
@@ -997,12 +1009,13 @@
997
1009
  msg["enums"] = [];
998
1010
  msg["messages"] = [];
999
1011
  msg["options"] = {};
1012
+ msg["oneofs"] = {};
1000
1013
  token = this.tn.next();
1001
1014
  if (token === Lang.OPTOPEN &amp;&amp; fld)
1002
1015
  this._parseFieldOptions(msg, fld, token),
1003
1016
  token = this.tn.next();
1004
1017
  if (token !== Lang.OPEN)
1005
- throw Error("Illegal OPEN after "+(isGroup ? "group" : "message")+" "+msg.name+" at line "+this.tn.line+": "+token+" ('"+Lang.OPEN+"' expected)");
1018
+ throw Error("Illegal start of "+(isGroup ? "group" : "message")+" "+msg.name+" at line "+this.tn.line+": "+token);
1006
1019
  // msg["extensions"] = undefined
1007
1020
  do {
1008
1021
  token = this.tn.next();
@@ -1013,6 +1026,8 @@
1013
1026
  break;
1014
1027
  } else if (Lang.RULE.test(token))
1015
1028
  this._parseMessageField(msg, token);
1029
+ else if (token === "oneof")
1030
+ this._parseMessageOneOf(msg, token);
1016
1031
  else if (token === "enum")
1017
1032
  this._parseEnum(msg, token);
1018
1033
  else if (token === "message")
@@ -1024,7 +1039,7 @@
1024
1039
  else if (token === "extend")
1025
1040
  this._parseExtend(msg, token);
1026
1041
  else
1027
- throw Error("Illegal token in message "+msg.name+" at line "+this.tn.line+": "+token+" (type or '"+Lang.CLOSE+"' expected)");
1042
+ throw Error("Illegal token in message "+msg.name+" at line "+this.tn.line+": "+token);
1028
1043
  } while (true);
1029
1044
  parent["messages"].push(msg);
1030
1045
  return msg;
@@ -1034,10 +1049,11 @@
1034
1049
  * Parses a message field.
1035
1050
  * @param {Object} msg Message definition
1036
1051
  * @param {string} token Initial token
1052
+ * @returns {!Object} Field descriptor
1037
1053
  * @throws {Error} If the message field cannot be parsed
1038
1054
  * @private
1039
1055
  */
1040
- Parser.prototype._parseMessageField = function(msg, token) {
1056
+ ParserPrototype._parseMessageField = function(msg, token) {
1041
1057
  /** @dict */
1042
1058
  var fld = {}, grp = null;
1043
1059
  fld["rule"] = token;
@@ -1066,21 +1082,48 @@
1066
1082
  fld["name"] = token;
1067
1083
  token = this.tn.next();
1068
1084
  if (token !== Lang.EQUAL)
1069
- throw Error("Illegal field id assignment in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token+" ('"+Lang.EQUAL+"' expected)");
1085
+ throw Error("Illegal token in field "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1070
1086
  token = this.tn.next();
1071
1087
  try {
1072
1088
  fld["id"] = this._parseId(token);
1073
1089
  } catch (e) {
1074
- throw Error("Illegal field id value in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1090
+ throw Error("Illegal field id in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1075
1091
  }
1076
1092
  token = this.tn.next();
1077
1093
  if (token === Lang.OPTOPEN)
1078
1094
  this._parseFieldOptions(msg, fld, token),
1079
1095
  token = this.tn.next();
1080
1096
  if (token !== Lang.END)
1081
- throw Error("Illegal field delimiter in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token+" ('"+Lang.END+"' expected)");
1097
+ throw Error("Illegal delimiter in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1082
1098
  }
1083
1099
  msg["fields"].push(fld);
1100
+ return fld;
1101
+ };
1102
+
1103
+ /**
1104
+ * Parses a message oneof.
1105
+ * @param {Object} msg Message definition
1106
+ * @param {string} token Initial token
1107
+ * @throws {Error} If the message oneof cannot be parsed
1108
+ * @private
1109
+ */
1110
+ ParserPrototype._parseMessageOneOf = function(msg, token) {
1111
+ token = this.tn.next();
1112
+ if (!Lang.NAME.test(token))
1113
+ throw Error("Illegal oneof name in message "+msg.name+" at line "+this.tn.line+": "+token);
1114
+ var name = token,
1115
+ fld;
1116
+ var fields = [];
1117
+ token = this.tn.next();
1118
+ if (token !== Lang.OPEN)
1119
+ throw Error("Illegal start of oneof "+name+" at line "+this.tn.line+": "+token);
1120
+ while (this.tn.peek() !== Lang.CLOSE) {
1121
+ fld = this._parseMessageField(msg, "optional");
1122
+ fld["oneof"] = name;
1123
+ fields.push(fld["id"]);
1124
+ }
1125
+ this.tn.next();
1126
+ msg["oneofs"][name] = fields;
1084
1127
  };
1085
1128
 
1086
1129
  /**
@@ -1091,7 +1134,7 @@
1091
1134
  * @throws {Error} If the message field options cannot be parsed
1092
1135
  * @private
1093
1136
  */
1094
- Parser.prototype._parseFieldOptions = function(msg, fld, token) {
1137
+ ParserPrototype._parseFieldOptions = function(msg, fld, token) {
1095
1138
  var first = true;
1096
1139
  do {
1097
1140
  token = this.tn.next();
@@ -1099,7 +1142,7 @@
1099
1142
  break;
1100
1143
  else if (token === Lang.OPTEND) {
1101
1144
  if (first)
1102
- throw Error("Illegal start of message field options in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1145
+ throw Error("Illegal start of options in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1103
1146
  token = this.tn.next();
1104
1147
  }
1105
1148
  this._parseFieldOption(msg, fld, token);
@@ -1115,18 +1158,18 @@
1115
1158
  * @throws {Error} If the mesage field option cannot be parsed
1116
1159
  * @private
1117
1160
  */
1118
- Parser.prototype._parseFieldOption = function(msg, fld, token) {
1161
+ ParserPrototype._parseFieldOption = function(msg, fld, token) {
1119
1162
  var custom = false;
1120
1163
  if (token === Lang.COPTOPEN)
1121
1164
  token = this.tn.next(),
1122
1165
  custom = true;
1123
1166
  if (!Lang.TYPEREF.test(token))
1124
- throw Error("Illegal field option in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1167
+ throw Error("Illegal field option in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1125
1168
  var name = token;
1126
1169
  token = this.tn.next();
1127
1170
  if (custom) {
1128
1171
  if (token !== Lang.COPTCLOSE)
1129
- throw Error("Illegal custom field option name delimiter in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token+" (')' expected)");
1172
+ throw Error("Illegal delimiter in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1130
1173
  name = '('+name+')';
1131
1174
  token = this.tn.next();
1132
1175
  if (Lang.FQTYPEREF.test(token))
@@ -1134,11 +1177,11 @@
1134
1177
  token = this.tn.next();
1135
1178
  }
1136
1179
  if (token !== Lang.EQUAL)
1137
- throw Error("Illegal field option operation in message "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token+" ('=' expected)");
1180
+ throw Error("Illegal token in "+msg.name+"#"+fld.name+" at line "+this.tn.line+": "+token);
1138
1181
  var value;
1139
1182
  token = this.tn.peek();
1140
1183
  if (token === Lang.STRINGOPEN || token === Lang.STRINGOPEN_SQ) {
1141
- value = this._parseString("message "+msg.name+"#"+fld.name);
1184
+ value = this._parseString();
1142
1185
  } else if (Lang.NUMBER.test(token, true))
1143
1186
  value = this._parseNumber(this.tn.next(), true);
1144
1187
  else if (Lang.BOOL.test(token))
@@ -1146,7 +1189,7 @@
1146
1189
  else if (Lang.TYPEREF.test(token))
1147
1190
  value = this.tn.next(); // TODO: Resolve?
1148
1191
  else
1149
- throw Error("Illegal field option value in message "+msg.name+"#"+fld.name+", option "+name+" at line "+this.tn.line+": "+token);
1192
+ throw Error("Illegal value in message "+msg.name+"#"+fld.name+", option "+name+" at line "+this.tn.line+": "+token);
1150
1193
  fld["options"][name] = value;
1151
1194
  };
1152
1195
 
@@ -1157,7 +1200,7 @@
1157
1200
  * @throws {Error} If the enum cannot be parsed
1158
1201
  * @private
1159
1202
  */
1160
- Parser.prototype._parseEnum = function(msg, token) {
1203
+ ParserPrototype._parseEnum = function(msg, token) {
1161
1204
  /** @dict */
1162
1205
  var enm = {};
1163
1206
  token = this.tn.next();
@@ -1166,7 +1209,7 @@
1166
1209
  enm["name"] = token;
1167
1210
  token = this.tn.next();
1168
1211
  if (token !== Lang.OPEN)
1169
- throw Error("Illegal OPEN after enum "+enm.name+" at line "+this.tn.line+": "+token);
1212
+ throw Error("Illegal start of enum "+enm.name+" at line "+this.tn.line+": "+token);
1170
1213
  enm["values"] = [];
1171
1214
  enm["options"] = {};
1172
1215
  do {
@@ -1181,7 +1224,7 @@
1181
1224
  this._parseOption(enm, token);
1182
1225
  else {
1183
1226
  if (!Lang.NAME.test(token))
1184
- throw Error("Illegal enum value name in enum "+enm.name+" at line "+this.tn.line+": "+token);
1227
+ throw Error("Illegal name in enum "+enm.name+" at line "+this.tn.line+": "+token);
1185
1228
  this._parseEnumValue(enm, token);
1186
1229
  }
1187
1230
  } while (true);
@@ -1195,18 +1238,18 @@
1195
1238
  * @throws {Error} If the enum value cannot be parsed
1196
1239
  * @private
1197
1240
  */
1198
- Parser.prototype._parseEnumValue = function(enm, token) {
1241
+ ParserPrototype._parseEnumValue = function(enm, token) {
1199
1242
  /** @dict */
1200
1243
  var val = {};
1201
1244
  val["name"] = token;
1202
1245
  token = this.tn.next();
1203
1246
  if (token !== Lang.EQUAL)
1204
- throw Error("Illegal enum value operator in enum "+enm.name+" at line "+this.tn.line+": "+token+" ('"+Lang.EQUAL+"' expected)");
1247
+ throw Error("Illegal token in enum "+enm.name+" at line "+this.tn.line+": "+token);
1205
1248
  token = this.tn.next();
1206
1249
  try {
1207
1250
  val["id"] = this._parseId(token, true);
1208
1251
  } catch (e) {
1209
- throw Error("Illegal enum value id in enum "+enm.name+" at line "+this.tn.line+": "+token);
1252
+ throw Error("Illegal id in enum "+enm.name+" at line "+this.tn.line+": "+token);
1210
1253
  }
1211
1254
  enm["values"].push(val);
1212
1255
  token = this.tn.next();
@@ -1216,7 +1259,7 @@
1216
1259
  token = this.tn.next();
1217
1260
  }
1218
1261
  if (token !== Lang.END)
1219
- throw Error("Illegal enum value delimiter in enum "+enm.name+" at line "+this.tn.line+": "+token+" ('"+Lang.END+"' expected)");
1262
+ throw Error("Illegal delimiter in enum "+enm.name+" at line "+this.tn.line+": "+token);
1220
1263
  };
1221
1264
 
1222
1265
  /**
@@ -1226,7 +1269,7 @@
1226
1269
  * @throws {Error} If the extensions statement cannot be parsed
1227
1270
  * @private
1228
1271
  */
1229
- Parser.prototype._parseExtensions = function(msg, token) {
1272
+ ParserPrototype._parseExtensions = function(msg, token) {
1230
1273
  /** @type {Array.&lt;number>} */
1231
1274
  var range = [];
1232
1275
  token = this.tn.next();
@@ -1238,7 +1281,7 @@
1238
1281
  range.push(this._parseNumber(token));
1239
1282
  token = this.tn.next();
1240
1283
  if (token !== 'to')
1241
- throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+" ('to' expected)");
1284
+ throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+": "+token);
1242
1285
  token = this.tn.next();
1243
1286
  if (token === "min")
1244
1287
  range.push(ProtoBuf.ID_MIN);
@@ -1248,7 +1291,7 @@
1248
1291
  range.push(this._parseNumber(token));
1249
1292
  token = this.tn.next();
1250
1293
  if (token !== Lang.END)
1251
- throw Error("Illegal extension delimiter in message "+msg.name+" at line "+this.tn.line+": "+token+" ('"+Lang.END+"' expected)");
1294
+ throw Error("Illegal extensions delimiter in message "+msg.name+" at line "+this.tn.line+": "+token);
1252
1295
  return range;
1253
1296
  };
1254
1297
 
@@ -1259,17 +1302,17 @@
1259
1302
  * @throws {Error} If the extend block cannot be parsed
1260
1303
  * @private
1261
1304
  */
1262
- Parser.prototype._parseExtend = function(parent, token) {
1305
+ ParserPrototype._parseExtend = function(parent, token) {
1263
1306
  token = this.tn.next();
1264
1307
  if (!Lang.TYPEREF.test(token))
1265
- throw Error("Illegal extended message name at line "+this.tn.line+": "+token);
1308
+ throw Error("Illegal message name at line "+this.tn.line+": "+token);
1266
1309
  /** @dict */
1267
1310
  var ext = {};
1268
1311
  ext["ref"] = token;
1269
1312
  ext["fields"] = [];
1270
1313
  token = this.tn.next();
1271
1314
  if (token !== Lang.OPEN)
1272
- throw Error("Illegal OPEN in extend "+ext.name+" at line "+this.tn.line+": "+token+" ('"+Lang.OPEN+"' expected)");
1315
+ throw Error("Illegal start of extend "+ext.name+" at line "+this.tn.line+": "+token);
1273
1316
  do {
1274
1317
  token = this.tn.next();
1275
1318
  if (token === Lang.CLOSE) {
@@ -1280,7 +1323,7 @@
1280
1323
  } else if (Lang.RULE.test(token))
1281
1324
  this._parseMessageField(ext, token);
1282
1325
  else
1283
- throw Error("Illegal token in extend "+ext.name+" at line "+this.tn.line+": "+token+" (rule or '"+Lang.CLOSE+"' expected)");
1326
+ throw Error("Illegal token in extend "+ext.name+" at line "+this.tn.line+": "+token);
1284
1327
  } while (true);
1285
1328
  parent["messages"].push(ext);
1286
1329
  return ext;
@@ -1290,7 +1333,7 @@
1290
1333
  * Returns a string representation of this object.
1291
1334
  * @returns {string} String representation as of "Parser"
1292
1335
  */
1293
- Parser.prototype.toString = function() {
1336
+ ParserPrototype.toString = function() {
1294
1337
  return "Parser";
1295
1338
  };
1296
1339
 
@@ -1323,14 +1366,22 @@
1323
1366
  * @exports ProtoBuf.Reflect.T
1324
1367
  * @constructor
1325
1368
  * @abstract
1326
- * @param {ProtoBuf.Reflect.T} parent Parent object
1369
+ * @param {!ProtoBuf.Builder} builder Builder reference
1370
+ * @param {?ProtoBuf.Reflect.T} parent Parent object
1327
1371
  * @param {string} name Object name
1328
1372
  */
1329
- var T = function(parent, name) {
1373
+ var T = function(builder, parent, name) {
1374
+
1375
+ /**
1376
+ * Builder reference.
1377
+ * @type {!ProtoBuf.Builder}
1378
+ * @expose
1379
+ */
1380
+ this.builder = builder;
1330
1381
 
1331
1382
  /**
1332
1383
  * Parent object.
1333
- * @type {ProtoBuf.Reflect.T|null}
1384
+ * @type {?ProtoBuf.Reflect.T}
1334
1385
  * @expose
1335
1386
  */
1336
1387
  this.parent = parent;
@@ -1350,12 +1401,18 @@
1350
1401
  this.className;
1351
1402
  };
1352
1403
 
1404
+ /**
1405
+ * @alias ProtoBuf.Reflect.T.prototype
1406
+ * @inner
1407
+ */
1408
+ var TPrototype = T.prototype;
1409
+
1353
1410
  /**
1354
1411
  * Returns the fully qualified name of this object.
1355
1412
  * @returns {string} Fully qualified name as of ".PATH.TO.THIS"
1356
1413
  * @expose
1357
1414
  */
1358
- T.prototype.fqn = function() {
1415
+ TPrototype.fqn = function() {
1359
1416
  var name = this.name,
1360
1417
  ptr = this;
1361
1418
  do {
@@ -1373,7 +1430,7 @@
1373
1430
  * @return String representation
1374
1431
  * @expose
1375
1432
  */
1376
- T.prototype.toString = function(includeClass) {
1433
+ TPrototype.toString = function(includeClass) {
1377
1434
  return (includeClass ? this.className + " " : "") + this.fqn();
1378
1435
  };
1379
1436
 
@@ -1382,7 +1439,7 @@
1382
1439
  * @throws {Error} If this type cannot be built directly
1383
1440
  * @expose
1384
1441
  */
1385
- T.prototype.build = function() {
1442
+ TPrototype.build = function() {
1386
1443
  throw Error(this.toString(true)+" cannot be built directly");
1387
1444
  };
1388
1445
 
@@ -1395,14 +1452,15 @@
1395
1452
  /**
1396
1453
  * Constructs a new Namespace.
1397
1454
  * @exports ProtoBuf.Reflect.Namespace
1398
- * @param {ProtoBuf.Reflect.Namespace|null} parent Namespace parent
1455
+ * @param {!ProtoBuf.Builder} builder Builder reference
1456
+ * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
1399
1457
  * @param {string} name Namespace name
1400
- * @param {Object.&lt;string,*>} options Namespace options
1458
+ * @param {Object.&lt;string,*>=} options Namespace options
1401
1459
  * @constructor
1402
1460
  * @extends ProtoBuf.Reflect.T
1403
1461
  */
1404
- var Namespace = function(parent, name, options) {
1405
- T.call(this, parent, name);
1462
+ var Namespace = function(builder, parent, name, options) {
1463
+ T.call(this, builder, parent, name);
1406
1464
 
1407
1465
  /**
1408
1466
  * @override
@@ -1411,19 +1469,22 @@
1411
1469
 
1412
1470
  /**
1413
1471
  * Children inside the namespace.
1414
- * @type {Array.&lt;ProtoBuf.Reflect.T>}
1472
+ * @type {!Array.&lt;ProtoBuf.Reflect.T>}
1415
1473
  */
1416
1474
  this.children = [];
1417
1475
 
1418
1476
  /**
1419
1477
  * Options.
1420
- * @type {Object.&lt;string, *>}
1478
+ * @type {!Object.&lt;string, *>}
1421
1479
  */
1422
1480
  this.options = options || {};
1423
1481
  };
1424
1482
 
1425
- // Extends T
1426
- Namespace.prototype = Object.create(T.prototype);
1483
+ /**
1484
+ * @alias ProtoBuf.Reflect.Namespace.prototype
1485
+ * @inner
1486
+ */
1487
+ var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
1427
1488
 
1428
1489
  /**
1429
1490
  * Returns an array of the namespace's children.
@@ -1431,7 +1492,7 @@
1431
1492
  * @return {Array.&lt;ProtoBuf.Reflect.T>}
1432
1493
  * @expose
1433
1494
  */
1434
- Namespace.prototype.getChildren = function(type) {
1495
+ NamespacePrototype.getChildren = function(type) {
1435
1496
  type = type || null;
1436
1497
  if (type == null)
1437
1498
  return this.children.slice();
@@ -1448,7 +1509,7 @@
1448
1509
  * @throws {Error} If the child cannot be added (duplicate)
1449
1510
  * @expose
1450
1511
  */
1451
- Namespace.prototype.addChild = function(child) {
1512
+ NamespacePrototype.addChild = function(child) {
1452
1513
  var other;
1453
1514
  if (other = this.getChild(child.name)) {
1454
1515
  // Try to revert camelcase transformation on collision
@@ -1468,7 +1529,7 @@
1468
1529
  * @return {?ProtoBuf.Reflect.T} The child or null if not found
1469
1530
  * @expose
1470
1531
  */
1471
- Namespace.prototype.getChild = function(nameOrId) {
1532
+ NamespacePrototype.getChild = function(nameOrId) {
1472
1533
  var key = typeof nameOrId === 'number' ? 'id' : 'name';
1473
1534
  for (var i=0, k=this.children.length; i&lt;k; ++i)
1474
1535
  if (this.children[i][key] === nameOrId)
@@ -1483,7 +1544,7 @@
1483
1544
  * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
1484
1545
  * @expose
1485
1546
  */
1486
- Namespace.prototype.resolve = function(qn, excludeFields) {
1547
+ NamespacePrototype.resolve = function(qn, excludeFields) {
1487
1548
  var part = qn.split("."),
1488
1549
  ptr = this,
1489
1550
  i = 0;
@@ -1517,7 +1578,7 @@
1517
1578
  * @return {Object.&lt;string,Function|Object>} Runtime namespace
1518
1579
  * @expose
1519
1580
  */
1520
- Namespace.prototype.build = function() {
1581
+ NamespacePrototype.build = function() {
1521
1582
  /** @dict */
1522
1583
  var ns = {};
1523
1584
  var children = this.children;
@@ -1535,7 +1596,7 @@
1535
1596
  * Builds the namespace's '$options' property.
1536
1597
  * @return {Object.&lt;string,*>}
1537
1598
  */
1538
- Namespace.prototype.buildOpt = function() {
1599
+ NamespacePrototype.buildOpt = function() {
1539
1600
  var opt = {},
1540
1601
  keys = Object.keys(this.options);
1541
1602
  for (var i=0, k=keys.length; i&lt;k; ++i) {
@@ -1556,7 +1617,7 @@
1556
1617
  * @param {string=} name Returns the option value if specified, otherwise all options are returned.
1557
1618
  * @return {*|Object.&lt;string,*>}null} Option value or NULL if there is no such option
1558
1619
  */
1559
- Namespace.prototype.getOption = function(name) {
1620
+ NamespacePrototype.getOption = function(name) {
1560
1621
  if (typeof name === 'undefined')
1561
1622
  return this.options;
1562
1623
  return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
@@ -1571,15 +1632,16 @@
1571
1632
  /**
1572
1633
  * Constructs a new Message.
1573
1634
  * @exports ProtoBuf.Reflect.Message
1574
- * @param {ProtoBuf.Reflect.Namespace} parent Parent message or namespace
1635
+ * @param {!ProtoBuf.Builder} builder Builder reference
1636
+ * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
1575
1637
  * @param {string} name Message name
1576
- * @param {Object.&lt;string,*>} options Message options
1638
+ * @param {Object.&lt;string,*>=} options Message options
1577
1639
  * @param {boolean=} isGroup `true` if this is a legacy group
1578
1640
  * @constructor
1579
1641
  * @extends ProtoBuf.Reflect.Namespace
1580
1642
  */
1581
- var Message = function(parent, name, options, isGroup) {
1582
- Namespace.call(this, parent, name, options);
1643
+ var Message = function(builder, parent, name, options, isGroup) {
1644
+ Namespace.call(this, builder, parent, name, options);
1583
1645
 
1584
1646
  /**
1585
1647
  * @override
@@ -1622,10 +1684,20 @@
1622
1684
  * @private
1623
1685
  */
1624
1686
  this._fieldsById = null;
1687
+
1688
+ /**
1689
+ * Cached fields by name.
1690
+ * @type {?Object.&lt;string,!ProtoBuf.Reflect.Message.Field>}
1691
+ * @private
1692
+ */
1693
+ this._fieldsByName = null;
1625
1694
  };
1626
1695
 
1627
- // Extends Namespace
1628
- Message.prototype = Object.create(Namespace.prototype);
1696
+ /**
1697
+ * @alias ProtoBuf.Reflect.Message.prototype
1698
+ * @inner
1699
+ */
1700
+ var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
1629
1701
 
1630
1702
  /**
1631
1703
  * Builds the message and returns the runtime counterpart, which is a fully functional class.
@@ -1635,14 +1707,15 @@
1635
1707
  * @throws {Error} If the message cannot be built
1636
1708
  * @expose
1637
1709
  */
1638
- Message.prototype.build = function(rebuild) {
1710
+ MessagePrototype.build = function(rebuild) {
1639
1711
  if (this.clazz &amp;&amp; !rebuild)
1640
1712
  return this.clazz;
1641
1713
 
1642
1714
  // Create the runtime Message class in its own scope
1643
1715
  var clazz = (function(ProtoBuf, T) {
1644
1716
 
1645
- var fields = T.getChildren(ProtoBuf.Reflect.Message.Field);
1717
+ var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
1718
+ oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
1646
1719
 
1647
1720
  /**
1648
1721
  * Constructs a new runtime Message.
@@ -1656,9 +1729,13 @@
1656
1729
  var Message = function(values, var_args) {
1657
1730
  ProtoBuf.Builder.Message.call(this);
1658
1731
 
1659
- // Create fields on the object itself and set default values
1660
- for (var i=0, k=fields.length, field; i&lt;k; ++i) {
1661
- this[(field = fields[i]).name] = field.repeated ? [] : null;
1732
+ // Create virtual oneof properties
1733
+ for (var i=0, k=oneofs.length; i&lt;k; ++i)
1734
+ this[oneofs[i].name] = null;
1735
+ // Create fields and set default values
1736
+ for (i=0, k=fields.length; i&lt;k; ++i) {
1737
+ var field = fields[i];
1738
+ this[field.name] = field.repeated ? [] : null;
1662
1739
  if (field.required &amp;&amp; field.defaultValue !== null)
1663
1740
  this[field.name] = field.defaultValue;
1664
1741
  }
@@ -1674,21 +1751,17 @@
1674
1751
  var keys = Object.keys(values);
1675
1752
  for (i=0, k=keys.length; i&lt;k; ++i)
1676
1753
  this.$set(keys[i], values[keys[i]]); // May throw
1677
- } else // set field values from arguments, in declaration order
1754
+ } else // Set field values from arguments, in declaration order
1678
1755
  for (i=0, k=arguments.length; i&lt;k; ++i)
1679
1756
  this.$set(fields[i].name, arguments[i]); // May throw
1680
1757
  }
1681
1758
  };
1682
1759
 
1683
1760
  /**
1684
- * The message's reflection type.
1685
- * @name ProtoBuf.Builder.Message#$type
1686
- * @type {!ProtoBuf.Reflect.Message}
1687
- * @expose
1761
+ * @alias ProtoBuf.Builder.Message.prototype
1762
+ * @inner
1688
1763
  */
1689
-
1690
- // Extends ProtoBuf.Builder.Message
1691
- Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
1764
+ var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
1692
1765
 
1693
1766
  /**
1694
1767
  * Adds a value to a repeated field.
@@ -1700,14 +1773,16 @@
1700
1773
  * @throws {Error} If the value cannot be added
1701
1774
  * @expose
1702
1775
  */
1703
- Message.prototype.add = function(key, value, noAssert) {
1704
- var field = T.getChild(key);
1705
- if (!field)
1706
- throw Error(this+"#"+key+" is undefined");
1707
- if (!(field instanceof ProtoBuf.Reflect.Message.Field))
1708
- throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
1709
- if (!field.repeated)
1710
- throw Error(this+"#"+key+" is not a repeated field");
1776
+ MessagePrototype.add = function(key, value, noAssert) {
1777
+ var field = T._fieldsByName[key];
1778
+ if (!noAssert) {
1779
+ if (!field)
1780
+ throw Error(this+"#"+key+" is undefined");
1781
+ if (!(field instanceof ProtoBuf.Reflect.Message.Field))
1782
+ throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
1783
+ if (!field.repeated)
1784
+ throw Error(this+"#"+key+" is not a repeated field");
1785
+ }
1711
1786
  if (this[field.name] === null)
1712
1787
  this[field.name] = [];
1713
1788
  this[field.name].push(noAssert ? value : field.verifyValue(value, true));
@@ -1723,7 +1798,7 @@
1723
1798
  * @throws {Error} If the value cannot be added
1724
1799
  * @expose
1725
1800
  */
1726
- Message.prototype.$add = Message.prototype.add;
1801
+ MessagePrototype.$add = MessagePrototype.add;
1727
1802
 
1728
1803
  /**
1729
1804
  * Sets a field's value.
@@ -1736,23 +1811,31 @@
1736
1811
  * @throws {Error} If the value cannot be set
1737
1812
  * @expose
1738
1813
  */
1739
- Message.prototype.set = function(key, value, noAssert) {
1814
+ MessagePrototype.set = function(key, value, noAssert) {
1740
1815
  if (key &amp;&amp; typeof key === 'object') {
1741
1816
  for (var i in key)
1742
1817
  if (key.hasOwnProperty(i))
1743
1818
  this.$set(i, key[i], noAssert);
1744
1819
  return this;
1745
1820
  }
1746
- if (noAssert) {
1747
- this[key] = value;
1748
- return this;
1821
+ var field = T._fieldsByName[key];
1822
+ if (!noAssert) {
1823
+ if (!field)
1824
+ throw Error(this+"#"+key+" is not a field: undefined");
1825
+ if (!(field instanceof ProtoBuf.Reflect.Message.Field))
1826
+ throw Error(this+"#"+key+" is not a field: "+field.toString(true));
1827
+ this[field.name] = (value = field.verifyValue(value)); // May throw
1828
+ } else {
1829
+ this[field.name] = value;
1830
+ }
1831
+ if (field.oneof) {
1832
+ if (value !== null) {
1833
+ if (this[field.oneof.name] !== null)
1834
+ this[this[field.oneof.name]] = null; // Unset the previous (field name is the oneof field's value)
1835
+ this[field.oneof.name] = field.name;
1836
+ } else if (field.oneof.name === key)
1837
+ this[field.oneof.name] = null;
1749
1838
  }
1750
- var field = T.getChild(key);
1751
- if (!field)
1752
- throw Error(this+"#"+key+" is not a field: undefined");
1753
- if (!(field instanceof ProtoBuf.Reflect.Message.Field))
1754
- throw Error(this+"#"+key+" is not a field: "+field.toString(true));
1755
- this[field.name] = field.verifyValue(value); // May throw
1756
1839
  return this;
1757
1840
  };
1758
1841
 
@@ -1762,26 +1845,26 @@
1762
1845
  * @function
1763
1846
  * @param {string} key Key
1764
1847
  * @param {*} value Value to set
1765
- * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
1848
+ * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
1766
1849
  * @throws {Error} If the value cannot be set
1767
1850
  * @expose
1768
1851
  */
1769
- Message.prototype.$set = Message.prototype.set;
1852
+ MessagePrototype.$set = MessagePrototype.set;
1770
1853
 
1771
1854
  /**
1772
1855
  * Gets a field's value.
1773
1856
  * @name ProtoBuf.Builder.Message#get
1774
1857
  * @function
1775
1858
  * @param {string} key Key
1776
- * @param {boolean=} noAssert Whether to no assert for an actual field, defaults to `false`
1859
+ * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
1777
1860
  * @return {*} Value
1778
1861
  * @throws {Error} If there is no such field
1779
1862
  * @expose
1780
1863
  */
1781
- Message.prototype.get = function(key, noAssert) {
1864
+ MessagePrototype.get = function(key, noAssert) {
1782
1865
  if (noAssert)
1783
1866
  return this[key];
1784
- var field = T.getChild(key);
1867
+ var field = T._fieldsByName[key];
1785
1868
  if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
1786
1869
  throw Error(this+"#"+key+" is not a field: undefined");
1787
1870
  if (!(field instanceof ProtoBuf.Reflect.Message.Field))
@@ -1798,7 +1881,7 @@
1798
1881
  * @throws {Error} If there is no such field
1799
1882
  * @expose
1800
1883
  */
1801
- Message.prototype.$get = Message.prototype.get;
1884
+ MessagePrototype.$get = MessagePrototype.get;
1802
1885
 
1803
1886
  // Getters and setters
1804
1887
 
@@ -1808,72 +1891,91 @@
1808
1891
  if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
1809
1892
  continue;
1810
1893
 
1811
- if (ProtoBuf.populateAccessors)
1894
+ if (T.builder.options['populateAccessors'])
1812
1895
  (function(field) {
1813
1896
  // set/get[SomeValue]
1814
1897
  var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
1815
1898
  return match.toUpperCase().replace('_','');
1816
1899
  });
1817
- Name = Name.substring(0,1).toUpperCase()+Name.substring(1);
1900
+ Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
1818
1901
 
1819
- // set/get_[some_value]
1902
+ // set/get_[some_value] FIXME: Do we really need these?
1820
1903
  var name = field.originalName.replace(/([A-Z])/g, function(match) {
1821
1904
  return "_"+match;
1822
1905
  });
1823
1906
 
1907
+ /**
1908
+ * The current field's unbound setter function.
1909
+ * @function
1910
+ * @param {*} value
1911
+ * @param {boolean=} noAssert
1912
+ * @returns {!ProtoBuf.Builder.Message}
1913
+ * @inner
1914
+ */
1915
+ var setter = function(value, noAssert) {
1916
+ this[field.name] = noAssert ? value : field.verifyValue(value);
1917
+ return this;
1918
+ };
1919
+
1920
+ /**
1921
+ * The current field's unbound getter function.
1922
+ * @function
1923
+ * @returns {*}
1924
+ * @inner
1925
+ */
1926
+ var getter = function() {
1927
+ return this[field.name];
1928
+ };
1929
+
1824
1930
  /**
1825
1931
  * Sets a value. This method is present for each field, but only if there is no name conflict with
1826
- * another field.
1932
+ * another field.
1827
1933
  * @name ProtoBuf.Builder.Message#set[SomeField]
1828
1934
  * @function
1829
1935
  * @param {*} value Value to set
1936
+ * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
1937
+ * @returns {!ProtoBuf.Builder.Message} this
1830
1938
  * @abstract
1831
1939
  * @throws {Error} If the value cannot be set
1832
1940
  */
1833
1941
  if (T.getChild("set"+Name) === null)
1834
- Message.prototype["set"+Name] = function(value) {
1835
- this.$set(field.name, value);
1836
- };
1942
+ MessagePrototype["set"+Name] = setter;
1837
1943
 
1838
1944
  /**
1839
1945
  * Sets a value. This method is present for each field, but only if there is no name conflict with
1840
- * another field.
1946
+ * another field.
1841
1947
  * @name ProtoBuf.Builder.Message#set_[some_field]
1842
1948
  * @function
1843
1949
  * @param {*} value Value to set
1950
+ * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
1951
+ * @returns {!ProtoBuf.Builder.Message} this
1844
1952
  * @abstract
1845
1953
  * @throws {Error} If the value cannot be set
1846
1954
  */
1847
1955
  if (T.getChild("set_"+name) === null)
1848
- Message.prototype["set_"+name] = function(value) {
1849
- this.$set(field.name, value);
1850
- };
1956
+ MessagePrototype["set_"+name] = setter;
1851
1957
 
1852
1958
  /**
1853
1959
  * Gets a value. This method is present for each field, but only if there is no name conflict with
1854
- * another field.
1960
+ * another field.
1855
1961
  * @name ProtoBuf.Builder.Message#get[SomeField]
1856
1962
  * @function
1857
1963
  * @abstract
1858
1964
  * @return {*} The value
1859
1965
  */
1860
1966
  if (T.getChild("get"+Name) === null)
1861
- Message.prototype["get"+Name] = function() {
1862
- return this.$get(field.name); // Does not throw, field exists
1863
- };
1967
+ MessagePrototype["get"+Name] = getter;
1864
1968
 
1865
1969
  /**
1866
1970
  * Gets a value. This method is present for each field, but only if there is no name conflict with
1867
- * another field.
1971
+ * another field.
1868
1972
  * @name ProtoBuf.Builder.Message#get_[some_field]
1869
1973
  * @function
1870
1974
  * @return {*} The value
1871
1975
  * @abstract
1872
1976
  */
1873
1977
  if (T.getChild("get_"+name) === null)
1874
- Message.prototype["get_"+name] = function() {
1875
- return this.$get(field.name); // Does not throw, field exists
1876
- };
1978
+ MessagePrototype["get_"+name] = getter;
1877
1979
 
1878
1980
  })(field);
1879
1981
  }
@@ -1894,7 +1996,7 @@
1894
1996
  * @see ProtoBuf.Builder.Message#encodeHex
1895
1997
  * @see ProtoBuf.Builder.Message#encodeAB
1896
1998
  */
1897
- Message.prototype.encode = function(buffer, noVerify) {
1999
+ MessagePrototype.encode = function(buffer, noVerify) {
1898
2000
  if (typeof buffer === 'boolean')
1899
2001
  noVerify = buffer,
1900
2002
  buffer = undefined;
@@ -1920,7 +2022,7 @@
1920
2022
  * @throws {Error} If the message cannot be calculated or if required fields are missing.
1921
2023
  * @expose
1922
2024
  */
1923
- Message.prototype.calculate = function() {
2025
+ MessagePrototype.calculate = function() {
1924
2026
  return T.calculate(this);
1925
2027
  };
1926
2028
 
@@ -1934,7 +2036,7 @@
1934
2036
  * returns the encoded ByteBuffer in the `encoded` property on the error.
1935
2037
  * @expose
1936
2038
  */
1937
- Message.prototype.encodeDelimited = function(buffer) {
2039
+ MessagePrototype.encodeDelimited = function(buffer) {
1938
2040
  var isNew = false;
1939
2041
  if (!buffer)
1940
2042
  buffer = new ByteBuffer(),
@@ -1955,7 +2057,7 @@
1955
2057
  * returns the encoded ArrayBuffer in the `encoded` property on the error.
1956
2058
  * @expose
1957
2059
  */
1958
- Message.prototype.encodeAB = function() {
2060
+ MessagePrototype.encodeAB = function() {
1959
2061
  try {
1960
2062
  return this.encode().toArrayBuffer();
1961
2063
  } catch (e) {
@@ -1973,7 +2075,7 @@
1973
2075
  * returns the encoded ArrayBuffer in the `encoded` property on the error.
1974
2076
  * @expose
1975
2077
  */
1976
- Message.prototype.toArrayBuffer = Message.prototype.encodeAB;
2078
+ MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
1977
2079
 
1978
2080
  /**
1979
2081
  * Directly encodes the message to a node Buffer.
@@ -1984,7 +2086,7 @@
1984
2086
  * missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
1985
2087
  * @expose
1986
2088
  */
1987
- Message.prototype.encodeNB = function() {
2089
+ MessagePrototype.encodeNB = function() {
1988
2090
  try {
1989
2091
  return this.encode().toBuffer();
1990
2092
  } catch (e) {
@@ -2002,7 +2104,7 @@
2002
2104
  * returns the encoded node Buffer in the `encoded` property on the error.
2003
2105
  * @expose
2004
2106
  */
2005
- Message.prototype.toBuffer = Message.prototype.encodeNB;
2107
+ MessagePrototype.toBuffer = MessagePrototype.encodeNB;
2006
2108
 
2007
2109
  /**
2008
2110
  * Directly encodes the message to a base64 encoded string.
@@ -2013,7 +2115,7 @@
2013
2115
  * still returns the encoded base64 string in the `encoded` property on the error.
2014
2116
  * @expose
2015
2117
  */
2016
- Message.prototype.encode64 = function() {
2118
+ MessagePrototype.encode64 = function() {
2017
2119
  try {
2018
2120
  return this.encode().toBase64();
2019
2121
  } catch (e) {
@@ -2031,7 +2133,7 @@
2031
2133
  * returns the encoded base64 string in the `encoded` property on the error.
2032
2134
  * @expose
2033
2135
  */
2034
- Message.prototype.toBase64 = Message.prototype.encode64;
2136
+ MessagePrototype.toBase64 = MessagePrototype.encode64;
2035
2137
 
2036
2138
  /**
2037
2139
  * Directly encodes the message to a hex encoded string.
@@ -2042,7 +2144,7 @@
2042
2144
  * still returns the encoded hex string in the `encoded` property on the error.
2043
2145
  * @expose
2044
2146
  */
2045
- Message.prototype.encodeHex = function() {
2147
+ MessagePrototype.encodeHex = function() {
2046
2148
  try {
2047
2149
  return this.encode().toHex();
2048
2150
  } catch (e) {
@@ -2060,38 +2162,38 @@
2060
2162
  * returns the encoded hex string in the `encoded` property on the error.
2061
2163
  * @expose
2062
2164
  */
2063
- Message.prototype.toHex = Message.prototype.encodeHex;
2165
+ MessagePrototype.toHex = MessagePrototype.encodeHex;
2064
2166
 
2065
2167
  /**
2066
2168
  * Clones a message object to a raw object.
2067
2169
  * @param {*} obj Object to clone
2068
- * @param {boolean} includeBuffers Whether to include native buffer data or not
2170
+ * @param {boolean} includeBinaryAsBase64 Whether to include binary data as base64 strings or not
2069
2171
  * @returns {*} Cloned object
2070
2172
  * @inner
2071
2173
  */
2072
- function cloneRaw(obj, includeBuffers) {
2174
+ function cloneRaw(obj, includeBinaryAsBase64) {
2073
2175
  var clone = {};
2074
2176
  for (var i in obj)
2075
2177
  if (obj.hasOwnProperty(i)) {
2076
2178
  if (obj[i] === null || typeof obj[i] !== 'object')
2077
2179
  clone[i] = obj[i];
2078
2180
  else if (obj[i] instanceof ByteBuffer) {
2079
- if (includeBuffers)
2080
- clone[i] = obj.toBuffer();
2181
+ if (includeBinaryAsBase64)
2182
+ clone[i] = obj[i].toBase64();
2081
2183
  } else // is a non-null object
2082
- clone[i] = cloneRaw(obj[i], includeBuffers);
2184
+ clone[i] = cloneRaw(obj[i], includeBinaryAsBase64);
2083
2185
  }
2084
2186
  return clone;
2085
2187
  }
2086
2188
 
2087
2189
  /**
2088
2190
  * Returns the message's raw payload.
2089
- * @param {boolean=} includeBuffers Whether to include native buffer data or not, defaults to `false`
2191
+ * @param {boolean=} includeBinaryAsBase64 Whether to include binary data as base64 strings or not, defaults to `false`
2090
2192
  * @returns {Object.&lt;string,*>} Raw payload
2091
2193
  * @expose
2092
2194
  */
2093
- Message.prototype.toRaw = function(includeBuffers) {
2094
- return cloneRaw(this, !!includeBuffers);
2195
+ MessagePrototype.toRaw = function(includeBinaryAsBase64) {
2196
+ return cloneRaw(this, !!includeBinaryAsBase64);
2095
2197
  };
2096
2198
 
2097
2199
  /**
@@ -2192,7 +2294,7 @@
2192
2294
  * @return {string} String representation as of ".Fully.Qualified.MessageName"
2193
2295
  * @expose
2194
2296
  */
2195
- Message.prototype.toString = function() {
2297
+ MessagePrototype.toString = function() {
2196
2298
  return T.toString();
2197
2299
  };
2198
2300
 
@@ -2216,7 +2318,7 @@
2216
2318
 
2217
2319
  if (Object.defineProperty)
2218
2320
  Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
2219
- Object.defineProperty(Message.prototype, "$type", {
2321
+ Object.defineProperty(MessagePrototype, "$type", {
2220
2322
  get: function() { return T; }
2221
2323
  });
2222
2324
 
@@ -2226,20 +2328,20 @@
2226
2328
 
2227
2329
  // Static enums and prototyped sub-messages / cached collections
2228
2330
  this._fields = [];
2229
- this._fieldsById = [];
2331
+ this._fieldsById = {};
2332
+ this._fieldsByName = {};
2230
2333
  for (var i=0, k=this.children.length, child; i&lt;k; i++) {
2231
2334
  child = this.children[i];
2232
2335
  if (child instanceof Enum)
2233
- clazz[child['name']] = child.build();
2336
+ clazz[child.name] = child.build();
2234
2337
  else if (child instanceof Message)
2235
- clazz[child['name']] = child.build();
2338
+ clazz[child.name] = child.build();
2236
2339
  else if (child instanceof Message.Field)
2237
2340
  child.build(),
2238
2341
  this._fields.push(child),
2239
- this._fieldsById[child.id] = child;
2240
- else if (child instanceof Extension) {
2241
- // Ignore
2242
- } else
2342
+ this._fieldsById[child.id] = child,
2343
+ this._fieldsByName[child.name] = child;
2344
+ else if (!(child instanceof Message.OneOf) &amp;&amp; !(child instanceof Extension)) // Not built
2243
2345
  throw Error("Illegal reflect child of "+this.toString(true)+": "+children[i].toString(true));
2244
2346
  }
2245
2347
 
@@ -2255,11 +2357,11 @@
2255
2357
  * @throws {Error} If required fields are missing or the message cannot be encoded for another reason
2256
2358
  * @expose
2257
2359
  */
2258
- Message.prototype.encode = function(message, buffer, noVerify) {
2360
+ MessagePrototype.encode = function(message, buffer, noVerify) {
2259
2361
  var fieldMissing = null,
2260
2362
  field;
2261
2363
  for (var i=0, k=this._fields.length, val; i&lt;k; ++i) {
2262
- field = this.children[i];
2364
+ field = this._fields[i];
2263
2365
  val = message[field.name];
2264
2366
  if (field.required &amp;&amp; val === null) {
2265
2367
  if (fieldMissing === null)
@@ -2282,7 +2384,7 @@
2282
2384
  * @throws {Error} If required fields are missing or the message cannot be calculated for another reason
2283
2385
  * @expose
2284
2386
  */
2285
- Message.prototype.calculate = function(message) {
2387
+ MessagePrototype.calculate = function(message) {
2286
2388
  for (var n=0, i=0, k=this._fields.length, field, val; i&lt;k; ++i) {
2287
2389
  field = this._fields[i];
2288
2390
  val = message[field.name];
@@ -2344,7 +2446,7 @@
2344
2446
  * @throws {Error} If the message cannot be decoded
2345
2447
  * @expose
2346
2448
  */
2347
- Message.prototype.decode = function(buffer, length, expectedGroupEndId) {
2449
+ MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
2348
2450
  length = typeof length === 'number' ? length : -1;
2349
2451
  var start = buffer.offset,
2350
2452
  msg = new (this.clazz)(),
@@ -2384,8 +2486,14 @@
2384
2486
  }
2385
2487
  if (field.repeated &amp;&amp; !field.options["packed"])
2386
2488
  msg[field.name].push(field.decode(wireType, buffer));
2387
- else
2489
+ else {
2388
2490
  msg[field.name] = field.decode(wireType, buffer);
2491
+ if (field.oneof) {
2492
+ if (this[field.oneof.name] !== null)
2493
+ this[this[field.oneof.name]] = null;
2494
+ msg[field.oneof.name] = field.name;
2495
+ }
2496
+ }
2389
2497
  }
2390
2498
 
2391
2499
  // Check if all required fields are present and set default values for optional fields that are not
@@ -2411,17 +2519,19 @@
2411
2519
  /**
2412
2520
  * Constructs a new Message Field.
2413
2521
  * @exports ProtoBuf.Reflect.Message.Field
2414
- * @param {ProtoBuf.Reflect.Message} message Message reference
2522
+ * @param {!ProtoBuf.Builder} builder Builder reference
2523
+ * @param {!ProtoBuf.Reflect.Message} message Message reference
2415
2524
  * @param {string} rule Rule, one of requried, optional, repeated
2416
2525
  * @param {string} type Data type, e.g. int32
2417
2526
  * @param {string} name Field name
2418
2527
  * @param {number} id Unique field id
2419
2528
  * @param {Object.&lt;string,*>=} options Options
2529
+ * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
2420
2530
  * @constructor
2421
2531
  * @extends ProtoBuf.Reflect.T
2422
2532
  */
2423
- var Field = function(message, rule, type, name, id, options) {
2424
- T.call(this, message, name);
2533
+ var Field = function(builder, message, rule, type, name, id, options, oneof) {
2534
+ T.call(this, builder, message, name);
2425
2535
 
2426
2536
  /**
2427
2537
  * @override
@@ -2478,6 +2588,13 @@
2478
2588
  */
2479
2589
  this.defaultValue = null;
2480
2590
 
2591
+ /**
2592
+ * Enclosing OneOf.
2593
+ * @type {?ProtoBuf.Reflect.Message.OneOf}
2594
+ * @expose
2595
+ */
2596
+ this.oneof = oneof || null;
2597
+
2481
2598
  /**
2482
2599
  * Original field name.
2483
2600
  * @type {string}
@@ -2486,22 +2603,34 @@
2486
2603
  this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
2487
2604
 
2488
2605
  // Convert field names to camel case notation if the override is set
2489
- if (ProtoBuf.convertFieldsToCamelCase &amp;&amp; !(this instanceof Message.ExtensionField)) {
2490
- this.name = this.name.replace(/_([a-zA-Z])/g, function($0, $1) {
2491
- return $1.toUpperCase();
2492
- });
2493
- }
2606
+ if (this.builder.options['convertFieldsToCamelCase'] &amp;&amp; !(this instanceof Message.ExtensionField))
2607
+ this.name = Field._toCamelCase(this.name);
2494
2608
  };
2495
2609
 
2496
- // Extends T
2497
- Field.prototype = Object.create(T.prototype);
2610
+ /**
2611
+ * Converts a field name to camel case.
2612
+ * @param {string} name Likely underscore notated name
2613
+ * @returns {string} Camel case notated name
2614
+ * @private
2615
+ */
2616
+ Field._toCamelCase = function(name) {
2617
+ return name.replace(/_([a-zA-Z])/g, function($0, $1) {
2618
+ return $1.toUpperCase();
2619
+ });
2620
+ };
2621
+
2622
+ /**
2623
+ * @alias ProtoBuf.Reflect.Message.Field.prototype
2624
+ * @inner
2625
+ */
2626
+ var FieldPrototype = Field.prototype = Object.create(T.prototype);
2498
2627
 
2499
2628
  /**
2500
2629
  * Builds the field.
2501
2630
  * @override
2502
2631
  * @expose
2503
2632
  */
2504
- Field.prototype.build = function() {
2633
+ FieldPrototype.build = function() {
2505
2634
  this.defaultValue = typeof this.options['default'] !== 'undefined'
2506
2635
  ? this.verifyValue(this.options['default']) : null;
2507
2636
  };
@@ -2534,7 +2663,7 @@
2534
2663
  * @throws {Error} If the value cannot be set for this field
2535
2664
  * @expose
2536
2665
  */
2537
- Field.prototype.verifyValue = function(value, skipRepeated) {
2666
+ FieldPrototype.verifyValue = function(value, skipRepeated) {
2538
2667
  skipRepeated = skipRepeated || false;
2539
2668
  var fail = function(val, msg) {
2540
2669
  throw Error("Illegal value for "+this.toString(true)+" of type "+this.type.name+": "+val+" ("+msg+")");
@@ -2622,20 +2751,18 @@
2622
2751
 
2623
2752
  // Length-delimited bytes
2624
2753
  case ProtoBuf.TYPES["bytes"]:
2625
- return value &amp;&amp; value instanceof ByteBuffer
2626
- ? value
2627
- : ByteBuffer.wrap(value);
2754
+ if (ByteBuffer.isByteBuffer(value))
2755
+ return value;
2756
+ return ByteBuffer.wrap(value, "base64");
2628
2757
 
2629
2758
  // Constant enum value
2630
2759
  case ProtoBuf.TYPES["enum"]: {
2631
2760
  var values = this.resolvedType.getChildren(Enum.Value);
2632
- for (i=0; i&lt;values.length; i++) {
2633
- if (values[i].name == value) {
2761
+ for (i=0; i&lt;values.length; i++)
2762
+ if (values[i].name == value)
2634
2763
  return values[i].id;
2635
- } else if (values[i].id == value) {
2764
+ else if (values[i].id == value)
2636
2765
  return values[i].id;
2637
- }
2638
- }
2639
2766
  fail(value, "not a valid enum value");
2640
2767
  }
2641
2768
  // Embedded message
@@ -2670,7 +2797,7 @@
2670
2797
  * @throws {Error} If the field cannot be encoded
2671
2798
  * @expose
2672
2799
  */
2673
- Field.prototype.encode = function(value, buffer) {
2800
+ FieldPrototype.encode = function(value, buffer) {
2674
2801
  if (this.type === null || typeof this.type !== 'object')
2675
2802
  throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
2676
2803
  if (value === null || (this.repeated &amp;&amp; value.length == 0))
@@ -2722,7 +2849,7 @@
2722
2849
  * @throws {Error} If the value cannot be encoded
2723
2850
  * @expose
2724
2851
  */
2725
- Field.prototype.encodeValue = function(value, buffer) {
2852
+ FieldPrototype.encodeValue = function(value, buffer) {
2726
2853
  if (value === null) return buffer; // Nothing to encode
2727
2854
  // Tag has already been written
2728
2855
 
@@ -2843,7 +2970,7 @@
2843
2970
  * @returns {number} Byte length
2844
2971
  * @expose
2845
2972
  */
2846
- Field.prototype.calculate = function(value) {
2973
+ FieldPrototype.calculate = function(value) {
2847
2974
  value = this.verifyValue(value); // May throw
2848
2975
  if (this.type === null || typeof this.type !== 'object')
2849
2976
  throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
@@ -2882,7 +3009,7 @@
2882
3009
  * @throws {Error} If the value cannot be calculated
2883
3010
  * @expose
2884
3011
  */
2885
- Field.prototype.calculateValue = function(value) {
3012
+ FieldPrototype.calculateValue = function(value) {
2886
3013
  if (value === null) return 0; // Nothing to encode
2887
3014
  // Tag has already been written
2888
3015
  var n;
@@ -2938,7 +3065,7 @@
2938
3065
  * @throws {Error} If the field cannot be decoded
2939
3066
  * @expose
2940
3067
  */
2941
- Field.prototype.decode = function(wireType, buffer, skipRepeated) {
3068
+ FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
2942
3069
  var value, nBytes;
2943
3070
  if (wireType != this.type.wireType &amp;&amp; (skipRepeated || (wireType != ProtoBuf.WIRE_TYPES.LDELIM || !this.repeated)))
2944
3071
  throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
@@ -3038,7 +3165,7 @@
3038
3165
 
3039
3166
  // We should never end here
3040
3167
  throw Error("[INTERNAL] Illegal wire type for "+this.toString(true)+": "+wireType);
3041
- }
3168
+ };
3042
3169
 
3043
3170
  /**
3044
3171
  * @alias ProtoBuf.Reflect.Message.Field
@@ -3049,7 +3176,8 @@
3049
3176
  /**
3050
3177
  * Constructs a new Message ExtensionField.
3051
3178
  * @exports ProtoBuf.Reflect.Message.ExtensionField
3052
- * @param {ProtoBuf.Reflect.Message} message Message reference
3179
+ * @param {!ProtoBuf.Builder} builder Builder reference
3180
+ * @param {!ProtoBuf.Reflect.Message} message Message reference
3053
3181
  * @param {string} rule Rule, one of requried, optional, repeated
3054
3182
  * @param {string} type Data type, e.g. int32
3055
3183
  * @param {string} name Field name
@@ -3058,8 +3186,8 @@
3058
3186
  * @constructor
3059
3187
  * @extends ProtoBuf.Reflect.Message.Field
3060
3188
  */
3061
- var ExtensionField = function(message, rule, type, name, id, options) {
3062
- Field.call(this, message, rule, type, name, id, options);
3189
+ var ExtensionField = function(builder, message, rule, type, name, id, options) {
3190
+ Field.call(this, builder, message, rule, type, name, id, options);
3063
3191
 
3064
3192
  /**
3065
3193
  * Extension reference.
@@ -3078,17 +3206,44 @@
3078
3206
  */
3079
3207
  Reflect.Message.ExtensionField = ExtensionField;
3080
3208
 
3209
+ /**
3210
+ * Constructs a new Message OneOf.
3211
+ * @exports ProtoBuf.Reflect.Message.OneOf
3212
+ * @param {!ProtoBuf.Builder} builder Builder reference
3213
+ * @param {!ProtoBuf.Reflect.Message} message Message reference
3214
+ * @param {string} name OneOf name
3215
+ * @constructor
3216
+ * @extends ProtoBuf.Reflect.T
3217
+ */
3218
+ var OneOf = function(builder, message, name) {
3219
+ T.call(this, builder, message, name);
3220
+
3221
+ /**
3222
+ * Enclosed fields.
3223
+ * @type {!Array.&lt;!ProtoBuf.Reflect.Message.Field>}
3224
+ * @expose
3225
+ */
3226
+ this.fields = [];
3227
+ };
3228
+
3229
+ /**
3230
+ * @alias ProtoBuf.Reflect.Message.OneOf
3231
+ * @expose
3232
+ */
3233
+ Reflect.Message.OneOf = OneOf;
3234
+
3081
3235
  /**
3082
3236
  * Constructs a new Enum.
3083
3237
  * @exports ProtoBuf.Reflect.Enum
3238
+ * @param {!ProtoBuf.Builder} builder Builder reference
3084
3239
  * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
3085
3240
  * @param {string} name Enum name
3086
3241
  * @param {Object.&lt;string,*>=} options Enum options
3087
3242
  * @constructor
3088
3243
  * @extends ProtoBuf.Reflect.Namespace
3089
3244
  */
3090
- var Enum = function(parent, name, options) {
3091
- Namespace.call(this, parent, name, options);
3245
+ var Enum = function(builder, parent, name, options) {
3246
+ Namespace.call(this, builder, parent, name, options);
3092
3247
 
3093
3248
  /**
3094
3249
  * @override
@@ -3103,15 +3258,18 @@
3103
3258
  this.object = null;
3104
3259
  };
3105
3260
 
3106
- // Extends Namespace
3107
- Enum.prototype = Object.create(Namespace.prototype);
3261
+ /**
3262
+ * @alias ProtoBuf.Reflect.Enum.prototype
3263
+ * @inner
3264
+ */
3265
+ var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
3108
3266
 
3109
3267
  /**
3110
3268
  * Builds this enum and returns the runtime counterpart.
3111
3269
  * @return {Object&lt;string,*>}
3112
3270
  * @expose
3113
3271
  */
3114
- Enum.prototype.build = function() {
3272
+ EnumPrototype.build = function() {
3115
3273
  var enm = {},
3116
3274
  values = this.getChildren(Enum.Value);
3117
3275
  for (var i=0, k=values.length; i&lt;k; ++i)
@@ -3130,14 +3288,15 @@
3130
3288
  /**
3131
3289
  * Constructs a new Enum Value.
3132
3290
  * @exports ProtoBuf.Reflect.Enum.Value
3291
+ * @param {!ProtoBuf.Builder} builder Builder reference
3133
3292
  * @param {!ProtoBuf.Reflect.Enum} enm Enum reference
3134
3293
  * @param {string} name Field name
3135
3294
  * @param {number} id Unique field id
3136
3295
  * @constructor
3137
3296
  * @extends ProtoBuf.Reflect.T
3138
3297
  */
3139
- var Value = function(enm, name, id) {
3140
- T.call(this, enm, name);
3298
+ var Value = function(builder, enm, name, id) {
3299
+ T.call(this, builder, enm, name);
3141
3300
 
3142
3301
  /**
3143
3302
  * @override
@@ -3165,12 +3324,13 @@
3165
3324
  * An extension (field).
3166
3325
  * @exports ProtoBuf.Reflect.Extension
3167
3326
  * @constructor
3168
- * @param {ProtoBuf.Reflect.T} parent Parent object
3327
+ * @param {!ProtoBuf.Builder} builder Builder reference
3328
+ * @param {!ProtoBuf.Reflect.T} parent Parent object
3169
3329
  * @param {string} name Object name
3170
3330
  * @param {!ProtoBuf.Reflect.Message.Field} field Extension field
3171
3331
  */
3172
- var Extension = function(parent, name, field) {
3173
- T.call(this, parent, name);
3332
+ var Extension = function(builder, parent, name, field) {
3333
+ T.call(this, builder, parent, name);
3174
3334
 
3175
3335
  /**
3176
3336
  * Extended message field.
@@ -3192,14 +3352,15 @@
3192
3352
  /**
3193
3353
  * Constructs a new Service.
3194
3354
  * @exports ProtoBuf.Reflect.Service
3355
+ * @param {!ProtoBuf.Builder} builder Builder reference
3195
3356
  * @param {!ProtoBuf.Reflect.Namespace} root Root
3196
3357
  * @param {string} name Service name
3197
3358
  * @param {Object.&lt;string,*>=} options Options
3198
3359
  * @constructor
3199
3360
  * @extends ProtoBuf.Reflect.Namespace
3200
3361
  */
3201
- var Service = function(root, name, options) {
3202
- Namespace.call(this, root, name, options);
3362
+ var Service = function(builder, root, name, options) {
3363
+ Namespace.call(this, builder, root, name, options);
3203
3364
 
3204
3365
  /**
3205
3366
  * @override
@@ -3213,8 +3374,11 @@
3213
3374
  this.clazz = null;
3214
3375
  };
3215
3376
 
3216
- // Extends Namespace
3217
- Service.prototype = Object.create(Namespace.prototype);
3377
+ /**
3378
+ * @alias ProtoBuf.Reflect.Service.prototype
3379
+ * @inner
3380
+ */
3381
+ var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
3218
3382
 
3219
3383
  /**
3220
3384
  * Builds the service and returns the runtime counterpart, which is a fully functional class.
@@ -3224,7 +3388,7 @@
3224
3388
  * @throws {Error} If the message cannot be built
3225
3389
  * @expose
3226
3390
  */
3227
- Service.prototype.build = function(rebuild) {
3391
+ ServicePrototype.build = function(rebuild) {
3228
3392
  if (this.clazz &amp;&amp; !rebuild)
3229
3393
  return this.clazz;
3230
3394
 
@@ -3256,12 +3420,15 @@
3256
3420
  };
3257
3421
  };
3258
3422
 
3259
- // Extends ProtoBuf.Builder.Service
3260
- Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
3423
+ /**
3424
+ * @alias ProtoBuf.Builder.Service.prototype
3425
+ * @inner
3426
+ */
3427
+ var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
3261
3428
 
3262
3429
  if (Object.defineProperty)
3263
3430
  Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
3264
- Object.defineProperty(Service.prototype, "$options", { "value": Service["$options"] });
3431
+ Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] });
3265
3432
 
3266
3433
  /**
3267
3434
  * Asynchronously performs an RPC call using the given RPC implementation.
@@ -3289,7 +3456,7 @@
3289
3456
  (function(method) {
3290
3457
 
3291
3458
  // service#Method(message, callback)
3292
- Service.prototype[method.name] = function(req, callback) {
3459
+ ServicePrototype[method.name] = function(req, callback) {
3293
3460
  try {
3294
3461
  if (!req || !(req instanceof method.resolvedRequestType.clazz)) {
3295
3462
  setTimeout(callback.bind(this, Error("Illegal request type provided to service method "+T.name+"#"+method.name)), 0);
@@ -3319,7 +3486,7 @@
3319
3486
 
3320
3487
  if (Object.defineProperty)
3321
3488
  Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
3322
- Object.defineProperty(Service.prototype[method.name], "$options", { "value": Service[method.name]["$options"] });
3489
+ Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
3323
3490
  })(rpc[i]);
3324
3491
  }
3325
3492
 
@@ -3337,14 +3504,15 @@
3337
3504
  /**
3338
3505
  * Abstract service method.
3339
3506
  * @exports ProtoBuf.Reflect.Service.Method
3507
+ * @param {!ProtoBuf.Builder} builder Builder reference
3340
3508
  * @param {!ProtoBuf.Reflect.Service} svc Service
3341
3509
  * @param {string} name Method name
3342
3510
  * @param {Object.&lt;string,*>=} options Options
3343
3511
  * @constructor
3344
3512
  * @extends ProtoBuf.Reflect.T
3345
3513
  */
3346
- var Method = function(svc, name, options) {
3347
- T.call(this, svc, name);
3514
+ var Method = function(builder, svc, name, options) {
3515
+ T.call(this, builder, svc, name);
3348
3516
 
3349
3517
  /**
3350
3518
  * @override
@@ -3359,8 +3527,11 @@
3359
3527
  this.options = options || {};
3360
3528
  };
3361
3529
 
3362
- // Extends T
3363
- Method.prototype = Object.create(T.prototype);
3530
+ /**
3531
+ * @alias ProtoBuf.Reflect.Service.Method.prototype
3532
+ * @inner
3533
+ */
3534
+ var MethodPrototype = Method.prototype = Object.create(T.prototype);
3364
3535
 
3365
3536
  /**
3366
3537
  * Builds the method's '$options' property.
@@ -3368,7 +3539,7 @@
3368
3539
  * @function
3369
3540
  * @return {Object.&lt;string,*>}
3370
3541
  */
3371
- Method.prototype.buildOpt = Namespace.prototype.buildOpt;
3542
+ MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
3372
3543
 
3373
3544
  /**
3374
3545
  * @alias ProtoBuf.Reflect.Service.Method
@@ -3379,6 +3550,7 @@
3379
3550
  /**
3380
3551
  * RPC service method.
3381
3552
  * @exports ProtoBuf.Reflect.Service.RPCMethod
3553
+ * @param {!ProtoBuf.Builder} builder Builder reference
3382
3554
  * @param {!ProtoBuf.Reflect.Service} svc Service
3383
3555
  * @param {string} name Method name
3384
3556
  * @param {string} request Request message name
@@ -3387,8 +3559,8 @@
3387
3559
  * @constructor
3388
3560
  * @extends ProtoBuf.Reflect.Service.Method
3389
3561
  */
3390
- var RPCMethod = function(svc, name, request, response, options) {
3391
- Method.call(this, svc, name, options);
3562
+ var RPCMethod = function(builder, svc, name, request, response, options) {
3563
+ Method.call(this, builder, svc, name, options);
3392
3564
 
3393
3565
  /**
3394
3566
  * @override
@@ -3434,6 +3606,7 @@
3434
3606
  Reflect.Service.RPCMethod = RPCMethod;
3435
3607
 
3436
3608
  return Reflect;
3609
+
3437
3610
  })(ProtoBuf);
3438
3611
 
3439
3612
  /**
@@ -3447,16 +3620,17 @@
3447
3620
  * Constructs a new Builder.
3448
3621
  * @exports ProtoBuf.Builder
3449
3622
  * @class Provides the functionality to build protocol messages.
3623
+ * @param {Object.&lt;string,*>=} options Options
3450
3624
  * @constructor
3451
3625
  */
3452
- var Builder = function() {
3626
+ var Builder = function(options) {
3453
3627
 
3454
3628
  /**
3455
3629
  * Namespace.
3456
3630
  * @type {ProtoBuf.Reflect.Namespace}
3457
3631
  * @expose
3458
3632
  */
3459
- this.ns = new Reflect.Namespace(null, ""); // Global namespace
3633
+ this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
3460
3634
 
3461
3635
  /**
3462
3636
  * Namespace pointer.
@@ -3492,13 +3666,26 @@
3492
3666
  * @expose
3493
3667
  */
3494
3668
  this.importRoot = null;
3669
+
3670
+ /**
3671
+ * Options.
3672
+ * @type {!Object.&lt;string, *>}
3673
+ * @expose
3674
+ */
3675
+ this.options = options || {};
3495
3676
  };
3496
3677
 
3678
+ /**
3679
+ * @alias ProtoBuf.Builder.prototype
3680
+ * @inner
3681
+ */
3682
+ var BuilderPrototype = Builder.prototype;
3683
+
3497
3684
  /**
3498
3685
  * Resets the pointer to the root namespace.
3499
3686
  * @expose
3500
3687
  */
3501
- Builder.prototype.reset = function() {
3688
+ BuilderPrototype.reset = function() {
3502
3689
  this.ptr = this.ns;
3503
3690
  };
3504
3691
 
@@ -3510,7 +3697,7 @@
3510
3697
  * @throws {Error} If the package name is invalid
3511
3698
  * @expose
3512
3699
  */
3513
- Builder.prototype.define = function(pkg, options) {
3700
+ BuilderPrototype.define = function(pkg, options) {
3514
3701
  if (typeof pkg !== 'string' || !Lang.TYPEREF.test(pkg))
3515
3702
  throw Error("Illegal package: "+pkg);
3516
3703
  var part = pkg.split("."), i;
@@ -3519,7 +3706,7 @@
3519
3706
  throw Error("Illegal package: "+part[i]);
3520
3707
  for (i=0; i&lt;part.length; i++) {
3521
3708
  if (this.ptr.getChild(part[i]) === null) // Keep existing namespace
3522
- this.ptr.addChild(new Reflect.Namespace(this.ptr, part[i], options));
3709
+ this.ptr.addChild(new Reflect.Namespace(this, this.ptr, part[i], options));
3523
3710
  this.ptr = this.ptr.getChild(part[i]);
3524
3711
  }
3525
3712
  return this;
@@ -3633,7 +3820,7 @@
3633
3820
  * @throws {Error} If a message definition is invalid
3634
3821
  * @expose
3635
3822
  */
3636
- Builder.prototype.create = function(defs) {
3823
+ BuilderPrototype.create = function(defs) {
3637
3824
  if (!defs)
3638
3825
  return this; // Nothing to create
3639
3826
  if (!ProtoBuf.Util.isArray(defs))
@@ -3642,35 +3829,51 @@
3642
3829
  return this;
3643
3830
 
3644
3831
  // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
3645
- var stack = [], def, obj, subObj, i, j;
3832
+ var stack = [];
3646
3833
  stack.push(defs); // One level [a, b, c]
3647
3834
  while (stack.length > 0) {
3648
3835
  defs = stack.pop();
3649
3836
  if (ProtoBuf.Util.isArray(defs)) { // Stack always contains entire namespaces
3650
3837
  while (defs.length > 0) {
3651
- def = defs.shift(); // Namespace always contains an array of messages, enums and services
3838
+ var def = defs.shift(); // Namespace always contains an array of messages, enums and services
3652
3839
  if (Builder.isValidMessage(def)) {
3653
- obj = new Reflect.Message(this.ptr, def["name"], def["options"], def["isGroup"]);
3840
+ var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"]);
3841
+ // Create OneOfs
3842
+ var oneofs = {};
3843
+ if (def["oneofs"]) {
3844
+ var keys = Object.keys(def["oneofs"]);
3845
+ for (var i=0, k=keys.length; i&lt;k; ++i)
3846
+ obj.addChild(oneofs[keys[i]] = new Reflect.Message.OneOf(this, obj, keys[i]));
3847
+ }
3654
3848
  // Create fields
3655
3849
  if (def["fields"] &amp;&amp; def["fields"].length > 0) {
3656
- for (i=0; i&lt;def["fields"].length; i++) { // i=Fields
3657
- if (obj.getChild(def['fields'][i]['id']) !== null)
3658
- throw Error("Duplicate field id in message "+obj.name+": "+def['fields'][i]['id']);
3659
- if (def["fields"][i]["options"]) {
3660
- subObj = Object.keys(def["fields"][i]["options"]);
3661
- for (j=0; j&lt;subObj.length; j++) { // j=Option names
3662
- if (typeof subObj[j] !== 'string')
3663
- throw Error("Illegal field option name in message "+obj.name+"#"+def["fields"][i]["name"]+": "+subObj[j]);
3664
- if (typeof def["fields"][i]["options"][subObj[j]] !== 'string' &amp;&amp; typeof def["fields"][i]["options"][subObj[j]] !== 'number' &amp;&amp; typeof def["fields"][i]["options"][subObj[j]] !== 'boolean')
3665
- throw Error("Illegal field option value in message "+obj.name+"#"+def["fields"][i]["name"]+"#"+subObj[j]+": "+def["fields"][i]["options"][subObj[j]]);
3850
+ for (i=0, k=def["fields"].length; i&lt;k; ++i) { // i:k=Fields
3851
+ var fld = def['fields'][i];
3852
+ if (obj.getChild(fld['id']) !== null)
3853
+ throw Error("Duplicate field id in message "+obj.name+": "+fld['id']);
3854
+ if (fld["options"]) {
3855
+ var opts = Object.keys(fld["options"]);
3856
+ for (var j= 0,l=opts.length; j&lt;l; ++j) { // j:l=Option names
3857
+ if (typeof opts[j] !== 'string')
3858
+ throw Error("Illegal field option name in message "+obj.name+"#"+fld["name"]+": "+opts[j]);
3859
+ if (typeof fld["options"][opts[j]] !== 'string' &amp;&amp; typeof fld["options"][opts[j]] !== 'number' &amp;&amp; typeof fld["options"][opts[j]] !== 'boolean')
3860
+ throw Error("Illegal field option value in message "+obj.name+"#"+fld["name"]+"#"+opts[j]+": "+fld["options"][opts[j]]);
3666
3861
  }
3667
- subObj = null;
3668
3862
  }
3669
- obj.addChild(new Reflect.Message.Field(obj, def["fields"][i]["rule"], def["fields"][i]["type"], def["fields"][i]["name"], def["fields"][i]["id"], def["fields"][i]["options"]));
3863
+ var oneof = null;
3864
+ if (typeof fld["oneof"] === 'string') {
3865
+ oneof = oneofs[fld["oneof"]];
3866
+ if (typeof oneof === 'undefined')
3867
+ throw Error("Illegal oneof in message "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
3868
+ }
3869
+ fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["type"], fld["name"], fld["id"], fld["options"], oneof);
3870
+ if (oneof)
3871
+ oneof.fields.push(fld);
3872
+ obj.addChild(fld);
3670
3873
  }
3671
3874
  }
3672
3875
  // Push enums and messages to stack
3673
- subObj = [];
3876
+ var subObj = [];
3674
3877
  if (typeof def["enums"] !== 'undefined' &amp;&amp; def['enums'].length > 0)
3675
3878
  for (i=0; i&lt;def["enums"].length; i++)
3676
3879
  subObj.push(def["enums"][i]);
@@ -3697,16 +3900,16 @@
3697
3900
  subObj = null;
3698
3901
  obj = null;
3699
3902
  } else if (Builder.isValidEnum(def)) {
3700
- obj = new Reflect.Enum(this.ptr, def["name"], def["options"]);
3903
+ obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"]);
3701
3904
  for (i=0; i&lt;def["values"].length; i++)
3702
- obj.addChild(new Reflect.Enum.Value(obj, def["values"][i]["name"], def["values"][i]["id"]));
3905
+ obj.addChild(new Reflect.Enum.Value(this, obj, def["values"][i]["name"], def["values"][i]["id"]));
3703
3906
  this.ptr.addChild(obj);
3704
3907
  obj = null;
3705
3908
  } else if (Builder.isValidService(def)) {
3706
- obj = new Reflect.Service(this.ptr, def["name"], def["options"]);
3909
+ obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
3707
3910
  for (i in def["rpc"])
3708
3911
  if (def["rpc"].hasOwnProperty(i))
3709
- obj.addChild(new Reflect.Service.RPCMethod(obj, i, def["rpc"][i]["request"], def["rpc"][i]["response"], def["rpc"][i]["options"]));
3912
+ obj.addChild(new Reflect.Service.RPCMethod(this, obj, i, def["rpc"][i]["request"], def["rpc"][i]["response"], def["rpc"][i]["options"]));
3710
3913
  this.ptr.addChild(obj);
3711
3914
  obj = null;
3712
3915
  } else if (Builder.isValidExtend(def)) {
@@ -3717,10 +3920,16 @@
3717
3920
  throw Error("Duplicate extended field id in message "+obj.name+": "+def['fields'][i]['id']);
3718
3921
  if (def['fields'][i]['id'] &lt; obj.extensions[0] || def['fields'][i]['id'] > obj.extensions[1])
3719
3922
  throw Error("Illegal extended field id in message "+obj.name+": "+def['fields'][i]['id']+" ("+obj.extensions.join(' to ')+" expected)");
3923
+ // Convert extension field names to camel case notation if the override is set
3924
+ var name = def["fields"][i]["name"];
3925
+ if (this.options['convertFieldsToCamelCase'])
3926
+ name = Reflect.Message.Field._toCamelCase(def["fields"][i]["name"]);
3720
3927
  // see #161: Extensions use their fully qualified name as their runtime key and...
3721
- var fld = new Reflect.Message.ExtensionField(obj, def["fields"][i]["rule"], def["fields"][i]["type"], this.ptr.fqn()+'.'+def["fields"][i]["name"], def["fields"][i]["id"], def["fields"][i]["options"]);
3722
- // ...are added on top of the current namespace as an extension which is used for resolving their type later on
3723
- var ext = new Reflect.Extension(this.ptr, def["fields"][i]["name"], fld);
3928
+ fld = new Reflect.Message.ExtensionField(this, obj, def["fields"][i]["rule"], def["fields"][i]["type"], this.ptr.fqn()+'.'+name, def["fields"][i]["id"], def["fields"][i]["options"]);
3929
+ // ...are added on top of the current namespace as an extension which is used for
3930
+ // resolving their type later on (the extension always keeps the original name to
3931
+ // prevent naming collisions)
3932
+ var ext = new Reflect.Extension(this, this.ptr, def["fields"][i]["name"], fld);
3724
3933
  fld.extension = ext;
3725
3934
  this.ptr.addChild(ext);
3726
3935
  obj.addChild(fld);
@@ -3750,7 +3959,7 @@
3750
3959
  * @throws {Error} If the definition or file cannot be imported
3751
3960
  * @expose
3752
3961
  */
3753
- Builder.prototype["import"] = function(json, filename) {
3962
+ BuilderPrototype["import"] = function(json, filename) {
3754
3963
  if (typeof filename === 'string') {
3755
3964
  if (ProtoBuf.Util.IS_NODE)
3756
3965
  filename = require("path")['resolve'](filename);
@@ -3884,7 +4093,7 @@
3884
4093
  * @throws {Error} If a type cannot be resolved
3885
4094
  * @expose
3886
4095
  */
3887
- Builder.prototype.resolveAll = function() {
4096
+ BuilderPrototype.resolveAll = function() {
3888
4097
  // Resolve all reflected objects
3889
4098
  var res;
3890
4099
  if (this.ptr == null || typeof this.ptr.type === 'object')
@@ -3927,9 +4136,7 @@
3927
4136
  // Should not happen as nothing else is implemented
3928
4137
  throw Error("Illegal service type in "+this.ptr.toString(true));
3929
4138
  }
3930
- } else if (this.ptr instanceof ProtoBuf.Reflect.Extension) {
3931
- // There are no runtime counterparts to extensions
3932
- } else
4139
+ } else if (!(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) &amp;&amp; !(this.ptr instanceof ProtoBuf.Reflect.Extension))
3933
4140
  throw Error("Illegal object in namespace: "+typeof(this.ptr)+":"+this.ptr);
3934
4141
  this.reset();
3935
4142
  };
@@ -3942,7 +4149,7 @@
3942
4149
  * @throws {Error} If a type could not be resolved
3943
4150
  * @expose
3944
4151
  */
3945
- Builder.prototype.build = function(path) {
4152
+ BuilderPrototype.build = function(path) {
3946
4153
  this.reset();
3947
4154
  if (!this.resolved)
3948
4155
  this.resolveAll(),
@@ -3971,7 +4178,7 @@
3971
4178
  * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
3972
4179
  * @return {ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
3973
4180
  */
3974
- Builder.prototype.lookup = function(path) {
4181
+ BuilderPrototype.lookup = function(path) {
3975
4182
  return path ? this.ns.resolve(path) : this.ns;
3976
4183
  };
3977
4184
 
@@ -3980,7 +4187,7 @@
3980
4187
  * @return {string} String representation as of "Builder"
3981
4188
  * @expose
3982
4189
  */
3983
- Builder.prototype.toString = function() {
4190
+ BuilderPrototype.toString = function() {
3984
4191
  return "Builder";
3985
4192
  };
3986
4193
 
@@ -4004,10 +4211,9 @@
4004
4211
  * @expose
4005
4212
  */
4006
4213
  ProtoBuf.loadProto = function(proto, builder, filename) {
4007
- if (typeof builder === 'string' || (builder &amp;&amp; typeof builder["file"] === 'string' &amp;&amp; typeof builder["root"] === 'string')) {
4008
- filename = builder;
4009
- builder = null;
4010
- }
4214
+ if (typeof builder === 'string' || (builder &amp;&amp; typeof builder["file"] === 'string' &amp;&amp; typeof builder["root"] === 'string'))
4215
+ filename = builder,
4216
+ builder = undefined;
4011
4217
  return ProtoBuf.loadJson((new ProtoBuf.DotProto.Parser(proto)).parse(), builder, filename);
4012
4218
  };
4013
4219
 
@@ -4074,18 +4280,18 @@
4074
4280
 
4075
4281
 
4076
4282
  /**
4077
- * Constructs a new Builder with the specified package defined.
4078
- * @param {string=} pkg Package name as fully qualified name, e.g. "My.Game". If no package is specified, the
4079
- * builder will only contain a global namespace.
4080
- * @param {Object.&lt;string,*>=} options Top level options
4081
- * @return {ProtoBuf.Builder} New Builder
4283
+ * Constructs a new empty Builder.
4284
+ * @param {Object.&lt;string,*>=} options Builder options, defaults to global options set on ProtoBuf
4285
+ * @return {!ProtoBuf.Builder} Builder
4082
4286
  * @expose
4083
4287
  */
4084
- ProtoBuf.newBuilder = function(pkg, options) {
4085
- var builder = new ProtoBuf.Builder();
4086
- if (typeof pkg !== 'undefined' &amp;&amp; pkg !== null)
4087
- builder.define(pkg, options);
4088
- return builder;
4288
+ ProtoBuf.newBuilder = function(options) {
4289
+ options = options || {};
4290
+ if (typeof options['convertFieldsToCamelCase'] === 'undefined')
4291
+ options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
4292
+ if (typeof options['populateAccessors'] === 'undefined')
4293
+ options['populateAccessors'] = ProtoBuf.populateAccessors;
4294
+ return new ProtoBuf.Builder(options);
4089
4295
  };
4090
4296
 
4091
4297
  /**
@@ -4107,7 +4313,6 @@
4107
4313
  json = JSON.parse(json);
4108
4314
  builder["import"](json, filename);
4109
4315
  builder.resolveAll();
4110
- builder.build();
4111
4316
  return builder;
4112
4317
  };
4113
4318
 
@@ -4148,8 +4353,8 @@
4148
4353
  return ProtoBuf;
4149
4354
  }
4150
4355
 
4151
- /* CommonJS */ if (typeof module !== 'undefined' &amp;&amp; module["exports"])
4152
- module["exports"] = init(require("bytebuffer"));
4356
+ /* CommonJS */ if (typeof require === 'function' &amp;&amp; typeof module === 'object' &amp;&amp; module &amp;&amp; typeof exports === 'object' &amp;&amp; exports)
4357
+ module['exports'] = init(require("bytebuffer"));
4153
4358
  /* AMD */ else if (typeof define === 'function' &amp;&amp; define["amd"])
4154
4359
  define(["ByteBuffer"], init);
4155
4360
  /* Global */ else
@@ -4166,13 +4371,13 @@
4166
4371
  </div>
4167
4372
 
4168
4373
  <nav>
4169
- <h2><a href="index.html">Index</a></h2><h3>Classes</h3><ul><li><a href="ProtoBuf.Builder.html">Builder</a></li><li><a href="ProtoBuf.Builder.Message.html">Message</a></li><li><a href="ProtoBuf.Builder.Service.html">Service</a></li><li><a href="ProtoBuf.DotProto.Parser.html">Parser</a></li><li><a href="ProtoBuf.DotProto.Tokenizer.html">Tokenizer</a></li><li><a href="ProtoBuf.Reflect.Enum.html">Enum</a></li><li><a href="ProtoBuf.Reflect.Enum.Value.html">Value</a></li><li><a href="ProtoBuf.Reflect.Extension.html">Extension</a></li><li><a href="ProtoBuf.Reflect.Message.html">Message</a></li><li><a href="ProtoBuf.Reflect.Message.ExtensionField.html">ExtensionField</a></li><li><a href="ProtoBuf.Reflect.Message.Field.html">Field</a></li><li><a href="ProtoBuf.Reflect.Namespace.html">Namespace</a></li><li><a href="ProtoBuf.Reflect.Service.html">Service</a></li><li><a href="ProtoBuf.Reflect.Service.Method.html">Method</a></li><li><a href="ProtoBuf.Reflect.Service.RPCMethod.html">RPCMethod</a></li><li><a href="ProtoBuf.Reflect.T.html">T</a></li></ul><h3>Namespaces</h3><ul><li><a href="ProtoBuf.html">ProtoBuf</a></li><li><a href="ProtoBuf.DotProto.html">DotProto</a></li><li><a href="ProtoBuf.Reflect.html">Reflect</a></li><li><a href="ProtoBuf.Util.html">Util</a></li></ul>
4374
+ <h2><a href="index.html">Index</a></h2><h3>Classes</h3><ul><li><a href="ProtoBuf.Builder.html">Builder</a></li><li><a href="ProtoBuf.Builder.Message.html">Message</a></li><li><a href="ProtoBuf.Builder.Service.html">Service</a></li><li><a href="ProtoBuf.DotProto.Parser.html">Parser</a></li><li><a href="ProtoBuf.DotProto.Tokenizer.html">Tokenizer</a></li><li><a href="ProtoBuf.Reflect.Enum.html">Enum</a></li><li><a href="ProtoBuf.Reflect.Enum.Value.html">Value</a></li><li><a href="ProtoBuf.Reflect.Extension.html">Extension</a></li><li><a href="ProtoBuf.Reflect.Message.html">Message</a></li><li><a href="ProtoBuf.Reflect.Message.ExtensionField.html">ExtensionField</a></li><li><a href="ProtoBuf.Reflect.Message.Field.html">Field</a></li><li><a href="ProtoBuf.Reflect.Message.OneOf.html">OneOf</a></li><li><a href="ProtoBuf.Reflect.Namespace.html">Namespace</a></li><li><a href="ProtoBuf.Reflect.Service.html">Service</a></li><li><a href="ProtoBuf.Reflect.Service.Method.html">Method</a></li><li><a href="ProtoBuf.Reflect.Service.RPCMethod.html">RPCMethod</a></li><li><a href="ProtoBuf.Reflect.T.html">T</a></li></ul><h3>Namespaces</h3><ul><li><a href="ProtoBuf.html">ProtoBuf</a></li><li><a href="ProtoBuf.DotProto.html">DotProto</a></li><li><a href="ProtoBuf.Reflect.html">Reflect</a></li><li><a href="ProtoBuf.Util.html">Util</a></li></ul>
4170
4375
  </nav>
4171
4376
 
4172
4377
  <br clear="both">
4173
4378
 
4174
4379
  <footer>
4175
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha9</a> on Tue Aug 26 2014 22:15:41 GMT+0200 (Mitteleuropäische Sommerzeit)
4380
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.0-alpha10</a> on Mon Nov 24 2014 18:08:26 GMT+0100 (Mitteleuropäische Zeit)
4176
4381
  </footer>
4177
4382
 
4178
4383
  <script> prettyPrint(); </script>