Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / node_modules / protobufjs / dist / protobuf-light.js
1 /*\r
2  Copyright 2013 Daniel Wirtz <dcode@dcode.io>\r
3 \r
4  Licensed under the Apache License, Version 2.0 (the "License");\r
5  you may not use this file except in compliance with the License.\r
6  You may obtain a copy of the License at\r
7 \r
8  http://www.apache.org/licenses/LICENSE-2.0\r
9 \r
10  Unless required by applicable law or agreed to in writing, software\r
11  distributed under the License is distributed on an "AS IS" BASIS,\r
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  See the License for the specific language governing permissions and\r
14  limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * @license protobuf.js (c) 2013 Daniel Wirtz <dcode@dcode.io>\r
19  * Released under the Apache License, Version 2.0\r
20  * see: https://github.com/dcodeIO/protobuf.js for details\r
21  */\r
22 (function(global, factory) {\r
23 \r
24     /* AMD */ if (typeof define === 'function' && define["amd"])\r
25         define(["bytebuffer"], factory);\r
26     /* CommonJS */ else if (typeof require === "function" && typeof module === "object" && module && module["exports"])\r
27         module["exports"] = factory(require("bytebuffer"), true);\r
28     /* Global */ else\r
29         (global["dcodeIO"] = global["dcodeIO"] || {})["ProtoBuf"] = factory(global["dcodeIO"]["ByteBuffer"]);\r
30 \r
31 })(this, function(ByteBuffer, isCommonJS) {\r
32     "use strict";\r
33 \r
34     /**\r
35      * The ProtoBuf namespace.\r
36      * @exports ProtoBuf\r
37      * @namespace\r
38      * @expose\r
39      */\r
40     var ProtoBuf = {};\r
41 \r
42     /**\r
43      * @type {!function(new: ByteBuffer, ...[*])}\r
44      * @expose\r
45      */\r
46     ProtoBuf.ByteBuffer = ByteBuffer;\r
47 \r
48     /**\r
49      * @type {?function(new: Long, ...[*])}\r
50      * @expose\r
51      */\r
52     ProtoBuf.Long = ByteBuffer.Long || null;\r
53 \r
54     /**\r
55      * ProtoBuf.js version.\r
56      * @type {string}\r
57      * @const\r
58      * @expose\r
59      */\r
60     ProtoBuf.VERSION = "5.0.3";\r
61 \r
62     /**\r
63      * Wire types.\r
64      * @type {Object.<string,number>}\r
65      * @const\r
66      * @expose\r
67      */\r
68     ProtoBuf.WIRE_TYPES = {};\r
69 \r
70     /**\r
71      * Varint wire type.\r
72      * @type {number}\r
73      * @expose\r
74      */\r
75     ProtoBuf.WIRE_TYPES.VARINT = 0;\r
76 \r
77     /**\r
78      * Fixed 64 bits wire type.\r
79      * @type {number}\r
80      * @const\r
81      * @expose\r
82      */\r
83     ProtoBuf.WIRE_TYPES.BITS64 = 1;\r
84 \r
85     /**\r
86      * Length delimited wire type.\r
87      * @type {number}\r
88      * @const\r
89      * @expose\r
90      */\r
91     ProtoBuf.WIRE_TYPES.LDELIM = 2;\r
92 \r
93     /**\r
94      * Start group wire type.\r
95      * @type {number}\r
96      * @const\r
97      * @expose\r
98      */\r
99     ProtoBuf.WIRE_TYPES.STARTGROUP = 3;\r
100 \r
101     /**\r
102      * End group wire type.\r
103      * @type {number}\r
104      * @const\r
105      * @expose\r
106      */\r
107     ProtoBuf.WIRE_TYPES.ENDGROUP = 4;\r
108 \r
109     /**\r
110      * Fixed 32 bits wire type.\r
111      * @type {number}\r
112      * @const\r
113      * @expose\r
114      */\r
115     ProtoBuf.WIRE_TYPES.BITS32 = 5;\r
116 \r
117     /**\r
118      * Packable wire types.\r
119      * @type {!Array.<number>}\r
120      * @const\r
121      * @expose\r
122      */\r
123     ProtoBuf.PACKABLE_WIRE_TYPES = [\r
124         ProtoBuf.WIRE_TYPES.VARINT,\r
125         ProtoBuf.WIRE_TYPES.BITS64,\r
126         ProtoBuf.WIRE_TYPES.BITS32\r
127     ];\r
128 \r
129     /**\r
130      * Types.\r
131      * @dict\r
132      * @type {!Object.<string,{name: string, wireType: number, defaultValue: *}>}\r
133      * @const\r
134      * @expose\r
135      */\r
136     ProtoBuf.TYPES = {\r
137         // According to the protobuf spec.\r
138         "int32": {\r
139             name: "int32",\r
140             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
141             defaultValue: 0\r
142         },\r
143         "uint32": {\r
144             name: "uint32",\r
145             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
146             defaultValue: 0\r
147         },\r
148         "sint32": {\r
149             name: "sint32",\r
150             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
151             defaultValue: 0\r
152         },\r
153         "int64": {\r
154             name: "int64",\r
155             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
156             defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined\r
157         },\r
158         "uint64": {\r
159             name: "uint64",\r
160             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
161             defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined\r
162         },\r
163         "sint64": {\r
164             name: "sint64",\r
165             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
166             defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined\r
167         },\r
168         "bool": {\r
169             name: "bool",\r
170             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
171             defaultValue: false\r
172         },\r
173         "double": {\r
174             name: "double",\r
175             wireType: ProtoBuf.WIRE_TYPES.BITS64,\r
176             defaultValue: 0\r
177         },\r
178         "string": {\r
179             name: "string",\r
180             wireType: ProtoBuf.WIRE_TYPES.LDELIM,\r
181             defaultValue: ""\r
182         },\r
183         "bytes": {\r
184             name: "bytes",\r
185             wireType: ProtoBuf.WIRE_TYPES.LDELIM,\r
186             defaultValue: null // overridden in the code, must be a unique instance\r
187         },\r
188         "fixed32": {\r
189             name: "fixed32",\r
190             wireType: ProtoBuf.WIRE_TYPES.BITS32,\r
191             defaultValue: 0\r
192         },\r
193         "sfixed32": {\r
194             name: "sfixed32",\r
195             wireType: ProtoBuf.WIRE_TYPES.BITS32,\r
196             defaultValue: 0\r
197         },\r
198         "fixed64": {\r
199             name: "fixed64",\r
200             wireType: ProtoBuf.WIRE_TYPES.BITS64,\r
201             defaultValue:  ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined\r
202         },\r
203         "sfixed64": {\r
204             name: "sfixed64",\r
205             wireType: ProtoBuf.WIRE_TYPES.BITS64,\r
206             defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined\r
207         },\r
208         "float": {\r
209             name: "float",\r
210             wireType: ProtoBuf.WIRE_TYPES.BITS32,\r
211             defaultValue: 0\r
212         },\r
213         "enum": {\r
214             name: "enum",\r
215             wireType: ProtoBuf.WIRE_TYPES.VARINT,\r
216             defaultValue: 0\r
217         },\r
218         "message": {\r
219             name: "message",\r
220             wireType: ProtoBuf.WIRE_TYPES.LDELIM,\r
221             defaultValue: null\r
222         },\r
223         "group": {\r
224             name: "group",\r
225             wireType: ProtoBuf.WIRE_TYPES.STARTGROUP,\r
226             defaultValue: null\r
227         }\r
228     };\r
229 \r
230     /**\r
231      * Valid map key types.\r
232      * @type {!Array.<!Object.<string,{name: string, wireType: number, defaultValue: *}>>}\r
233      * @const\r
234      * @expose\r
235      */\r
236     ProtoBuf.MAP_KEY_TYPES = [\r
237         ProtoBuf.TYPES["int32"],\r
238         ProtoBuf.TYPES["sint32"],\r
239         ProtoBuf.TYPES["sfixed32"],\r
240         ProtoBuf.TYPES["uint32"],\r
241         ProtoBuf.TYPES["fixed32"],\r
242         ProtoBuf.TYPES["int64"],\r
243         ProtoBuf.TYPES["sint64"],\r
244         ProtoBuf.TYPES["sfixed64"],\r
245         ProtoBuf.TYPES["uint64"],\r
246         ProtoBuf.TYPES["fixed64"],\r
247         ProtoBuf.TYPES["bool"],\r
248         ProtoBuf.TYPES["string"],\r
249         ProtoBuf.TYPES["bytes"]\r
250     ];\r
251 \r
252     /**\r
253      * Minimum field id.\r
254      * @type {number}\r
255      * @const\r
256      * @expose\r
257      */\r
258     ProtoBuf.ID_MIN = 1;\r
259 \r
260     /**\r
261      * Maximum field id.\r
262      * @type {number}\r
263      * @const\r
264      * @expose\r
265      */\r
266     ProtoBuf.ID_MAX = 0x1FFFFFFF;\r
267 \r
268     /**\r
269      * If set to `true`, field names will be converted from underscore notation to camel case. Defaults to `false`.\r
270      *  Must be set prior to parsing.\r
271      * @type {boolean}\r
272      * @expose\r
273      */\r
274     ProtoBuf.convertFieldsToCamelCase = false;\r
275 \r
276     /**\r
277      * By default, messages are populated with (setX, set_x) accessors for each field. This can be disabled by\r
278      *  setting this to `false` prior to building messages.\r
279      * @type {boolean}\r
280      * @expose\r
281      */\r
282     ProtoBuf.populateAccessors = true;\r
283 \r
284     /**\r
285      * By default, messages are populated with default values if a field is not present on the wire. To disable\r
286      *  this behavior, set this setting to `false`.\r
287      * @type {boolean}\r
288      * @expose\r
289      */\r
290     ProtoBuf.populateDefaults = true;\r
291 \r
292     /**\r
293      * @alias ProtoBuf.Util\r
294      * @expose\r
295      */\r
296     ProtoBuf.Util = (function() {\r
297         "use strict";\r
298 \r
299         /**\r
300          * ProtoBuf utilities.\r
301          * @exports ProtoBuf.Util\r
302          * @namespace\r
303          */\r
304         var Util = {};\r
305 \r
306         /**\r
307          * Flag if running in node or not.\r
308          * @type {boolean}\r
309          * @const\r
310          * @expose\r
311          */\r
312         Util.IS_NODE = !!(\r
313             typeof process === 'object' && process+'' === '[object process]' && !process['browser']\r
314         );\r
315 \r
316         /**\r
317          * Constructs a XMLHttpRequest object.\r
318          * @return {XMLHttpRequest}\r
319          * @throws {Error} If XMLHttpRequest is not supported\r
320          * @expose\r
321          */\r
322         Util.XHR = function() {\r
323             // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html\r
324             var XMLHttpFactories = [\r
325                 function () {return new XMLHttpRequest()},\r
326                 function () {return new ActiveXObject("Msxml2.XMLHTTP")},\r
327                 function () {return new ActiveXObject("Msxml3.XMLHTTP")},\r
328                 function () {return new ActiveXObject("Microsoft.XMLHTTP")}\r
329             ];\r
330             /** @type {?XMLHttpRequest} */\r
331             var xhr = null;\r
332             for (var i=0;i<XMLHttpFactories.length;i++) {\r
333                 try { xhr = XMLHttpFactories[i](); }\r
334                 catch (e) { continue; }\r
335                 break;\r
336             }\r
337             if (!xhr)\r
338                 throw Error("XMLHttpRequest is not supported");\r
339             return xhr;\r
340         };\r
341 \r
342         /**\r
343          * Fetches a resource.\r
344          * @param {string} path Resource path\r
345          * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will\r
346          *   be fetched synchronously. If the request failed, contents will be null.\r
347          * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.\r
348          * @expose\r
349          */\r
350         Util.fetch = function(path, callback) {\r
351             if (callback && typeof callback != 'function')\r
352                 callback = null;\r
353             if (Util.IS_NODE) {\r
354                 var fs = require("fs");\r
355                 if (callback) {\r
356                     fs.readFile(path, function(err, data) {\r
357                         if (err)\r
358                             callback(null);\r
359                         else\r
360                             callback(""+data);\r
361                     });\r
362                 } else\r
363                     try {\r
364                         return fs.readFileSync(path);\r
365                     } catch (e) {\r
366                         return null;\r
367                     }\r
368             } else {\r
369                 var xhr = Util.XHR();\r
370                 xhr.open('GET', path, callback ? true : false);\r
371                 // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');\r
372                 xhr.setRequestHeader('Accept', 'text/plain');\r
373                 if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');\r
374                 if (callback) {\r
375                     xhr.onreadystatechange = function() {\r
376                         if (xhr.readyState != 4) return;\r
377                         if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))\r
378                             callback(xhr.responseText);\r
379                         else\r
380                             callback(null);\r
381                     };\r
382                     if (xhr.readyState == 4)\r
383                         return;\r
384                     xhr.send(null);\r
385                 } else {\r
386                     xhr.send(null);\r
387                     if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))\r
388                         return xhr.responseText;\r
389                     return null;\r
390                 }\r
391             }\r
392         };\r
393 \r
394         /**\r
395          * Converts a string to camel case.\r
396          * @param {string} str\r
397          * @returns {string}\r
398          * @expose\r
399          */\r
400         Util.toCamelCase = function(str) {\r
401             return str.replace(/_([a-zA-Z])/g, function ($0, $1) {\r
402                 return $1.toUpperCase();\r
403             });\r
404         };\r
405 \r
406         return Util;\r
407     })();\r
408 \r
409     /**\r
410      * Language expressions.\r
411      * @type {!Object.<string,!RegExp>}\r
412      * @expose\r
413      */\r
414     ProtoBuf.Lang = {\r
415 \r
416         // Characters always ending a statement\r
417         DELIM: /[\s\{\}=;:\[\],'"\(\)<>]/g,\r
418 \r
419         // Field rules\r
420         RULE: /^(?:required|optional|repeated|map)$/,\r
421 \r
422         // Field types\r
423         TYPE: /^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,\r
424 \r
425         // Names\r
426         NAME: /^[a-zA-Z_][a-zA-Z_0-9]*$/,\r
427 \r
428         // Type definitions\r
429         TYPEDEF: /^[a-zA-Z][a-zA-Z_0-9]*$/,\r
430 \r
431         // Type references\r
432         TYPEREF: /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,\r
433 \r
434         // Fully qualified type references\r
435         FQTYPEREF: /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/,\r
436 \r
437         // All numbers\r
438         NUMBER: /^-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+|([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?)|inf|nan)$/,\r
439 \r
440         // Decimal numbers\r
441         NUMBER_DEC: /^(?:[1-9][0-9]*|0)$/,\r
442 \r
443         // Hexadecimal numbers\r
444         NUMBER_HEX: /^0[xX][0-9a-fA-F]+$/,\r
445 \r
446         // Octal numbers\r
447         NUMBER_OCT: /^0[0-7]+$/,\r
448 \r
449         // Floating point numbers\r
450         NUMBER_FLT: /^([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?|inf|nan)$/,\r
451 \r
452         // Booleans\r
453         BOOL: /^(?:true|false)$/i,\r
454 \r
455         // Id numbers\r
456         ID: /^(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,\r
457 \r
458         // Negative id numbers (enum values)\r
459         NEGID: /^\-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,\r
460 \r
461         // Whitespaces\r
462         WHITESPACE: /\s/,\r
463 \r
464         // All strings\r
465         STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,\r
466 \r
467         // Double quoted strings\r
468         STRING_DQ: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,\r
469 \r
470         // Single quoted strings\r
471         STRING_SQ: /(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g\r
472     };\r
473 \r
474 \r
475     /**\r
476      * @alias ProtoBuf.Reflect\r
477      * @expose\r
478      */\r
479     ProtoBuf.Reflect = (function(ProtoBuf) {\r
480         "use strict";\r
481 \r
482         /**\r
483          * Reflection types.\r
484          * @exports ProtoBuf.Reflect\r
485          * @namespace\r
486          */\r
487         var Reflect = {};\r
488 \r
489         /**\r
490          * Constructs a Reflect base class.\r
491          * @exports ProtoBuf.Reflect.T\r
492          * @constructor\r
493          * @abstract\r
494          * @param {!ProtoBuf.Builder} builder Builder reference\r
495          * @param {?ProtoBuf.Reflect.T} parent Parent object\r
496          * @param {string} name Object name\r
497          */\r
498         var T = function(builder, parent, name) {\r
499 \r
500             /**\r
501              * Builder reference.\r
502              * @type {!ProtoBuf.Builder}\r
503              * @expose\r
504              */\r
505             this.builder = builder;\r
506 \r
507             /**\r
508              * Parent object.\r
509              * @type {?ProtoBuf.Reflect.T}\r
510              * @expose\r
511              */\r
512             this.parent = parent;\r
513 \r
514             /**\r
515              * Object name in namespace.\r
516              * @type {string}\r
517              * @expose\r
518              */\r
519             this.name = name;\r
520 \r
521             /**\r
522              * Fully qualified class name\r
523              * @type {string}\r
524              * @expose\r
525              */\r
526             this.className;\r
527         };\r
528 \r
529         /**\r
530          * @alias ProtoBuf.Reflect.T.prototype\r
531          * @inner\r
532          */\r
533         var TPrototype = T.prototype;\r
534 \r
535         /**\r
536          * Returns the fully qualified name of this object.\r
537          * @returns {string} Fully qualified name as of ".PATH.TO.THIS"\r
538          * @expose\r
539          */\r
540         TPrototype.fqn = function() {\r
541             var name = this.name,\r
542                 ptr = this;\r
543             do {\r
544                 ptr = ptr.parent;\r
545                 if (ptr == null)\r
546                     break;\r
547                 name = ptr.name+"."+name;\r
548             } while (true);\r
549             return name;\r
550         };\r
551 \r
552         /**\r
553          * Returns a string representation of this Reflect object (its fully qualified name).\r
554          * @param {boolean=} includeClass Set to true to include the class name. Defaults to false.\r
555          * @return String representation\r
556          * @expose\r
557          */\r
558         TPrototype.toString = function(includeClass) {\r
559             return (includeClass ? this.className + " " : "") + this.fqn();\r
560         };\r
561 \r
562         /**\r
563          * Builds this type.\r
564          * @throws {Error} If this type cannot be built directly\r
565          * @expose\r
566          */\r
567         TPrototype.build = function() {\r
568             throw Error(this.toString(true)+" cannot be built directly");\r
569         };\r
570 \r
571         /**\r
572          * @alias ProtoBuf.Reflect.T\r
573          * @expose\r
574          */\r
575         Reflect.T = T;\r
576 \r
577         /**\r
578          * Constructs a new Namespace.\r
579          * @exports ProtoBuf.Reflect.Namespace\r
580          * @param {!ProtoBuf.Builder} builder Builder reference\r
581          * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent\r
582          * @param {string} name Namespace name\r
583          * @param {Object.<string,*>=} options Namespace options\r
584          * @param {string?} syntax The syntax level of this definition (e.g., proto3)\r
585          * @constructor\r
586          * @extends ProtoBuf.Reflect.T\r
587          */\r
588         var Namespace = function(builder, parent, name, options, syntax) {\r
589             T.call(this, builder, parent, name);\r
590 \r
591             /**\r
592              * @override\r
593              */\r
594             this.className = "Namespace";\r
595 \r
596             /**\r
597              * Children inside the namespace.\r
598              * @type {!Array.<ProtoBuf.Reflect.T>}\r
599              */\r
600             this.children = [];\r
601 \r
602             /**\r
603              * Options.\r
604              * @type {!Object.<string, *>}\r
605              */\r
606             this.options = options || {};\r
607 \r
608             /**\r
609              * Syntax level (e.g., proto2 or proto3).\r
610              * @type {!string}\r
611              */\r
612             this.syntax = syntax || "proto2";\r
613         };\r
614 \r
615         /**\r
616          * @alias ProtoBuf.Reflect.Namespace.prototype\r
617          * @inner\r
618          */\r
619         var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);\r
620 \r
621         /**\r
622          * Returns an array of the namespace's children.\r
623          * @param {ProtoBuf.Reflect.T=} type Filter type (returns instances of this type only). Defaults to null (all children).\r
624          * @return {Array.<ProtoBuf.Reflect.T>}\r
625          * @expose\r
626          */\r
627         NamespacePrototype.getChildren = function(type) {\r
628             type = type || null;\r
629             if (type == null)\r
630                 return this.children.slice();\r
631             var children = [];\r
632             for (var i=0, k=this.children.length; i<k; ++i)\r
633                 if (this.children[i] instanceof type)\r
634                     children.push(this.children[i]);\r
635             return children;\r
636         };\r
637 \r
638         /**\r
639          * Adds a child to the namespace.\r
640          * @param {ProtoBuf.Reflect.T} child Child\r
641          * @throws {Error} If the child cannot be added (duplicate)\r
642          * @expose\r
643          */\r
644         NamespacePrototype.addChild = function(child) {\r
645             var other;\r
646             if (other = this.getChild(child.name)) {\r
647                 // Try to revert camelcase transformation on collision\r
648                 if (other instanceof Message.Field && other.name !== other.originalName && this.getChild(other.originalName) === null)\r
649                     other.name = other.originalName; // Revert previous first (effectively keeps both originals)\r
650                 else if (child instanceof Message.Field && child.name !== child.originalName && this.getChild(child.originalName) === null)\r
651                     child.name = child.originalName;\r
652                 else\r
653                     throw Error("Duplicate name in namespace "+this.toString(true)+": "+child.name);\r
654             }\r
655             this.children.push(child);\r
656         };\r
657 \r
658         /**\r
659          * Gets a child by its name or id.\r
660          * @param {string|number} nameOrId Child name or id\r
661          * @return {?ProtoBuf.Reflect.T} The child or null if not found\r
662          * @expose\r
663          */\r
664         NamespacePrototype.getChild = function(nameOrId) {\r
665             var key = typeof nameOrId === 'number' ? 'id' : 'name';\r
666             for (var i=0, k=this.children.length; i<k; ++i)\r
667                 if (this.children[i][key] === nameOrId)\r
668                     return this.children[i];\r
669             return null;\r
670         };\r
671 \r
672         /**\r
673          * Resolves a reflect object inside of this namespace.\r
674          * @param {string|!Array.<string>} qn Qualified name to resolve\r
675          * @param {boolean=} excludeNonNamespace Excludes non-namespace types, defaults to `false`\r
676          * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found\r
677          * @expose\r
678          */\r
679         NamespacePrototype.resolve = function(qn, excludeNonNamespace) {\r
680             var part = typeof qn === 'string' ? qn.split(".") : qn,\r
681                 ptr = this,\r
682                 i = 0;\r
683             if (part[i] === "") { // Fully qualified name, e.g. ".My.Message'\r
684                 while (ptr.parent !== null)\r
685                     ptr = ptr.parent;\r
686                 i++;\r
687             }\r
688             var child;\r
689             do {\r
690                 do {\r
691                     if (!(ptr instanceof Reflect.Namespace)) {\r
692                         ptr = null;\r
693                         break;\r
694                     }\r
695                     child = ptr.getChild(part[i]);\r
696                     if (!child || !(child instanceof Reflect.T) || (excludeNonNamespace && !(child instanceof Reflect.Namespace))) {\r
697                         ptr = null;\r
698                         break;\r
699                     }\r
700                     ptr = child; i++;\r
701                 } while (i < part.length);\r
702                 if (ptr != null)\r
703                     break; // Found\r
704                 // Else search the parent\r
705                 if (this.parent !== null)\r
706                     return this.parent.resolve(qn, excludeNonNamespace);\r
707             } while (ptr != null);\r
708             return ptr;\r
709         };\r
710 \r
711         /**\r
712          * Determines the shortest qualified name of the specified type, if any, relative to this namespace.\r
713          * @param {!ProtoBuf.Reflect.T} t Reflection type\r
714          * @returns {string} The shortest qualified name or, if there is none, the fqn\r
715          * @expose\r
716          */\r
717         NamespacePrototype.qn = function(t) {\r
718             var part = [], ptr = t;\r
719             do {\r
720                 part.unshift(ptr.name);\r
721                 ptr = ptr.parent;\r
722             } while (ptr !== null);\r
723             for (var len=1; len <= part.length; len++) {\r
724                 var qn = part.slice(part.length-len);\r
725                 if (t === this.resolve(qn, t instanceof Reflect.Namespace))\r
726                     return qn.join(".");\r
727             }\r
728             return t.fqn();\r
729         };\r
730 \r
731         /**\r
732          * Builds the namespace and returns the runtime counterpart.\r
733          * @return {Object.<string,Function|Object>} Runtime namespace\r
734          * @expose\r
735          */\r
736         NamespacePrototype.build = function() {\r
737             /** @dict */\r
738             var ns = {};\r
739             var children = this.children;\r
740             for (var i=0, k=children.length, child; i<k; ++i) {\r
741                 child = children[i];\r
742                 if (child instanceof Namespace)\r
743                     ns[child.name] = child.build();\r
744             }\r
745             if (Object.defineProperty)\r
746                 Object.defineProperty(ns, "$options", { "value": this.buildOpt() });\r
747             return ns;\r
748         };\r
749 \r
750         /**\r
751          * Builds the namespace's '$options' property.\r
752          * @return {Object.<string,*>}\r
753          */\r
754         NamespacePrototype.buildOpt = function() {\r
755             var opt = {},\r
756                 keys = Object.keys(this.options);\r
757             for (var i=0, k=keys.length; i<k; ++i) {\r
758                 var key = keys[i],\r
759                     val = this.options[keys[i]];\r
760                 // TODO: Options are not resolved, yet.\r
761                 // if (val instanceof Namespace) {\r
762                 //     opt[key] = val.build();\r
763                 // } else {\r
764                 opt[key] = val;\r
765                 // }\r
766             }\r
767             return opt;\r
768         };\r
769 \r
770         /**\r
771          * Gets the value assigned to the option with the specified name.\r
772          * @param {string=} name Returns the option value if specified, otherwise all options are returned.\r
773          * @return {*|Object.<string,*>}null} Option value or NULL if there is no such option\r
774          */\r
775         NamespacePrototype.getOption = function(name) {\r
776             if (typeof name === 'undefined')\r
777                 return this.options;\r
778             return typeof this.options[name] !== 'undefined' ? this.options[name] : null;\r
779         };\r
780 \r
781         /**\r
782          * @alias ProtoBuf.Reflect.Namespace\r
783          * @expose\r
784          */\r
785         Reflect.Namespace = Namespace;\r
786 \r
787         /**\r
788          * Constructs a new Element implementation that checks and converts values for a\r
789          * particular field type, as appropriate.\r
790          *\r
791          * An Element represents a single value: either the value of a singular field,\r
792          * or a value contained in one entry of a repeated field or map field. This\r
793          * class does not implement these higher-level concepts; it only encapsulates\r
794          * the low-level typechecking and conversion.\r
795          *\r
796          * @exports ProtoBuf.Reflect.Element\r
797          * @param {{name: string, wireType: number}} type Resolved data type\r
798          * @param {ProtoBuf.Reflect.T|null} resolvedType Resolved type, if relevant\r
799          * (e.g. submessage field).\r
800          * @param {boolean} isMapKey Is this element a Map key? The value will be\r
801          * converted to string form if so.\r
802          * @param {string} syntax Syntax level of defining message type, e.g.,\r
803          * proto2 or proto3.\r
804          * @param {string} name Name of the field containing this element (for error\r
805          * messages)\r
806          * @constructor\r
807          */\r
808         var Element = function(type, resolvedType, isMapKey, syntax, name) {\r
809 \r
810             /**\r
811              * Element type, as a string (e.g., int32).\r
812              * @type {{name: string, wireType: number}}\r
813              */\r
814             this.type = type;\r
815 \r
816             /**\r
817              * Element type reference to submessage or enum definition, if needed.\r
818              * @type {ProtoBuf.Reflect.T|null}\r
819              */\r
820             this.resolvedType = resolvedType;\r
821 \r
822             /**\r
823              * Element is a map key.\r
824              * @type {boolean}\r
825              */\r
826             this.isMapKey = isMapKey;\r
827 \r
828             /**\r
829              * Syntax level of defining message type, e.g., proto2 or proto3.\r
830              * @type {string}\r
831              */\r
832             this.syntax = syntax;\r
833 \r
834             /**\r
835              * Name of the field containing this element (for error messages)\r
836              * @type {string}\r
837              */\r
838             this.name = name;\r
839 \r
840             if (isMapKey && ProtoBuf.MAP_KEY_TYPES.indexOf(type) < 0)\r
841                 throw Error("Invalid map key type: " + type.name);\r
842         };\r
843 \r
844         var ElementPrototype = Element.prototype;\r
845 \r
846         /**\r
847          * Obtains a (new) default value for the specified type.\r
848          * @param type {string|{name: string, wireType: number}} Field type\r
849          * @returns {*} Default value\r
850          * @inner\r
851          */\r
852         function mkDefault(type) {\r
853             if (typeof type === 'string')\r
854                 type = ProtoBuf.TYPES[type];\r
855             if (typeof type.defaultValue === 'undefined')\r
856                 throw Error("default value for type "+type.name+" is not supported");\r
857             if (type == ProtoBuf.TYPES["bytes"])\r
858                 return new ByteBuffer(0);\r
859             return type.defaultValue;\r
860         }\r
861 \r
862         /**\r
863          * Returns the default value for this field in proto3.\r
864          * @function\r
865          * @param type {string|{name: string, wireType: number}} the field type\r
866          * @returns {*} Default value\r
867          */\r
868         Element.defaultFieldValue = mkDefault;\r
869 \r
870         /**\r
871          * Makes a Long from a value.\r
872          * @param {{low: number, high: number, unsigned: boolean}|string|number} value Value\r
873          * @param {boolean=} unsigned Whether unsigned or not, defaults to reuse it from Long-like objects or to signed for\r
874          *  strings and numbers\r
875          * @returns {!Long}\r
876          * @throws {Error} If the value cannot be converted to a Long\r
877          * @inner\r
878          */\r
879         function mkLong(value, unsigned) {\r
880             if (value && typeof value.low === 'number' && typeof value.high === 'number' && typeof value.unsigned === 'boolean'\r
881                 && value.low === value.low && value.high === value.high)\r
882                 return new ProtoBuf.Long(value.low, value.high, typeof unsigned === 'undefined' ? value.unsigned : unsigned);\r
883             if (typeof value === 'string')\r
884                 return ProtoBuf.Long.fromString(value, unsigned || false, 10);\r
885             if (typeof value === 'number')\r
886                 return ProtoBuf.Long.fromNumber(value, unsigned || false);\r
887             throw Error("not convertible to Long");\r
888         }\r
889 \r
890         ElementPrototype.toString = function() {\r
891             return (this.name || '') + (this.isMapKey ? 'map' : 'value') + ' element';\r
892         }\r
893 \r
894         /**\r
895          * Checks if the given value can be set for an element of this type (singular\r
896          * field or one element of a repeated field or map).\r
897          * @param {*} value Value to check\r
898          * @return {*} Verified, maybe adjusted, value\r
899          * @throws {Error} If the value cannot be verified for this element slot\r
900          * @expose\r
901          */\r
902         ElementPrototype.verifyValue = function(value) {\r
903             var self = this;\r
904             function fail(val, msg) {\r
905                 throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");\r
906             }\r
907             switch (this.type) {\r
908                 // Signed 32bit\r
909                 case ProtoBuf.TYPES["int32"]:\r
910                 case ProtoBuf.TYPES["sint32"]:\r
911                 case ProtoBuf.TYPES["sfixed32"]:\r
912                     // Account for !NaN: value === value\r
913                     if (typeof value !== 'number' || (value === value && value % 1 !== 0))\r
914                         fail(typeof value, "not an integer");\r
915                     return value > 4294967295 ? value | 0 : value;\r
916 \r
917                 // Unsigned 32bit\r
918                 case ProtoBuf.TYPES["uint32"]:\r
919                 case ProtoBuf.TYPES["fixed32"]:\r
920                     if (typeof value !== 'number' || (value === value && value % 1 !== 0))\r
921                         fail(typeof value, "not an integer");\r
922                     return value < 0 ? value >>> 0 : value;\r
923 \r
924                 // Signed 64bit\r
925                 case ProtoBuf.TYPES["int64"]:\r
926                 case ProtoBuf.TYPES["sint64"]:\r
927                 case ProtoBuf.TYPES["sfixed64"]: {\r
928                     if (ProtoBuf.Long)\r
929                         try {\r
930                             return mkLong(value, false);\r
931                         } catch (e) {\r
932                             fail(typeof value, e.message);\r
933                         }\r
934                     else\r
935                         fail(typeof value, "requires Long.js");\r
936                 }\r
937 \r
938                 // Unsigned 64bit\r
939                 case ProtoBuf.TYPES["uint64"]:\r
940                 case ProtoBuf.TYPES["fixed64"]: {\r
941                     if (ProtoBuf.Long)\r
942                         try {\r
943                             return mkLong(value, true);\r
944                         } catch (e) {\r
945                             fail(typeof value, e.message);\r
946                         }\r
947                     else\r
948                         fail(typeof value, "requires Long.js");\r
949                 }\r
950 \r
951                 // Bool\r
952                 case ProtoBuf.TYPES["bool"]:\r
953                     if (typeof value !== 'boolean')\r
954                         fail(typeof value, "not a boolean");\r
955                     return value;\r
956 \r
957                 // Float\r
958                 case ProtoBuf.TYPES["float"]:\r
959                 case ProtoBuf.TYPES["double"]:\r
960                     if (typeof value !== 'number')\r
961                         fail(typeof value, "not a number");\r
962                     return value;\r
963 \r
964                 // Length-delimited string\r
965                 case ProtoBuf.TYPES["string"]:\r
966                     if (typeof value !== 'string' && !(value && value instanceof String))\r
967                         fail(typeof value, "not a string");\r
968                     return ""+value; // Convert String object to string\r
969 \r
970                 // Length-delimited bytes\r
971                 case ProtoBuf.TYPES["bytes"]:\r
972                     if (ByteBuffer.isByteBuffer(value))\r
973                         return value;\r
974                     return ByteBuffer.wrap(value, "base64");\r
975 \r
976                 // Constant enum value\r
977                 case ProtoBuf.TYPES["enum"]: {\r
978                     var values = this.resolvedType.getChildren(ProtoBuf.Reflect.Enum.Value);\r
979                     for (i=0; i<values.length; i++)\r
980                         if (values[i].name == value)\r
981                             return values[i].id;\r
982                         else if (values[i].id == value)\r
983                             return values[i].id;\r
984 \r
985                     if (this.syntax === 'proto3') {\r
986                         // proto3: just make sure it's an integer.\r
987                         if (typeof value !== 'number' || (value === value && value % 1 !== 0))\r
988                             fail(typeof value, "not an integer");\r
989                         if (value > 4294967295 || value < 0)\r
990                             fail(typeof value, "not in range for uint32")\r
991                         return value;\r
992                     } else {\r
993                         // proto2 requires enum values to be valid.\r
994                         fail(value, "not a valid enum value");\r
995                     }\r
996                 }\r
997                 // Embedded message\r
998                 case ProtoBuf.TYPES["group"]:\r
999                 case ProtoBuf.TYPES["message"]: {\r
1000                     if (!value || typeof value !== 'object')\r
1001                         fail(typeof value, "object expected");\r
1002                     if (value instanceof this.resolvedType.clazz)\r
1003                         return value;\r
1004                     if (value instanceof ProtoBuf.Builder.Message) {\r
1005                         // Mismatched type: Convert to object (see: https://github.com/dcodeIO/ProtoBuf.js/issues/180)\r
1006                         var obj = {};\r
1007                         for (var i in value)\r
1008                             if (value.hasOwnProperty(i))\r
1009                                 obj[i] = value[i];\r
1010                         value = obj;\r
1011                     }\r
1012                     // Else let's try to construct one from a key-value object\r
1013                     return new (this.resolvedType.clazz)(value); // May throw for a hundred of reasons\r
1014                 }\r
1015             }\r
1016 \r
1017             // We should never end here\r
1018             throw Error("[INTERNAL] Illegal value for "+this.toString(true)+": "+value+" (undefined type "+this.type+")");\r
1019         };\r
1020 \r
1021         /**\r
1022          * Calculates the byte length of an element on the wire.\r
1023          * @param {number} id Field number\r
1024          * @param {*} value Field value\r
1025          * @returns {number} Byte length\r
1026          * @throws {Error} If the value cannot be calculated\r
1027          * @expose\r
1028          */\r
1029         ElementPrototype.calculateLength = function(id, value) {\r
1030             if (value === null) return 0; // Nothing to encode\r
1031             // Tag has already been written\r
1032             var n;\r
1033             switch (this.type) {\r
1034                 case ProtoBuf.TYPES["int32"]:\r
1035                     return value < 0 ? ByteBuffer.calculateVarint64(value) : ByteBuffer.calculateVarint32(value);\r
1036                 case ProtoBuf.TYPES["uint32"]:\r
1037                     return ByteBuffer.calculateVarint32(value);\r
1038                 case ProtoBuf.TYPES["sint32"]:\r
1039                     return ByteBuffer.calculateVarint32(ByteBuffer.zigZagEncode32(value));\r
1040                 case ProtoBuf.TYPES["fixed32"]:\r
1041                 case ProtoBuf.TYPES["sfixed32"]:\r
1042                 case ProtoBuf.TYPES["float"]:\r
1043                     return 4;\r
1044                 case ProtoBuf.TYPES["int64"]:\r
1045                 case ProtoBuf.TYPES["uint64"]:\r
1046                     return ByteBuffer.calculateVarint64(value);\r
1047                 case ProtoBuf.TYPES["sint64"]:\r
1048                     return ByteBuffer.calculateVarint64(ByteBuffer.zigZagEncode64(value));\r
1049                 case ProtoBuf.TYPES["fixed64"]:\r
1050                 case ProtoBuf.TYPES["sfixed64"]:\r
1051                     return 8;\r
1052                 case ProtoBuf.TYPES["bool"]:\r
1053                     return 1;\r
1054                 case ProtoBuf.TYPES["enum"]:\r
1055                     return ByteBuffer.calculateVarint32(value);\r
1056                 case ProtoBuf.TYPES["double"]:\r
1057                     return 8;\r
1058                 case ProtoBuf.TYPES["string"]:\r
1059                     n = ByteBuffer.calculateUTF8Bytes(value);\r
1060                     return ByteBuffer.calculateVarint32(n) + n;\r
1061                 case ProtoBuf.TYPES["bytes"]:\r
1062                     if (value.remaining() < 0)\r
1063                         throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");\r
1064                     return ByteBuffer.calculateVarint32(value.remaining()) + value.remaining();\r
1065                 case ProtoBuf.TYPES["message"]:\r
1066                     n = this.resolvedType.calculate(value);\r
1067                     return ByteBuffer.calculateVarint32(n) + n;\r
1068                 case ProtoBuf.TYPES["group"]:\r
1069                     n = this.resolvedType.calculate(value);\r
1070                     return n + ByteBuffer.calculateVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);\r
1071             }\r
1072             // We should never end here\r
1073             throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");\r
1074         };\r
1075 \r
1076         /**\r
1077          * Encodes a value to the specified buffer. Does not encode the key.\r
1078          * @param {number} id Field number\r
1079          * @param {*} value Field value\r
1080          * @param {ByteBuffer} buffer ByteBuffer to encode to\r
1081          * @return {ByteBuffer} The ByteBuffer for chaining\r
1082          * @throws {Error} If the value cannot be encoded\r
1083          * @expose\r
1084          */\r
1085         ElementPrototype.encodeValue = function(id, value, buffer) {\r
1086             if (value === null) return buffer; // Nothing to encode\r
1087             // Tag has already been written\r
1088 \r
1089             switch (this.type) {\r
1090                 // 32bit signed varint\r
1091                 case ProtoBuf.TYPES["int32"]:\r
1092                     // "If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes\r
1093                     // long â€“ it is, effectively, treated like a very large unsigned integer." (see #122)\r
1094                     if (value < 0)\r
1095                         buffer.writeVarint64(value);\r
1096                     else\r
1097                         buffer.writeVarint32(value);\r
1098                     break;\r
1099 \r
1100                 // 32bit unsigned varint\r
1101                 case ProtoBuf.TYPES["uint32"]:\r
1102                     buffer.writeVarint32(value);\r
1103                     break;\r
1104 \r
1105                 // 32bit varint zig-zag\r
1106                 case ProtoBuf.TYPES["sint32"]:\r
1107                     buffer.writeVarint32ZigZag(value);\r
1108                     break;\r
1109 \r
1110                 // Fixed unsigned 32bit\r
1111                 case ProtoBuf.TYPES["fixed32"]:\r
1112                     buffer.writeUint32(value);\r
1113                     break;\r
1114 \r
1115                 // Fixed signed 32bit\r
1116                 case ProtoBuf.TYPES["sfixed32"]:\r
1117                     buffer.writeInt32(value);\r
1118                     break;\r
1119 \r
1120                 // 64bit varint as-is\r
1121                 case ProtoBuf.TYPES["int64"]:\r
1122                 case ProtoBuf.TYPES["uint64"]:\r
1123                     buffer.writeVarint64(value); // throws\r
1124                     break;\r
1125 \r
1126                 // 64bit varint zig-zag\r
1127                 case ProtoBuf.TYPES["sint64"]:\r
1128                     buffer.writeVarint64ZigZag(value); // throws\r
1129                     break;\r
1130 \r
1131                 // Fixed unsigned 64bit\r
1132                 case ProtoBuf.TYPES["fixed64"]:\r
1133                     buffer.writeUint64(value); // throws\r
1134                     break;\r
1135 \r
1136                 // Fixed signed 64bit\r
1137                 case ProtoBuf.TYPES["sfixed64"]:\r
1138                     buffer.writeInt64(value); // throws\r
1139                     break;\r
1140 \r
1141                 // Bool\r
1142                 case ProtoBuf.TYPES["bool"]:\r
1143                     if (typeof value === 'string')\r
1144                         buffer.writeVarint32(value.toLowerCase() === 'false' ? 0 : !!value);\r
1145                     else\r
1146                         buffer.writeVarint32(value ? 1 : 0);\r
1147                     break;\r
1148 \r
1149                 // Constant enum value\r
1150                 case ProtoBuf.TYPES["enum"]:\r
1151                     buffer.writeVarint32(value);\r
1152                     break;\r
1153 \r
1154                 // 32bit float\r
1155                 case ProtoBuf.TYPES["float"]:\r
1156                     buffer.writeFloat32(value);\r
1157                     break;\r
1158 \r
1159                 // 64bit float\r
1160                 case ProtoBuf.TYPES["double"]:\r
1161                     buffer.writeFloat64(value);\r
1162                     break;\r
1163 \r
1164                 // Length-delimited string\r
1165                 case ProtoBuf.TYPES["string"]:\r
1166                     buffer.writeVString(value);\r
1167                     break;\r
1168 \r
1169                 // Length-delimited bytes\r
1170                 case ProtoBuf.TYPES["bytes"]:\r
1171                     if (value.remaining() < 0)\r
1172                         throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");\r
1173                     var prevOffset = value.offset;\r
1174                     buffer.writeVarint32(value.remaining());\r
1175                     buffer.append(value);\r
1176                     value.offset = prevOffset;\r
1177                     break;\r
1178 \r
1179                 // Embedded message\r
1180                 case ProtoBuf.TYPES["message"]:\r
1181                     var bb = new ByteBuffer().LE();\r
1182                     this.resolvedType.encode(value, bb);\r
1183                     buffer.writeVarint32(bb.offset);\r
1184                     buffer.append(bb.flip());\r
1185                     break;\r
1186 \r
1187                 // Legacy group\r
1188                 case ProtoBuf.TYPES["group"]:\r
1189                     this.resolvedType.encode(value, buffer);\r
1190                     buffer.writeVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);\r
1191                     break;\r
1192 \r
1193                 default:\r
1194                     // We should never end here\r
1195                     throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");\r
1196             }\r
1197             return buffer;\r
1198         };\r
1199 \r
1200         /**\r
1201          * Decode one element value from the specified buffer.\r
1202          * @param {ByteBuffer} buffer ByteBuffer to decode from\r
1203          * @param {number} wireType The field wire type\r
1204          * @param {number} id The field number\r
1205          * @return {*} Decoded value\r
1206          * @throws {Error} If the field cannot be decoded\r
1207          * @expose\r
1208          */\r
1209         ElementPrototype.decode = function(buffer, wireType, id) {\r
1210             if (wireType != this.type.wireType)\r
1211                 throw Error("Unexpected wire type for element");\r
1212 \r
1213             var value, nBytes;\r
1214             switch (this.type) {\r
1215                 // 32bit signed varint\r
1216                 case ProtoBuf.TYPES["int32"]:\r
1217                     return buffer.readVarint32() | 0;\r
1218 \r
1219                 // 32bit unsigned varint\r
1220                 case ProtoBuf.TYPES["uint32"]:\r
1221                     return buffer.readVarint32() >>> 0;\r
1222 \r
1223                 // 32bit signed varint zig-zag\r
1224                 case ProtoBuf.TYPES["sint32"]:\r
1225                     return buffer.readVarint32ZigZag() | 0;\r
1226 \r
1227                 // Fixed 32bit unsigned\r
1228                 case ProtoBuf.TYPES["fixed32"]:\r
1229                     return buffer.readUint32() >>> 0;\r
1230 \r
1231                 case ProtoBuf.TYPES["sfixed32"]:\r
1232                     return buffer.readInt32() | 0;\r
1233 \r
1234                 // 64bit signed varint\r
1235                 case ProtoBuf.TYPES["int64"]:\r
1236                     return buffer.readVarint64();\r
1237 \r
1238                 // 64bit unsigned varint\r
1239                 case ProtoBuf.TYPES["uint64"]:\r
1240                     return buffer.readVarint64().toUnsigned();\r
1241 \r
1242                 // 64bit signed varint zig-zag\r
1243                 case ProtoBuf.TYPES["sint64"]:\r
1244                     return buffer.readVarint64ZigZag();\r
1245 \r
1246                 // Fixed 64bit unsigned\r
1247                 case ProtoBuf.TYPES["fixed64"]:\r
1248                     return buffer.readUint64();\r
1249 \r
1250                 // Fixed 64bit signed\r
1251                 case ProtoBuf.TYPES["sfixed64"]:\r
1252                     return buffer.readInt64();\r
1253 \r
1254                 // Bool varint\r
1255                 case ProtoBuf.TYPES["bool"]:\r
1256                     return !!buffer.readVarint32();\r
1257 \r
1258                 // Constant enum value (varint)\r
1259                 case ProtoBuf.TYPES["enum"]:\r
1260                     // The following Builder.Message#set will already throw\r
1261                     return buffer.readVarint32();\r
1262 \r
1263                 // 32bit float\r
1264                 case ProtoBuf.TYPES["float"]:\r
1265                     return buffer.readFloat();\r
1266 \r
1267                 // 64bit float\r
1268                 case ProtoBuf.TYPES["double"]:\r
1269                     return buffer.readDouble();\r
1270 \r
1271                 // Length-delimited string\r
1272                 case ProtoBuf.TYPES["string"]:\r
1273                     return buffer.readVString();\r
1274 \r
1275                 // Length-delimited bytes\r
1276                 case ProtoBuf.TYPES["bytes"]: {\r
1277                     nBytes = buffer.readVarint32();\r
1278                     if (buffer.remaining() < nBytes)\r
1279                         throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());\r
1280                     value = buffer.clone(); // Offset already set\r
1281                     value.limit = value.offset+nBytes;\r
1282                     buffer.offset += nBytes;\r
1283                     return value;\r
1284                 }\r
1285 \r
1286                 // Length-delimited embedded message\r
1287                 case ProtoBuf.TYPES["message"]: {\r
1288                     nBytes = buffer.readVarint32();\r
1289                     return this.resolvedType.decode(buffer, nBytes);\r
1290                 }\r
1291 \r
1292                 // Legacy group\r
1293                 case ProtoBuf.TYPES["group"]:\r
1294                     return this.resolvedType.decode(buffer, -1, id);\r
1295             }\r
1296 \r
1297             // We should never end here\r
1298             throw Error("[INTERNAL] Illegal decode type");\r
1299         };\r
1300 \r
1301         /**\r
1302          * Converts a value from a string to the canonical element type.\r
1303          *\r
1304          * Legal only when isMapKey is true.\r
1305          *\r
1306          * @param {string} str The string value\r
1307          * @returns {*} The value\r
1308          */\r
1309         ElementPrototype.valueFromString = function(str) {\r
1310             if (!this.isMapKey) {\r
1311                 throw Error("valueFromString() called on non-map-key element");\r
1312             }\r
1313 \r
1314             switch (this.type) {\r
1315                 case ProtoBuf.TYPES["int32"]:\r
1316                 case ProtoBuf.TYPES["sint32"]:\r
1317                 case ProtoBuf.TYPES["sfixed32"]:\r
1318                 case ProtoBuf.TYPES["uint32"]:\r
1319                 case ProtoBuf.TYPES["fixed32"]:\r
1320                     return this.verifyValue(parseInt(str));\r
1321 \r
1322                 case ProtoBuf.TYPES["int64"]:\r
1323                 case ProtoBuf.TYPES["sint64"]:\r
1324                 case ProtoBuf.TYPES["sfixed64"]:\r
1325                 case ProtoBuf.TYPES["uint64"]:\r
1326                 case ProtoBuf.TYPES["fixed64"]:\r
1327                       // Long-based fields support conversions from string already.\r
1328                       return this.verifyValue(str);\r
1329 \r
1330                 case ProtoBuf.TYPES["bool"]:\r
1331                       return str === "true";\r
1332 \r
1333                 case ProtoBuf.TYPES["string"]:\r
1334                       return this.verifyValue(str);\r
1335 \r
1336                 case ProtoBuf.TYPES["bytes"]:\r
1337                       return ByteBuffer.fromBinary(str);\r
1338             }\r
1339         };\r
1340 \r
1341         /**\r
1342          * Converts a value from the canonical element type to a string.\r
1343          *\r
1344          * It should be the case that `valueFromString(valueToString(val))` returns\r
1345          * a value equivalent to `verifyValue(val)` for every legal value of `val`\r
1346          * according to this element type.\r
1347          *\r
1348          * This may be used when the element must be stored or used as a string,\r
1349          * e.g., as a map key on an Object.\r
1350          *\r
1351          * Legal only when isMapKey is true.\r
1352          *\r
1353          * @param {*} val The value\r
1354          * @returns {string} The string form of the value.\r
1355          */\r
1356         ElementPrototype.valueToString = function(value) {\r
1357             if (!this.isMapKey) {\r
1358                 throw Error("valueToString() called on non-map-key element");\r
1359             }\r
1360 \r
1361             if (this.type === ProtoBuf.TYPES["bytes"]) {\r
1362                 return value.toString("binary");\r
1363             } else {\r
1364                 return value.toString();\r
1365             }\r
1366         };\r
1367 \r
1368         /**\r
1369          * @alias ProtoBuf.Reflect.Element\r
1370          * @expose\r
1371          */\r
1372         Reflect.Element = Element;\r
1373 \r
1374         /**\r
1375          * Constructs a new Message.\r
1376          * @exports ProtoBuf.Reflect.Message\r
1377          * @param {!ProtoBuf.Builder} builder Builder reference\r
1378          * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace\r
1379          * @param {string} name Message name\r
1380          * @param {Object.<string,*>=} options Message options\r
1381          * @param {boolean=} isGroup `true` if this is a legacy group\r
1382          * @param {string?} syntax The syntax level of this definition (e.g., proto3)\r
1383          * @constructor\r
1384          * @extends ProtoBuf.Reflect.Namespace\r
1385          */\r
1386         var Message = function(builder, parent, name, options, isGroup, syntax) {\r
1387             Namespace.call(this, builder, parent, name, options, syntax);\r
1388 \r
1389             /**\r
1390              * @override\r
1391              */\r
1392             this.className = "Message";\r
1393 \r
1394             /**\r
1395              * Extensions range.\r
1396              * @type {!Array.<number>|undefined}\r
1397              * @expose\r
1398              */\r
1399             this.extensions = undefined;\r
1400 \r
1401             /**\r
1402              * Runtime message class.\r
1403              * @type {?function(new:ProtoBuf.Builder.Message)}\r
1404              * @expose\r
1405              */\r
1406             this.clazz = null;\r
1407 \r
1408             /**\r
1409              * Whether this is a legacy group or not.\r
1410              * @type {boolean}\r
1411              * @expose\r
1412              */\r
1413             this.isGroup = !!isGroup;\r
1414 \r
1415             // The following cached collections are used to efficiently iterate over or look up fields when decoding.\r
1416 \r
1417             /**\r
1418              * Cached fields.\r
1419              * @type {?Array.<!ProtoBuf.Reflect.Message.Field>}\r
1420              * @private\r
1421              */\r
1422             this._fields = null;\r
1423 \r
1424             /**\r
1425              * Cached fields by id.\r
1426              * @type {?Object.<number,!ProtoBuf.Reflect.Message.Field>}\r
1427              * @private\r
1428              */\r
1429             this._fieldsById = null;\r
1430 \r
1431             /**\r
1432              * Cached fields by name.\r
1433              * @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}\r
1434              * @private\r
1435              */\r
1436             this._fieldsByName = null;\r
1437         };\r
1438 \r
1439         /**\r
1440          * @alias ProtoBuf.Reflect.Message.prototype\r
1441          * @inner\r
1442          */\r
1443         var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);\r
1444 \r
1445         /**\r
1446          * Builds the message and returns the runtime counterpart, which is a fully functional class.\r
1447          * @see ProtoBuf.Builder.Message\r
1448          * @param {boolean=} rebuild Whether to rebuild or not, defaults to false\r
1449          * @return {ProtoBuf.Reflect.Message} Message class\r
1450          * @throws {Error} If the message cannot be built\r
1451          * @expose\r
1452          */\r
1453         MessagePrototype.build = function(rebuild) {\r
1454             if (this.clazz && !rebuild)\r
1455                 return this.clazz;\r
1456 \r
1457             // Create the runtime Message class in its own scope\r
1458             var clazz = (function(ProtoBuf, T) {\r
1459 \r
1460                 var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),\r
1461                     oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);\r
1462 \r
1463                 /**\r
1464                  * Constructs a new runtime Message.\r
1465                  * @name ProtoBuf.Builder.Message\r
1466                  * @class Barebone of all runtime messages.\r
1467                  * @param {!Object.<string,*>|string} values Preset values\r
1468                  * @param {...string} var_args\r
1469                  * @constructor\r
1470                  * @throws {Error} If the message cannot be created\r
1471                  */\r
1472                 var Message = function(values, var_args) {\r
1473                     ProtoBuf.Builder.Message.call(this);\r
1474 \r
1475                     // Create virtual oneof properties\r
1476                     for (var i=0, k=oneofs.length; i<k; ++i)\r
1477                         this[oneofs[i].name] = null;\r
1478                     // Create fields and set default values\r
1479                     for (i=0, k=fields.length; i<k; ++i) {\r
1480                         var field = fields[i];\r
1481                         this[field.name] =\r
1482                             field.repeated ? [] :\r
1483                             (field.map ? new ProtoBuf.Map(field) : null);\r
1484                         if ((field.required || T.syntax === 'proto3') &&\r
1485                             field.defaultValue !== null)\r
1486                             this[field.name] = field.defaultValue;\r
1487                     }\r
1488 \r
1489                     if (arguments.length > 0) {\r
1490                         var value;\r
1491                         // Set field values from a values object\r
1492                         if (arguments.length === 1 && values !== null && typeof values === 'object' &&\r
1493                             /* not _another_ Message */ (typeof values.encode !== 'function' || values instanceof Message) &&\r
1494                             /* not a repeated field */ !Array.isArray(values) &&\r
1495                             /* not a Map */ !(values instanceof ProtoBuf.Map) &&\r
1496                             /* not a ByteBuffer */ !ByteBuffer.isByteBuffer(values) &&\r
1497                             /* not an ArrayBuffer */ !(values instanceof ArrayBuffer) &&\r
1498                             /* not a Long */ !(ProtoBuf.Long && values instanceof ProtoBuf.Long)) {\r
1499                             this.$set(values);\r
1500                         } else // Set field values from arguments, in declaration order\r
1501                             for (i=0, k=arguments.length; i<k; ++i)\r
1502                                 if (typeof (value = arguments[i]) !== 'undefined')\r
1503                                     this.$set(fields[i].name, value); // May throw\r
1504                     }\r
1505                 };\r
1506 \r
1507                 /**\r
1508                  * @alias ProtoBuf.Builder.Message.prototype\r
1509                  * @inner\r
1510                  */\r
1511                 var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);\r
1512 \r
1513                 /**\r
1514                  * Adds a value to a repeated field.\r
1515                  * @name ProtoBuf.Builder.Message#add\r
1516                  * @function\r
1517                  * @param {string} key Field name\r
1518                  * @param {*} value Value to add\r
1519                  * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)\r
1520                  * @returns {!ProtoBuf.Builder.Message} this\r
1521                  * @throws {Error} If the value cannot be added\r
1522                  * @expose\r
1523                  */\r
1524                 MessagePrototype.add = function(key, value, noAssert) {\r
1525                     var field = T._fieldsByName[key];\r
1526                     if (!noAssert) {\r
1527                         if (!field)\r
1528                             throw Error(this+"#"+key+" is undefined");\r
1529                         if (!(field instanceof ProtoBuf.Reflect.Message.Field))\r
1530                             throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message\r
1531                         if (!field.repeated)\r
1532                             throw Error(this+"#"+key+" is not a repeated field");\r
1533                         value = field.verifyValue(value, true);\r
1534                     }\r
1535                     if (this[key] === null)\r
1536                         this[key] = [];\r
1537                     this[key].push(value);\r
1538                     return this;\r
1539                 };\r
1540 \r
1541                 /**\r
1542                  * Adds a value to a repeated field. This is an alias for {@link ProtoBuf.Builder.Message#add}.\r
1543                  * @name ProtoBuf.Builder.Message#$add\r
1544                  * @function\r
1545                  * @param {string} key Field name\r
1546                  * @param {*} value Value to add\r
1547                  * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)\r
1548                  * @returns {!ProtoBuf.Builder.Message} this\r
1549                  * @throws {Error} If the value cannot be added\r
1550                  * @expose\r
1551                  */\r
1552                 MessagePrototype.$add = MessagePrototype.add;\r
1553 \r
1554                 /**\r
1555                  * Sets a field's value.\r
1556                  * @name ProtoBuf.Builder.Message#set\r
1557                  * @function\r
1558                  * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values\r
1559                  * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted\r
1560                  * @param {boolean=} noAssert Whether to not assert for an actual field / proper value type, defaults to `false`\r
1561                  * @returns {!ProtoBuf.Builder.Message} this\r
1562                  * @throws {Error} If the value cannot be set\r
1563                  * @expose\r
1564                  */\r
1565                 MessagePrototype.set = function(keyOrObj, value, noAssert) {\r
1566                     if (keyOrObj && typeof keyOrObj === 'object') {\r
1567                         noAssert = value;\r
1568                         for (var ikey in keyOrObj) {\r
1569                             // Check if virtual oneof field - don't set these\r
1570                             if (keyOrObj.hasOwnProperty(ikey) && typeof (value = keyOrObj[ikey]) !== 'undefined' && T._oneofsByName[ikey] === undefined)\r
1571                                 this.$set(ikey, value, noAssert);\r
1572                         }\r
1573                         return this;\r
1574                     }\r
1575                     var field = T._fieldsByName[keyOrObj];\r
1576                     if (!noAssert) {\r
1577                         if (!field)\r
1578                             throw Error(this+"#"+keyOrObj+" is not a field: undefined");\r
1579                         if (!(field instanceof ProtoBuf.Reflect.Message.Field))\r
1580                             throw Error(this+"#"+keyOrObj+" is not a field: "+field.toString(true));\r
1581                         this[field.name] = (value = field.verifyValue(value)); // May throw\r
1582                     } else\r
1583                         this[keyOrObj] = value;\r
1584                     if (field && field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)\r
1585                         var currentField = this[field.oneof.name]; // Virtual field references currently set field\r
1586                         if (value !== null) {\r
1587                             if (currentField !== null && currentField !== field.name)\r
1588                                 this[currentField] = null; // Clear currently set field\r
1589                             this[field.oneof.name] = field.name; // Point virtual field at this field\r
1590                         } else if (/* value === null && */currentField === keyOrObj)\r
1591                             this[field.oneof.name] = null; // Clear virtual field (current field explicitly cleared)\r
1592                     }\r
1593                     return this;\r
1594                 };\r
1595 \r
1596                 /**\r
1597                  * Sets a field's value. This is an alias for [@link ProtoBuf.Builder.Message#set}.\r
1598                  * @name ProtoBuf.Builder.Message#$set\r
1599                  * @function\r
1600                  * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values\r
1601                  * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted\r
1602                  * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`\r
1603                  * @throws {Error} If the value cannot be set\r
1604                  * @expose\r
1605                  */\r
1606                 MessagePrototype.$set = MessagePrototype.set;\r
1607 \r
1608                 /**\r
1609                  * Gets a field's value.\r
1610                  * @name ProtoBuf.Builder.Message#get\r
1611                  * @function\r
1612                  * @param {string} key Key\r
1613                  * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`\r
1614                  * @return {*} Value\r
1615                  * @throws {Error} If there is no such field\r
1616                  * @expose\r
1617                  */\r
1618                 MessagePrototype.get = function(key, noAssert) {\r
1619                     if (noAssert)\r
1620                         return this[key];\r
1621                     var field = T._fieldsByName[key];\r
1622                     if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))\r
1623                         throw Error(this+"#"+key+" is not a field: undefined");\r
1624                     if (!(field instanceof ProtoBuf.Reflect.Message.Field))\r
1625                         throw Error(this+"#"+key+" is not a field: "+field.toString(true));\r
1626                     return this[field.name];\r
1627                 };\r
1628 \r
1629                 /**\r
1630                  * Gets a field's value. This is an alias for {@link ProtoBuf.Builder.Message#$get}.\r
1631                  * @name ProtoBuf.Builder.Message#$get\r
1632                  * @function\r
1633                  * @param {string} key Key\r
1634                  * @return {*} Value\r
1635                  * @throws {Error} If there is no such field\r
1636                  * @expose\r
1637                  */\r
1638                 MessagePrototype.$get = MessagePrototype.get;\r
1639 \r
1640                 // Getters and setters\r
1641 \r
1642                 for (var i=0; i<fields.length; i++) {\r
1643                     var field = fields[i];\r
1644                     // no setters for extension fields as these are named by their fqn\r
1645                     if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)\r
1646                         continue;\r
1647 \r
1648                     if (T.builder.options['populateAccessors'])\r
1649                         (function(field) {\r
1650                             // set/get[SomeValue]\r
1651                             var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {\r
1652                                 return match.toUpperCase().replace('_','');\r
1653                             });\r
1654                             Name = Name.substring(0,1).toUpperCase() + Name.substring(1);\r
1655 \r
1656                             // set/get_[some_value] FIXME: Do we really need these?\r
1657                             var name = field.originalName.replace(/([A-Z])/g, function(match) {\r
1658                                 return "_"+match;\r
1659                             });\r
1660 \r
1661                             /**\r
1662                              * The current field's unbound setter function.\r
1663                              * @function\r
1664                              * @param {*} value\r
1665                              * @param {boolean=} noAssert\r
1666                              * @returns {!ProtoBuf.Builder.Message}\r
1667                              * @inner\r
1668                              */\r
1669                             var setter = function(value, noAssert) {\r
1670                                 this[field.name] = noAssert ? value : field.verifyValue(value);\r
1671                                 return this;\r
1672                             };\r
1673 \r
1674                             /**\r
1675                              * The current field's unbound getter function.\r
1676                              * @function\r
1677                              * @returns {*}\r
1678                              * @inner\r
1679                              */\r
1680                             var getter = function() {\r
1681                                 return this[field.name];\r
1682                             };\r
1683 \r
1684                             if (T.getChild("set"+Name) === null)\r
1685                                 /**\r
1686                                  * Sets a value. This method is present for each field, but only if there is no name conflict with\r
1687                                  *  another field.\r
1688                                  * @name ProtoBuf.Builder.Message#set[SomeField]\r
1689                                  * @function\r
1690                                  * @param {*} value Value to set\r
1691                                  * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`\r
1692                                  * @returns {!ProtoBuf.Builder.Message} this\r
1693                                  * @abstract\r
1694                                  * @throws {Error} If the value cannot be set\r
1695                                  */\r
1696                                 MessagePrototype["set"+Name] = setter;\r
1697 \r
1698                             if (T.getChild("set_"+name) === null)\r
1699                                 /**\r
1700                                  * Sets a value. This method is present for each field, but only if there is no name conflict with\r
1701                                  *  another field.\r
1702                                  * @name ProtoBuf.Builder.Message#set_[some_field]\r
1703                                  * @function\r
1704                                  * @param {*} value Value to set\r
1705                                  * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`\r
1706                                  * @returns {!ProtoBuf.Builder.Message} this\r
1707                                  * @abstract\r
1708                                  * @throws {Error} If the value cannot be set\r
1709                                  */\r
1710                                 MessagePrototype["set_"+name] = setter;\r
1711 \r
1712                             if (T.getChild("get"+Name) === null)\r
1713                                 /**\r
1714                                  * Gets a value. This method is present for each field, but only if there is no name conflict with\r
1715                                  *  another field.\r
1716                                  * @name ProtoBuf.Builder.Message#get[SomeField]\r
1717                                  * @function\r
1718                                  * @abstract\r
1719                                  * @return {*} The value\r
1720                                  */\r
1721                                 MessagePrototype["get"+Name] = getter;\r
1722 \r
1723                             if (T.getChild("get_"+name) === null)\r
1724                                 /**\r
1725                                  * Gets a value. This method is present for each field, but only if there is no name conflict with\r
1726                                  *  another field.\r
1727                                  * @name ProtoBuf.Builder.Message#get_[some_field]\r
1728                                  * @function\r
1729                                  * @return {*} The value\r
1730                                  * @abstract\r
1731                                  */\r
1732                                 MessagePrototype["get_"+name] = getter;\r
1733 \r
1734                         })(field);\r
1735                 }\r
1736 \r
1737                 // En-/decoding\r
1738 \r
1739                 /**\r
1740                  * Encodes the message.\r
1741                  * @name ProtoBuf.Builder.Message#$encode\r
1742                  * @function\r
1743                  * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.\r
1744                  * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`\r
1745                  * @return {!ByteBuffer} Encoded message as a ByteBuffer\r
1746                  * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still\r
1747                  *  returns the encoded ByteBuffer in the `encoded` property on the error.\r
1748                  * @expose\r
1749                  * @see ProtoBuf.Builder.Message#encode64\r
1750                  * @see ProtoBuf.Builder.Message#encodeHex\r
1751                  * @see ProtoBuf.Builder.Message#encodeAB\r
1752                  */\r
1753                 MessagePrototype.encode = function(buffer, noVerify) {\r
1754                     if (typeof buffer === 'boolean')\r
1755                         noVerify = buffer,\r
1756                         buffer = undefined;\r
1757                     var isNew = false;\r
1758                     if (!buffer)\r
1759                         buffer = new ByteBuffer(),\r
1760                         isNew = true;\r
1761                     var le = buffer.littleEndian;\r
1762                     try {\r
1763                         T.encode(this, buffer.LE(), noVerify);\r
1764                         return (isNew ? buffer.flip() : buffer).LE(le);\r
1765                     } catch (e) {\r
1766                         buffer.LE(le);\r
1767                         throw(e);\r
1768                     }\r
1769                 };\r
1770 \r
1771                 /**\r
1772                  * Encodes a message using the specified data payload.\r
1773                  * @param {!Object.<string,*>} data Data payload\r
1774                  * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.\r
1775                  * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`\r
1776                  * @return {!ByteBuffer} Encoded message as a ByteBuffer\r
1777                  * @expose\r
1778                  */\r
1779                 Message.encode = function(data, buffer, noVerify) {\r
1780                     return new Message(data).encode(buffer, noVerify);\r
1781                 };\r
1782 \r
1783                 /**\r
1784                  * Calculates the byte length of the message.\r
1785                  * @name ProtoBuf.Builder.Message#calculate\r
1786                  * @function\r
1787                  * @returns {number} Byte length\r
1788                  * @throws {Error} If the message cannot be calculated or if required fields are missing.\r
1789                  * @expose\r
1790                  */\r
1791                 MessagePrototype.calculate = function() {\r
1792                     return T.calculate(this);\r
1793                 };\r
1794 \r
1795                 /**\r
1796                  * Encodes the varint32 length-delimited message.\r
1797                  * @name ProtoBuf.Builder.Message#encodeDelimited\r
1798                  * @function\r
1799                  * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.\r
1800                  * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`\r
1801                  * @return {!ByteBuffer} Encoded message as a ByteBuffer\r
1802                  * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still\r
1803                  *  returns the encoded ByteBuffer in the `encoded` property on the error.\r
1804                  * @expose\r
1805                  */\r
1806                 MessagePrototype.encodeDelimited = function(buffer, noVerify) {\r
1807                     var isNew = false;\r
1808                     if (!buffer)\r
1809                         buffer = new ByteBuffer(),\r
1810                         isNew = true;\r
1811                     var enc = new ByteBuffer().LE();\r
1812                     T.encode(this, enc, noVerify).flip();\r
1813                     buffer.writeVarint32(enc.remaining());\r
1814                     buffer.append(enc);\r
1815                     return isNew ? buffer.flip() : buffer;\r
1816                 };\r
1817 \r
1818                 /**\r
1819                  * Directly encodes the message to an ArrayBuffer.\r
1820                  * @name ProtoBuf.Builder.Message#encodeAB\r
1821                  * @function\r
1822                  * @return {ArrayBuffer} Encoded message as ArrayBuffer\r
1823                  * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still\r
1824                  *  returns the encoded ArrayBuffer in the `encoded` property on the error.\r
1825                  * @expose\r
1826                  */\r
1827                 MessagePrototype.encodeAB = function() {\r
1828                     try {\r
1829                         return this.encode().toArrayBuffer();\r
1830                     } catch (e) {\r
1831                         if (e["encoded"]) e["encoded"] = e["encoded"].toArrayBuffer();\r
1832                         throw(e);\r
1833                     }\r
1834                 };\r
1835 \r
1836                 /**\r
1837                  * Returns the message as an ArrayBuffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeAB}.\r
1838                  * @name ProtoBuf.Builder.Message#toArrayBuffer\r
1839                  * @function\r
1840                  * @return {ArrayBuffer} Encoded message as ArrayBuffer\r
1841                  * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still\r
1842                  *  returns the encoded ArrayBuffer in the `encoded` property on the error.\r
1843                  * @expose\r
1844                  */\r
1845                 MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;\r
1846 \r
1847                 /**\r
1848                  * Directly encodes the message to a node Buffer.\r
1849                  * @name ProtoBuf.Builder.Message#encodeNB\r
1850                  * @function\r
1851                  * @return {!Buffer}\r
1852                  * @throws {Error} If the message cannot be encoded, not running under node.js or if required fields are\r
1853                  *  missing. The later still returns the encoded node Buffer in the `encoded` property on the error.\r
1854                  * @expose\r
1855                  */\r
1856                 MessagePrototype.encodeNB = function() {\r
1857                     try {\r
1858                         return this.encode().toBuffer();\r
1859                     } catch (e) {\r
1860                         if (e["encoded"]) e["encoded"] = e["encoded"].toBuffer();\r
1861                         throw(e);\r
1862                     }\r
1863                 };\r
1864 \r
1865                 /**\r
1866                  * Returns the message as a node Buffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeNB}.\r
1867                  * @name ProtoBuf.Builder.Message#toBuffer\r
1868                  * @function\r
1869                  * @return {!Buffer}\r
1870                  * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still\r
1871                  *  returns the encoded node Buffer in the `encoded` property on the error.\r
1872                  * @expose\r
1873                  */\r
1874                 MessagePrototype.toBuffer = MessagePrototype.encodeNB;\r
1875 \r
1876                 /**\r
1877                  * Directly encodes the message to a base64 encoded string.\r
1878                  * @name ProtoBuf.Builder.Message#encode64\r
1879                  * @function\r
1880                  * @return {string} Base64 encoded string\r
1881                  * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later\r
1882                  *  still returns the encoded base64 string in the `encoded` property on the error.\r
1883                  * @expose\r
1884                  */\r
1885                 MessagePrototype.encode64 = function() {\r
1886                     try {\r
1887                         return this.encode().toBase64();\r
1888                     } catch (e) {\r
1889                         if (e["encoded"]) e["encoded"] = e["encoded"].toBase64();\r
1890                         throw(e);\r
1891                     }\r
1892                 };\r
1893 \r
1894                 /**\r
1895                  * Returns the message as a base64 encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encode64}.\r
1896                  * @name ProtoBuf.Builder.Message#toBase64\r
1897                  * @function\r
1898                  * @return {string} Base64 encoded string\r
1899                  * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still\r
1900                  *  returns the encoded base64 string in the `encoded` property on the error.\r
1901                  * @expose\r
1902                  */\r
1903                 MessagePrototype.toBase64 = MessagePrototype.encode64;\r
1904 \r
1905                 /**\r
1906                  * Directly encodes the message to a hex encoded string.\r
1907                  * @name ProtoBuf.Builder.Message#encodeHex\r
1908                  * @function\r
1909                  * @return {string} Hex encoded string\r
1910                  * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later\r
1911                  *  still returns the encoded hex string in the `encoded` property on the error.\r
1912                  * @expose\r
1913                  */\r
1914                 MessagePrototype.encodeHex = function() {\r
1915                     try {\r
1916                         return this.encode().toHex();\r
1917                     } catch (e) {\r
1918                         if (e["encoded"]) e["encoded"] = e["encoded"].toHex();\r
1919                         throw(e);\r
1920                     }\r
1921                 };\r
1922 \r
1923                 /**\r
1924                  * Returns the message as a hex encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encodeHex}.\r
1925                  * @name ProtoBuf.Builder.Message#toHex\r
1926                  * @function\r
1927                  * @return {string} Hex encoded string\r
1928                  * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still\r
1929                  *  returns the encoded hex string in the `encoded` property on the error.\r
1930                  * @expose\r
1931                  */\r
1932                 MessagePrototype.toHex = MessagePrototype.encodeHex;\r
1933 \r
1934                 /**\r
1935                  * Clones a message object or field value to a raw object.\r
1936                  * @param {*} obj Object to clone\r
1937                  * @param {boolean} binaryAsBase64 Whether to include binary data as base64 strings or as a buffer otherwise\r
1938                  * @param {boolean} longsAsStrings Whether to encode longs as strings\r
1939                  * @param {!ProtoBuf.Reflect.T=} resolvedType The resolved field type if a field\r
1940                  * @returns {*} Cloned object\r
1941                  * @inner\r
1942                  */\r
1943                 function cloneRaw(obj, binaryAsBase64, longsAsStrings, resolvedType) {\r
1944                     if (obj === null || typeof obj !== 'object') {\r
1945                         // Convert enum values to their respective names\r
1946                         if (resolvedType && resolvedType instanceof ProtoBuf.Reflect.Enum) {\r
1947                             var name = ProtoBuf.Reflect.Enum.getName(resolvedType.object, obj);\r
1948                             if (name !== null)\r
1949                                 return name;\r
1950                         }\r
1951                         // Pass-through string, number, boolean, null...\r
1952                         return obj;\r
1953                     }\r
1954                     // Convert ByteBuffers to raw buffer or strings\r
1955                     if (ByteBuffer.isByteBuffer(obj))\r
1956                         return binaryAsBase64 ? obj.toBase64() : obj.toBuffer();\r
1957                     // Convert Longs to proper objects or strings\r
1958                     if (ProtoBuf.Long.isLong(obj))\r
1959                         return longsAsStrings ? obj.toString() : ProtoBuf.Long.fromValue(obj);\r
1960                     var clone;\r
1961                     // Clone arrays\r
1962                     if (Array.isArray(obj)) {\r
1963                         clone = [];\r
1964                         obj.forEach(function(v, k) {\r
1965                             clone[k] = cloneRaw(v, binaryAsBase64, longsAsStrings, resolvedType);\r
1966                         });\r
1967                         return clone;\r
1968                     }\r
1969                     clone = {};\r
1970                     // Convert maps to objects\r
1971                     if (obj instanceof ProtoBuf.Map) {\r
1972                         var it = obj.entries();\r
1973                         for (var e = it.next(); !e.done; e = it.next())\r
1974                             clone[obj.keyElem.valueToString(e.value[0])] = cloneRaw(e.value[1], binaryAsBase64, longsAsStrings, obj.valueElem.resolvedType);\r
1975                         return clone;\r
1976                     }\r
1977                     // Everything else is a non-null object\r
1978                     var type = obj.$type,\r
1979                         field = undefined;\r
1980                     for (var i in obj)\r
1981                         if (obj.hasOwnProperty(i)) {\r
1982                             if (type && (field = type.getChild(i)))\r
1983                                 clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings, field.resolvedType);\r
1984                             else\r
1985                                 clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings);\r
1986                         }\r
1987                     return clone;\r
1988                 }\r
1989 \r
1990                 /**\r
1991                  * Returns the message's raw payload.\r
1992                  * @param {boolean=} binaryAsBase64 Whether to include binary data as base64 strings instead of Buffers, defaults to `false`\r
1993                  * @param {boolean} longsAsStrings Whether to encode longs as strings\r
1994                  * @returns {Object.<string,*>} Raw payload\r
1995                  * @expose\r
1996                  */\r
1997                 MessagePrototype.toRaw = function(binaryAsBase64, longsAsStrings) {\r
1998                     return cloneRaw(this, !!binaryAsBase64, !!longsAsStrings, this.$type);\r
1999                 };\r
2000 \r
2001                 /**\r
2002                  * Encodes a message to JSON.\r
2003                  * @returns {string} JSON string\r
2004                  * @expose\r
2005                  */\r
2006                 MessagePrototype.encodeJSON = function() {\r
2007                     return JSON.stringify(\r
2008                         cloneRaw(this,\r
2009                              /* binary-as-base64 */ true,\r
2010                              /* longs-as-strings */ true,\r
2011                              this.$type\r
2012                         )\r
2013                     );\r
2014                 };\r
2015 \r
2016                 /**\r
2017                  * Decodes a message from the specified buffer or string.\r
2018                  * @name ProtoBuf.Builder.Message.decode\r
2019                  * @function\r
2020                  * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from\r
2021                  * @param {(number|string)=} length Message length. Defaults to decode all the remainig data.\r
2022                  * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64\r
2023                  * @return {!ProtoBuf.Builder.Message} Decoded message\r
2024                  * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still\r
2025                  *  returns the decoded message with missing fields in the `decoded` property on the error.\r
2026                  * @expose\r
2027                  * @see ProtoBuf.Builder.Message.decode64\r
2028                  * @see ProtoBuf.Builder.Message.decodeHex\r
2029                  */\r
2030                 Message.decode = function(buffer, length, enc) {\r
2031                     if (typeof length === 'string')\r
2032                         enc = length,\r
2033                         length = -1;\r
2034                     if (typeof buffer === 'string')\r
2035                         buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");\r
2036                     else if (!ByteBuffer.isByteBuffer(buffer))\r
2037                         buffer = ByteBuffer.wrap(buffer); // May throw\r
2038                     var le = buffer.littleEndian;\r
2039                     try {\r
2040                         var msg = T.decode(buffer.LE(), length);\r
2041                         buffer.LE(le);\r
2042                         return msg;\r
2043                     } catch (e) {\r
2044                         buffer.LE(le);\r
2045                         throw(e);\r
2046                     }\r
2047                 };\r
2048 \r
2049                 /**\r
2050                  * Decodes a varint32 length-delimited message from the specified buffer or string.\r
2051                  * @name ProtoBuf.Builder.Message.decodeDelimited\r
2052                  * @function\r
2053                  * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from\r
2054                  * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64\r
2055                  * @return {ProtoBuf.Builder.Message} Decoded message or `null` if not enough bytes are available yet\r
2056                  * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still\r
2057                  *  returns the decoded message with missing fields in the `decoded` property on the error.\r
2058                  * @expose\r
2059                  */\r
2060                 Message.decodeDelimited = function(buffer, enc) {\r
2061                     if (typeof buffer === 'string')\r
2062                         buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");\r
2063                     else if (!ByteBuffer.isByteBuffer(buffer))\r
2064                         buffer = ByteBuffer.wrap(buffer); // May throw\r
2065                     if (buffer.remaining() < 1)\r
2066                         return null;\r
2067                     var off = buffer.offset,\r
2068                         len = buffer.readVarint32();\r
2069                     if (buffer.remaining() < len) {\r
2070                         buffer.offset = off;\r
2071                         return null;\r
2072                     }\r
2073                     try {\r
2074                         var msg = T.decode(buffer.slice(buffer.offset, buffer.offset + len).LE());\r
2075                         buffer.offset += len;\r
2076                         return msg;\r
2077                     } catch (err) {\r
2078                         buffer.offset += len;\r
2079                         throw err;\r
2080                     }\r
2081                 };\r
2082 \r
2083                 /**\r
2084                  * Decodes the message from the specified base64 encoded string.\r
2085                  * @name ProtoBuf.Builder.Message.decode64\r
2086                  * @function\r
2087                  * @param {string} str String to decode from\r
2088                  * @return {!ProtoBuf.Builder.Message} Decoded message\r
2089                  * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still\r
2090                  *  returns the decoded message with missing fields in the `decoded` property on the error.\r
2091                  * @expose\r
2092                  */\r
2093                 Message.decode64 = function(str) {\r
2094                     return Message.decode(str, "base64");\r
2095                 };\r
2096 \r
2097                 /**\r
2098                  * Decodes the message from the specified hex encoded string.\r
2099                  * @name ProtoBuf.Builder.Message.decodeHex\r
2100                  * @function\r
2101                  * @param {string} str String to decode from\r
2102                  * @return {!ProtoBuf.Builder.Message} Decoded message\r
2103                  * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still\r
2104                  *  returns the decoded message with missing fields in the `decoded` property on the error.\r
2105                  * @expose\r
2106                  */\r
2107                 Message.decodeHex = function(str) {\r
2108                     return Message.decode(str, "hex");\r
2109                 };\r
2110 \r
2111                 /**\r
2112                  * Decodes the message from a JSON string.\r
2113                  * @name ProtoBuf.Builder.Message.decodeJSON\r
2114                  * @function\r
2115                  * @param {string} str String to decode from\r
2116                  * @return {!ProtoBuf.Builder.Message} Decoded message\r
2117                  * @throws {Error} If the message cannot be decoded or if required fields are\r
2118                  * missing.\r
2119                  * @expose\r
2120                  */\r
2121                 Message.decodeJSON = function(str) {\r
2122                     return new Message(JSON.parse(str));\r
2123                 };\r
2124 \r
2125                 // Utility\r
2126 \r
2127                 /**\r
2128                  * Returns a string representation of this Message.\r
2129                  * @name ProtoBuf.Builder.Message#toString\r
2130                  * @function\r
2131                  * @return {string} String representation as of ".Fully.Qualified.MessageName"\r
2132                  * @expose\r
2133                  */\r
2134                 MessagePrototype.toString = function() {\r
2135                     return T.toString();\r
2136                 };\r
2137 \r
2138                 // Properties\r
2139 \r
2140                 /**\r
2141                  * Message options.\r
2142                  * @name ProtoBuf.Builder.Message.$options\r
2143                  * @type {Object.<string,*>}\r
2144                  * @expose\r
2145                  */\r
2146                 var $optionsS; // cc needs this\r
2147 \r
2148                 /**\r
2149                  * Message options.\r
2150                  * @name ProtoBuf.Builder.Message#$options\r
2151                  * @type {Object.<string,*>}\r
2152                  * @expose\r
2153                  */\r
2154                 var $options;\r
2155 \r
2156                 /**\r
2157                  * Reflection type.\r
2158                  * @name ProtoBuf.Builder.Message.$type\r
2159                  * @type {!ProtoBuf.Reflect.Message}\r
2160                  * @expose\r
2161                  */\r
2162                 var $typeS;\r
2163 \r
2164                 /**\r
2165                  * Reflection type.\r
2166                  * @name ProtoBuf.Builder.Message#$type\r
2167                  * @type {!ProtoBuf.Reflect.Message}\r
2168                  * @expose\r
2169                  */\r
2170                 var $type;\r
2171 \r
2172                 if (Object.defineProperty)\r
2173                     Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),\r
2174                     Object.defineProperty(MessagePrototype, "$options", { "value": Message["$options"] }),\r
2175                     Object.defineProperty(Message, "$type", { "value": T }),\r
2176                     Object.defineProperty(MessagePrototype, "$type", { "value": T });\r
2177 \r
2178                 return Message;\r
2179 \r
2180             })(ProtoBuf, this);\r
2181 \r
2182             // Static enums and prototyped sub-messages / cached collections\r
2183             this._fields = [];\r
2184             this._fieldsById = {};\r
2185             this._fieldsByName = {};\r
2186             this._oneofsByName = {};\r
2187             for (var i=0, k=this.children.length, child; i<k; i++) {\r
2188                 child = this.children[i];\r
2189                 if (child instanceof Enum || child instanceof Message || child instanceof Service) {\r
2190                     if (clazz.hasOwnProperty(child.name))\r
2191                         throw Error("Illegal reflect child of "+this.toString(true)+": "+child.toString(true)+" cannot override static property '"+child.name+"'");\r
2192                     clazz[child.name] = child.build();\r
2193                 } else if (child instanceof Message.Field)\r
2194                     child.build(),\r
2195                     this._fields.push(child),\r
2196                     this._fieldsById[child.id] = child,\r
2197                     this._fieldsByName[child.name] = child;\r
2198                 else if (child instanceof Message.OneOf) {\r
2199                     this._oneofsByName[child.name] = child;\r
2200                 }\r
2201                 else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built\r
2202                     throw Error("Illegal reflect child of "+this.toString(true)+": "+this.children[i].toString(true));\r
2203             }\r
2204 \r
2205             return this.clazz = clazz;\r
2206         };\r
2207 \r
2208         /**\r
2209          * Encodes a runtime message's contents to the specified buffer.\r
2210          * @param {!ProtoBuf.Builder.Message} message Runtime message to encode\r
2211          * @param {ByteBuffer} buffer ByteBuffer to write to\r
2212          * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`\r
2213          * @return {ByteBuffer} The ByteBuffer for chaining\r
2214          * @throws {Error} If required fields are missing or the message cannot be encoded for another reason\r
2215          * @expose\r
2216          */\r
2217         MessagePrototype.encode = function(message, buffer, noVerify) {\r
2218             var fieldMissing = null,\r
2219                 field;\r
2220             for (var i=0, k=this._fields.length, val; i<k; ++i) {\r
2221                 field = this._fields[i];\r
2222                 val = message[field.name];\r
2223                 if (field.required && val === null) {\r
2224                     if (fieldMissing === null)\r
2225                         fieldMissing = field;\r
2226                 } else\r
2227                     field.encode(noVerify ? val : field.verifyValue(val), buffer, message);\r
2228             }\r
2229             if (fieldMissing !== null) {\r
2230                 var err = Error("Missing at least one required field for "+this.toString(true)+": "+fieldMissing);\r
2231                 err["encoded"] = buffer; // Still expose what we got\r
2232                 throw(err);\r
2233             }\r
2234             return buffer;\r
2235         };\r
2236 \r
2237         /**\r
2238          * Calculates a runtime message's byte length.\r
2239          * @param {!ProtoBuf.Builder.Message} message Runtime message to encode\r
2240          * @returns {number} Byte length\r
2241          * @throws {Error} If required fields are missing or the message cannot be calculated for another reason\r
2242          * @expose\r
2243          */\r
2244         MessagePrototype.calculate = function(message) {\r
2245             for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {\r
2246                 field = this._fields[i];\r
2247                 val = message[field.name];\r
2248                 if (field.required && val === null)\r
2249                    throw Error("Missing at least one required field for "+this.toString(true)+": "+field);\r
2250                 else\r
2251                     n += field.calculate(val, message);\r
2252             }\r
2253             return n;\r
2254         };\r
2255 \r
2256         /**\r
2257          * Skips all data until the end of the specified group has been reached.\r
2258          * @param {number} expectedId Expected GROUPEND id\r
2259          * @param {!ByteBuffer} buf ByteBuffer\r
2260          * @returns {boolean} `true` if a value as been skipped, `false` if the end has been reached\r
2261          * @throws {Error} If it wasn't possible to find the end of the group (buffer overrun or end tag mismatch)\r
2262          * @inner\r
2263          */\r
2264         function skipTillGroupEnd(expectedId, buf) {\r
2265             var tag = buf.readVarint32(), // Throws on OOB\r
2266                 wireType = tag & 0x07,\r
2267                 id = tag >>> 3;\r
2268             switch (wireType) {\r
2269                 case ProtoBuf.WIRE_TYPES.VARINT:\r
2270                     do tag = buf.readUint8();\r
2271                     while ((tag & 0x80) === 0x80);\r
2272                     break;\r
2273                 case ProtoBuf.WIRE_TYPES.BITS64:\r
2274                     buf.offset += 8;\r
2275                     break;\r
2276                 case ProtoBuf.WIRE_TYPES.LDELIM:\r
2277                     tag = buf.readVarint32(); // reads the varint\r
2278                     buf.offset += tag;        // skips n bytes\r
2279                     break;\r
2280                 case ProtoBuf.WIRE_TYPES.STARTGROUP:\r
2281                     skipTillGroupEnd(id, buf);\r
2282                     break;\r
2283                 case ProtoBuf.WIRE_TYPES.ENDGROUP:\r
2284                     if (id === expectedId)\r
2285                         return false;\r
2286                     else\r
2287                         throw Error("Illegal GROUPEND after unknown group: "+id+" ("+expectedId+" expected)");\r
2288                 case ProtoBuf.WIRE_TYPES.BITS32:\r
2289                     buf.offset += 4;\r
2290                     break;\r
2291                 default:\r
2292                     throw Error("Illegal wire type in unknown group "+expectedId+": "+wireType);\r
2293             }\r
2294             return true;\r
2295         }\r
2296 \r
2297         /**\r
2298          * Decodes an encoded message and returns the decoded message.\r
2299          * @param {ByteBuffer} buffer ByteBuffer to decode from\r
2300          * @param {number=} length Message length. Defaults to decode all remaining data.\r
2301          * @param {number=} expectedGroupEndId Expected GROUPEND id if this is a legacy group\r
2302          * @return {ProtoBuf.Builder.Message} Decoded message\r
2303          * @throws {Error} If the message cannot be decoded\r
2304          * @expose\r
2305          */\r
2306         MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {\r
2307             if (typeof length !== 'number')\r
2308                 length = -1;\r
2309             var start = buffer.offset,\r
2310                 msg = new (this.clazz)(),\r
2311                 tag, wireType, id, field;\r
2312             while (buffer.offset < start+length || (length === -1 && buffer.remaining() > 0)) {\r
2313                 tag = buffer.readVarint32();\r
2314                 wireType = tag & 0x07;\r
2315                 id = tag >>> 3;\r
2316                 if (wireType === ProtoBuf.WIRE_TYPES.ENDGROUP) {\r
2317                     if (id !== expectedGroupEndId)\r
2318                         throw Error("Illegal group end indicator for "+this.toString(true)+": "+id+" ("+(expectedGroupEndId ? expectedGroupEndId+" expected" : "not a group")+")");\r
2319                     break;\r
2320                 }\r
2321                 if (!(field = this._fieldsById[id])) {\r
2322                     // "messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing."\r
2323                     switch (wireType) {\r
2324                         case ProtoBuf.WIRE_TYPES.VARINT:\r
2325                             buffer.readVarint32();\r
2326                             break;\r
2327                         case ProtoBuf.WIRE_TYPES.BITS32:\r
2328                             buffer.offset += 4;\r
2329                             break;\r
2330                         case ProtoBuf.WIRE_TYPES.BITS64:\r
2331                             buffer.offset += 8;\r
2332                             break;\r
2333                         case ProtoBuf.WIRE_TYPES.LDELIM:\r
2334                             var len = buffer.readVarint32();\r
2335                             buffer.offset += len;\r
2336                             break;\r
2337                         case ProtoBuf.WIRE_TYPES.STARTGROUP:\r
2338                             while (skipTillGroupEnd(id, buffer)) {}\r
2339                             break;\r
2340                         default:\r
2341                             throw Error("Illegal wire type for unknown field "+id+" in "+this.toString(true)+"#decode: "+wireType);\r
2342                     }\r
2343                     continue;\r
2344                 }\r
2345                 if (field.repeated && !field.options["packed"]) {\r
2346                     msg[field.name].push(field.decode(wireType, buffer));\r
2347                 } else if (field.map) {\r
2348                     var keyval = field.decode(wireType, buffer);\r
2349                     msg[field.name].set(keyval[0], keyval[1]);\r
2350                 } else {\r
2351                     msg[field.name] = field.decode(wireType, buffer);\r
2352                     if (field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)\r
2353                         var currentField = msg[field.oneof.name]; // Virtual field references currently set field\r
2354                         if (currentField !== null && currentField !== field.name)\r
2355                             msg[currentField] = null; // Clear currently set field\r
2356                         msg[field.oneof.name] = field.name; // Point virtual field at this field\r
2357                     }\r
2358                 }\r
2359             }\r
2360 \r
2361             // Check if all required fields are present and set default values for optional fields that are not\r
2362             for (var i=0, k=this._fields.length; i<k; ++i) {\r
2363                 field = this._fields[i];\r
2364                 if (msg[field.name] === null) {\r
2365                     if (this.syntax === "proto3") { // Proto3 sets default values by specification\r
2366                         msg[field.name] = field.defaultValue;\r
2367                     } else if (field.required) {\r
2368                         var err = Error("Missing at least one required field for " + this.toString(true) + ": " + field.name);\r
2369                         err["decoded"] = msg; // Still expose what we got\r
2370                         throw(err);\r
2371                     } else if (ProtoBuf.populateDefaults && field.defaultValue !== null)\r
2372                         msg[field.name] = field.defaultValue;\r
2373                 }\r
2374             }\r
2375             return msg;\r
2376         };\r
2377 \r
2378         /**\r
2379          * @alias ProtoBuf.Reflect.Message\r
2380          * @expose\r
2381          */\r
2382         Reflect.Message = Message;\r
2383 \r
2384         /**\r
2385          * Constructs a new Message Field.\r
2386          * @exports ProtoBuf.Reflect.Message.Field\r
2387          * @param {!ProtoBuf.Builder} builder Builder reference\r
2388          * @param {!ProtoBuf.Reflect.Message} message Message reference\r
2389          * @param {string} rule Rule, one of requried, optional, repeated\r
2390          * @param {string?} keytype Key data type, if any.\r
2391          * @param {string} type Data type, e.g. int32\r
2392          * @param {string} name Field name\r
2393          * @param {number} id Unique field id\r
2394          * @param {Object.<string,*>=} options Options\r
2395          * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf\r
2396          * @param {string?} syntax The syntax level of this definition (e.g., proto3)\r
2397          * @constructor\r
2398          * @extends ProtoBuf.Reflect.T\r
2399          */\r
2400         var Field = function(builder, message, rule, keytype, type, name, id, options, oneof, syntax) {\r
2401             T.call(this, builder, message, name);\r
2402 \r
2403             /**\r
2404              * @override\r
2405              */\r
2406             this.className = "Message.Field";\r
2407 \r
2408             /**\r
2409              * Message field required flag.\r
2410              * @type {boolean}\r
2411              * @expose\r
2412              */\r
2413             this.required = rule === "required";\r
2414 \r
2415             /**\r
2416              * Message field repeated flag.\r
2417              * @type {boolean}\r
2418              * @expose\r
2419              */\r
2420             this.repeated = rule === "repeated";\r
2421 \r
2422             /**\r
2423              * Message field map flag.\r
2424              * @type {boolean}\r
2425              * @expose\r
2426              */\r
2427             this.map = rule === "map";\r
2428 \r
2429             /**\r
2430              * Message field key type. Type reference string if unresolved, protobuf\r
2431              * type if resolved. Valid only if this.map === true, null otherwise.\r
2432              * @type {string|{name: string, wireType: number}|null}\r
2433              * @expose\r
2434              */\r
2435             this.keyType = keytype || null;\r
2436 \r
2437             /**\r
2438              * Message field type. Type reference string if unresolved, protobuf type if\r
2439              * resolved. In a map field, this is the value type.\r
2440              * @type {string|{name: string, wireType: number}}\r
2441              * @expose\r
2442              */\r
2443             this.type = type;\r
2444 \r
2445             /**\r
2446              * Resolved type reference inside the global namespace.\r
2447              * @type {ProtoBuf.Reflect.T|null}\r
2448              * @expose\r
2449              */\r
2450             this.resolvedType = null;\r
2451 \r
2452             /**\r
2453              * Unique message field id.\r
2454              * @type {number}\r
2455              * @expose\r
2456              */\r
2457             this.id = id;\r
2458 \r
2459             /**\r
2460              * Message field options.\r
2461              * @type {!Object.<string,*>}\r
2462              * @dict\r
2463              * @expose\r
2464              */\r
2465             this.options = options || {};\r
2466 \r
2467             /**\r
2468              * Default value.\r
2469              * @type {*}\r
2470              * @expose\r
2471              */\r
2472             this.defaultValue = null;\r
2473 \r
2474             /**\r
2475              * Enclosing OneOf.\r
2476              * @type {?ProtoBuf.Reflect.Message.OneOf}\r
2477              * @expose\r
2478              */\r
2479             this.oneof = oneof || null;\r
2480 \r
2481             /**\r
2482              * Syntax level of this definition (e.g., proto3).\r
2483              * @type {string}\r
2484              * @expose\r
2485              */\r
2486             this.syntax = syntax || 'proto2';\r
2487 \r
2488             /**\r
2489              * Original field name.\r
2490              * @type {string}\r
2491              * @expose\r
2492              */\r
2493             this.originalName = this.name; // Used to revert camelcase transformation on naming collisions\r
2494 \r
2495             /**\r
2496              * Element implementation. Created in build() after types are resolved.\r
2497              * @type {ProtoBuf.Element}\r
2498              * @expose\r
2499              */\r
2500             this.element = null;\r
2501 \r
2502             /**\r
2503              * Key element implementation, for map fields. Created in build() after\r
2504              * types are resolved.\r
2505              * @type {ProtoBuf.Element}\r
2506              * @expose\r
2507              */\r
2508             this.keyElement = null;\r
2509 \r
2510             // Convert field names to camel case notation if the override is set\r
2511             if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))\r
2512                 this.name = ProtoBuf.Util.toCamelCase(this.name);\r
2513         };\r
2514 \r
2515         /**\r
2516          * @alias ProtoBuf.Reflect.Message.Field.prototype\r
2517          * @inner\r
2518          */\r
2519         var FieldPrototype = Field.prototype = Object.create(T.prototype);\r
2520 \r
2521         /**\r
2522          * Builds the field.\r
2523          * @override\r
2524          * @expose\r
2525          */\r
2526         FieldPrototype.build = function() {\r
2527             this.element = new Element(this.type, this.resolvedType, false, this.syntax, this.name);\r
2528             if (this.map)\r
2529                 this.keyElement = new Element(this.keyType, undefined, true, this.syntax, this.name);\r
2530 \r
2531             // In proto3, fields do not have field presence, and every field is set to\r
2532             // its type's default value ("", 0, 0.0, or false).\r
2533             if (this.syntax === 'proto3' && !this.repeated && !this.map)\r
2534                 this.defaultValue = Element.defaultFieldValue(this.type);\r
2535 \r
2536             // Otherwise, default values are present when explicitly specified\r
2537             else if (typeof this.options['default'] !== 'undefined')\r
2538                 this.defaultValue = this.verifyValue(this.options['default']);\r
2539         };\r
2540 \r
2541         /**\r
2542          * Checks if the given value can be set for this field.\r
2543          * @param {*} value Value to check\r
2544          * @param {boolean=} skipRepeated Whether to skip the repeated value check or not. Defaults to false.\r
2545          * @return {*} Verified, maybe adjusted, value\r
2546          * @throws {Error} If the value cannot be set for this field\r
2547          * @expose\r
2548          */\r
2549         FieldPrototype.verifyValue = function(value, skipRepeated) {\r
2550             skipRepeated = skipRepeated || false;\r
2551             var self = this;\r
2552             function fail(val, msg) {\r
2553                 throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");\r
2554             }\r
2555             if (value === null) { // NULL values for optional fields\r
2556                 if (this.required)\r
2557                     fail(typeof value, "required");\r
2558                 if (this.syntax === 'proto3' && this.type !== ProtoBuf.TYPES["message"])\r
2559                     fail(typeof value, "proto3 field without field presence cannot be null");\r
2560                 return null;\r
2561             }\r
2562             var i;\r
2563             if (this.repeated && !skipRepeated) { // Repeated values as arrays\r
2564                 if (!Array.isArray(value))\r
2565                     value = [value];\r
2566                 var res = [];\r
2567                 for (i=0; i<value.length; i++)\r
2568                     res.push(this.element.verifyValue(value[i]));\r
2569                 return res;\r
2570             }\r
2571             if (this.map && !skipRepeated) { // Map values as objects\r
2572                 if (!(value instanceof ProtoBuf.Map)) {\r
2573                     // If not already a Map, attempt to convert.\r
2574                     if (!(value instanceof Object)) {\r
2575                         fail(typeof value,\r
2576                              "expected ProtoBuf.Map or raw object for map field");\r
2577                     }\r
2578                     return new ProtoBuf.Map(this, value);\r
2579                 } else {\r
2580                     return value;\r
2581                 }\r
2582             }\r
2583             // All non-repeated fields expect no array\r
2584             if (!this.repeated && Array.isArray(value))\r
2585                 fail(typeof value, "no array expected");\r
2586 \r
2587             return this.element.verifyValue(value);\r
2588         };\r
2589 \r
2590         /**\r
2591          * Determines whether the field will have a presence on the wire given its\r
2592          * value.\r
2593          * @param {*} value Verified field value\r
2594          * @param {!ProtoBuf.Builder.Message} message Runtime message\r
2595          * @return {boolean} Whether the field will be present on the wire\r
2596          */\r
2597         FieldPrototype.hasWirePresence = function(value, message) {\r
2598             if (this.syntax !== 'proto3')\r
2599                 return (value !== null);\r
2600             if (this.oneof && message[this.oneof.name] === this.name)\r
2601                 return true;\r
2602             switch (this.type) {\r
2603                 case ProtoBuf.TYPES["int32"]:\r
2604                 case ProtoBuf.TYPES["sint32"]:\r
2605                 case ProtoBuf.TYPES["sfixed32"]:\r
2606                 case ProtoBuf.TYPES["uint32"]:\r
2607                 case ProtoBuf.TYPES["fixed32"]:\r
2608                     return value !== 0;\r
2609 \r
2610                 case ProtoBuf.TYPES["int64"]:\r
2611                 case ProtoBuf.TYPES["sint64"]:\r
2612                 case ProtoBuf.TYPES["sfixed64"]:\r
2613                 case ProtoBuf.TYPES["uint64"]:\r
2614                 case ProtoBuf.TYPES["fixed64"]:\r
2615                     return value.low !== 0 || value.high !== 0;\r
2616 \r
2617                 case ProtoBuf.TYPES["bool"]:\r
2618                     return value;\r
2619 \r
2620                 case ProtoBuf.TYPES["float"]:\r
2621                 case ProtoBuf.TYPES["double"]:\r
2622                     return value !== 0.0;\r
2623 \r
2624                 case ProtoBuf.TYPES["string"]:\r
2625                     return value.length > 0;\r
2626 \r
2627                 case ProtoBuf.TYPES["bytes"]:\r
2628                     return value.remaining() > 0;\r
2629 \r
2630                 case ProtoBuf.TYPES["enum"]:\r
2631                     return value !== 0;\r
2632 \r
2633                 case ProtoBuf.TYPES["message"]:\r
2634                     return value !== null;\r
2635                 default:\r
2636                     return true;\r
2637             }\r
2638         };\r
2639 \r
2640         /**\r
2641          * Encodes the specified field value to the specified buffer.\r
2642          * @param {*} value Verified field value\r
2643          * @param {ByteBuffer} buffer ByteBuffer to encode to\r
2644          * @param {!ProtoBuf.Builder.Message} message Runtime message\r
2645          * @return {ByteBuffer} The ByteBuffer for chaining\r
2646          * @throws {Error} If the field cannot be encoded\r
2647          * @expose\r
2648          */\r
2649         FieldPrototype.encode = function(value, buffer, message) {\r
2650             if (this.type === null || typeof this.type !== 'object')\r
2651                 throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);\r
2652             if (value === null || (this.repeated && value.length == 0))\r
2653                 return buffer; // Optional omitted\r
2654             try {\r
2655                 if (this.repeated) {\r
2656                     var i;\r
2657                     // "Only repeated fields of primitive numeric types (types which use the varint, 32-bit, or 64-bit wire\r
2658                     // types) can be declared 'packed'."\r
2659                     if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {\r
2660                         // "All of the elements of the field are packed into a single key-value pair with wire type 2\r
2661                         // (length-delimited). Each element is encoded the same way it would be normally, except without a\r
2662                         // tag preceding it."\r
2663                         buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);\r
2664                         buffer.ensureCapacity(buffer.offset += 1); // We do not know the length yet, so let's assume a varint of length 1\r
2665                         var start = buffer.offset; // Remember where the contents begin\r
2666                         for (i=0; i<value.length; i++)\r
2667                             this.element.encodeValue(this.id, value[i], buffer);\r
2668                         var len = buffer.offset-start,\r
2669                             varintLen = ByteBuffer.calculateVarint32(len);\r
2670                         if (varintLen > 1) { // We need to move the contents\r
2671                             var contents = buffer.slice(start, buffer.offset);\r
2672                             start += varintLen-1;\r
2673                             buffer.offset = start;\r
2674                             buffer.append(contents);\r
2675                         }\r
2676                         buffer.writeVarint32(len, start-varintLen);\r
2677                     } else {\r
2678                         // "If your message definition has repeated elements (without the [packed=true] option), the encoded\r
2679                         // message has zero or more key-value pairs with the same tag number"\r
2680                         for (i=0; i<value.length; i++)\r
2681                             buffer.writeVarint32((this.id << 3) | this.type.wireType),\r
2682                             this.element.encodeValue(this.id, value[i], buffer);\r
2683                     }\r
2684                 } else if (this.map) {\r
2685                     // Write out each map entry as a submessage.\r
2686                     value.forEach(function(val, key, m) {\r
2687                         // Compute the length of the submessage (key, val) pair.\r
2688                         var length =\r
2689                             ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +\r
2690                             this.keyElement.calculateLength(1, key) +\r
2691                             ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +\r
2692                             this.element.calculateLength(2, val);\r
2693 \r
2694                         // Submessage with wire type of length-delimited.\r
2695                         buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);\r
2696                         buffer.writeVarint32(length);\r
2697 \r
2698                         // Write out the key and val.\r
2699                         buffer.writeVarint32((1 << 3) | this.keyType.wireType);\r
2700                         this.keyElement.encodeValue(1, key, buffer);\r
2701                         buffer.writeVarint32((2 << 3) | this.type.wireType);\r
2702                         this.element.encodeValue(2, val, buffer);\r
2703                     }, this);\r
2704                 } else {\r
2705                     if (this.hasWirePresence(value, message)) {\r
2706                         buffer.writeVarint32((this.id << 3) | this.type.wireType);\r
2707                         this.element.encodeValue(this.id, value, buffer);\r
2708                     }\r
2709                 }\r
2710             } catch (e) {\r
2711                 throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");\r
2712             }\r
2713             return buffer;\r
2714         };\r
2715 \r
2716         /**\r
2717          * Calculates the length of this field's value on the network level.\r
2718          * @param {*} value Field value\r
2719          * @param {!ProtoBuf.Builder.Message} message Runtime message\r
2720          * @returns {number} Byte length\r
2721          * @expose\r
2722          */\r
2723         FieldPrototype.calculate = function(value, message) {\r
2724             value = this.verifyValue(value); // May throw\r
2725             if (this.type === null || typeof this.type !== 'object')\r
2726                 throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);\r
2727             if (value === null || (this.repeated && value.length == 0))\r
2728                 return 0; // Optional omitted\r
2729             var n = 0;\r
2730             try {\r
2731                 if (this.repeated) {\r
2732                     var i, ni;\r
2733                     if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {\r
2734                         n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);\r
2735                         ni = 0;\r
2736                         for (i=0; i<value.length; i++)\r
2737                             ni += this.element.calculateLength(this.id, value[i]);\r
2738                         n += ByteBuffer.calculateVarint32(ni);\r
2739                         n += ni;\r
2740                     } else {\r
2741                         for (i=0; i<value.length; i++)\r
2742                             n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType),\r
2743                             n += this.element.calculateLength(this.id, value[i]);\r
2744                     }\r
2745                 } else if (this.map) {\r
2746                     // Each map entry becomes a submessage.\r
2747                     value.forEach(function(val, key, m) {\r
2748                         // Compute the length of the submessage (key, val) pair.\r
2749                         var length =\r
2750                             ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +\r
2751                             this.keyElement.calculateLength(1, key) +\r
2752                             ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +\r
2753                             this.element.calculateLength(2, val);\r
2754 \r
2755                         n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);\r
2756                         n += ByteBuffer.calculateVarint32(length);\r
2757                         n += length;\r
2758                     }, this);\r
2759                 } else {\r
2760                     if (this.hasWirePresence(value, message)) {\r
2761                         n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType);\r
2762                         n += this.element.calculateLength(this.id, value);\r
2763                     }\r
2764                 }\r
2765             } catch (e) {\r
2766                 throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");\r
2767             }\r
2768             return n;\r
2769         };\r
2770 \r
2771         /**\r
2772          * Decode the field value from the specified buffer.\r
2773          * @param {number} wireType Leading wire type\r
2774          * @param {ByteBuffer} buffer ByteBuffer to decode from\r
2775          * @param {boolean=} skipRepeated Whether to skip the repeated check or not. Defaults to false.\r
2776          * @return {*} Decoded value: array for packed repeated fields, [key, value] for\r
2777          *             map fields, or an individual value otherwise.\r
2778          * @throws {Error} If the field cannot be decoded\r
2779          * @expose\r
2780          */\r
2781         FieldPrototype.decode = function(wireType, buffer, skipRepeated) {\r
2782             var value, nBytes;\r
2783 \r
2784             // We expect wireType to match the underlying type's wireType unless we see\r
2785             // a packed repeated field, or unless this is a map field.\r
2786             var wireTypeOK =\r
2787                 (!this.map && wireType == this.type.wireType) ||\r
2788                 (!skipRepeated && this.repeated && this.options["packed"] &&\r
2789                  wireType == ProtoBuf.WIRE_TYPES.LDELIM) ||\r
2790                 (this.map && wireType == ProtoBuf.WIRE_TYPES.LDELIM);\r
2791             if (!wireTypeOK)\r
2792                 throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");\r
2793 \r
2794             // Handle packed repeated fields.\r
2795             if (wireType == ProtoBuf.WIRE_TYPES.LDELIM && this.repeated && this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {\r
2796                 if (!skipRepeated) {\r
2797                     nBytes = buffer.readVarint32();\r
2798                     nBytes = buffer.offset + nBytes; // Limit\r
2799                     var values = [];\r
2800                     while (buffer.offset < nBytes)\r
2801                         values.push(this.decode(this.type.wireType, buffer, true));\r
2802                     return values;\r
2803                 }\r
2804                 // Read the next value otherwise...\r
2805             }\r
2806 \r
2807             // Handle maps.\r
2808             if (this.map) {\r
2809                 // Read one (key, value) submessage, and return [key, value]\r
2810                 var key = Element.defaultFieldValue(this.keyType);\r
2811                 value = Element.defaultFieldValue(this.type);\r
2812 \r
2813                 // Read the length\r
2814                 nBytes = buffer.readVarint32();\r
2815                 if (buffer.remaining() < nBytes)\r
2816                     throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());\r
2817 \r
2818                 // Get a sub-buffer of this key/value submessage\r
2819                 var msgbuf = buffer.clone();\r
2820                 msgbuf.limit = msgbuf.offset + nBytes;\r
2821                 buffer.offset += nBytes;\r
2822 \r
2823                 while (msgbuf.remaining() > 0) {\r
2824                     var tag = msgbuf.readVarint32();\r
2825                     wireType = tag & 0x07;\r
2826                     var id = tag >>> 3;\r
2827                     if (id === 1) {\r
2828                         key = this.keyElement.decode(msgbuf, wireType, id);\r
2829                     } else if (id === 2) {\r
2830                         value = this.element.decode(msgbuf, wireType, id);\r
2831                     } else {\r
2832                         throw Error("Unexpected tag in map field key/value submessage");\r
2833                     }\r
2834                 }\r
2835 \r
2836                 return [key, value];\r
2837             }\r
2838 \r
2839             // Handle singular and non-packed repeated field values.\r
2840             return this.element.decode(buffer, wireType, this.id);\r
2841         };\r
2842 \r
2843         /**\r
2844          * @alias ProtoBuf.Reflect.Message.Field\r
2845          * @expose\r
2846          */\r
2847         Reflect.Message.Field = Field;\r
2848 \r
2849         /**\r
2850          * Constructs a new Message ExtensionField.\r
2851          * @exports ProtoBuf.Reflect.Message.ExtensionField\r
2852          * @param {!ProtoBuf.Builder} builder Builder reference\r
2853          * @param {!ProtoBuf.Reflect.Message} message Message reference\r
2854          * @param {string} rule Rule, one of requried, optional, repeated\r
2855          * @param {string} type Data type, e.g. int32\r
2856          * @param {string} name Field name\r
2857          * @param {number} id Unique field id\r
2858          * @param {!Object.<string,*>=} options Options\r
2859          * @constructor\r
2860          * @extends ProtoBuf.Reflect.Message.Field\r
2861          */\r
2862         var ExtensionField = function(builder, message, rule, type, name, id, options) {\r
2863             Field.call(this, builder, message, rule, /* keytype = */ null, type, name, id, options);\r
2864 \r
2865             /**\r
2866              * Extension reference.\r
2867              * @type {!ProtoBuf.Reflect.Extension}\r
2868              * @expose\r
2869              */\r
2870             this.extension;\r
2871         };\r
2872 \r
2873         // Extends Field\r
2874         ExtensionField.prototype = Object.create(Field.prototype);\r
2875 \r
2876         /**\r
2877          * @alias ProtoBuf.Reflect.Message.ExtensionField\r
2878          * @expose\r
2879          */\r
2880         Reflect.Message.ExtensionField = ExtensionField;\r
2881 \r
2882         /**\r
2883          * Constructs a new Message OneOf.\r
2884          * @exports ProtoBuf.Reflect.Message.OneOf\r
2885          * @param {!ProtoBuf.Builder} builder Builder reference\r
2886          * @param {!ProtoBuf.Reflect.Message} message Message reference\r
2887          * @param {string} name OneOf name\r
2888          * @constructor\r
2889          * @extends ProtoBuf.Reflect.T\r
2890          */\r
2891         var OneOf = function(builder, message, name) {\r
2892             T.call(this, builder, message, name);\r
2893 \r
2894             /**\r
2895              * Enclosed fields.\r
2896              * @type {!Array.<!ProtoBuf.Reflect.Message.Field>}\r
2897              * @expose\r
2898              */\r
2899             this.fields = [];\r
2900         };\r
2901 \r
2902         /**\r
2903          * @alias ProtoBuf.Reflect.Message.OneOf\r
2904          * @expose\r
2905          */\r
2906         Reflect.Message.OneOf = OneOf;\r
2907 \r
2908         /**\r
2909          * Constructs a new Enum.\r
2910          * @exports ProtoBuf.Reflect.Enum\r
2911          * @param {!ProtoBuf.Builder} builder Builder reference\r
2912          * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object\r
2913          * @param {string} name Enum name\r
2914          * @param {Object.<string,*>=} options Enum options\r
2915          * @param {string?} syntax The syntax level (e.g., proto3)\r
2916          * @constructor\r
2917          * @extends ProtoBuf.Reflect.Namespace\r
2918          */\r
2919         var Enum = function(builder, parent, name, options, syntax) {\r
2920             Namespace.call(this, builder, parent, name, options, syntax);\r
2921 \r
2922             /**\r
2923              * @override\r
2924              */\r
2925             this.className = "Enum";\r
2926 \r
2927             /**\r
2928              * Runtime enum object.\r
2929              * @type {Object.<string,number>|null}\r
2930              * @expose\r
2931              */\r
2932             this.object = null;\r
2933         };\r
2934 \r
2935         /**\r
2936          * Gets the string name of an enum value.\r
2937          * @param {!ProtoBuf.Builder.Enum} enm Runtime enum\r
2938          * @param {number} value Enum value\r
2939          * @returns {?string} Name or `null` if not present\r
2940          * @expose\r
2941          */\r
2942         Enum.getName = function(enm, value) {\r
2943             var keys = Object.keys(enm);\r
2944             for (var i=0, key; i<keys.length; ++i)\r
2945                 if (enm[key = keys[i]] === value)\r
2946                     return key;\r
2947             return null;\r
2948         };\r
2949 \r
2950         /**\r
2951          * @alias ProtoBuf.Reflect.Enum.prototype\r
2952          * @inner\r
2953          */\r
2954         var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);\r
2955 \r
2956         /**\r
2957          * Builds this enum and returns the runtime counterpart.\r
2958          * @param {boolean} rebuild Whether to rebuild or not, defaults to false\r
2959          * @returns {!Object.<string,number>}\r
2960          * @expose\r
2961          */\r
2962         EnumPrototype.build = function(rebuild) {\r
2963             if (this.object && !rebuild)\r
2964                 return this.object;\r
2965             var enm = new ProtoBuf.Builder.Enum(),\r
2966                 values = this.getChildren(Enum.Value);\r
2967             for (var i=0, k=values.length; i<k; ++i)\r
2968                 enm[values[i]['name']] = values[i]['id'];\r
2969             if (Object.defineProperty)\r
2970                 Object.defineProperty(enm, '$options', {\r
2971                     "value": this.buildOpt(),\r
2972                     "enumerable": false\r
2973                 });\r
2974             return this.object = enm;\r
2975         };\r
2976 \r
2977         /**\r
2978          * @alias ProtoBuf.Reflect.Enum\r
2979          * @expose\r
2980          */\r
2981         Reflect.Enum = Enum;\r
2982 \r
2983         /**\r
2984          * Constructs a new Enum Value.\r
2985          * @exports ProtoBuf.Reflect.Enum.Value\r
2986          * @param {!ProtoBuf.Builder} builder Builder reference\r
2987          * @param {!ProtoBuf.Reflect.Enum} enm Enum reference\r
2988          * @param {string} name Field name\r
2989          * @param {number} id Unique field id\r
2990          * @constructor\r
2991          * @extends ProtoBuf.Reflect.T\r
2992          */\r
2993         var Value = function(builder, enm, name, id) {\r
2994             T.call(this, builder, enm, name);\r
2995 \r
2996             /**\r
2997              * @override\r
2998              */\r
2999             this.className = "Enum.Value";\r
3000 \r
3001             /**\r
3002              * Unique enum value id.\r
3003              * @type {number}\r
3004              * @expose\r
3005              */\r
3006             this.id = id;\r
3007         };\r
3008 \r
3009         // Extends T\r
3010         Value.prototype = Object.create(T.prototype);\r
3011 \r
3012         /**\r
3013          * @alias ProtoBuf.Reflect.Enum.Value\r
3014          * @expose\r
3015          */\r
3016         Reflect.Enum.Value = Value;\r
3017 \r
3018         /**\r
3019          * An extension (field).\r
3020          * @exports ProtoBuf.Reflect.Extension\r
3021          * @constructor\r
3022          * @param {!ProtoBuf.Builder} builder Builder reference\r
3023          * @param {!ProtoBuf.Reflect.T} parent Parent object\r
3024          * @param {string} name Object name\r
3025          * @param {!ProtoBuf.Reflect.Message.Field} field Extension field\r
3026          */\r
3027         var Extension = function(builder, parent, name, field) {\r
3028             T.call(this, builder, parent, name);\r
3029 \r
3030             /**\r
3031              * Extended message field.\r
3032              * @type {!ProtoBuf.Reflect.Message.Field}\r
3033              * @expose\r
3034              */\r
3035             this.field = field;\r
3036         };\r
3037 \r
3038         // Extends T\r
3039         Extension.prototype = Object.create(T.prototype);\r
3040 \r
3041         /**\r
3042          * @alias ProtoBuf.Reflect.Extension\r
3043          * @expose\r
3044          */\r
3045         Reflect.Extension = Extension;\r
3046 \r
3047         /**\r
3048          * Constructs a new Service.\r
3049          * @exports ProtoBuf.Reflect.Service\r
3050          * @param {!ProtoBuf.Builder} builder Builder reference\r
3051          * @param {!ProtoBuf.Reflect.Namespace} root Root\r
3052          * @param {string} name Service name\r
3053          * @param {Object.<string,*>=} options Options\r
3054          * @constructor\r
3055          * @extends ProtoBuf.Reflect.Namespace\r
3056          */\r
3057         var Service = function(builder, root, name, options) {\r
3058             Namespace.call(this, builder, root, name, options);\r
3059 \r
3060             /**\r
3061              * @override\r
3062              */\r
3063             this.className = "Service";\r
3064 \r
3065             /**\r
3066              * Built runtime service class.\r
3067              * @type {?function(new:ProtoBuf.Builder.Service)}\r
3068              */\r
3069             this.clazz = null;\r
3070         };\r
3071 \r
3072         /**\r
3073          * @alias ProtoBuf.Reflect.Service.prototype\r
3074          * @inner\r
3075          */\r
3076         var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);\r
3077 \r
3078         /**\r
3079          * Builds the service and returns the runtime counterpart, which is a fully functional class.\r
3080          * @see ProtoBuf.Builder.Service\r
3081          * @param {boolean=} rebuild Whether to rebuild or not\r
3082          * @return {Function} Service class\r
3083          * @throws {Error} If the message cannot be built\r
3084          * @expose\r
3085          */\r
3086         ServicePrototype.build = function(rebuild) {\r
3087             if (this.clazz && !rebuild)\r
3088                 return this.clazz;\r
3089 \r
3090             // Create the runtime Service class in its own scope\r
3091             return this.clazz = (function(ProtoBuf, T) {\r
3092 \r
3093                 /**\r
3094                  * Constructs a new runtime Service.\r
3095                  * @name ProtoBuf.Builder.Service\r
3096                  * @param {function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))=} rpcImpl RPC implementation receiving the method name and the message\r
3097                  * @class Barebone of all runtime services.\r
3098                  * @constructor\r
3099                  * @throws {Error} If the service cannot be created\r
3100                  */\r
3101                 var Service = function(rpcImpl) {\r
3102                     ProtoBuf.Builder.Service.call(this);\r
3103 \r
3104                     /**\r
3105                      * Service implementation.\r
3106                      * @name ProtoBuf.Builder.Service#rpcImpl\r
3107                      * @type {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))}\r
3108                      * @expose\r
3109                      */\r
3110                     this.rpcImpl = rpcImpl || function(name, msg, callback) {\r
3111                         // This is what a user has to implement: A function receiving the method name, the actual message to\r
3112                         // send (type checked) and the callback that's either provided with the error as its first\r
3113                         // argument or null and the actual response message.\r
3114                         setTimeout(callback.bind(this, Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")), 0); // Must be async!\r
3115                     };\r
3116                 };\r
3117 \r
3118                 /**\r
3119                  * @alias ProtoBuf.Builder.Service.prototype\r
3120                  * @inner\r
3121                  */\r
3122                 var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);\r
3123 \r
3124                 /**\r
3125                  * Asynchronously performs an RPC call using the given RPC implementation.\r
3126                  * @name ProtoBuf.Builder.Service.[Method]\r
3127                  * @function\r
3128                  * @param {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))} rpcImpl RPC implementation\r
3129                  * @param {ProtoBuf.Builder.Message} req Request\r
3130                  * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving\r
3131                  *  the error if any and the response either as a pre-parsed message or as its raw bytes\r
3132                  * @abstract\r
3133                  */\r
3134 \r
3135                 /**\r
3136                  * Asynchronously performs an RPC call using the instance's RPC implementation.\r
3137                  * @name ProtoBuf.Builder.Service#[Method]\r
3138                  * @function\r
3139                  * @param {ProtoBuf.Builder.Message} req Request\r
3140                  * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving\r
3141                  *  the error if any and the response either as a pre-parsed message or as its raw bytes\r
3142                  * @abstract\r
3143                  */\r
3144 \r
3145                 var rpc = T.getChildren(ProtoBuf.Reflect.Service.RPCMethod);\r
3146                 for (var i=0; i<rpc.length; i++) {\r
3147                     (function(method) {\r
3148 \r
3149                         // service#Method(message, callback)\r
3150                         ServicePrototype[method.name] = function(req, callback) {\r
3151                             try {\r
3152                                 try {\r
3153                                     // If given as a buffer, decode the request. Will throw a TypeError if not a valid buffer.\r
3154                                     req = method.resolvedRequestType.clazz.decode(ByteBuffer.wrap(req));\r
3155                                 } catch (err) {\r
3156                                     if (!(err instanceof TypeError))\r
3157                                         throw err;\r
3158                                 }\r
3159                                 if (req === null || typeof req !== 'object')\r
3160                                     throw Error("Illegal arguments");\r
3161                                 if (!(req instanceof method.resolvedRequestType.clazz))\r
3162                                     req = new method.resolvedRequestType.clazz(req);\r
3163                                 this.rpcImpl(method.fqn(), req, function(err, res) { // Assumes that this is properly async\r
3164                                     if (err) {\r
3165                                         callback(err);\r
3166                                         return;\r
3167                                     }\r
3168                                     // Coalesce to empty string when service response has empty content\r
3169                                     if (res === null)\r
3170                                         res = ''\r
3171                                     try { res = method.resolvedResponseType.clazz.decode(res); } catch (notABuffer) {}\r
3172                                     if (!res || !(res instanceof method.resolvedResponseType.clazz)) {\r
3173                                         callback(Error("Illegal response type received in service method "+ T.name+"#"+method.name));\r
3174                                         return;\r
3175                                     }\r
3176                                     callback(null, res);\r
3177                                 });\r
3178                             } catch (err) {\r
3179                                 setTimeout(callback.bind(this, err), 0);\r
3180                             }\r
3181                         };\r
3182 \r
3183                         // Service.Method(rpcImpl, message, callback)\r
3184                         Service[method.name] = function(rpcImpl, req, callback) {\r
3185                             new Service(rpcImpl)[method.name](req, callback);\r
3186                         };\r
3187 \r
3188                         if (Object.defineProperty)\r
3189                             Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),\r
3190                             Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });\r
3191                     })(rpc[i]);\r
3192                 }\r
3193 \r
3194                 // Properties\r
3195 \r
3196                 /**\r
3197                  * Service options.\r
3198                  * @name ProtoBuf.Builder.Service.$options\r
3199                  * @type {Object.<string,*>}\r
3200                  * @expose\r
3201                  */\r
3202                 var $optionsS; // cc needs this\r
3203 \r
3204                 /**\r
3205                  * Service options.\r
3206                  * @name ProtoBuf.Builder.Service#$options\r
3207                  * @type {Object.<string,*>}\r
3208                  * @expose\r
3209                  */\r
3210                 var $options;\r
3211 \r
3212                 /**\r
3213                  * Reflection type.\r
3214                  * @name ProtoBuf.Builder.Service.$type\r
3215                  * @type {!ProtoBuf.Reflect.Service}\r
3216                  * @expose\r
3217                  */\r
3218                 var $typeS;\r
3219 \r
3220                 /**\r
3221                  * Reflection type.\r
3222                  * @name ProtoBuf.Builder.Service#$type\r
3223                  * @type {!ProtoBuf.Reflect.Service}\r
3224                  * @expose\r
3225                  */\r
3226                 var $type;\r
3227 \r
3228                 if (Object.defineProperty)\r
3229                     Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),\r
3230                     Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] }),\r
3231                     Object.defineProperty(Service, "$type", { "value": T }),\r
3232                     Object.defineProperty(ServicePrototype, "$type", { "value": T });\r
3233 \r
3234                 return Service;\r
3235 \r
3236             })(ProtoBuf, this);\r
3237         };\r
3238 \r
3239         /**\r
3240          * @alias ProtoBuf.Reflect.Service\r
3241          * @expose\r
3242          */\r
3243         Reflect.Service = Service;\r
3244 \r
3245         /**\r
3246          * Abstract service method.\r
3247          * @exports ProtoBuf.Reflect.Service.Method\r
3248          * @param {!ProtoBuf.Builder} builder Builder reference\r
3249          * @param {!ProtoBuf.Reflect.Service} svc Service\r
3250          * @param {string} name Method name\r
3251          * @param {Object.<string,*>=} options Options\r
3252          * @constructor\r
3253          * @extends ProtoBuf.Reflect.T\r
3254          */\r
3255         var Method = function(builder, svc, name, options) {\r
3256             T.call(this, builder, svc, name);\r
3257 \r
3258             /**\r
3259              * @override\r
3260              */\r
3261             this.className = "Service.Method";\r
3262 \r
3263             /**\r
3264              * Options.\r
3265              * @type {Object.<string, *>}\r
3266              * @expose\r
3267              */\r
3268             this.options = options || {};\r
3269         };\r
3270 \r
3271         /**\r
3272          * @alias ProtoBuf.Reflect.Service.Method.prototype\r
3273          * @inner\r
3274          */\r
3275         var MethodPrototype = Method.prototype = Object.create(T.prototype);\r
3276 \r
3277         /**\r
3278          * Builds the method's '$options' property.\r
3279          * @name ProtoBuf.Reflect.Service.Method#buildOpt\r
3280          * @function\r
3281          * @return {Object.<string,*>}\r
3282          */\r
3283         MethodPrototype.buildOpt = NamespacePrototype.buildOpt;\r
3284 \r
3285         /**\r
3286          * @alias ProtoBuf.Reflect.Service.Method\r
3287          * @expose\r
3288          */\r
3289         Reflect.Service.Method = Method;\r
3290 \r
3291         /**\r
3292          * RPC service method.\r
3293          * @exports ProtoBuf.Reflect.Service.RPCMethod\r
3294          * @param {!ProtoBuf.Builder} builder Builder reference\r
3295          * @param {!ProtoBuf.Reflect.Service} svc Service\r
3296          * @param {string} name Method name\r
3297          * @param {string} request Request message name\r
3298          * @param {string} response Response message name\r
3299          * @param {boolean} request_stream Whether requests are streamed\r
3300          * @param {boolean} response_stream Whether responses are streamed\r
3301          * @param {Object.<string,*>=} options Options\r
3302          * @constructor\r
3303          * @extends ProtoBuf.Reflect.Service.Method\r
3304          */\r
3305         var RPCMethod = function(builder, svc, name, request, response, request_stream, response_stream, options) {\r
3306             Method.call(this, builder, svc, name, options);\r
3307 \r
3308             /**\r
3309              * @override\r
3310              */\r
3311             this.className = "Service.RPCMethod";\r
3312 \r
3313             /**\r
3314              * Request message name.\r
3315              * @type {string}\r
3316              * @expose\r
3317              */\r
3318             this.requestName = request;\r
3319 \r
3320             /**\r
3321              * Response message name.\r
3322              * @type {string}\r
3323              * @expose\r
3324              */\r
3325             this.responseName = response;\r
3326 \r
3327             /**\r
3328              * Whether requests are streamed\r
3329              * @type {bool}\r
3330              * @expose\r
3331              */\r
3332             this.requestStream = request_stream;\r
3333 \r
3334             /**\r
3335              * Whether responses are streamed\r
3336              * @type {bool}\r
3337              * @expose\r
3338              */\r
3339             this.responseStream = response_stream;\r
3340 \r
3341             /**\r
3342              * Resolved request message type.\r
3343              * @type {ProtoBuf.Reflect.Message}\r
3344              * @expose\r
3345              */\r
3346             this.resolvedRequestType = null;\r
3347 \r
3348             /**\r
3349              * Resolved response message type.\r
3350              * @type {ProtoBuf.Reflect.Message}\r
3351              * @expose\r
3352              */\r
3353             this.resolvedResponseType = null;\r
3354         };\r
3355 \r
3356         // Extends Method\r
3357         RPCMethod.prototype = Object.create(Method.prototype);\r
3358 \r
3359         /**\r
3360          * @alias ProtoBuf.Reflect.Service.RPCMethod\r
3361          * @expose\r
3362          */\r
3363         Reflect.Service.RPCMethod = RPCMethod;\r
3364 \r
3365         return Reflect;\r
3366 \r
3367     })(ProtoBuf);\r
3368 \r
3369     /**\r
3370      * @alias ProtoBuf.Builder\r
3371      * @expose\r
3372      */\r
3373     ProtoBuf.Builder = (function(ProtoBuf, Lang, Reflect) {\r
3374         "use strict";\r
3375 \r
3376         /**\r
3377          * Constructs a new Builder.\r
3378          * @exports ProtoBuf.Builder\r
3379          * @class Provides the functionality to build protocol messages.\r
3380          * @param {Object.<string,*>=} options Options\r
3381          * @constructor\r
3382          */\r
3383         var Builder = function(options) {\r
3384 \r
3385             /**\r
3386              * Namespace.\r
3387              * @type {ProtoBuf.Reflect.Namespace}\r
3388              * @expose\r
3389              */\r
3390             this.ns = new Reflect.Namespace(this, null, ""); // Global namespace\r
3391 \r
3392             /**\r
3393              * Namespace pointer.\r
3394              * @type {ProtoBuf.Reflect.T}\r
3395              * @expose\r
3396              */\r
3397             this.ptr = this.ns;\r
3398 \r
3399             /**\r
3400              * Resolved flag.\r
3401              * @type {boolean}\r
3402              * @expose\r
3403              */\r
3404             this.resolved = false;\r
3405 \r
3406             /**\r
3407              * The current building result.\r
3408              * @type {Object.<string,ProtoBuf.Builder.Message|Object>|null}\r
3409              * @expose\r
3410              */\r
3411             this.result = null;\r
3412 \r
3413             /**\r
3414              * Imported files.\r
3415              * @type {Array.<string>}\r
3416              * @expose\r
3417              */\r
3418             this.files = {};\r
3419 \r
3420             /**\r
3421              * Import root override.\r
3422              * @type {?string}\r
3423              * @expose\r
3424              */\r
3425             this.importRoot = null;\r
3426 \r
3427             /**\r
3428              * Options.\r
3429              * @type {!Object.<string, *>}\r
3430              * @expose\r
3431              */\r
3432             this.options = options || {};\r
3433         };\r
3434 \r
3435         /**\r
3436          * @alias ProtoBuf.Builder.prototype\r
3437          * @inner\r
3438          */\r
3439         var BuilderPrototype = Builder.prototype;\r
3440 \r
3441         // ----- Definition tests -----\r
3442 \r
3443         /**\r
3444          * Tests if a definition most likely describes a message.\r
3445          * @param {!Object} def\r
3446          * @returns {boolean}\r
3447          * @expose\r
3448          */\r
3449         Builder.isMessage = function(def) {\r
3450             // Messages require a string name\r
3451             if (typeof def["name"] !== 'string')\r
3452                 return false;\r
3453             // Messages do not contain values (enum) or rpc methods (service)\r
3454             if (typeof def["values"] !== 'undefined' || typeof def["rpc"] !== 'undefined')\r
3455                 return false;\r
3456             return true;\r
3457         };\r
3458 \r
3459         /**\r
3460          * Tests if a definition most likely describes a message field.\r
3461          * @param {!Object} def\r
3462          * @returns {boolean}\r
3463          * @expose\r
3464          */\r
3465         Builder.isMessageField = function(def) {\r
3466             // Message fields require a string rule, name and type and an id\r
3467             if (typeof def["rule"] !== 'string' || typeof def["name"] !== 'string' || typeof def["type"] !== 'string' || typeof def["id"] === 'undefined')\r
3468                 return false;\r
3469             return true;\r
3470         };\r
3471 \r
3472         /**\r
3473          * Tests if a definition most likely describes an enum.\r
3474          * @param {!Object} def\r
3475          * @returns {boolean}\r
3476          * @expose\r
3477          */\r
3478         Builder.isEnum = function(def) {\r
3479             // Enums require a string name\r
3480             if (typeof def["name"] !== 'string')\r
3481                 return false;\r
3482             // Enums require at least one value\r
3483             if (typeof def["values"] === 'undefined' || !Array.isArray(def["values"]) || def["values"].length === 0)\r
3484                 return false;\r
3485             return true;\r
3486         };\r
3487 \r
3488         /**\r
3489          * Tests if a definition most likely describes a service.\r
3490          * @param {!Object} def\r
3491          * @returns {boolean}\r
3492          * @expose\r
3493          */\r
3494         Builder.isService = function(def) {\r
3495             // Services require a string name and an rpc object\r
3496             if (typeof def["name"] !== 'string' || typeof def["rpc"] !== 'object' || !def["rpc"])\r
3497                 return false;\r
3498             return true;\r
3499         };\r
3500 \r
3501         /**\r
3502          * Tests if a definition most likely describes an extended message\r
3503          * @param {!Object} def\r
3504          * @returns {boolean}\r
3505          * @expose\r
3506          */\r
3507         Builder.isExtend = function(def) {\r
3508             // Extends rquire a string ref\r
3509             if (typeof def["ref"] !== 'string')\r
3510                 return false;\r
3511             return true;\r
3512         };\r
3513 \r
3514         // ----- Building -----\r
3515 \r
3516         /**\r
3517          * Resets the pointer to the root namespace.\r
3518          * @returns {!ProtoBuf.Builder} this\r
3519          * @expose\r
3520          */\r
3521         BuilderPrototype.reset = function() {\r
3522             this.ptr = this.ns;\r
3523             return this;\r
3524         };\r
3525 \r
3526         /**\r
3527          * Defines a namespace on top of the current pointer position and places the pointer on it.\r
3528          * @param {string} namespace\r
3529          * @return {!ProtoBuf.Builder} this\r
3530          * @expose\r
3531          */\r
3532         BuilderPrototype.define = function(namespace) {\r
3533             if (typeof namespace !== 'string' || !Lang.TYPEREF.test(namespace))\r
3534                 throw Error("illegal namespace: "+namespace);\r
3535             namespace.split(".").forEach(function(part) {\r
3536                 var ns = this.ptr.getChild(part);\r
3537                 if (ns === null) // Keep existing\r
3538                     this.ptr.addChild(ns = new Reflect.Namespace(this, this.ptr, part));\r
3539                 this.ptr = ns;\r
3540             }, this);\r
3541             return this;\r
3542         };\r
3543 \r
3544         /**\r
3545          * Creates the specified definitions at the current pointer position.\r
3546          * @param {!Array.<!Object>} defs Messages, enums or services to create\r
3547          * @returns {!ProtoBuf.Builder} this\r
3548          * @throws {Error} If a message definition is invalid\r
3549          * @expose\r
3550          */\r
3551         BuilderPrototype.create = function(defs) {\r
3552             if (!defs)\r
3553                 return this; // Nothing to create\r
3554             if (!Array.isArray(defs))\r
3555                 defs = [defs];\r
3556             else {\r
3557                 if (defs.length === 0)\r
3558                     return this;\r
3559                 defs = defs.slice();\r
3560             }\r
3561 \r
3562             // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.\r
3563             var stack = [defs];\r
3564             while (stack.length > 0) {\r
3565                 defs = stack.pop();\r
3566 \r
3567                 if (!Array.isArray(defs)) // Stack always contains entire namespaces\r
3568                     throw Error("not a valid namespace: "+JSON.stringify(defs));\r
3569 \r
3570                 while (defs.length > 0) {\r
3571                     var def = defs.shift(); // Namespaces always contain an array of messages, enums and services\r
3572 \r
3573                     if (Builder.isMessage(def)) {\r
3574                         var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"], def["syntax"]);\r
3575 \r
3576                         // Create OneOfs\r
3577                         var oneofs = {};\r
3578                         if (def["oneofs"])\r
3579                             Object.keys(def["oneofs"]).forEach(function(name) {\r
3580                                 obj.addChild(oneofs[name] = new Reflect.Message.OneOf(this, obj, name));\r
3581                             }, this);\r
3582 \r
3583                         // Create fields\r
3584                         if (def["fields"])\r
3585                             def["fields"].forEach(function(fld) {\r
3586                                 if (obj.getChild(fld["id"]|0) !== null)\r
3587                                     throw Error("duplicate or invalid field id in "+obj.name+": "+fld['id']);\r
3588                                 if (fld["options"] && typeof fld["options"] !== 'object')\r
3589                                     throw Error("illegal field options in "+obj.name+"#"+fld["name"]);\r
3590                                 var oneof = null;\r
3591                                 if (typeof fld["oneof"] === 'string' && !(oneof = oneofs[fld["oneof"]]))\r
3592                                     throw Error("illegal oneof in "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);\r
3593                                 fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["keytype"], fld["type"], fld["name"], fld["id"], fld["options"], oneof, def["syntax"]);\r
3594                                 if (oneof)\r
3595                                     oneof.fields.push(fld);\r
3596                                 obj.addChild(fld);\r
3597                             }, this);\r
3598 \r
3599                         // Push children to stack\r
3600                         var subObj = [];\r
3601                         if (def["enums"])\r
3602                             def["enums"].forEach(function(enm) {\r
3603                                 subObj.push(enm);\r
3604                             });\r
3605                         if (def["messages"])\r
3606                             def["messages"].forEach(function(msg) {\r
3607                                 subObj.push(msg);\r
3608                             });\r
3609                         if (def["services"])\r
3610                             def["services"].forEach(function(svc) {\r
3611                                 subObj.push(svc);\r
3612                             });\r
3613 \r
3614                         // Set extension ranges\r
3615                         if (def["extensions"]) {\r
3616                             if (typeof def["extensions"][0] === 'number') // pre 5.0.1\r
3617                                 obj.extensions = [ def["extensions"] ];\r
3618                             else\r
3619                                 obj.extensions = def["extensions"];\r
3620                         }\r
3621 \r
3622                         // Create on top of current namespace\r
3623                         this.ptr.addChild(obj);\r
3624                         if (subObj.length > 0) {\r
3625                             stack.push(defs); // Push the current level back\r
3626                             defs = subObj; // Continue processing sub level\r
3627                             subObj = null;\r
3628                             this.ptr = obj; // And move the pointer to this namespace\r
3629                             obj = null;\r
3630                             continue;\r
3631                         }\r
3632                         subObj = null;\r
3633 \r
3634                     } else if (Builder.isEnum(def)) {\r
3635 \r
3636                         obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"], def["syntax"]);\r
3637                         def["values"].forEach(function(val) {\r
3638                             obj.addChild(new Reflect.Enum.Value(this, obj, val["name"], val["id"]));\r
3639                         }, this);\r
3640                         this.ptr.addChild(obj);\r
3641 \r
3642                     } else if (Builder.isService(def)) {\r
3643 \r
3644                         obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);\r
3645                         Object.keys(def["rpc"]).forEach(function(name) {\r
3646                             var mtd = def["rpc"][name];\r
3647                             obj.addChild(new Reflect.Service.RPCMethod(this, obj, name, mtd["request"], mtd["response"], !!mtd["request_stream"], !!mtd["response_stream"], mtd["options"]));\r
3648                         }, this);\r
3649                         this.ptr.addChild(obj);\r
3650 \r
3651                     } else if (Builder.isExtend(def)) {\r
3652 \r
3653                         obj = this.ptr.resolve(def["ref"], true);\r
3654                         if (obj) {\r
3655                             def["fields"].forEach(function(fld) {\r
3656                                 if (obj.getChild(fld['id']|0) !== null)\r
3657                                     throw Error("duplicate extended field id in "+obj.name+": "+fld['id']);\r
3658                                 // Check if field id is allowed to be extended\r
3659                                 if (obj.extensions) {\r
3660                                     var valid = false;\r
3661                                     obj.extensions.forEach(function(range) {\r
3662                                         if (fld["id"] >= range[0] && fld["id"] <= range[1])\r
3663                                             valid = true;\r
3664                                     });\r
3665                                     if (!valid)\r
3666                                         throw Error("illegal extended field id in "+obj.name+": "+fld['id']+" (not within valid ranges)");\r
3667                                 }\r
3668                                 // Convert extension field names to camel case notation if the override is set\r
3669                                 var name = fld["name"];\r
3670                                 if (this.options['convertFieldsToCamelCase'])\r
3671                                     name = ProtoBuf.Util.toCamelCase(name);\r
3672                                 // see #161: Extensions use their fully qualified name as their runtime key and...\r
3673                                 var field = new Reflect.Message.ExtensionField(this, obj, fld["rule"], fld["type"], this.ptr.fqn()+'.'+name, fld["id"], fld["options"]);\r
3674                                 // ...are added on top of the current namespace as an extension which is used for\r
3675                                 // resolving their type later on (the extension always keeps the original name to\r
3676                                 // prevent naming collisions)\r
3677                                 var ext = new Reflect.Extension(this, this.ptr, fld["name"], field);\r
3678                                 field.extension = ext;\r
3679                                 this.ptr.addChild(ext);\r
3680                                 obj.addChild(field);\r
3681                             }, this);\r
3682 \r
3683                         } else if (!/\.?google\.protobuf\./.test(def["ref"])) // Silently skip internal extensions\r
3684                             throw Error("extended message "+def["ref"]+" is not defined");\r
3685 \r
3686                     } else\r
3687                         throw Error("not a valid definition: "+JSON.stringify(def));\r
3688 \r
3689                     def = null;\r
3690                     obj = null;\r
3691                 }\r
3692                 // Break goes here\r
3693                 defs = null;\r
3694                 this.ptr = this.ptr.parent; // Namespace done, continue at parent\r
3695             }\r
3696             this.resolved = false; // Require re-resolve\r
3697             this.result = null; // Require re-build\r
3698             return this;\r
3699         };\r
3700 \r
3701         /**\r
3702          * Propagates syntax to all children.\r
3703          * @param {!Object} parent\r
3704          * @inner\r
3705          */\r
3706         function propagateSyntax(parent) {\r
3707             if (parent['messages']) {\r
3708                 parent['messages'].forEach(function(child) {\r
3709                     child["syntax"] = parent["syntax"];\r
3710                     propagateSyntax(child);\r
3711                 });\r
3712             }\r
3713             if (parent['enums']) {\r
3714                 parent['enums'].forEach(function(child) {\r
3715                     child["syntax"] = parent["syntax"];\r
3716                 });\r
3717             }\r
3718         }\r
3719 \r
3720         /**\r
3721          * Imports another definition into this builder.\r
3722          * @param {Object.<string,*>} json Parsed import\r
3723          * @param {(string|{root: string, file: string})=} filename Imported file name\r
3724          * @returns {!ProtoBuf.Builder} this\r
3725          * @throws {Error} If the definition or file cannot be imported\r
3726          * @expose\r
3727          */\r
3728         BuilderPrototype["import"] = function(json, filename) {\r
3729             var delim = '/';\r
3730 \r
3731             // Make sure to skip duplicate imports\r
3732 \r
3733             if (typeof filename === 'string') {\r
3734 \r
3735                 if (ProtoBuf.Util.IS_NODE)\r
3736                     filename = require("path")['resolve'](filename);\r
3737                 if (this.files[filename] === true)\r
3738                     return this.reset();\r
3739                 this.files[filename] = true;\r
3740 \r
3741             } else if (typeof filename === 'object') { // Object with root, file.\r
3742 \r
3743                 var root = filename.root;\r
3744                 if (ProtoBuf.Util.IS_NODE)\r
3745                     root = require("path")['resolve'](root);\r
3746                 if (root.indexOf("\\") >= 0 || filename.file.indexOf("\\") >= 0)\r
3747                     delim = '\\';\r
3748                 var fname;\r
3749                 if (ProtoBuf.Util.IS_NODE)\r
3750                     fname = require("path")['join'](root, filename.file);\r
3751                 else\r
3752                     fname = root + delim + filename.file;\r
3753                 if (this.files[fname] === true)\r
3754                     return this.reset();\r
3755                 this.files[fname] = true;\r
3756             }\r
3757 \r
3758             // Import imports\r
3759 \r
3760             if (json['imports'] && json['imports'].length > 0) {\r
3761                 var importRoot,\r
3762                     resetRoot = false;\r
3763 \r
3764                 if (typeof filename === 'object') { // If an import root is specified, override\r
3765 \r
3766                     this.importRoot = filename["root"]; resetRoot = true; // ... and reset afterwards\r
3767                     importRoot = this.importRoot;\r
3768                     filename = filename["file"];\r
3769                     if (importRoot.indexOf("\\") >= 0 || filename.indexOf("\\") >= 0)\r
3770                         delim = '\\';\r
3771 \r
3772                 } else if (typeof filename === 'string') {\r
3773 \r
3774                     if (this.importRoot) // If import root is overridden, use it\r
3775                         importRoot = this.importRoot;\r
3776                     else { // Otherwise compute from filename\r
3777                         if (filename.indexOf("/") >= 0) { // Unix\r
3778                             importRoot = filename.replace(/\/[^\/]*$/, "");\r
3779                             if (/* /file.proto */ importRoot === "")\r
3780                                 importRoot = "/";\r
3781                         } else if (filename.indexOf("\\") >= 0) { // Windows\r
3782                             importRoot = filename.replace(/\\[^\\]*$/, "");\r
3783                             delim = '\\';\r
3784                         } else\r
3785                             importRoot = ".";\r
3786                     }\r
3787 \r
3788                 } else\r
3789                     importRoot = null;\r
3790 \r
3791                 for (var i=0; i<json['imports'].length; i++) {\r
3792                     if (typeof json['imports'][i] === 'string') { // Import file\r
3793                         if (!importRoot)\r
3794                             throw Error("cannot determine import root");\r
3795                         var importFilename = json['imports'][i];\r
3796                         if (importFilename === "google/protobuf/descriptor.proto")\r
3797                             continue; // Not needed and therefore not used\r
3798                         if (ProtoBuf.Util.IS_NODE)\r
3799                             importFilename = require("path")['join'](importRoot, importFilename);\r
3800                         else\r
3801                             importFilename = importRoot + delim + importFilename;\r
3802                         if (this.files[importFilename] === true)\r
3803                             continue; // Already imported\r
3804                         if (/\.proto$/i.test(importFilename) && !ProtoBuf.DotProto)       // If this is a light build\r
3805                             importFilename = importFilename.replace(/\.proto$/, ".json"); // always load the JSON file\r
3806                         var contents = ProtoBuf.Util.fetch(importFilename);\r
3807                         if (contents === null)\r
3808                             throw Error("failed to import '"+importFilename+"' in '"+filename+"': file not found");\r
3809                         if (/\.json$/i.test(importFilename)) // Always possible\r
3810                             this["import"](JSON.parse(contents+""), importFilename); // May throw\r
3811                         else\r
3812                             this["import"](ProtoBuf.DotProto.Parser.parse(contents), importFilename); // May throw\r
3813                     } else // Import structure\r
3814                         if (!filename)\r
3815                             this["import"](json['imports'][i]);\r
3816                         else if (/\.(\w+)$/.test(filename)) // With extension: Append _importN to the name portion to make it unique\r
3817                             this["import"](json['imports'][i], filename.replace(/^(.+)\.(\w+)$/, function($0, $1, $2) { return $1+"_import"+i+"."+$2; }));\r
3818                         else // Without extension: Append _importN to make it unique\r
3819                             this["import"](json['imports'][i], filename+"_import"+i);\r
3820                 }\r
3821                 if (resetRoot) // Reset import root override when all imports are done\r
3822                     this.importRoot = null;\r
3823             }\r
3824 \r
3825             // Import structures\r
3826 \r
3827             if (json['package'])\r
3828                 this.define(json['package']);\r
3829             if (json['syntax'])\r
3830                 propagateSyntax(json);\r
3831             var base = this.ptr;\r
3832             if (json['options'])\r
3833                 Object.keys(json['options']).forEach(function(key) {\r
3834                     base.options[key] = json['options'][key];\r
3835                 });\r
3836             if (json['messages'])\r
3837                 this.create(json['messages']),\r
3838                 this.ptr = base;\r
3839             if (json['enums'])\r
3840                 this.create(json['enums']),\r
3841                 this.ptr = base;\r
3842             if (json['services'])\r
3843                 this.create(json['services']),\r
3844                 this.ptr = base;\r
3845             if (json['extends'])\r
3846                 this.create(json['extends']);\r
3847 \r
3848             return this.reset();\r
3849         };\r
3850 \r
3851         /**\r
3852          * Resolves all namespace objects.\r
3853          * @throws {Error} If a type cannot be resolved\r
3854          * @returns {!ProtoBuf.Builder} this\r
3855          * @expose\r
3856          */\r
3857         BuilderPrototype.resolveAll = function() {\r
3858             // Resolve all reflected objects\r
3859             var res;\r
3860             if (this.ptr == null || typeof this.ptr.type === 'object')\r
3861                 return this; // Done (already resolved)\r
3862 \r
3863             if (this.ptr instanceof Reflect.Namespace) { // Resolve children\r
3864 \r
3865                 this.ptr.children.forEach(function(child) {\r
3866                     this.ptr = child;\r
3867                     this.resolveAll();\r
3868                 }, this);\r
3869 \r
3870             } else if (this.ptr instanceof Reflect.Message.Field) { // Resolve type\r
3871 \r
3872                 if (!Lang.TYPE.test(this.ptr.type)) {\r
3873                     if (!Lang.TYPEREF.test(this.ptr.type))\r
3874                         throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);\r
3875                     res = (this.ptr instanceof Reflect.Message.ExtensionField ? this.ptr.extension.parent : this.ptr.parent).resolve(this.ptr.type, true);\r
3876                     if (!res)\r
3877                         throw Error("unresolvable type reference in "+this.ptr.toString(true)+": "+this.ptr.type);\r
3878                     this.ptr.resolvedType = res;\r
3879                     if (res instanceof Reflect.Enum) {\r
3880                         this.ptr.type = ProtoBuf.TYPES["enum"];\r
3881                         if (this.ptr.syntax === 'proto3' && res.syntax !== 'proto3')\r
3882                             throw Error("proto3 message cannot reference proto2 enum");\r
3883                     }\r
3884                     else if (res instanceof Reflect.Message)\r
3885                         this.ptr.type = res.isGroup ? ProtoBuf.TYPES["group"] : ProtoBuf.TYPES["message"];\r
3886                     else\r
3887                         throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);\r
3888                 } else\r
3889                     this.ptr.type = ProtoBuf.TYPES[this.ptr.type];\r
3890 \r
3891                 // If it's a map field, also resolve the key type. The key type can be only a numeric, string, or bool type\r
3892                 // (i.e., no enums or messages), so we don't need to resolve against the current namespace.\r
3893                 if (this.ptr.map) {\r
3894                     if (!Lang.TYPE.test(this.ptr.keyType))\r
3895                         throw Error("illegal key type for map field in "+this.ptr.toString(true)+": "+this.ptr.keyType);\r
3896                     this.ptr.keyType = ProtoBuf.TYPES[this.ptr.keyType];\r
3897                 }\r
3898 \r
3899                 // If it's a repeated and packable field then proto3 mandates it should be packed by\r
3900                 // default\r
3901                 if (\r
3902                   this.ptr.syntax === 'proto3' &&\r
3903                   this.ptr.repeated && this.ptr.options.packed === undefined &&\r
3904                   ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.ptr.type.wireType) !== -1\r
3905                 ) {\r
3906                   this.ptr.options.packed = true;\r
3907                 }\r
3908 \r
3909             } else if (this.ptr instanceof ProtoBuf.Reflect.Service.Method) {\r
3910 \r
3911                 if (this.ptr instanceof ProtoBuf.Reflect.Service.RPCMethod) {\r
3912                     res = this.ptr.parent.resolve(this.ptr.requestName, true);\r
3913                     if (!res || !(res instanceof ProtoBuf.Reflect.Message))\r
3914                         throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.requestName);\r
3915                     this.ptr.resolvedRequestType = res;\r
3916                     res = this.ptr.parent.resolve(this.ptr.responseName, true);\r
3917                     if (!res || !(res instanceof ProtoBuf.Reflect.Message))\r
3918                         throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.responseName);\r
3919                     this.ptr.resolvedResponseType = res;\r
3920                 } else // Should not happen as nothing else is implemented\r
3921                     throw Error("illegal service type in "+this.ptr.toString(true));\r
3922 \r
3923             } else if (\r
3924                 !(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && // Not built\r
3925                 !(this.ptr instanceof ProtoBuf.Reflect.Extension) && // Not built\r
3926                 !(this.ptr instanceof ProtoBuf.Reflect.Enum.Value) // Built in enum\r
3927             )\r
3928                 throw Error("illegal object in namespace: "+typeof(this.ptr)+": "+this.ptr);\r
3929 \r
3930             return this.reset();\r
3931         };\r
3932 \r
3933         /**\r
3934          * Builds the protocol. This will first try to resolve all definitions and, if this has been successful,\r
3935          * return the built package.\r
3936          * @param {(string|Array.<string>)=} path Specifies what to return. If omitted, the entire namespace will be returned.\r
3937          * @returns {!ProtoBuf.Builder.Message|!Object.<string,*>}\r
3938          * @throws {Error} If a type could not be resolved\r
3939          * @expose\r
3940          */\r
3941         BuilderPrototype.build = function(path) {\r
3942             this.reset();\r
3943             if (!this.resolved)\r
3944                 this.resolveAll(),\r
3945                 this.resolved = true,\r
3946                 this.result = null; // Require re-build\r
3947             if (this.result === null) // (Re-)Build\r
3948                 this.result = this.ns.build();\r
3949             if (!path)\r
3950                 return this.result;\r
3951             var part = typeof path === 'string' ? path.split(".") : path,\r
3952                 ptr = this.result; // Build namespace pointer (no hasChild etc.)\r
3953             for (var i=0; i<part.length; i++)\r
3954                 if (ptr[part[i]])\r
3955                     ptr = ptr[part[i]];\r
3956                 else {\r
3957                     ptr = null;\r
3958                     break;\r
3959                 }\r
3960             return ptr;\r
3961         };\r
3962 \r
3963         /**\r
3964          * Similar to {@link ProtoBuf.Builder#build}, but looks up the internal reflection descriptor.\r
3965          * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.\r
3966          * @param {boolean=} excludeNonNamespace Excludes non-namespace types like fields, defaults to `false`\r
3967          * @returns {?ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found\r
3968          */\r
3969         BuilderPrototype.lookup = function(path, excludeNonNamespace) {\r
3970             return path ? this.ns.resolve(path, excludeNonNamespace) : this.ns;\r
3971         };\r
3972 \r
3973         /**\r
3974          * Returns a string representation of this object.\r
3975          * @return {string} String representation as of "Builder"\r
3976          * @expose\r
3977          */\r
3978         BuilderPrototype.toString = function() {\r
3979             return "Builder";\r
3980         };\r
3981 \r
3982         // ----- Base classes -----\r
3983         // Exist for the sole purpose of being able to "... instanceof ProtoBuf.Builder.Message" etc.\r
3984 \r
3985         /**\r
3986          * @alias ProtoBuf.Builder.Message\r
3987          */\r
3988         Builder.Message = function() {};\r
3989 \r
3990         /**\r
3991          * @alias ProtoBuf.Builder.Enum\r
3992          */\r
3993         Builder.Enum = function() {};\r
3994 \r
3995         /**\r
3996          * @alias ProtoBuf.Builder.Message\r
3997          */\r
3998         Builder.Service = function() {};\r
3999 \r
4000         return Builder;\r
4001 \r
4002     })(ProtoBuf, ProtoBuf.Lang, ProtoBuf.Reflect);\r
4003 \r
4004     /**\r
4005      * @alias ProtoBuf.Map\r
4006      * @expose\r
4007      */\r
4008     ProtoBuf.Map = (function(ProtoBuf, Reflect) {\r
4009         "use strict";\r
4010 \r
4011         /**\r
4012          * Constructs a new Map. A Map is a container that is used to implement map\r
4013          * fields on message objects. It closely follows the ES6 Map API; however,\r
4014          * it is distinct because we do not want to depend on external polyfills or\r
4015          * on ES6 itself.\r
4016          *\r
4017          * @exports ProtoBuf.Map\r
4018          * @param {!ProtoBuf.Reflect.Field} field Map field\r
4019          * @param {Object.<string,*>=} contents Initial contents\r
4020          * @constructor\r
4021          */\r
4022         var Map = function(field, contents) {\r
4023             if (!field.map)\r
4024                 throw Error("field is not a map");\r
4025 \r
4026             /**\r
4027              * The field corresponding to this map.\r
4028              * @type {!ProtoBuf.Reflect.Field}\r
4029              */\r
4030             this.field = field;\r
4031 \r
4032             /**\r
4033              * Element instance corresponding to key type.\r
4034              * @type {!ProtoBuf.Reflect.Element}\r
4035              */\r
4036             this.keyElem = new Reflect.Element(field.keyType, null, true, field.syntax);\r
4037 \r
4038             /**\r
4039              * Element instance corresponding to value type.\r
4040              * @type {!ProtoBuf.Reflect.Element}\r
4041              */\r
4042             this.valueElem = new Reflect.Element(field.type, field.resolvedType, false, field.syntax);\r
4043 \r
4044             /**\r
4045              * Internal map: stores mapping of (string form of key) -> (key, value)\r
4046              * pair.\r
4047              *\r
4048              * We provide map semantics for arbitrary key types, but we build on top\r
4049              * of an Object, which has only string keys. In order to avoid the need\r
4050              * to convert a string key back to its native type in many situations,\r
4051              * we store the native key value alongside the value. Thus, we only need\r
4052              * a one-way mapping from a key type to its string form that guarantees\r
4053              * uniqueness and equality (i.e., str(K1) === str(K2) if and only if K1\r
4054              * === K2).\r
4055              *\r
4056              * @type {!Object<string, {key: *, value: *}>}\r
4057              */\r
4058             this.map = {};\r
4059 \r
4060             /**\r
4061              * Returns the number of elements in the map.\r
4062              */\r
4063             Object.defineProperty(this, "size", {\r
4064                 get: function() { return Object.keys(this.map).length; }\r
4065             });\r
4066 \r
4067             // Fill initial contents from a raw object.\r
4068             if (contents) {\r
4069                 var keys = Object.keys(contents);\r
4070                 for (var i = 0; i < keys.length; i++) {\r
4071                     var key = this.keyElem.valueFromString(keys[i]);\r
4072                     var val = this.valueElem.verifyValue(contents[keys[i]]);\r
4073                     this.map[this.keyElem.valueToString(key)] =\r
4074                         { key: key, value: val };\r
4075                 }\r
4076             }\r
4077         };\r
4078 \r
4079         var MapPrototype = Map.prototype;\r
4080 \r
4081         /**\r
4082          * Helper: return an iterator over an array.\r
4083          * @param {!Array<*>} arr the array\r
4084          * @returns {!Object} an iterator\r
4085          * @inner\r
4086          */\r
4087         function arrayIterator(arr) {\r
4088             var idx = 0;\r
4089             return {\r
4090                 next: function() {\r
4091                     if (idx < arr.length)\r
4092                         return { done: false, value: arr[idx++] };\r
4093                     return { done: true };\r
4094                 }\r
4095             }\r
4096         }\r
4097 \r
4098         /**\r
4099          * Clears the map.\r
4100          */\r
4101         MapPrototype.clear = function() {\r
4102             this.map = {};\r
4103         };\r
4104 \r
4105         /**\r
4106          * Deletes a particular key from the map.\r
4107          * @returns {boolean} Whether any entry with this key was deleted.\r
4108          */\r
4109         MapPrototype["delete"] = function(key) {\r
4110             var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));\r
4111             var hadKey = keyValue in this.map;\r
4112             delete this.map[keyValue];\r
4113             return hadKey;\r
4114         };\r
4115 \r
4116         /**\r
4117          * Returns an iterator over [key, value] pairs in the map.\r
4118          * @returns {Object} The iterator\r
4119          */\r
4120         MapPrototype.entries = function() {\r
4121             var entries = [];\r
4122             var strKeys = Object.keys(this.map);\r
4123             for (var i = 0, entry; i < strKeys.length; i++)\r
4124                 entries.push([(entry=this.map[strKeys[i]]).key, entry.value]);\r
4125             return arrayIterator(entries);\r
4126         };\r
4127 \r
4128         /**\r
4129          * Returns an iterator over keys in the map.\r
4130          * @returns {Object} The iterator\r
4131          */\r
4132         MapPrototype.keys = function() {\r
4133             var keys = [];\r
4134             var strKeys = Object.keys(this.map);\r
4135             for (var i = 0; i < strKeys.length; i++)\r
4136                 keys.push(this.map[strKeys[i]].key);\r
4137             return arrayIterator(keys);\r
4138         };\r
4139 \r
4140         /**\r
4141          * Returns an iterator over values in the map.\r
4142          * @returns {!Object} The iterator\r
4143          */\r
4144         MapPrototype.values = function() {\r
4145             var values = [];\r
4146             var strKeys = Object.keys(this.map);\r
4147             for (var i = 0; i < strKeys.length; i++)\r
4148                 values.push(this.map[strKeys[i]].value);\r
4149             return arrayIterator(values);\r
4150         };\r
4151 \r
4152         /**\r
4153          * Iterates over entries in the map, calling a function on each.\r
4154          * @param {function(this:*, *, *, *)} cb The callback to invoke with value, key, and map arguments.\r
4155          * @param {Object=} thisArg The `this` value for the callback\r
4156          */\r
4157         MapPrototype.forEach = function(cb, thisArg) {\r
4158             var strKeys = Object.keys(this.map);\r
4159             for (var i = 0, entry; i < strKeys.length; i++)\r
4160                 cb.call(thisArg, (entry=this.map[strKeys[i]]).value, entry.key, this);\r
4161         };\r
4162 \r
4163         /**\r
4164          * Sets a key in the map to the given value.\r
4165          * @param {*} key The key\r
4166          * @param {*} value The value\r
4167          * @returns {!ProtoBuf.Map} The map instance\r
4168          */\r
4169         MapPrototype.set = function(key, value) {\r
4170             var keyValue = this.keyElem.verifyValue(key);\r
4171             var valValue = this.valueElem.verifyValue(value);\r
4172             this.map[this.keyElem.valueToString(keyValue)] =\r
4173                 { key: keyValue, value: valValue };\r
4174             return this;\r
4175         };\r
4176 \r
4177         /**\r
4178          * Gets the value corresponding to a key in the map.\r
4179          * @param {*} key The key\r
4180          * @returns {*|undefined} The value, or `undefined` if key not present\r
4181          */\r
4182         MapPrototype.get = function(key) {\r
4183             var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));\r
4184             if (!(keyValue in this.map))\r
4185                 return undefined;\r
4186             return this.map[keyValue].value;\r
4187         };\r
4188 \r
4189         /**\r
4190          * Determines whether the given key is present in the map.\r
4191          * @param {*} key The key\r
4192          * @returns {boolean} `true` if the key is present\r
4193          */\r
4194         MapPrototype.has = function(key) {\r
4195             var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));\r
4196             return (keyValue in this.map);\r
4197         };\r
4198 \r
4199         return Map;\r
4200     })(ProtoBuf, ProtoBuf.Reflect);\r
4201 \r
4202 \r
4203     /**\r
4204      * Constructs a new empty Builder.\r
4205      * @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf\r
4206      * @return {!ProtoBuf.Builder} Builder\r
4207      * @expose\r
4208      */\r
4209     ProtoBuf.newBuilder = function(options) {\r
4210         options = options || {};\r
4211         if (typeof options['convertFieldsToCamelCase'] === 'undefined')\r
4212             options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;\r
4213         if (typeof options['populateAccessors'] === 'undefined')\r
4214             options['populateAccessors'] = ProtoBuf.populateAccessors;\r
4215         return new ProtoBuf.Builder(options);\r
4216     };\r
4217 \r
4218     /**\r
4219      * Loads a .json definition and returns the Builder.\r
4220      * @param {!*|string} json JSON definition\r
4221      * @param {(ProtoBuf.Builder|string|{root: string, file: string})=} builder Builder to append to. Will create a new one if omitted.\r
4222      * @param {(string|{root: string, file: string})=} filename The corresponding file name if known. Must be specified for imports.\r
4223      * @return {ProtoBuf.Builder} Builder to create new messages\r
4224      * @throws {Error} If the definition cannot be parsed or built\r
4225      * @expose\r
4226      */\r
4227     ProtoBuf.loadJson = function(json, builder, filename) {\r
4228         if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))\r
4229             filename = builder,\r
4230             builder = null;\r
4231         if (!builder || typeof builder !== 'object')\r
4232             builder = ProtoBuf.newBuilder();\r
4233         if (typeof json === 'string')\r
4234             json = JSON.parse(json);\r
4235         builder["import"](json, filename);\r
4236         builder.resolveAll();\r
4237         return builder;\r
4238     };\r
4239 \r
4240     /**\r
4241      * Loads a .json file and returns the Builder.\r
4242      * @param {string|!{root: string, file: string}} filename Path to json file or an object specifying 'file' with\r
4243      *  an overridden 'root' path for all imported files.\r
4244      * @param {function(?Error, !ProtoBuf.Builder=)=} callback Callback that will receive `null` as the first and\r
4245      *  the Builder as its second argument on success, otherwise the error as its first argument. If omitted, the\r
4246      *  file will be read synchronously and this function will return the Builder.\r
4247      * @param {ProtoBuf.Builder=} builder Builder to append to. Will create a new one if omitted.\r
4248      * @return {?ProtoBuf.Builder|undefined} The Builder if synchronous (no callback specified, will be NULL if the\r
4249      *   request has failed), else undefined\r
4250      * @expose\r
4251      */\r
4252     ProtoBuf.loadJsonFile = function(filename, callback, builder) {\r
4253         if (callback && typeof callback === 'object')\r
4254             builder = callback,\r
4255             callback = null;\r
4256         else if (!callback || typeof callback !== 'function')\r
4257             callback = null;\r
4258         if (callback)\r
4259             return ProtoBuf.Util.fetch(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(contents) {\r
4260                 if (contents === null) {\r
4261                     callback(Error("Failed to fetch file"));\r
4262                     return;\r
4263                 }\r
4264                 try {\r
4265                     callback(null, ProtoBuf.loadJson(JSON.parse(contents), builder, filename));\r
4266                 } catch (e) {\r
4267                     callback(e);\r
4268                 }\r
4269             });\r
4270         var contents = ProtoBuf.Util.fetch(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename);\r
4271         return contents === null ? null : ProtoBuf.loadJson(JSON.parse(contents), builder, filename);\r
4272     };\r
4273 \r
4274     return ProtoBuf;\r
4275 });\r