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
@@ -38,7 +38,7 @@
38
38
  * @const
39
39
  * @expose
40
40
  */
41
- ProtoBuf.VERSION = "3.6.0";
41
+ ProtoBuf.VERSION = "3.8.2";
42
42
 
43
43
  /**
44
44
  * Wire types.
@@ -234,138 +234,138 @@
234
234
  */
235
235
  ProtoBuf.populateAccessors = true;
236
236
 
237
- /**
238
- * @alias ProtoBuf.Util
239
- * @expose
240
- */
241
- ProtoBuf.Util = (function() {
242
- "use strict";
243
-
244
- // Object.create polyfill
245
- // ref: https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
246
- if (!Object.create)
247
- /** @expose */
248
- Object.create = function (o) {
249
- if (arguments.length > 1)
250
- throw Error('Object.create polyfill only accepts the first parameter.');
251
- function F() {}
252
- F.prototype = o;
253
- return new F();
254
- };
255
-
256
- /**
257
- * ProtoBuf utilities.
258
- * @exports ProtoBuf.Util
259
- * @namespace
260
- */
261
- var Util = {};
262
-
263
- /**
264
- * Flag if running in node (fs is available) or not.
265
- * @type {boolean}
266
- * @const
267
- * @expose
268
- */
269
- Util.IS_NODE = false;
270
- try {
271
- // There is no reliable way to detect node.js as an environment, so our
272
- // best bet is to feature-detect what we actually need.
273
- Util.IS_NODE =
274
- typeof require === 'function' &&
275
- typeof require("fs").readFileSync === 'function' &&
276
- typeof require("path").resolve === 'function';
277
- } catch (e) {}
278
-
279
- /**
280
- * Constructs a XMLHttpRequest object.
281
- * @return {XMLHttpRequest}
282
- * @throws {Error} If XMLHttpRequest is not supported
283
- * @expose
284
- */
285
- Util.XHR = function() {
286
- // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
287
- var XMLHttpFactories = [
288
- function () {return new XMLHttpRequest()},
289
- function () {return new ActiveXObject("Msxml2.XMLHTTP")},
290
- function () {return new ActiveXObject("Msxml3.XMLHTTP")},
291
- function () {return new ActiveXObject("Microsoft.XMLHTTP")}
292
- ];
293
- /** @type {?XMLHttpRequest} */
294
- var xhr = null;
295
- for (var i=0;i<XMLHttpFactories.length;i++) {
296
- try { xhr = XMLHttpFactories[i](); }
297
- catch (e) { continue; }
298
- break;
299
- }
300
- if (!xhr)
301
- throw Error("XMLHttpRequest is not supported");
302
- return xhr;
303
- };
304
-
305
- /**
306
- * Fetches a resource.
307
- * @param {string} path Resource path
308
- * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
309
- * be fetched synchronously. If the request failed, contents will be null.
310
- * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
311
- * @expose
312
- */
313
- Util.fetch = function(path, callback) {
314
- if (callback && typeof callback != 'function')
315
- callback = null;
316
- if (Util.IS_NODE) {
317
- if (callback) {
318
- require("fs").readFile(path, function(err, data) {
319
- if (err)
320
- callback(null);
321
- else
322
- callback(""+data);
323
- });
324
- } else
325
- try {
326
- return require("fs").readFileSync(path);
327
- } catch (e) {
328
- return null;
329
- }
330
- } else {
331
- var xhr = Util.XHR();
332
- xhr.open('GET', path, callback ? true : false);
333
- // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
334
- xhr.setRequestHeader('Accept', 'text/plain');
335
- if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
336
- if (callback) {
337
- xhr.onreadystatechange = function() {
338
- if (xhr.readyState != 4) return;
339
- if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
340
- callback(xhr.responseText);
341
- else
342
- callback(null);
343
- };
344
- if (xhr.readyState == 4)
345
- return;
346
- xhr.send(null);
347
- } else {
348
- xhr.send(null);
349
- if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
350
- return xhr.responseText;
351
- return null;
352
- }
353
- }
354
- };
355
-
356
- /**
357
- * Tests if an object is an array.
358
- * @function
359
- * @param {*} obj Object to test
360
- * @returns {boolean} true if it is an array, else false
361
- * @expose
362
- */
363
- Util.isArray = Array.isArray || function(obj) {
364
- return Object.prototype.toString.call(obj) === "[object Array]";
365
- };
366
-
367
- return Util;
368
- })();
237
+ /**
238
+ * @alias ProtoBuf.Util
239
+ * @expose
240
+ */
241
+ ProtoBuf.Util = (function() {
242
+ "use strict";
243
+
244
+ // Object.create polyfill
245
+ // ref: https://developer.mozilla.org/de/docs/JavaScript/Reference/Global_Objects/Object/create
246
+ if (!Object.create)
247
+ /** @expose */
248
+ Object.create = function (o) {
249
+ if (arguments.length > 1)
250
+ throw Error('Object.create polyfill only accepts the first parameter.');
251
+ function F() {}
252
+ F.prototype = o;
253
+ return new F();
254
+ };
255
+
256
+ /**
257
+ * ProtoBuf utilities.
258
+ * @exports ProtoBuf.Util
259
+ * @namespace
260
+ */
261
+ var Util = {};
262
+
263
+ /**
264
+ * Flag if running in node (fs is available) or not.
265
+ * @type {boolean}
266
+ * @const
267
+ * @expose
268
+ */
269
+ Util.IS_NODE = false;
270
+ try {
271
+ // There is no reliable way to detect node.js as an environment, so our
272
+ // best bet is to feature-detect what we actually need.
273
+ Util.IS_NODE =
274
+ typeof require === 'function' &&
275
+ typeof require("fs").readFileSync === 'function' &&
276
+ typeof require("path").resolve === 'function';
277
+ } catch (e) {}
278
+
279
+ /**
280
+ * Constructs a XMLHttpRequest object.
281
+ * @return {XMLHttpRequest}
282
+ * @throws {Error} If XMLHttpRequest is not supported
283
+ * @expose
284
+ */
285
+ Util.XHR = function() {
286
+ // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
287
+ var XMLHttpFactories = [
288
+ function () {return new XMLHttpRequest()},
289
+ function () {return new ActiveXObject("Msxml2.XMLHTTP")},
290
+ function () {return new ActiveXObject("Msxml3.XMLHTTP")},
291
+ function () {return new ActiveXObject("Microsoft.XMLHTTP")}
292
+ ];
293
+ /** @type {?XMLHttpRequest} */
294
+ var xhr = null;
295
+ for (var i=0;i<XMLHttpFactories.length;i++) {
296
+ try { xhr = XMLHttpFactories[i](); }
297
+ catch (e) { continue; }
298
+ break;
299
+ }
300
+ if (!xhr)
301
+ throw Error("XMLHttpRequest is not supported");
302
+ return xhr;
303
+ };
304
+
305
+ /**
306
+ * Fetches a resource.
307
+ * @param {string} path Resource path
308
+ * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
309
+ * be fetched synchronously. If the request failed, contents will be null.
310
+ * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
311
+ * @expose
312
+ */
313
+ Util.fetch = function(path, callback) {
314
+ if (callback && typeof callback != 'function')
315
+ callback = null;
316
+ if (Util.IS_NODE) {
317
+ if (callback) {
318
+ require("fs").readFile(path, function(err, data) {
319
+ if (err)
320
+ callback(null);
321
+ else
322
+ callback(""+data);
323
+ });
324
+ } else
325
+ try {
326
+ return require("fs").readFileSync(path);
327
+ } catch (e) {
328
+ return null;
329
+ }
330
+ } else {
331
+ var xhr = Util.XHR();
332
+ xhr.open('GET', path, callback ? true : false);
333
+ // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
334
+ xhr.setRequestHeader('Accept', 'text/plain');
335
+ if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
336
+ if (callback) {
337
+ xhr.onreadystatechange = function() {
338
+ if (xhr.readyState != 4) return;
339
+ if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
340
+ callback(xhr.responseText);
341
+ else
342
+ callback(null);
343
+ };
344
+ if (xhr.readyState == 4)
345
+ return;
346
+ xhr.send(null);
347
+ } else {
348
+ xhr.send(null);
349
+ if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
350
+ return xhr.responseText;
351
+ return null;
352
+ }
353
+ }
354
+ };
355
+
356
+ /**
357
+ * Tests if an object is an array.
358
+ * @function
359
+ * @param {*} obj Object to test
360
+ * @returns {boolean} true if it is an array, else false
361
+ * @expose
362
+ */
363
+ Util.isArray = Array.isArray || function(obj) {
364
+ return Object.prototype.toString.call(obj) === "[object Array]";
365
+ };
366
+
367
+ return Util;
368
+ })();
369
369
 
370
370
  /**
371
371
  * Language expressions.
@@ -402,7 +402,7 @@
402
402
  ID: /^(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
403
403
  NEGID: /^\-?(?:[1-9][0-9]*|0|0x[0-9a-fA-F]+|0[0-7]+)$/,
404
404
  WHITESPACE: /\s/,
405
- STRING: /['"]([^'"\\]*(\\.[^"\\]*)*)['"]/g,
405
+ STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
406
406
  BOOL: /^(?:true|false)$/i
407
407
  };
408
408
 
@@ -426,14 +426,22 @@
426
426
  * @exports ProtoBuf.Reflect.T
427
427
  * @constructor
428
428
  * @abstract
429
- * @param {ProtoBuf.Reflect.T} parent Parent object
429
+ * @param {!ProtoBuf.Builder} builder Builder reference
430
+ * @param {?ProtoBuf.Reflect.T} parent Parent object
430
431
  * @param {string} name Object name
431
432
  */
