Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / node_modules / protobufjs / src / ProtoBuf / Builder.js
diff --git a/legacy-libs/grpc/node_modules/protobufjs/src/ProtoBuf/Builder.js b/legacy-libs/grpc/node_modules/protobufjs/src/ProtoBuf/Builder.js
new file mode 100644 (file)
index 0000000..18eeba8
--- /dev/null
@@ -0,0 +1,634 @@
+/**\r
+ * @alias ProtoBuf.Builder\r
+ * @expose\r
+ */\r
+ProtoBuf.Builder = (function(ProtoBuf, Lang, Reflect) {\r
+    "use strict";\r
+\r
+    /**\r
+     * Constructs a new Builder.\r
+     * @exports ProtoBuf.Builder\r
+     * @class Provides the functionality to build protocol messages.\r
+     * @param {Object.<string,*>=} options Options\r
+     * @constructor\r
+     */\r
+    var Builder = function(options) {\r
+\r
+        /**\r
+         * Namespace.\r
+         * @type {ProtoBuf.Reflect.Namespace}\r
+         * @expose\r
+         */\r
+        this.ns = new Reflect.Namespace(this, null, ""); // Global namespace\r
+\r
+        /**\r
+         * Namespace pointer.\r
+         * @type {ProtoBuf.Reflect.T}\r
+         * @expose\r
+         */\r
+        this.ptr = this.ns;\r
+\r
+        /**\r
+         * Resolved flag.\r
+         * @type {boolean}\r
+         * @expose\r
+         */\r
+        this.resolved = false;\r
+\r
+        /**\r
+         * The current building result.\r
+         * @type {Object.<string,ProtoBuf.Builder.Message|Object>|null}\r
+         * @expose\r
+         */\r
+        this.result = null;\r
+\r
+        /**\r
+         * Imported files.\r
+         * @type {Array.<string>}\r
+         * @expose\r
+         */\r
+        this.files = {};\r
+\r
+        /**\r
+         * Import root override.\r
+         * @type {?string}\r
+         * @expose\r
+         */\r
+        this.importRoot = null;\r
+\r
+        /**\r
+         * Options.\r
+         * @type {!Object.<string, *>}\r
+         * @expose\r
+         */\r
+        this.options = options || {};\r
+    };\r
+\r
+    /**\r
+     * @alias ProtoBuf.Builder.prototype\r
+     * @inner\r
+     */\r
+    var BuilderPrototype = Builder.prototype;\r
+\r
+    // ----- Definition tests -----\r
+\r
+    /**\r
+     * Tests if a definition most likely describes a message.\r
+     * @param {!Object} def\r
+     * @returns {boolean}\r
+     * @expose\r
+     */\r
+    Builder.isMessage = function(def) {\r
+        // Messages require a string name\r
+        if (typeof def["name"] !== 'string')\r
+            return false;\r
+        // Messages do not contain values (enum) or rpc methods (service)\r
+        if (typeof def["values"] !== 'undefined' || typeof def["rpc"] !== 'undefined')\r
+            return false;\r
+        return true;\r
+    };\r
+\r
+    /**\r
+     * Tests if a definition most likely describes a message field.\r
+     * @param {!Object} def\r
+     * @returns {boolean}\r
+     * @expose\r
+     */\r
+    Builder.isMessageField = function(def) {\r
+        // Message fields require a string rule, name and type and an id\r
+        if (typeof def["rule"] !== 'string' || typeof def["name"] !== 'string' || typeof def["type"] !== 'string' || typeof def["id"] === 'undefined')\r
+            return false;\r
+        return true;\r
+    };\r
+\r
+    /**\r
+     * Tests if a definition most likely describes an enum.\r
+     * @param {!Object} def\r
+     * @returns {boolean}\r
+     * @expose\r
+     */\r
+    Builder.isEnum = function(def) {\r
+        // Enums require a string name\r
+        if (typeof def["name"] !== 'string')\r
+            return false;\r
+        // Enums require at least one value\r
+        if (typeof def["values"] === 'undefined' || !Array.isArray(def["values"]) || def["values"].length === 0)\r
+            return false;\r
+        return true;\r
+    };\r
+\r
+    /**\r
+     * Tests if a definition most likely describes a service.\r
+     * @param {!Object} def\r
+     * @returns {boolean}\r
+     * @expose\r
+     */\r
+    Builder.isService = function(def) {\r
+        // Services require a string name and an rpc object\r
+        if (typeof def["name"] !== 'string' || typeof def["rpc"] !== 'object' || !def["rpc"])\r
+            return false;\r
+        return true;\r
+    };\r
+\r
+    /**\r
+     * Tests if a definition most likely describes an extended message\r
+     * @param {!Object} def\r
+     * @returns {boolean}\r
+     * @expose\r
+     */\r
+    Builder.isExtend = function(def) {\r
+        // Extends rquire a string ref\r
+        if (typeof def["ref"] !== 'string')\r
+            return false;\r
+        return true;\r
+    };\r
+\r
+    // ----- Building -----\r
+\r
+    /**\r
+     * Resets the pointer to the root namespace.\r
+     * @returns {!ProtoBuf.Builder} this\r
+     * @expose\r
+     */\r
+    BuilderPrototype.reset = function() {\r
+        this.ptr = this.ns;\r
+        return this;\r
+    };\r
+\r
+    /**\r
+     * Defines a namespace on top of the current pointer position and places the pointer on it.\r
+     * @param {string} namespace\r
+     * @return {!ProtoBuf.Builder} this\r
+     * @expose\r
+     */\r
+    BuilderPrototype.define = function(namespace) {\r
+        if (typeof namespace !== 'string' || !Lang.TYPEREF.test(namespace))\r
+            throw Error("illegal namespace: "+namespace);\r
+        namespace.split(".").forEach(function(part) {\r
+            var ns = this.ptr.getChild(part);\r
+            if (ns === null) // Keep existing\r
+                this.ptr.addChild(ns = new Reflect.Namespace(this, this.ptr, part));\r
+            this.ptr = ns;\r
+        }, this);\r
+        return this;\r
+    };\r
+\r
+    /**\r
+     * Creates the specified definitions at the current pointer position.\r
+     * @param {!Array.<!Object>} defs Messages, enums or services to create\r
+     * @returns {!ProtoBuf.Builder} this\r
+     * @throws {Error} If a message definition is invalid\r
+     * @expose\r
+     */\r
+    BuilderPrototype.create = function(defs) {\r
+        if (!defs)\r
+            return this; // Nothing to create\r
+        if (!Array.isArray(defs))\r
+            defs = [defs];\r
+        else {\r
+            if (defs.length === 0)\r
+                return this;\r
+            defs = defs.slice();\r
+        }\r
+\r
+        // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.\r
+        var stack = [defs];\r
+        while (stack.length > 0) {\r
+            defs = stack.pop();\r
+\r
+            if (!Array.isArray(defs)) // Stack always contains entire namespaces\r
+                throw Error("not a valid namespace: "+JSON.stringify(defs));\r
+\r
+            while (defs.length > 0) {\r
+                var def = defs.shift(); // Namespaces always contain an array of messages, enums and services\r
+\r
+                if (Builder.isMessage(def)) {\r
+                    var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"], def["syntax"]);\r
+\r
+                    // Create OneOfs\r
+                    var oneofs = {};\r
+                    if (def["oneofs"])\r
+                        Object.keys(def["oneofs"]).forEach(function(name) {\r
+                            obj.addChild(oneofs[name] = new Reflect.Message.OneOf(this, obj, name));\r
+                        }, this);\r
+\r
+                    // Create fields\r
+                    if (def["fields"])\r
+                        def["fields"].forEach(function(fld) {\r
+                            if (obj.getChild(fld["id"]|0) !== null)\r
+                                throw Error("duplicate or invalid field id in "+obj.name+": "+fld['id']);\r
+                            if (fld["options"] && typeof fld["options"] !== 'object')\r
+                                throw Error("illegal field options in "+obj.name+"#"+fld["name"]);\r
+                            var oneof = null;\r
+                            if (typeof fld["oneof"] === 'string' && !(oneof = oneofs[fld["oneof"]]))\r
+                                throw Error("illegal oneof in "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);\r
+                            fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["keytype"], fld["type"], fld["name"], fld["id"], fld["options"], oneof, def["syntax"]);\r
+                            if (oneof)\r
+                                oneof.fields.push(fld);\r
+                            obj.addChild(fld);\r
+                        }, this);\r
+\r
+                    // Push children to stack\r
+                    var subObj = [];\r
+                    if (def["enums"])\r
+                        def["enums"].forEach(function(enm) {\r
+                            subObj.push(enm);\r
+                        });\r
+                    if (def["messages"])\r
+                        def["messages"].forEach(function(msg) {\r
+                            subObj.push(msg);\r
+                        });\r
+                    if (def["services"])\r
+                        def["services"].forEach(function(svc) {\r
+                            subObj.push(svc);\r
+                        });\r
+\r
+                    // Set extension ranges\r
+                    if (def["extensions"]) {\r
+                        if (typeof def["extensions"][0] === 'number') // pre 5.0.1\r
+                            obj.extensions = [ def["extensions"] ];\r
+                        else\r
+                            obj.extensions = def["extensions"];\r
+                    }\r
+\r
+                    // Create on top of current namespace\r
+                    this.ptr.addChild(obj);\r
+                    if (subObj.length > 0) {\r
+                        stack.push(defs); // Push the current level back\r
+                        defs = subObj; // Continue processing sub level\r
+                        subObj = null;\r
+                        this.ptr = obj; // And move the pointer to this namespace\r
+                        obj = null;\r
+                        continue;\r
+                    }\r
+                    subObj = null;\r
+\r
+                } else if (Builder.isEnum(def)) {\r
+\r
+                    obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"], def["syntax"]);\r
+                    def["values"].forEach(function(val) {\r
+                        obj.addChild(new Reflect.Enum.Value(this, obj, val["name"], val["id"]));\r
+                    }, this);\r
+                    this.ptr.addChild(obj);\r
+\r
+                } else if (Builder.isService(def)) {\r
+\r
+                    obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);\r
+                    Object.keys(def["rpc"]).forEach(function(name) {\r
+                        var mtd = def["rpc"][name];\r
+                        obj.addChild(new Reflect.Service.RPCMethod(this, obj, name, mtd["request"], mtd["response"], !!mtd["request_stream"], !!mtd["response_stream"], mtd["options"]));\r
+                    }, this);\r
+                    this.ptr.addChild(obj);\r
+\r
+                } else if (Builder.isExtend(def)) {\r
+\r
+                    obj = this.ptr.resolve(def["ref"], true);\r
+                    if (obj) {\r
+                        def["fields"].forEach(function(fld) {\r
+                            if (obj.getChild(fld['id']|0) !== null)\r
+                                throw Error("duplicate extended field id in "+obj.name+": "+fld['id']);\r
+                            // Check if field id is allowed to be extended\r
+                            if (obj.extensions) {\r
+                                var valid = false;\r
+                                obj.extensions.forEach(function(range) {\r
+                                    if (fld["id"] >= range[0] && fld["id"] <= range[1])\r
+                                        valid = true;\r
+                                });\r
+                                if (!valid)\r
+                                    throw Error("illegal extended field id in "+obj.name+": "+fld['id']+" (not within valid ranges)");\r
+                            }\r
+                            // Convert extension field names to camel case notation if the override is set\r
+                            var name = fld["name"];\r
+                            if (this.options['convertFieldsToCamelCase'])\r
+                                name = ProtoBuf.Util.toCamelCase(name);\r
+                            // see #161: Extensions use their fully qualified name as their runtime key and...\r
+                            var field = new Reflect.Message.ExtensionField(this, obj, fld["rule"], fld["type"], this.ptr.fqn()+'.'+name, fld["id"], fld["options"]);\r
+                            // ...are added on top of the current namespace as an extension which is used for\r
+                            // resolving their type later on (the extension always keeps the original name to\r
+                            // prevent naming collisions)\r
+                            var ext = new Reflect.Extension(this, this.ptr, fld["name"], field);\r
+                            field.extension = ext;\r
+                            this.ptr.addChild(ext);\r
+                            obj.addChild(field);\r
+                        }, this);\r
+\r
+                    } else if (!/\.?google\.protobuf\./.test(def["ref"])) // Silently skip internal extensions\r
+                        throw Error("extended message "+def["ref"]+" is not defined");\r
+\r
+                } else\r
+                    throw Error("not a valid definition: "+JSON.stringify(def));\r
+\r
+                def = null;\r
+                obj = null;\r
+            }\r
+            // Break goes here\r
+            defs = null;\r
+            this.ptr = this.ptr.parent; // Namespace done, continue at parent\r
+        }\r
+        this.resolved = false; // Require re-resolve\r
+        this.result = null; // Require re-build\r
+        return this;\r
+    };\r
+\r
+    /**\r
+     * Propagates syntax to all children.\r
+     * @param {!Object} parent\r
+     * @inner\r
+     */\r
+    function propagateSyntax(parent) {\r
+        if (parent['messages']) {\r
+            parent['messages'].forEach(function(child) {\r
+                child["syntax"] = parent["syntax"];\r
+                propagateSyntax(child);\r
+            });\r
+        }\r
+        if (parent['enums']) {\r
+            parent['enums'].forEach(function(child) {\r
+                child["syntax"] = parent["syntax"];\r
+            });\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Imports another definition into this builder.\r
+     * @param {Object.<string,*>} json Parsed import\r
+     * @param {(string|{root: string, file: string})=} filename Imported file name\r
+     * @returns {!ProtoBuf.Builder} this\r
+     * @throws {Error} If the definition or file cannot be imported\r
+     * @expose\r
+     */\r
+    BuilderPrototype["import"] = function(json, filename) {\r
+        var delim = '/';\r
+\r
+        // Make sure to skip duplicate imports\r
+\r
+        if (typeof filename === 'string') {\r
+\r
+            if (ProtoBuf.Util.IS_NODE)\r
+                filename = require("path")['resolve'](filename);\r
+            if (this.files[filename] === true)\r
+                return this.reset();\r
+            this.files[filename] = true;\r
+\r
+        } else if (typeof filename === 'object') { // Object with root, file.\r
+\r
+            var root = filename.root;\r
+            if (ProtoBuf.Util.IS_NODE)\r
+                root = require("path")['resolve'](root);\r
+            if (root.indexOf("\\") >= 0 || filename.file.indexOf("\\") >= 0)\r
+                delim = '\\';\r
+            var fname;\r
+            if (ProtoBuf.Util.IS_NODE)\r
+                fname = require("path")['join'](root, filename.file);\r
+            else\r
+                fname = root + delim + filename.file;\r
+            if (this.files[fname] === true)\r
+                return this.reset();\r
+            this.files[fname] = true;\r
+        }\r
+\r
+        // Import imports\r
+\r
+        if (json['imports'] && json['imports'].length > 0) {\r
+            var importRoot,\r
+                resetRoot = false;\r
+\r
+            if (typeof filename === 'object') { // If an import root is specified, override\r
+\r
+                this.importRoot = filename["root"]; resetRoot = true; // ... and reset afterwards\r
+                importRoot = this.importRoot;\r
+                filename = filename["file"];\r
+                if (importRoot.indexOf("\\") >= 0 || filename.indexOf("\\") >= 0)\r
+                    delim = '\\';\r
+\r
+            } else if (typeof filename === 'string') {\r
+\r
+                if (this.importRoot) // If import root is overridden, use it\r
+                    importRoot = this.importRoot;\r
+                else { // Otherwise compute from filename\r
+                    if (filename.indexOf("/") >= 0) { // Unix\r
+                        importRoot = filename.replace(/\/[^\/]*$/, "");\r
+                        if (/* /file.proto */ importRoot === "")\r
+                            importRoot = "/";\r
+                    } else if (filename.indexOf("\\") >= 0) { // Windows\r
+                        importRoot = filename.replace(/\\[^\\]*$/, "");\r
+                        delim = '\\';\r
+                    } else\r
+                        importRoot = ".";\r
+                }\r
+\r
+            } else\r
+                importRoot = null;\r
+\r
+            for (var i=0; i<json['imports'].length; i++) {\r
+                if (typeof json['imports'][i] === 'string') { // Import file\r
+                    if (!importRoot)\r
+                        throw Error("cannot determine import root");\r
+                    var importFilename = json['imports'][i];\r
+                    if (importFilename === "google/protobuf/descriptor.proto")\r
+                        continue; // Not needed and therefore not used\r
+                    if (ProtoBuf.Util.IS_NODE)\r
+                        importFilename = require("path")['join'](importRoot, importFilename);\r
+                    else\r
+                        importFilename = importRoot + delim + importFilename;\r
+                    if (this.files[importFilename] === true)\r
+                        continue; // Already imported\r
+                    if (/\.proto$/i.test(importFilename) && !ProtoBuf.DotProto)       // If this is a light build\r
+                        importFilename = importFilename.replace(/\.proto$/, ".json"); // always load the JSON file\r
+                    var contents = ProtoBuf.Util.fetch(importFilename);\r
+                    if (contents === null)\r
+                        throw Error("failed to import '"+importFilename+"' in '"+filename+"': file not found");\r
+                    if (/\.json$/i.test(importFilename)) // Always possible\r
+                        this["import"](JSON.parse(contents+""), importFilename); // May throw\r
+                    else\r
+                        this["import"](ProtoBuf.DotProto.Parser.parse(contents), importFilename); // May throw\r
+                } else // Import structure\r
+                    if (!filename)\r
+                        this["import"](json['imports'][i]);\r
+                    else if (/\.(\w+)$/.test(filename)) // With extension: Append _importN to the name portion to make it unique\r
+                        this["import"](json['imports'][i], filename.replace(/^(.+)\.(\w+)$/, function($0, $1, $2) { return $1+"_import"+i+"."+$2; }));\r
+                    else // Without extension: Append _importN to make it unique\r
+                        this["import"](json['imports'][i], filename+"_import"+i);\r
+            }\r
+            if (resetRoot) // Reset import root override when all imports are done\r
+                this.importRoot = null;\r
+        }\r
+\r
+        // Import structures\r
+\r
+        if (json['package'])\r
+            this.define(json['package']);\r
+        if (json['syntax'])\r
+            propagateSyntax(json);\r
+        var base = this.ptr;\r
+        if (json['options'])\r
+            Object.keys(json['options']).forEach(function(key) {\r
+                base.options[key] = json['options'][key];\r
+            });\r
+        if (json['messages'])\r
+            this.create(json['messages']),\r
+            this.ptr = base;\r
+        if (json['enums'])\r
+            this.create(json['enums']),\r
+            this.ptr = base;\r
+        if (json['services'])\r
+            this.create(json['services']),\r
+            this.ptr = base;\r
+        if (json['extends'])\r
+            this.create(json['extends']);\r
+\r
+        return this.reset();\r
+    };\r
+\r
+    /**\r
+     * Resolves all namespace objects.\r
+     * @throws {Error} If a type cannot be resolved\r
+     * @returns {!ProtoBuf.Builder} this\r
+     * @expose\r
+     */\r
+    BuilderPrototype.resolveAll = function() {\r
+        // Resolve all reflected objects\r
+        var res;\r
+        if (this.ptr == null || typeof this.ptr.type === 'object')\r
+            return this; // Done (already resolved)\r
+\r
+        if (this.ptr instanceof Reflect.Namespace) { // Resolve children\r
+\r
+            this.ptr.children.forEach(function(child) {\r
+                this.ptr = child;\r
+                this.resolveAll();\r
+            }, this);\r
+\r
+        } else if (this.ptr instanceof Reflect.Message.Field) { // Resolve type\r
+\r
+            if (!Lang.TYPE.test(this.ptr.type)) {\r
+                if (!Lang.TYPEREF.test(this.ptr.type))\r
+                    throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);\r
+                res = (this.ptr instanceof Reflect.Message.ExtensionField ? this.ptr.extension.parent : this.ptr.parent).resolve(this.ptr.type, true);\r
+                if (!res)\r
+                    throw Error("unresolvable type reference in "+this.ptr.toString(true)+": "+this.ptr.type);\r
+                this.ptr.resolvedType = res;\r
+                if (res instanceof Reflect.Enum) {\r
+                    this.ptr.type = ProtoBuf.TYPES["enum"];\r
+                    if (this.ptr.syntax === 'proto3' && res.syntax !== 'proto3')\r
+                        throw Error("proto3 message cannot reference proto2 enum");\r
+                }\r
+                else if (res instanceof Reflect.Message)\r
+                    this.ptr.type = res.isGroup ? ProtoBuf.TYPES["group"] : ProtoBuf.TYPES["message"];\r
+                else\r
+                    throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);\r
+            } else\r
+                this.ptr.type = ProtoBuf.TYPES[this.ptr.type];\r
+\r
+            // If it's a map field, also resolve the key type. The key type can be only a numeric, string, or bool type\r
+            // (i.e., no enums or messages), so we don't need to resolve against the current namespace.\r
+            if (this.ptr.map) {\r
+                if (!Lang.TYPE.test(this.ptr.keyType))\r
+                    throw Error("illegal key type for map field in "+this.ptr.toString(true)+": "+this.ptr.keyType);\r
+                this.ptr.keyType = ProtoBuf.TYPES[this.ptr.keyType];\r
+            }\r
+\r
+            // If it's a repeated and packable field then proto3 mandates it should be packed by\r
+            // default\r
+            if (\r
+              this.ptr.syntax === 'proto3' &&\r
+              this.ptr.repeated && this.ptr.options.packed === undefined &&\r
+              ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.ptr.type.wireType) !== -1\r
+            ) {\r
+              this.ptr.options.packed = true;\r
+            }\r
+\r
+        } else if (this.ptr instanceof ProtoBuf.Reflect.Service.Method) {\r
+\r
+            if (this.ptr instanceof ProtoBuf.Reflect.Service.RPCMethod) {\r
+                res = this.ptr.parent.resolve(this.ptr.requestName, true);\r
+                if (!res || !(res instanceof ProtoBuf.Reflect.Message))\r
+                    throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.requestName);\r
+                this.ptr.resolvedRequestType = res;\r
+                res = this.ptr.parent.resolve(this.ptr.responseName, true);\r
+                if (!res || !(res instanceof ProtoBuf.Reflect.Message))\r
+                    throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.responseName);\r
+                this.ptr.resolvedResponseType = res;\r
+            } else // Should not happen as nothing else is implemented\r
+                throw Error("illegal service type in "+this.ptr.toString(true));\r
+\r
+        } else if (\r
+            !(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && // Not built\r
+            !(this.ptr instanceof ProtoBuf.Reflect.Extension) && // Not built\r
+            !(this.ptr instanceof ProtoBuf.Reflect.Enum.Value) // Built in enum\r
+        )\r
+            throw Error("illegal object in namespace: "+typeof(this.ptr)+": "+this.ptr);\r
+\r
+        return this.reset();\r
+    };\r
+\r
+    /**\r
+     * Builds the protocol. This will first try to resolve all definitions and, if this has been successful,\r
+     * return the built package.\r
+     * @param {(string|Array.<string>)=} path Specifies what to return. If omitted, the entire namespace will be returned.\r
+     * @returns {!ProtoBuf.Builder.Message|!Object.<string,*>}\r
+     * @throws {Error} If a type could not be resolved\r
+     * @expose\r
+     */\r
+    BuilderPrototype.build = function(path) {\r
+        this.reset();\r
+        if (!this.resolved)\r
+            this.resolveAll(),\r
+            this.resolved = true,\r
+            this.result = null; // Require re-build\r
+        if (this.result === null) // (Re-)Build\r
+            this.result = this.ns.build();\r
+        if (!path)\r
+            return this.result;\r
+        var part = typeof path === 'string' ? path.split(".") : path,\r
+            ptr = this.result; // Build namespace pointer (no hasChild etc.)\r
+        for (var i=0; i<part.length; i++)\r
+            if (ptr[part[i]])\r
+                ptr = ptr[part[i]];\r
+            else {\r
+                ptr = null;\r
+                break;\r
+            }\r
+        return ptr;\r
+    };\r
+\r
+    /**\r
+     * Similar to {@link ProtoBuf.Builder#build}, but looks up the internal reflection descriptor.\r
+     * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.\r
+     * @param {boolean=} excludeNonNamespace Excludes non-namespace types like fields, defaults to `false`\r
+     * @returns {?ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found\r
+     */\r
+    BuilderPrototype.lookup = function(path, excludeNonNamespace) {\r
+        return path ? this.ns.resolve(path, excludeNonNamespace) : this.ns;\r
+    };\r
+\r
+    /**\r
+     * Returns a string representation of this object.\r
+     * @return {string} String representation as of "Builder"\r
+     * @expose\r
+     */\r
+    BuilderPrototype.toString = function() {\r
+        return "Builder";\r
+    };\r
+\r
+    // ----- Base classes -----\r
+    // Exist for the sole purpose of being able to "... instanceof ProtoBuf.Builder.Message" etc.\r
+\r
+    /**\r
+     * @alias ProtoBuf.Builder.Message\r
+     */\r
+    Builder.Message = function() {};\r
+\r
+    /**\r
+     * @alias ProtoBuf.Builder.Enum\r
+     */\r
+    Builder.Enum = function() {};\r
+\r
+    /**\r
+     * @alias ProtoBuf.Builder.Message\r
+     */\r
+    Builder.Service = function() {};\r
+\r
+    return Builder;\r
+\r
+})(ProtoBuf, ProtoBuf.Lang, ProtoBuf.Reflect);\r