432
- var T = function(parent, name) {
433
+ var T = function(builder, parent, name) {
434
+
435
+ /**
436
+ * Builder reference.
437
+ * @type {!ProtoBuf.Builder}
438
+ * @expose
439
+ */
440
+ this.builder = builder;
433
441
 
434
442
  /**
435
443
  * Parent object.
436
- * @type {ProtoBuf.Reflect.T|null}
444
+ * @type {?ProtoBuf.Reflect.T}
437
445
  * @expose
438
446
  */
439
447
  this.parent = parent;
@@ -453,12 +461,18 @@
453
461
  this.className;
454
462
  };
455
463
 
464
+ /**
465
+ * @alias ProtoBuf.Reflect.T.prototype
466
+ * @inner
467
+ */
468
+ var TPrototype = T.prototype;
469
+
456
470
  /**
457
471
  * Returns the fully qualified name of this object.
458
472
  * @returns {string} Fully qualified name as of ".PATH.TO.THIS"
459
473
  * @expose
460
474
  */
461
- T.prototype.fqn = function() {
475
+ TPrototype.fqn = function() {
462
476
  var name = this.name,
463
477
  ptr = this;
464
478
  do {
@@ -476,7 +490,7 @@
476
490
  * @return String representation
477
491
  * @expose
478
492
  */
479
- T.prototype.toString = function(includeClass) {
493
+ TPrototype.toString = function(includeClass) {
480
494
  return (includeClass ? this.className + " " : "") + this.fqn();
481
495
  };
482
496
 
@@ -485,7 +499,7 @@
485
499
  * @throws {Error} If this type cannot be built directly
486
500
  * @expose
487
501
  */
488
- T.prototype.build = function() {
502
+ TPrototype.build = function() {
489
503
  throw Error(this.toString(true)+" cannot be built directly");
490
504
  };
491
505
 
@@ -498,14 +512,15 @@
498
512
  /**
499
513
  * Constructs a new Namespace.
500
514
  * @exports ProtoBuf.Reflect.Namespace
501
- * @param {ProtoBuf.Reflect.Namespace|null} parent Namespace parent
515
+ * @param {!ProtoBuf.Builder} builder Builder reference
516
+ * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
502
517
  * @param {string} name Namespace name
503
- * @param {Object.<string,*>} options Namespace options
518
+ * @param {Object.<string,*>=} options Namespace options
504
519
  * @constructor
505
520
  * @extends ProtoBuf.Reflect.T
506
521
  */
507
- var Namespace = function(parent, name, options) {
508
- T.call(this, parent, name);
522
+ var Namespace = function(builder, parent, name, options) {
523
+ T.call(this, builder, parent, name);
509
524
 
510
525
  /**
511
526
  * @override
@@ -514,19 +529,22 @@
514
529
 
515
530
  /**
516
531
  * Children inside the namespace.
517
- * @type {Array.<ProtoBuf.Reflect.T>}
532
+ * @type {!Array.<ProtoBuf.Reflect.T>}
518
533
  */
519
534
  this.children = [];
520
535
 
521
536
  /**
522
537
  * Options.
523
- * @type {Object.<string, *>}
538
+ * @type {!Object.<string, *>}
524
539
  */
525
540
  this.options = options || {};
526
541
  };
527
542
 
528
- // Extends T
529
- Namespace.prototype = Object.create(T.prototype);
543
+ /**
544
+ * @alias ProtoBuf.Reflect.Namespace.prototype
545
+ * @inner
546
+ */
547
+ var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
530
548
 
531
549
  /**
532
550
  * Returns an array of the namespace's children.
@@ -534,7 +552,7 @@
534
552
  * @return {Array.<ProtoBuf.Reflect.T>}
535
553
  * @expose
536
554
  */
537
- Namespace.prototype.getChildren = function(type) {
555
+ NamespacePrototype.getChildren = function(type) {
538
556
  type = type || null;
539
557
  if (type == null)
540
558
  return this.children.slice();
@@ -551,7 +569,7 @@
551
569
  * @throws {Error} If the child cannot be added (duplicate)
552
570
  * @expose
553
571
  */
554
- Namespace.prototype.addChild = function(child) {
572
+ NamespacePrototype.addChild = function(child) {
555
573
  var other;
556
574
  if (other = this.getChild(child.name)) {
557
575
  // Try to revert camelcase transformation on collision
@@ -571,7 +589,7 @@
571
589
  * @return {?ProtoBuf.Reflect.T} The child or null if not found
572
590
  * @expose
573
591
  */
574
- Namespace.prototype.getChild = function(nameOrId) {
592
+ NamespacePrototype.getChild = function(nameOrId) {
575
593
  var key = typeof nameOrId === 'number' ? 'id' : 'name';
576
594
  for (var i=0, k=this.children.length; i<k; ++i)
577
595
  if (this.children[i][key] === nameOrId)
@@ -586,7 +604,7 @@
586
604
  * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
587
605
  * @expose
588
606
  */
589
- Namespace.prototype.resolve = function(qn, excludeFields) {
607
+ NamespacePrototype.resolve = function(qn, excludeFields) {
590
608
  var part = qn.split("."),
591
609
  ptr = this,
592
610
  i = 0;
@@ -620,7 +638,7 @@
620
638
  * @return {Object.<string,Function|Object>} Runtime namespace
621
639
  * @expose
622
640
  */
623
- Namespace.prototype.build = function() {
641
+ NamespacePrototype.build = function() {
624
642
  /** @dict */
625
643
  var ns = {};
626
644
  var children = this.children;
@@ -638,7 +656,7 @@
638
656
  * Builds the namespace's '$options' property.
639
657
  * @return {Object.<string,*>}
640
658
  */
641
- Namespace.prototype.buildOpt = function() {
659
+ NamespacePrototype.buildOpt = function() {
642
660
  var opt = {},
643
661
  keys = Object.keys(this.options);
644
662
  for (var i=0, k=keys.length; i<k; ++i) {
@@ -659,7 +677,7 @@
659
677
  * @param {string=} name Returns the option value if specified, otherwise all options are returned.
660
678
  * @return {*|Object.<string,*>}null} Option value or NULL if there is no such option
661
679
  */
662
- Namespace.prototype.getOption = function(name) {
680
+ NamespacePrototype.getOption = function(name) {
663
681
  if (typeof name === 'undefined')
664
682
  return this.options;
665
683
  return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
@@ -674,15 +692,16 @@
674
692
  /**
675
693
  * Constructs a new Message.
676
694
  * @exports ProtoBuf.Reflect.Message
677
- * @param {ProtoBuf.Reflect.Namespace} parent Parent message or namespace
695
+ * @param {!ProtoBuf.Builder} builder Builder reference
696
+ * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
678
697
  * @param {string} name Message name
679
- * @param {Object.<string,*>} options Message options
698
+ * @param {Object.<string,*>=} options Message options
680
699
  * @param {boolean=} isGroup `true` if this is a legacy group
681
700
  * @constructor
682
701
  * @extends ProtoBuf.Reflect.Namespace
683
702
  */
684
- var Message = function(parent, name, options, isGroup) {
685
- Namespace.call(this, parent, name, options);
703
+ var Message = function(builder, parent, name, options, isGroup) {
704
+ Namespace.call(this, builder, parent, name, options);
686
705
 
687
706
  /**
688
707
  * @override
@@ -725,10 +744,20 @@
725
744
  * @private
726
745
  */
727
746
  this._fieldsById = null;
747
+
748
+ /**
749
+ * Cached fields by name.
750
+ * @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}
751
+ * @private
752
+ */
753
+ this._fieldsByName = null;
728
754
  };
729
755
 
730
- // Extends Namespace
731
- Message.prototype = Object.create(Namespace.prototype);
756
+ /**
757
+ * @alias ProtoBuf.Reflect.Message.prototype
758
+ * @inner
759
+ */
760
+ var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
732
761
 
733
762
  /**
734
763
  * Builds the message and returns the runtime counterpart, which is a fully functional class.
@@ -738,14 +767,15 @@
738
767
  * @throws {Error} If the message cannot be built
739
768
  * @expose
740
769
  */
741
- Message.prototype.build = function(rebuild) {
770
+ MessagePrototype.build = function(rebuild) {
742
771
  if (this.clazz && !rebuild)
743
772
  return this.clazz;
744
773
 
745
774
  // Create the runtime Message class in its own scope
746
775
  var clazz = (function(ProtoBuf, T) {
747
776
 
748
- var fields = T.getChildren(ProtoBuf.Reflect.Message.Field);
777
+ var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
778
+ oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
749
779
 
750
780
  /**
751
781
  * Constructs a new runtime Message.
@@ -759,9 +789,13 @@
759
789
  var Message = function(values, var_args) {
760
790
  ProtoBuf.Builder.Message.call(this);
761
791
 
762
- // Create fields on the object itself and set default values
763
- for (var i=0, k=fields.length, field; i<k; ++i) {
764
- this[(field = fields[i]).name] = field.repeated ? [] : null;
792
+ // Create virtual oneof properties
793
+ for (var i=0, k=oneofs.length; i<k; ++i)
794
+ this[oneofs[i].name] = null;
795
+ // Create fields and set default values
796
+ for (i=0, k=fields.length; i<k; ++i) {
797
+ var field = fields[i];
798
+ this[field.name] = field.repeated ? [] : null;
765
799
  if (field.required && field.defaultValue !== null)
766
800
  this[field.name] = field.defaultValue;
767
801
  }
@@ -777,21 +811,17 @@
777
811
  var keys = Object.keys(values);
778
812
  for (i=0, k=keys.length; i<k; ++i)
779
813
  this.$set(keys[i], values[keys[i]]); // May throw
780
- } else // set field values from arguments, in declaration order
814
+ } else // Set field values from arguments, in declaration order
781
815
  for (i=0, k=arguments.length; i<k; ++i)
782
816
  this.$set(fields[i].name, arguments[i]); // May throw
783
817
  }
784
818
  };
785
819
 
786
820
  /**
787
- * The message's reflection type.
788
- * @name ProtoBuf.Builder.Message#$type
789
- * @type {!ProtoBuf.Reflect.Message}
790
- * @expose
821
+ * @alias ProtoBuf.Builder.Message.prototype
822
+ * @inner
791
823
  */
792
-
793
- // Extends ProtoBuf.Builder.Message
794
- Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
824
+ var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
795
825
 
796
826
  /**
797
827
  * Adds a value to a repeated field.
@@ -803,14 +833,16 @@
803
833
  * @throws {Error} If the value cannot be added
804
834
  * @expose
805
835
  */
806
- Message.prototype.add = function(key, value, noAssert) {
807
- var field = T.getChild(key);
808
- if (!field)
809
- throw Error(this+"#"+key+" is undefined");
810
- if (!(field instanceof ProtoBuf.Reflect.Message.Field))
811
- throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
812
- if (!field.repeated)
813
- throw Error(this+"#"+key+" is not a repeated field");
836
+ MessagePrototype.add = function(key, value, noAssert) {
837
+ var field = T._fieldsByName[key];
838
+ if (!noAssert) {
839
+ if (!field)
840
+ throw Error(this+"#"+key+" is undefined");
841
+ if (!(field instanceof ProtoBuf.Reflect.Message.Field))
842
+ throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
843
+ if (!field.repeated)
844
+ throw Error(this+"#"+key+" is not a repeated field");
845
+ }
814
846
  if (this[field.name] === null)
815
847
  this[field.name] = [];
816
848
  this[field.name].push(noAssert ? value : field.verifyValue(value, true));
@@ -826,7 +858,7 @@
826
858
  * @throws {Error} If the value cannot be added
827
859
  * @expose
828
860
  */
829
- Message.prototype.$add = Message.prototype.add;
861
+ MessagePrototype.$add = MessagePrototype.add;
830
862
 
831
863
  /**
832
864
  * Sets a field's value.
@@ -839,23 +871,31 @@
839
871
  * @throws {Error} If the value cannot be set
840
872
  * @expose
841
873
  */
842
- Message.prototype.set = function(key, value, noAssert) {
874
+ MessagePrototype.set = function(key, value, noAssert) {
843
875
  if (key && typeof key === 'object') {
844
876
  for (var i in key)
845
877
  if (key.hasOwnProperty(i))
846
878
  this.$set(i, key[i], noAssert);
847
879
  return this;
848
880
  }
849
- if (noAssert) {
850
- this[key] = value;
851
- return this;
881
+ var field = T._fieldsByName[key];
882
+ if (!noAssert) {
883
+ if (!field)
884
+ throw Error(this+"#"+key+" is not a field: undefined");
885
+ if (!(field instanceof ProtoBuf.Reflect.Message.Field))
886
+ throw Error(this+"#"+key+" is not a field: "+field.toString(true));
887
+ this[field.name] = (value = field.verifyValue(value)); // May throw
888
+ } else {
889
+ this[field.name] = value;
890
+ }
891
+ if (field.oneof) {
892
+ if (value !== null) {
893
+ if (this[field.oneof.name] !== null)
894
+ this[this[field.oneof.name]] = null; // Unset the previous (field name is the oneof field's value)
895
+ this[field.oneof.name] = field.name;
896
+ } else if (field.oneof.name === key)
897
+ this[field.oneof.name] = null;
852
898
  }
853
- var field = T.getChild(key);
854
- if (!field)
855
- throw Error(this+"#"+key+" is not a field: undefined");
856
- if (!(field instanceof ProtoBuf.Reflect.Message.Field))
857
- throw Error(this+"#"+key+" is not a field: "+field.toString(true));
858
- this[field.name] = field.verifyValue(value); // May throw
859
899
  return this;
860
900
  };
861
901
 
@@ -865,26 +905,26 @@
865
905
  * @function
866
906
  * @param {string} key Key
867
907
  * @param {*} value Value to set
868
- * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
908
+ * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
869
909
  * @throws {Error} If the value cannot be set
870
910
  * @expose
871
911
  */
872
- Message.prototype.$set = Message.prototype.set;
912
+ MessagePrototype.$set = MessagePrototype.set;
873
913
 
874
914
  /**
875
915
  * Gets a field's value.
876
916
  * @name ProtoBuf.Builder.Message#get
877
917
  * @function
878
918
  * @param {string} key Key
879
- * @param {boolean=} noAssert Whether to no assert for an actual field, defaults to `false`
919
+ * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
880
920
  * @return {*} Value
881
921
  * @throws {Error} If there is no such field
882
922
  * @expose
883
923
  */
884
- Message.prototype.get = function(key, noAssert) {
924
+ MessagePrototype.get = function(key, noAssert) {
885
925
  if (noAssert)
886
926
  return this[key];
887
- var field = T.getChild(key);
927
+ var field = T._fieldsByName[key];
888
928
  if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
889
929
  throw Error(this+"#"+key+" is not a field: undefined");
890
930
  if (!(field instanceof ProtoBuf.Reflect.Message.Field))
@@ -901,7 +941,7 @@
901
941
  * @throws {Error} If there is no such field
902
942
  * @expose
903
943
  */
904
- Message.prototype.$get = Message.prototype.get;
944
+ MessagePrototype.$get = MessagePrototype.get;
905
945
 
906
946
  // Getters and setters
907
947
 
@@ -911,72 +951,91 @@
911
951
  if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
912
952
  continue;
913
953
 
914
- if (ProtoBuf.populateAccessors)
954
+ if (T.builder.options['populateAccessors'])
915
955
  (function(field) {
916
956
  // set/get[SomeValue]
917
957
  var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
918
958
  return match.toUpperCase().replace('_','');
919
959
  });
920
- Name = Name.substring(0,1).toUpperCase()+Name.substring(1);
960
+ Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
921
961
 
922
- // set/get_[some_value]
962
+ // set/get_[some_value] FIXME: Do we really need these?
923
963
  var name = field.originalName.replace(/([A-Z])/g, function(match) {
924
964
  return "_"+match;
925
965
  });
926
966
 
967
+ /**
968
+ * The current field's unbound setter function.
969
+ * @function
970
+ * @param {*} value
971
+ * @param {boolean=} noAssert
972
+ * @returns {!ProtoBuf.Builder.Message}
973
+ * @inner
974
+ */
975
+ var setter = function(value, noAssert) {
976
+ this[field.name] = noAssert ? value : field.verifyValue(value);
977
+ return this;
978
+ };
979
+
980
+ /**
981
+ * The current field's unbound getter function.
982
+ * @function
983
+ * @returns {*}
984
+ * @inner
985
+ */
986
+ var getter = function() {
987
+ return this[field.name];
988
+ };
989
+
927
990
  /**
928
991
  * Sets a value. This method is present for each field, but only if there is no name conflict with
929
- * another field.
992
+ * another field.
930
993
  * @name ProtoBuf.Builder.Message#set[SomeField]
931
994
  * @function
932
995
  * @param {*} value Value to set
996
+ * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
997
+ * @returns {!ProtoBuf.Builder.Message} this
933
998
  * @abstract
934
999
  * @throws {Error} If the value cannot be set
935
1000
  */
936
1001
  if (T.getChild("set"+Name) === null)
937
- Message.prototype["set"+Name] = function(value) {
938
- this.$set(field.name, value);
939
- };
1002
+ MessagePrototype["set"+Name] = setter;
940
1003
 
941
1004
  /**
942
1005
  * Sets a value. This method is present for each field, but only if there is no name conflict with
943
- * another field.
1006
+ * another field.
944
1007
  * @name ProtoBuf.Builder.Message#set_[some_field]
945
1008
  * @function
946
1009
  * @param {*} value Value to set
1010
+ * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
1011
+ * @returns {!ProtoBuf.Builder.Message} this
947
1012
  * @abstract
948
1013
  * @throws {Error} If the value cannot be set
949
1014
  */
950
1015
  if (T.getChild("set_"+name) === null)
951
- Message.prototype["set_"+name] = function(value) {
952
- this.$set(field.name, value);
953
- };
1016
+ MessagePrototype["set_"+name] = setter;
954
1017
 
955
1018
  /**
956
1019
  * Gets a value. This method is present for each field, but only if there is no name conflict with
957
- * another field.
1020
+ * another field.
958
1021
  * @name ProtoBuf.Builder.Message#get[SomeField]
959
1022
  * @function
960
1023
  * @abstract
961
1024
  * @return {*} The value
962
1025
  */
963
1026
  if (T.getChild("get"+Name) === null)
964
- Message.prototype["get"+Name] = function() {
965
- return this.$get(field.name); // Does not throw, field exists
966
- };
1027
+ MessagePrototype["get"+Name] = getter;
967
1028
 
968
1029
  /**
969
1030
  * Gets a value. This method is present for each field, but only if there is no name conflict with
970
- * another field.
1031
+ * another field.
971
1032
  * @name ProtoBuf.Builder.Message#get_[some_field]
972
1033
  * @function
973
1034
  * @return {*} The value
974
1035
  * @abstract
975
1036
  */
976
1037
  if (T.getChild("get_"+name) === null)
977
- Message.prototype["get_"+name] = function() {
978
- return this.$get(field.name); // Does not throw, field exists
979
- };
1038
+ MessagePrototype["get_"+name] = getter;
980
1039
 
981
1040
  })(field);
982
1041
  }
@@ -997,7 +1056,7 @@
997
1056
  * @see ProtoBuf.Builder.Message#encodeHex
998
1057
  * @see ProtoBuf.Builder.Message#encodeAB
999
1058
  */
1000
- Message.prototype.encode = function(buffer, noVerify) {
1059
+ MessagePrototype.encode = function(buffer, noVerify) {
1001
1060
  if (typeof buffer === 'boolean')
1002
1061
  noVerify = buffer,
1003
1062
  buffer = undefined;
@@ -1023,7 +1082,7 @@
1023
1082
  * @throws {Error} If the message cannot be calculated or if required fields are missing.
1024
1083
  * @expose
1025
1084
  */
1026
- Message.prototype.calculate = function() {
1085
+ MessagePrototype.calculate = function() {
1027
1086
  return T.calculate(this);
1028
1087
  };
1029
1088
 
@@ -1037,7 +1096,7 @@
1037
1096
  * returns the encoded ByteBuffer in the `encoded` property on the error.
1038
1097
  * @expose
1039
1098
  */
1040
- Message.prototype.encodeDelimited = function(buffer) {
1099
+ MessagePrototype.encodeDelimited = function(buffer) {
1041
1100
  var isNew = false;
1042
1101
  if (!buffer)
1043
1102
  buffer = new ByteBuffer(),
@@ -1058,7 +1117,7 @@
1058
1117
  * returns the encoded ArrayBuffer in the `encoded` property on the error.
1059
1118
  * @expose
1060
1119
  */
1061
- Message.prototype.encodeAB = function() {
1120
+ MessagePrototype.encodeAB = function() {
1062
1121
  try {
1063
1122
  return this.encode().toArrayBuffer();
1064
1123
  } catch (e) {
@@ -1076,7 +1135,7 @@
1076
1135
  * returns the encoded ArrayBuffer in the `encoded` property on the error.
1077
1136
  * @expose
1078
1137
  */
1079
- Message.prototype.toArrayBuffer = Message.prototype.encodeAB;
1138
+ MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
1080
1139
 
1081
1140
  /**
1082
1141
  * Directly encodes the message to a node Buffer.
@@ -1087,7 +1146,7 @@
1087
1146
  * missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
1088
1147
  * @expose
1089
1148
  */
1090
- Message.prototype.encodeNB = function() {
1149
+ MessagePrototype.encodeNB = function() {
1091
1150
  try {
1092
1151
  return this.encode().toBuffer();
1093
1152
  } catch (e) {
@@ -1105,7 +1164,7 @@
1105
1164
  * returns the encoded node Buffer in the `encoded` property on the error.
1106
1165
  * @expose
1107
1166
  */
1108
- Message.prototype.toBuffer = Message.prototype.encodeNB;
1167
+ MessagePrototype.toBuffer = MessagePrototype.encodeNB;
1109
1168
 
1110
1169
  /**
1111
1170
  * Directly encodes the message to a base64 encoded string.
@@ -1116,7 +1175,7 @@
1116
1175
  * still returns the encoded base64 string in the `encoded` property on the error.
1117
1176
  * @expose
1118
1177
  */
1119
- Message.prototype.encode64 = function() {
1178
+ MessagePrototype.encode64 = function() {
1120
1179
  try {
1121
1180
  return this.encode().toBase64();
1122
1181
  } catch (e) {
@@ -1134,7 +1193,7 @@
1134
1193
  * returns the encoded base64 string in the `encoded` property on the error.
1135
1194
  * @expose
1136
1195
  */
1137
- Message.prototype.toBase64 = Message.prototype.encode64;
1196
+ MessagePrototype.toBase64 = MessagePrototype.encode64;
1138
1197
 
1139
1198
  /**
1140
1199
  * Directly encodes the message to a hex encoded string.
@@ -1145,7 +1204,7 @@
1145
1204
  * still returns the encoded hex string in the `encoded` property on the error.
1146
1205
  * @expose
1147
1206
  */
1148
- Message.prototype.encodeHex = function() {
1207
+ MessagePrototype.encodeHex = function() {
1149
1208
  try {
1150
1209
  return this.encode().toHex();
1151
1210
  } catch (e) {
@@ -1163,38 +1222,38 @@
1163
1222
  * returns the encoded hex string in the `encoded` property on the error.
1164
1223
  * @expose
1165
1224
  */
1166
- Message.prototype.toHex = Message.prototype.encodeHex;
1225
+ MessagePrototype.toHex = MessagePrototype.encodeHex;
1167
1226
 
1168
1227
  /**
1169
1228
  * Clones a message object to a raw object.
1170
1229
  * @param {*} obj Object to clone
1171
- * @param {boolean} includeBuffers Whether to include native buffer data or not
1230
+ * @param {boolean} includeBinaryAsBase64 Whether to include binary data as base64 strings or not
1172
1231
  * @returns {*} Cloned object
1173
1232
  * @inner
1174
1233
  */
1175
- function cloneRaw(obj, includeBuffers) {
1234
+ function cloneRaw(obj, includeBinaryAsBase64) {
1176
1235
  var clone = {};
1177
1236
  for (var i in obj)
1178
1237
  if (obj.hasOwnProperty(i)) {
1179
1238
  if (obj[i] === null || typeof obj[i] !== 'object')
1180
1239
  clone[i] = obj[i];
1181
1240
  else if (obj[i] instanceof ByteBuffer) {
1182
- if (includeBuffers)
1183
- clone[i] = obj.toBuffer();
1241
+ if (includeBinaryAsBase64)
1242
+ clone[i] = obj[i].toBase64();
1184
1243
  } else // is a non-null object
1185
- clone[i] = cloneRaw(obj[i], includeBuffers);
1244
+ clone[i] = cloneRaw(obj[i], includeBinaryAsBase64);
1186
1245
  }
1187
1246
  return clone;
1188
1247
  }
1189
1248
 
1190
1249
  /**
1191
1250
  * Returns the message's raw payload.
1192
- * @param {boolean=} includeBuffers Whether to include native buffer data or not, defaults to `false`
1251
+ * @param {boolean=} includeBinaryAsBase64 Whether to include binary data as base64 strings or not, defaults to `false`
1193
1252
  * @returns {Object.<string,*>} Raw payload
1194
1253
  * @expose
1195
1254
  */
1196
- Message.prototype.toRaw = function(includeBuffers) {
1197
- return cloneRaw(this, !!includeBuffers);
1255
+ MessagePrototype.toRaw = function(includeBinaryAsBase64) {
1256
+ return cloneRaw(this, !!includeBinaryAsBase64);
1198
1257
  };
1199
1258
 
1200
1259
  /**
@@ -1295,7 +1354,7 @@
1295
1354
  * @return {string} String representation as of ".Fully.Qualified.MessageName"
1296
1355
  * @expose
1297
1356
  */
1298
- Message.prototype.toString = function() {
1357
+ MessagePrototype.toString = function() {
1299
1358
  return T.toString();
1300
1359
  };
1301
1360
 
@@ -1319,7 +1378,7 @@
1319
1378
 
1320
1379
  if (Object.defineProperty)
1321
1380
  Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
1322
- Object.defineProperty(Message.prototype, "$type", {
1381
+ Object.defineProperty(MessagePrototype, "$type", {
1323
1382
  get: function() { return T; }
1324
1383
  });
1325
1384
 
@@ -1329,20 +1388,20 @@
1329
1388
 
1330
1389
  // Static enums and prototyped sub-messages / cached collections
1331
1390
  this._fields = [];
1332
- this._fieldsById = [];
1391
+ this._fieldsById = {};
1392
+ this._fieldsByName = {};
1333
1393
  for (var i=0, k=this.children.length, child; i<k; i++) {
1334
1394
  child = this.children[i];
1335
1395
  if (child instanceof Enum)
1336
- clazz[child['name']] = child.build();
1396
+ clazz[child.name] = child.build();
1337
1397
  else if (child instanceof Message)
1338
- clazz[child['name']] = child.build();
1398
+ clazz[child.name] = child.build();
1339
1399
  else if (child instanceof Message.Field)
1340
1400
  child.build(),
1341
1401
  this._fields.push(child),
1342
- this._fieldsById[child.id] = child;
1343
- else if (child instanceof Extension) {
1344
- // Ignore
1345
- } else
1402
+ this._fieldsById[child.id] = child,
1403
+ this._fieldsByName[child.name] = child;
1404
+ else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built
1346
1405
  throw Error("Illegal reflect child of "+this.toString(true)+": "+children[i].toString(true));
1347
1406
  }
1348
1407
 
@@ -1358,11 +1417,11 @@
1358
1417
  * @throws {Error} If required fields are missing or the message cannot be encoded for another reason
1359
1418
  * @expose
1360
1419
  */
1361
- Message.prototype.encode = function(message, buffer, noVerify) {
1420
+ MessagePrototype.encode = function(message, buffer, noVerify) {
1362
1421
  var fieldMissing = null,
1363
1422
  field;
1364
1423
  for (var i=0, k=this._fields.length, val; i<k; ++i) {
1365
- field = this.children[i];
1424
+ field = this._fields[i];
1366
1425
  val = message[field.name];
1367
1426
  if (field.required && val === null) {
1368
1427
  if (fieldMissing === null)
@@ -1385,7 +1444,7 @@
1385
1444
  * @throws {Error} If required fields are missing or the message cannot be calculated for another reason
1386
1445
  * @expose
1387
1446
  */
1388
- Message.prototype.calculate = function(message) {
1447
+ MessagePrototype.calculate = function(message) {
1389
1448
  for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {
1390
1449
  field = this._fields[i];
1391
1450
  val = message[field.name];
@@ -1447,7 +1506,7 @@
1447
1506
  * @throws {Error} If the message cannot be decoded
1448
1507
  * @expose
1449
1508
  */
1450
- Message.prototype.decode = function(buffer, length, expectedGroupEndId) {
1509
+ MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
1451
1510
  length = typeof length === 'number' ? length : -1;
1452
1511
  var start = buffer.offset,
1453
1512
  msg = new (this.clazz)(),
@@ -1487,8 +1546,14 @@
1487
1546
  }
1488
1547
  if (field.repeated && !field.options["packed"])
1489
1548
  msg[field.name].push(field.decode(wireType, buffer));
1490
- else
1549
+ else {
1491
1550
  msg[field.name] = field.decode(wireType, buffer);
1551
+ if (field.oneof) {
1552
+ if (this[field.oneof.name] !== null)
1553
+ this[this[field.oneof.name]] = null;
1554
+ msg[field.oneof.name] = field.name;
1555
+ }
1556
+ }
1492
1557
  }
1493
1558
 
1494
1559
  // Check if all required fields are present and set default values for optional fields that are not
@@ -1514,17 +1579,19 @@
1514
1579
  /**
1515
1580
  * Constructs a new Message Field.
1516
1581
  * @exports ProtoBuf.Reflect.Message.Field
1517
- * @param {ProtoBuf.Reflect.Message} message Message reference
1582
+ * @param {!ProtoBuf.Builder} builder Builder reference
1583
+ * @param {!ProtoBuf.Reflect.Message} message Message reference
1518
1584
  * @param {string} rule Rule, one of requried, optional, repeated
1519
1585
  * @param {string} type Data type, e.g. int32
1520
1586
  * @param {string} name Field name
1521
1587
  * @param {number} id Unique field id
1522
1588
  * @param {Object.<string,*>=} options Options
1589
+ * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
1523
1590
  * @constructor
1524
1591
  * @extends ProtoBuf.Reflect.T
1525
1592
  */
1526
- var Field = function(message, rule, type, name, id, options) {
1527
- T.call(this, message, name);
1593
+ var Field = function(builder, message, rule, type, name, id, options, oneof) {
1594
+ T.call(this, builder, message, name);
1528
1595
 
1529
1596
  /**
1530
1597
  * @override
@@ -1581,6 +1648,13 @@
1581
1648
  */
1582
1649
  this.defaultValue = null;
1583
1650
 
1651
+ /**
1652
+ * Enclosing OneOf.
1653
+ * @type {?ProtoBuf.Reflect.Message.OneOf}
1654
+ * @expose
1655
+ */
1656
+ this.oneof = oneof || null;
1657
+
1584
1658
  /**
1585
1659
  * Original field name.
1586
1660
  * @type {string}
@@ -1589,22 +1663,34 @@
1589
1663
  this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
1590
1664
 
1591
1665
  // Convert field names to camel case notation if the override is set
1592
- if (ProtoBuf.convertFieldsToCamelCase && !(this instanceof Message.ExtensionField)) {
1593
- this.name = this.name.replace(/_([a-zA-Z])/g, function($0, $1) {
1594
- return $1.toUpperCase();
1595
- });
1596
- }
1666
+ if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))
1667
+ this.name = Field._toCamelCase(this.name);
1597
1668
  };
1598
1669
 
1599
- // Extends T
1600
- Field.prototype = Object.create(T.prototype);
1670
+ /**
1671
+ * Converts a field name to camel case.
1672
+ * @param {string} name Likely underscore notated name
1673
+ * @returns {string} Camel case notated name
1674
+ * @private
1675
+ */
1676
+ Field._toCamelCase = function(name) {
1677
+ return name.replace(/_([a-zA-Z])/g, function($0, $1) {
1678
+ return $1.toUpperCase();
1679
+ });
1680
+ };
1681
+
1682
+ /**
1683
+ * @alias ProtoBuf.Reflect.Message.Field.prototype
1684
+ * @inner
1685
+ */
1686
+ var FieldPrototype = Field.prototype = Object.create(T.prototype);
1601
1687
 
1602
1688
  /**
1603
1689
  * Builds the field.
1604
1690
  * @override
1605
1691
  * @expose
1606
1692
  */
1607
- Field.prototype.build = function() {
1693
+ FieldPrototype.build = function() {
1608
1694
  this.defaultValue = typeof this.options['default'] !== 'undefined'
1609
1695
  ? this.verifyValue(this.options['default']) : null;
1610
1696
  };
@@ -1637,7 +1723,7 @@
1637
1723
  * @throws {Error} If the value cannot be set for this field
1638
1724
  * @expose
1639
1725
  */
1640
- Field.prototype.verifyValue = function(value, skipRepeated) {
1726
+ FieldPrototype.verifyValue = function(value, skipRepeated) {
1641
1727
  skipRepeated = skipRepeated || false;
1642
1728
  var fail = function(val, msg) {
1643
1729
  throw Error("Illegal value for "+this.toString(true)+" of type "+this.type.name+": "+val+" ("+msg+")");
@@ -1725,20 +1811,18 @@
1725
1811
 
1726
1812
  // Length-delimited bytes
1727
1813
  case ProtoBuf.TYPES["bytes"]:
1728
- return value && value instanceof ByteBuffer
1729
- ? value
1730
- : ByteBuffer.wrap(value);
1814
+ if (ByteBuffer.isByteBuffer(value))
1815
+ return value;
1816
+ return ByteBuffer.wrap(value, "base64");
1731
1817
 
1732
1818
  // Constant enum value
1733
1819
  case ProtoBuf.TYPES["enum"]: {
1734
1820
  var values = this.resolvedType.getChildren(Enum.Value);
1735
- for (i=0; i<values.length; i++) {
1736
- if (values[i].name == value) {
1821
+ for (i=0; i<values.length; i++)
1822
+ if (values[i].name == value)
1737
1823
  return values[i].id;
1738
- } else if (values[i].id == value) {
1824
+ else if (values[i].id == value)
1739
1825
  return values[i].id;
1740
- }
1741
- }
1742
1826
  fail(value, "not a valid enum value");
1743
1827
  }
1744
1828
  // Embedded message
@@ -1773,7 +1857,7 @@
1773
1857
  * @throws {Error} If the field cannot be encoded
1774
1858
  * @expose
1775
1859
  */
1776
- Field.prototype.encode = function(value, buffer) {
1860
+ FieldPrototype.encode = function(value, buffer) {
1777
1861
  if (this.type === null || typeof this.type !== 'object')
1778
1862
  throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
1779
1863
  if (value === null || (this.repeated && value.length == 0))
@@ -1825,7 +1909,7 @@
1825
1909
  * @throws {Error} If the value cannot be encoded
1826
1910
  * @expose
1827
1911
  */
1828
- Field.prototype.encodeValue = function(value, buffer) {
1912
+ FieldPrototype.encodeValue = function(value, buffer) {
1829
1913
  if (value === null) return buffer; // Nothing to encode
1830
1914
  // Tag has already been written
1831
1915
 
@@ -1946,7 +2030,7 @@
1946
2030
  * @returns {number} Byte length
1947
2031
  * @expose
1948
2032
  */
1949
- Field.prototype.calculate = function(value) {
2033
+ FieldPrototype.calculate = function(value) {
1950
2034
  value = this.verifyValue(value); // May throw
1951
2035
  if (this.type === null || typeof this.type !== 'object')
1952
2036
  throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
@@ -1985,7 +2069,7 @@
1985
2069
  * @throws {Error} If the value cannot be calculated
1986
2070
  * @expose
1987
2071
  */
1988
- Field.prototype.calculateValue = function(value) {
2072
+ FieldPrototype.calculateValue = function(value) {
1989
2073
  if (value === null) return 0; // Nothing to encode
1990
2074
  // Tag has already been written
1991
2075
  var n;
@@ -2041,7 +2125,7 @@
2041
2125
  * @throws {Error} If the field cannot be decoded
2042
2126
  * @expose
2043
2127
  */
2044
- Field.prototype.decode = function(wireType, buffer, skipRepeated) {
2128
+ FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
2045
2129
  var value, nBytes;
2046
2130
  if (wireType != this.type.wireType && (skipRepeated || (wireType != ProtoBuf.WIRE_TYPES.LDELIM || !this.repeated)))
2047
2131
  throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
@@ -2141,7 +2225,7 @@
2141
2225
 
2142
2226
  // We should never end here
2143
2227
  throw Error("[INTERNAL] Illegal wire type for "+this.toString(true)+": "+wireType);
2144
- }
2228
+ };
2145
2229
 
2146
2230
  /**
2147
2231
  * @alias ProtoBuf.Reflect.Message.Field
@@ -2152,7 +2236,8 @@
2152
2236
  /**
2153
2237
  * Constructs a new Message ExtensionField.
2154
2238
  * @exports ProtoBuf.Reflect.Message.ExtensionField
2155
- * @param {ProtoBuf.Reflect.Message} message Message reference
2239
+ * @param {!ProtoBuf.Builder} builder Builder reference
2240
+ * @param {!ProtoBuf.Reflect.Message} message Message reference
2156
2241
  * @param {string} rule Rule, one of requried, optional, repeated
2157
2242
  * @param {string} type Data type, e.g. int32
2158
2243
  * @param {string} name Field name
@@ -2161,8 +2246,8 @@
2161
2246
  * @constructor
2162
2247
  * @extends ProtoBuf.Reflect.Message.Field
2163
2248
  */
2164
- var ExtensionField = function(message, rule, type, name, id, options) {
2165
- Field.call(this, message, rule, type, name, id, options);
2249
+ var ExtensionField = function(builder, message, rule, type, name, id, options) {
2250
+ Field.call(this, builder, message, rule, type, name, id, options);
2166
2251
 
2167
2252
  /**
2168
2253
  * Extension reference.
@@ -2181,17 +2266,44 @@
2181
2266
  */
2182
2267
  Reflect.Message.ExtensionField = ExtensionField;
2183
2268
 
2269
+ /**
2270
+ * Constructs a new Message OneOf.
2271
+ * @exports ProtoBuf.Reflect.Message.OneOf
2272
+ * @param {!ProtoBuf.Builder} builder Builder reference
2273
+ * @param {!ProtoBuf.Reflect.Message} message Message reference
2274
+ * @param {string} name OneOf name
2275
+ * @constructor
2276
+ * @extends ProtoBuf.Reflect.T
2277
+ */
2278
+ var OneOf = function(builder, message, name) {
2279
+ T.call(this, builder, message, name);
2280
+
2281
+ /**
2282
+ * Enclosed fields.
2283
+ * @type {!Array.<!ProtoBuf.Reflect.Message.Field>}
2284
+ * @expose
2285
+ */
2286
+ this.fields = [];
2287
+ };
2288
+
2289
+ /**
2290
+ * @alias ProtoBuf.Reflect.Message.OneOf
2291
+ * @expose
2292
+ */
2293
+ Reflect.Message.OneOf = OneOf;
2294
+
2184
2295
  /**
2185
2296
  * Constructs a new Enum.
2186
2297
  * @exports ProtoBuf.Reflect.Enum
2298
+ * @param {!ProtoBuf.Builder} builder Builder reference
2187
2299
  * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
2188
2300
  * @param {string} name Enum name
2189
2301
  * @param {Object.<string,*>=} options Enum options
2190
2302
  * @constructor
2191
2303
  * @extends ProtoBuf.Reflect.Namespace
2192
2304
  */
2193
- var Enum = function(parent, name, options) {
2194
- Namespace.call(this, parent, name, options);
2305
+ var Enum = function(builder, parent, name, options) {
2306
+ Namespace.call(this, builder, parent, name, options);
2195
2307
 
2196
2308
  /**
2197
2309
  * @override
@@ -2206,15 +2318,18 @@
2206
2318
  this.object = null;
2207
2319
  };
2208
2320
 
2209
- // Extends Namespace
2210
- Enum.prototype = Object.create(Namespace.prototype);
2321
+ /**
2322
+ * @alias ProtoBuf.Reflect.Enum.prototype
2323
+ * @inner
2324
+ */
2325
+ var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
2211
2326
 
2212
2327
  /**
2213
2328
  * Builds this enum and returns the runtime counterpart.
2214
2329
  * @return {Object<string,*>}
2215
2330
  * @expose
2216
2331
  */
2217
- Enum.prototype.build = function() {
2332
+ EnumPrototype.build = function() {
2218
2333
  var enm = {},
2219
2334
  values = this.getChildren(Enum.Value);
2220
2335
  for (var i=0, k=values.length; i<k; ++i)
@@ -2233,14 +2348,15 @@
2233
2348
  /**
2234
2349
  * Constructs a new Enum Value.
2235
2350
  * @exports ProtoBuf.Reflect.Enum.Value
2351
+ * @param {!ProtoBuf.Builder} builder Builder reference
2236
2352
  * @param {!ProtoBuf.Reflect.Enum} enm Enum reference
2237
2353
  * @param {string} name Field name
2238
2354
  * @param {number} id Unique field id
2239
2355
  * @constructor
2240
2356
  * @extends ProtoBuf.Reflect.T
2241
2357
  */
2242
- var Value = function(enm, name, id) {
2243
- T.call(this, enm, name);
2358
+ var Value = function(builder, enm, name, id) {
2359
+ T.call(this, builder, enm, name);
2244
2360
 
2245
2361
  /**
2246
2362
  * @override
@@ -2268,12 +2384,13 @@
2268
2384
  * An extension (field).
2269
2385
  * @exports ProtoBuf.Reflect.Extension
2270
2386
  * @constructor
2271
- * @param {ProtoBuf.Reflect.T} parent Parent object
2387
+ * @param {!ProtoBuf.Builder} builder Builder reference
2388
+ * @param {!ProtoBuf.Reflect.T} parent Parent object
2272
2389
  * @param {string} name Object name
2273
2390
  * @param {!ProtoBuf.Reflect.Message.Field} field Extension field
2274
2391
  */
2275
- var Extension = function(parent, name, field) {
2276
- T.call(this, parent, name);
2392
+ var Extension = function(builder, parent, name, field) {
2393
+ T.call(this, builder, parent, name);
2277
2394
 
2278
2395
  /**
2279
2396
  * Extended message field.
@@ -2295,14 +2412,15 @@
2295
2412
  /**
2296
2413
  * Constructs a new Service.
2297
2414
  * @exports ProtoBuf.Reflect.Service
2415
+ * @param {!ProtoBuf.Builder} builder Builder reference
2298
2416
  * @param {!ProtoBuf.Reflect.Namespace} root Root
2299
2417
  * @param {string} name Service name
2300
2418
  * @param {Object.<string,*>=} options Options
2301
2419
  * @constructor
2302
2420
  * @extends ProtoBuf.Reflect.Namespace
2303
2421
  */
2304
- var Service = function(root, name, options) {
2305
- Namespace.call(this, root, name, options);
2422
+ var Service = function(builder, root, name, options) {
2423
+ Namespace.call(this, builder, root, name, options);
2306
2424
 
2307
2425
  /**
2308
2426
  * @override
@@ -2316,8 +2434,11 @@
2316
2434
  this.clazz = null;
2317
2435
  };
2318
2436
 
2319
- // Extends Namespace
2320
- Service.prototype = Object.create(Namespace.prototype);
2437
+ /**
2438
+ * @alias ProtoBuf.Reflect.Service.prototype
2439
+ * @inner
2440
+ */
2441
+ var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
2321
2442
 
2322
2443
  /**
2323
2444
  * Builds the service and returns the runtime counterpart, which is a fully functional class.
@@ -2327,7 +2448,7 @@
2327
2448
  * @throws {Error} If the message cannot be built
2328
2449
  * @expose
2329
2450
  */
2330
- Service.prototype.build = function(rebuild) {
2451
+ ServicePrototype.build = function(rebuild) {
2331
2452
  if (this.clazz && !rebuild)
2332
2453
  return this.clazz;
2333
2454
 
@@ -2359,12 +2480,15 @@
2359
2480
  };
2360
2481
  };
2361
2482
 
2362
- // Extends ProtoBuf.Builder.Service
2363
- Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
2483
+ /**
2484
+ * @alias ProtoBuf.Builder.Service.prototype
2485
+ * @inner
2486
+ */
2487
+ var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
2364
2488
 
2365
2489
  if (Object.defineProperty)
2366
2490
  Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
2367
- Object.defineProperty(Service.prototype, "$options", { "value": Service["$options"] });
2491
+ Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] });
2368
2492
 
2369
2493
  /**
2370
2494
  * Asynchronously performs an RPC call using the given RPC implementation.
@@ -2392,7 +2516,7 @@
2392
2516
  (function(method) {
2393
2517
 
2394
2518
  // service#Method(message, callback)
2395
- Service.prototype[method.name] = function(req, callback) {
2519
+ ServicePrototype[method.name] = function(req, callback) {
2396
2520
  try {
2397
2521
  if (!req || !(req instanceof method.resolvedRequestType.clazz)) {
2398
2522
  setTimeout(callback.bind(this, Error("Illegal request type provided to service method "+T.name+"#"+method.name)), 0);
@@ -2422,7 +2546,7 @@
2422
2546
 
2423
2547
  if (Object.defineProperty)
2424
2548
  Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
2425
- Object.defineProperty(Service.prototype[method.name], "$options", { "value": Service[method.name]["$options"] });
2549
+ Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
2426
2550
  })(rpc[i]);
2427
2551
  }
2428
2552
 
@@ -2440,14 +2564,15 @@
2440
2564
  /**
2441
2565
  * Abstract service method.
2442
2566
  * @exports ProtoBuf.Reflect.Service.Method
2567
+ * @param {!ProtoBuf.Builder} builder Builder reference
2443
2568
  * @param {!ProtoBuf.Reflect.Service} svc Service
2444
2569
  * @param {string} name Method name
2445
2570
  * @param {Object.<string,*>=} options Options
2446
2571
  * @constructor
2447
2572
  * @extends ProtoBuf.Reflect.T
2448
2573
  */
2449
- var Method = function(svc, name, options) {
2450
- T.call(this, svc, name);
2574
+ var Method = function(builder, svc, name, options) {
2575
+ T.call(this, builder, svc, name);
2451
2576
 
2452
2577
  /**
2453
2578
  * @override
@@ -2462,8 +2587,11 @@
2462
2587
  this.options = options || {};
2463
2588
  };
2464
2589
 
2465
- // Extends T
2466
- Method.prototype = Object.create(T.prototype);
2590
+ /**
2591
+ * @alias ProtoBuf.Reflect.Service.Method.prototype
2592
+ * @inner
2593
+ */
2594
+ var MethodPrototype = Method.prototype = Object.create(T.prototype);
2467
2595
 
2468
2596
  /**
2469
2597
  * Builds the method's '$options' property.
@@ -2471,7 +2599,7 @@
2471
2599
  * @function
2472
2600
  * @return {Object.<string,*>}
2473
2601
  */
2474
- Method.prototype.buildOpt = Namespace.prototype.buildOpt;
2602
+ MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
2475
2603
 
2476
2604
  /**
2477
2605
  * @alias ProtoBuf.Reflect.Service.Method
@@ -2482,6 +2610,7 @@
2482
2610
  /**
2483
2611
  * RPC service method.
2484
2612
  * @exports ProtoBuf.Reflect.Service.RPCMethod
2613
+ * @param {!ProtoBuf.Builder} builder Builder reference
2485
2614
  * @param {!ProtoBuf.Reflect.Service} svc Service
2486
2615
  * @param {string} name Method name
2487
2616
  * @param {string} request Request message name
@@ -2490,8 +2619,8 @@
2490
2619
  * @constructor
2491
2620
  * @extends ProtoBuf.Reflect.Service.Method
2492
2621
  */
2493
- var RPCMethod = function(svc, name, request, response, options) {
2494
- Method.call(this, svc, name, options);
2622
+ var RPCMethod = function(builder, svc, name, request, response, options) {
2623
+ Method.call(this, builder, svc, name, options);
2495
2624
 
2496
2625
  /**
2497
2626
  * @override
@@ -2537,6 +2666,7 @@
2537
2666
  Reflect.Service.RPCMethod = RPCMethod;
2538
2667
 
2539
2668
  return Reflect;
2669
+
2540
2670
  })(ProtoBuf);
2541
2671
 
2542
2672
  /**
@@ -2550,16 +2680,17 @@
2550
2680
  * Constructs a new Builder.
2551
2681
  * @exports ProtoBuf.Builder
2552
2682
  * @class Provides the functionality to build protocol messages.
2683
+ * @param {Object.<string,*>=} options Options
2553
2684
  * @constructor
2554
2685
  */
2555
- var Builder = function() {
2686
+ var Builder = function(options) {
2556
2687
 
2557
2688
  /**
2558
2689
  * Namespace.
2559
2690
  * @type {ProtoBuf.Reflect.Namespace}
2560
2691
  * @expose
2561
2692
  */
2562
- this.ns = new Reflect.Namespace(null, ""); // Global namespace
2693
+ this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
2563
2694
 
2564
2695
  /**
2565
2696
  * Namespace pointer.
@@ -2595,13 +2726,26 @@
2595
2726
  * @expose
2596
2727
  */
2597
2728
  this.importRoot = null;
2729
+
2730
+ /**
2731
+ * Options.
2732
+ * @type {!Object.<string, *>}
2733
+ * @expose
2734
+ */
2735
+ this.options = options || {};
2598
2736
  };
2599
2737
 
2738
+ /**
2739
+ * @alias ProtoBuf.Builder.prototype
2740
+ * @inner
2741
+ */
2742
+ var BuilderPrototype = Builder.prototype;
2743
+
2600
2744
  /**
2601
2745
  * Resets the pointer to the root namespace.
2602
2746
  * @expose
2603
2747
  */
2604
- Builder.prototype.reset = function() {
2748
+ BuilderPrototype.reset = function() {
2605
2749
  this.ptr = this.ns;
2606
2750
  };
2607
2751
 
@@ -2613,7 +2757,7 @@
2613
2757
  * @throws {Error} If the package name is invalid
2614
2758
  * @expose
2615
2759
  */
2616
- Builder.prototype.define = function(pkg, options) {
2760
+ BuilderPrototype.define = function(pkg, options) {
2617
2761
  if (typeof pkg !== 'string' || !Lang.TYPEREF.test(pkg))
2618
2762
  throw Error("Illegal package: "+pkg);
2619
2763
  var part = pkg.split("."), i;
@@ -2622,7 +2766,7 @@
2622
2766
  throw Error("Illegal package: "+part[i]);
2623
2767
  for (i=0; i<part.length; i++) {
2624
2768
  if (this.ptr.getChild(part[i]) === null) // Keep existing namespace
2625
- this.ptr.addChild(new Reflect.Namespace(this.ptr, part[i], options));
2769
+ this.ptr.addChild(new Reflect.Namespace(this, this.ptr, part[i], options));
2626
2770
  this.ptr = this.ptr.getChild(part[i]);
2627
2771
  }
2628
2772
  return this;
@@ -2736,7 +2880,7 @@
2736
2880
  * @throws {Error} If a message definition is invalid
2737
2881
  * @expose
2738
2882
  */
2739
- Builder.prototype.create = function(defs) {
2883
+ BuilderPrototype.create = function(defs) {
2740
2884
  if (!defs)
2741
2885
  return this; // Nothing to create
2742
2886
  if (!ProtoBuf.Util.isArray(defs))
@@ -2745,35 +2889,51 @@
2745
2889
  return this;
2746
2890
 
2747
2891
  // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
2748
- var stack = [], def, obj, subObj, i, j;
2892
+ var stack = [];
2749
2893
  stack.push(defs); // One level [a, b, c]
2750
2894
  while (stack.length > 0) {
2751
2895
  defs = stack.pop();
2752
2896
  if (ProtoBuf.Util.isArray(defs)) { // Stack always contains entire namespaces
2753
2897
  while (defs.length > 0) {
2754
- def = defs.shift(); // Namespace always contains an array of messages, enums and services
2898
+ var def = defs.shift(); // Namespace always contains an array of messages, enums and services
2755
2899
  if (Builder.isValidMessage(def)) {
2756
- obj = new Reflect.Message(this.ptr, def["name"], def["options"], def["isGroup"]);
2900
+ var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"]);
2901
+ // Create OneOfs
2902
+ var oneofs = {};
2903
+ if (def["oneofs"]) {
2904
+ var keys = Object.keys(def["oneofs"]);
2905
+ for (var i=0, k=keys.length; i<k; ++i)
2906
+ obj.addChild(oneofs[keys[i]] = new Reflect.Message.OneOf(this, obj, keys[i]));
2907
+ }
2757
2908
  // Create fields
2758
2909
  if (def["fields"] && def["fields"].length > 0) {
2759
- for (i=0; i<def["fields"].length; i++) { // i=Fields
2760
- if (obj.getChild(def['fields'][i]['id']) !== null)
2761
- throw Error("Duplicate field id in message "+obj.name+": "+def['fields'][i]['id']);
2762
- if (def["fields"][i]["options"]) {
2763
- subObj = Object.keys(def["fields"][i]["options"]);
2764
- for (j=0; j<subObj.length; j++) { // j=Option names
2765
- if (typeof subObj[j] !== 'string')
2766
- throw Error("Illegal field option name in message "+obj.name+"#"+def["fields"][i]["name"]+": "+subObj[j]);
2767
- if (typeof def["fields"][i]["options"][subObj[j]] !== 'string' && typeof def["fields"][i]["options"][subObj[j]] !== 'number' && typeof def["fields"][i]["options"][subObj[j]] !== 'boolean')
2768
- throw Error("Illegal field option value in message "+obj.name+"#"+def["fields"][i]["name"]+"#"+subObj[j]+": "+def["fields"][i]["options"][subObj[j]]);
2910
+ for (i=0, k=def["fields"].length; i<k; ++i) { // i:k=Fields
2911
+ var fld = def['fields'][i];
2912
+ if (obj.getChild(fld['id']) !== null)
2913
+ throw Error("Duplicate field id in message "+obj.name+": "+fld['id']);
2914
+ if (fld["options"]) {
2915
+ var opts = Object.keys(fld["options"]);
2916
+ for (var j= 0,l=opts.length; j<l; ++j) { // j:l=Option names
2917
+ if (typeof opts[j] !== 'string')
2918
+ throw Error("Illegal field option name in message "+obj.name+"#"+fld["name"]+": "+opts[j]);
2919
+ if (typeof fld["options"][opts[j]] !== 'string' && typeof fld["options"][opts[j]] !== 'number' && typeof fld["options"][opts[j]] !== 'boolean')
2920
+ throw Error("Illegal field option value in message "+obj.name+"#"+fld["name"]+"#"+opts[j]+": "+fld["options"][opts[j]]);
2769
2921
  }
2770
- subObj = null;
2771
2922
  }
2772
- 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"]));
2923
+ var oneof = null;
2924
+ if (typeof fld["oneof"] === 'string') {
2925
+ oneof = oneofs[fld["oneof"]];
2926
+ if (typeof oneof === 'undefined')
2927
+ throw Error("Illegal oneof in message "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
2928
+ }
2929
+ fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["type"], fld["name"], fld["id"], fld["options"], oneof);
2930
+ if (oneof)
2931
+ oneof.fields.push(fld);
2932
+ obj.addChild(fld);
2773
2933
  }
2774
2934
  }
2775
2935
  // Push enums and messages to stack
2776
- subObj = [];
2936
+ var subObj = [];
2777
2937
  if (typeof def["enums"] !== 'undefined' && def['enums'].length > 0)
2778
2938
  for (i=0; i<def["enums"].length; i++)
2779
2939
  subObj.push(def["enums"][i]);
@@ -2800,16 +2960,16 @@
2800
2960
  subObj = null;
2801
2961
  obj = null;
2802
2962
  } else if (Builder.isValidEnum(def)) {
2803
- obj = new Reflect.Enum(this.ptr, def["name"], def["options"]);
2963
+ obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"]);
2804
2964
  for (i=0; i<def["values"].length; i++)
2805
- obj.addChild(new Reflect.Enum.Value(obj, def["values"][i]["name"], def["values"][i]["id"]));
2965
+ obj.addChild(new Reflect.Enum.Value(this, obj, def["values"][i]["name"], def["values"][i]["id"]));
2806
2966
  this.ptr.addChild(obj);
2807
2967
  obj = null;
2808
2968
  } else if (Builder.isValidService(def)) {
2809
- obj = new Reflect.Service(this.ptr, def["name"], def["options"]);
2969
+ obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
2810
2970
  for (i in def["rpc"])
2811
2971
  if (def["rpc"].hasOwnProperty(i))
2812
- obj.addChild(new Reflect.Service.RPCMethod(obj, i, def["rpc"][i]["request"], def["rpc"][i]["response"], def["rpc"][i]["options"]));
2972
+ obj.addChild(new Reflect.Service.RPCMethod(this, obj, i, def["rpc"][i]["request"], def["rpc"][i]["response"], def["rpc"][i]["options"]));
2813
2973
  this.ptr.addChild(obj);
2814
2974
  obj = null;
2815
2975
  } else if (Builder.isValidExtend(def)) {
@@ -2820,10 +2980,16 @@
2820
2980
  throw Error("Duplicate extended field id in message "+obj.name+": "+def['fields'][i]['id']);
2821
2981
  if (def['fields'][i]['id'] < obj.extensions[0] || def['fields'][i]['id'] > obj.extensions[1])
2822
2982
  throw Error("Illegal extended field id in message "+obj.name+": "+def['fields'][i]['id']+" ("+obj.extensions.join(' to ')+" expected)");
2983
+ // Convert extension field names to camel case notation if the override is set
2984
+ var name = def["fields"][i]["name"];
2985
+ if (this.options['convertFieldsToCamelCase'])
2986
+ name = Reflect.Message.Field._toCamelCase(def["fields"][i]["name"]);
2823
2987
  // see #161: Extensions use their fully qualified name as their runtime key and...
2824
- 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"]);
2825
- // ...are added on top of the current namespace as an extension which is used for resolving their type later on
2826
- var ext = new Reflect.Extension(this.ptr, def["fields"][i]["name"], fld);
2988
+ 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"]);
2989
+ // ...are added on top of the current namespace as an extension which is used for
2990
+ // resolving their type later on (the extension always keeps the original name to
2991
+ // prevent naming collisions)
2992
+ var ext = new Reflect.Extension(this, this.ptr, def["fields"][i]["name"], fld);
2827
2993
  fld.extension = ext;
2828
2994
  this.ptr.addChild(ext);
2829
2995
  obj.addChild(fld);
@@ -2853,7 +3019,7 @@
2853
3019
  * @throws {Error} If the definition or file cannot be imported
2854
3020
  * @expose
2855
3021
  */
2856
- Builder.prototype["import"] = function(json, filename) {
3022
+ BuilderPrototype["import"] = function(json, filename) {
2857
3023
  if (typeof filename === 'string') {
2858
3024
  if (ProtoBuf.Util.IS_NODE)
2859
3025
  filename = require("path")['resolve'](filename);
@@ -2987,7 +3153,7 @@
2987
3153
  * @throws {Error} If a type cannot be resolved
2988
3154
  * @expose
2989
3155
  */
2990
- Builder.prototype.resolveAll = function() {
3156
+ BuilderPrototype.resolveAll = function() {
2991
3157
  // Resolve all reflected objects
2992
3158
  var res;
2993
3159
  if (this.ptr == null || typeof this.ptr.type === 'object')
@@ -3030,9 +3196,7 @@
3030
3196
  // Should not happen as nothing else is implemented
3031
3197
  throw Error("Illegal service type in "+this.ptr.toString(true));
3032
3198
  }
3033
- } else if (this.ptr instanceof ProtoBuf.Reflect.Extension) {
3034
- // There are no runtime counterparts to extensions
3035
- } else
3199
+ } else if (!(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && !(this.ptr instanceof ProtoBuf.Reflect.Extension))
3036
3200
  throw Error("Illegal object in namespace: "+typeof(this.ptr)+":"+this.ptr);
3037
3201
  this.reset();
3038
3202
  };
@@ -3045,7 +3209,7 @@
3045
3209
  * @throws {Error} If a type could not be resolved
3046
3210
  * @expose
3047
3211
  */
3048
- Builder.prototype.build = function(path) {
3212
+ BuilderPrototype.build = function(path) {
3049
3213
  this.reset();
3050
3214
  if (!this.resolved)
3051
3215
  this.resolveAll(),
@@ -3074,7 +3238,7 @@
3074
3238
  * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
3075
3239
  * @return {ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
3076
3240
  */
3077
- Builder.prototype.lookup = function(path) {
3241
+ BuilderPrototype.lookup = function(path) {
3078
3242
  return path ? this.ns.resolve(path) : this.ns;
3079
3243
  };
3080
3244
 
@@ -3083,7 +3247,7 @@
3083
3247
  * @return {string} String representation as of "Builder"
3084
3248
  * @expose
3085
3249
  */
3086
- Builder.prototype.toString = function() {
3250
+ BuilderPrototype.toString = function() {
3087
3251
  return "Builder";
3088
3252
  };
3089
3253
 
@@ -3098,18 +3262,18 @@
3098
3262
 
3099
3263
 
3100
3264
  /**
3101
- * Constructs a new Builder with the specified package defined.
3102
- * @param {string=} pkg Package name as fully qualified name, e.g. "My.Game". If no package is specified, the
3103
- * builder will only contain a global namespace.
3104
- * @param {Object.<string,*>=} options Top level options
3105
- * @return {ProtoBuf.Builder} New Builder
3265
+ * Constructs a new empty Builder.
3266
+ * @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf
3267
+ * @return {!ProtoBuf.Builder} Builder
3106
3268
  * @expose
3107
3269
  */
3108
- ProtoBuf.newBuilder = function(pkg, options) {
3109
- var builder = new ProtoBuf.Builder();
3110
- if (typeof pkg !== 'undefined' && pkg !== null)
3111
- builder.define(pkg, options);
3112
- return builder;
3270
+ ProtoBuf.newBuilder = function(options) {
3271
+ options = options || {};
3272
+ if (typeof options['convertFieldsToCamelCase'] === 'undefined')
3273
+ options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
3274
+ if (typeof options['populateAccessors'] === 'undefined')
3275
+ options['populateAccessors'] = ProtoBuf.populateAccessors;
3276
+ return new ProtoBuf.Builder(options);
3113
3277
  };
3114
3278
 
3115
3279
  /**
@@ -3131,7 +3295,6 @@
3131
3295
  json = JSON.parse(json);
3132
3296
  builder["import"](json, filename);
3133
3297
  builder.resolveAll();
3134
- builder.build();
3135
3298
  return builder;
3136
3299
  };
3137
3300
 
@@ -3172,8 +3335,8 @@
3172
3335
  return ProtoBuf;
3173
3336
  }
3174
3337
 
3175
- /* CommonJS */ if (typeof module !== 'undefined' && module["exports"])
3176
- module["exports"] = init(require("bytebuffer"));
3338
+ /* CommonJS */ if (typeof require === 'function' && typeof module === 'object' && module && typeof exports === 'object' && exports)
3339
+ module['exports'] = init(require("bytebuffer"));
3177
3340
  /* AMD */ else if (typeof define === 'function' && define["amd"])
3178
3341
  define(["ByteBuffer"], init);
3179
3342
  /* Global */ else