Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / node_modules / protobufjs / src / ProtoBuf / DotProto / Parser.js
diff --git a/legacy-libs/grpc-cloned/node_modules/protobufjs/src/ProtoBuf/DotProto/Parser.js b/legacy-libs/grpc-cloned/node_modules/protobufjs/src/ProtoBuf/DotProto/Parser.js
new file mode 100644 (file)
index 0000000..36595ee
--- /dev/null
@@ -0,0 +1,700 @@
+/*?\r
+ // --- Scope ----------------------\r
+ // Lang      : Language expressions\r
+ // Tokenizer : DotProto Tokenizer\r
+ */\r
+/**\r
+ * Constructs a new Parser.\r
+ * @exports ProtoBuf.DotProto.Parser\r
+ * @class prototype parser\r
+ * @param {string} source Source\r
+ * @constructor\r
+ */\r
+var Parser = function(source) {\r
+\r
+    /**\r
+     * Tokenizer.\r
+     * @type {!ProtoBuf.DotProto.Tokenizer}\r
+     * @expose\r
+     */\r
+    this.tn = new Tokenizer(source);\r
+\r
+    /**\r
+     * Whether parsing proto3 or not.\r
+     * @type {boolean}\r
+     */\r
+    this.proto3 = false;\r
+};\r
+\r
+/**\r
+ * @alias ProtoBuf.DotProto.Parser.prototype\r
+ * @inner\r
+ */\r
+var ParserPrototype = Parser.prototype;\r
+\r
+/**\r
+ * Parses the source.\r
+ * @returns {!Object}\r
+ * @throws {Error} If the source cannot be parsed\r
+ * @expose\r
+ */\r
+ParserPrototype.parse = function() {\r
+    var topLevel = {\r
+        "name": "[ROOT]", // temporary\r
+        "package": null,\r
+        "messages": [],\r
+        "enums": [],\r
+        "imports": [],\r
+        "options": {},\r
+        "services": []\r
+        // "syntax": undefined\r
+    };\r
+    var token,\r
+        head = true,\r
+        weak;\r
+    try {\r
+        while (token = this.tn.next()) {\r
+            switch (token) {\r
+                case 'package':\r
+                    if (!head || topLevel["package"] !== null)\r
+                        throw Error("unexpected 'package'");\r
+                    token = this.tn.next();\r
+                    if (!Lang.TYPEREF.test(token))\r
+                        throw Error("illegal package name: " + token);\r
+                    this.tn.skip(";");\r
+                    topLevel["package"] = token;\r
+                    break;\r
+                case 'import':\r
+                    if (!head)\r
+                        throw Error("unexpected 'import'");\r
+                    token = this.tn.peek();\r
+                    if (token === "public" || (weak = token === "weak")) // token ignored\r
+                        this.tn.next();\r
+                    token = this._readString();\r
+                    this.tn.skip(";");\r
+                    if (!weak) // import ignored\r
+                        topLevel["imports"].push(token);\r
+                    break;\r
+                case 'syntax':\r
+                    if (!head)\r
+                        throw Error("unexpected 'syntax'");\r
+                    this.tn.skip("=");\r
+                    if ((topLevel["syntax"] = this._readString()) === "proto3")\r
+                        this.proto3 = true;\r
+                    this.tn.skip(";");\r
+                    break;\r
+                case 'message':\r
+                    this._parseMessage(topLevel, null);\r
+                    head = false;\r
+                    break;\r
+                case 'enum':\r
+                    this._parseEnum(topLevel);\r
+                    head = false;\r
+                    break;\r
+                case 'option':\r
+                    this._parseOption(topLevel);\r
+                    break;\r
+                case 'service':\r
+                    this._parseService(topLevel);\r
+                    break;\r
+                case 'extend':\r
+                    this._parseExtend(topLevel);\r
+                    break;\r
+                default:\r
+                    throw Error("unexpected '" + token + "'");\r
+            }\r
+        }\r
+    } catch (e) {\r
+        e.message = "Parse error at line "+this.tn.line+": " + e.message;\r
+        throw e;\r
+    }\r
+    delete topLevel["name"];\r
+    return topLevel;\r
+};\r
+\r
+/**\r
+ * Parses the specified source.\r
+ * @returns {!Object}\r
+ * @throws {Error} If the source cannot be parsed\r
+ * @expose\r
+ */\r
+Parser.parse = function(source) {\r
+    return new Parser(source).parse();\r
+};\r
+\r
+// ----- Conversion ------\r
+\r
+/**\r
+ * Converts a numerical string to an id.\r
+ * @param {string} value\r
+ * @param {boolean=} mayBeNegative\r
+ * @returns {number}\r
+ * @inner\r
+ */\r
+function mkId(value, mayBeNegative) {\r
+    var id = -1,\r
+        sign = 1;\r
+    if (value.charAt(0) == '-') {\r
+        sign = -1;\r
+        value = value.substring(1);\r
+    }\r
+    if (Lang.NUMBER_DEC.test(value))\r
+        id = parseInt(value);\r
+    else if (Lang.NUMBER_HEX.test(value))\r
+        id = parseInt(value.substring(2), 16);\r
+    else if (Lang.NUMBER_OCT.test(value))\r
+        id = parseInt(value.substring(1), 8);\r
+    else\r
+        throw Error("illegal id value: " + (sign < 0 ? '-' : '') + value);\r
+    id = (sign*id)|0; // Force to 32bit\r
+    if (!mayBeNegative && id < 0)\r
+        throw Error("illegal id value: " + (sign < 0 ? '-' : '') + value);\r
+    return id;\r
+}\r
+\r
+/**\r
+ * Converts a numerical string to a number.\r
+ * @param {string} val\r
+ * @returns {number}\r
+ * @inner\r
+ */\r
+function mkNumber(val) {\r
+    var sign = 1;\r
+    if (val.charAt(0) == '-') {\r
+        sign = -1;\r
+        val = val.substring(1);\r
+    }\r
+    if (Lang.NUMBER_DEC.test(val))\r
+        return sign * parseInt(val, 10);\r
+    else if (Lang.NUMBER_HEX.test(val))\r
+        return sign * parseInt(val.substring(2), 16);\r
+    else if (Lang.NUMBER_OCT.test(val))\r
+        return sign * parseInt(val.substring(1), 8);\r
+    else if (val === 'inf')\r
+        return sign * Infinity;\r
+    else if (val === 'nan')\r
+        return NaN;\r
+    else if (Lang.NUMBER_FLT.test(val))\r
+        return sign * parseFloat(val);\r
+    throw Error("illegal number value: " + (sign < 0 ? '-' : '') + val);\r
+}\r
+\r
+// ----- Reading ------\r
+\r
+/**\r
+ * Reads a string.\r
+ * @returns {string}\r
+ * @private\r
+ */\r
+ParserPrototype._readString = function() {\r
+    var value = "",\r
+        token,\r
+        delim;\r
+    do {\r
+        delim = this.tn.next();\r
+        if (delim !== "'" && delim !== '"')\r
+            throw Error("illegal string delimiter: "+delim);\r
+        value += this.tn.next();\r
+        this.tn.skip(delim);\r
+        token = this.tn.peek();\r
+    } while (token === '"' || token === '"'); // multi line?\r
+    return value;\r
+};\r
+\r
+/**\r
+ * Reads a value.\r
+ * @param {boolean=} mayBeTypeRef\r
+ * @returns {number|boolean|string}\r
+ * @private\r
+ */\r
+ParserPrototype._readValue = function(mayBeTypeRef) {\r
+    var token = this.tn.peek(),\r
+        value;\r
+    if (token === '"' || token === "'")\r
+        return this._readString();\r
+    this.tn.next();\r
+    if (Lang.NUMBER.test(token))\r
+        return mkNumber(token);\r
+    if (Lang.BOOL.test(token))\r
+        return (token.toLowerCase() === 'true');\r
+    if (mayBeTypeRef && Lang.TYPEREF.test(token))\r
+        return token;\r
+    throw Error("illegal value: "+token);\r
+\r
+};\r
+\r
+// ----- Parsing constructs -----\r
+\r
+/**\r
+ * Parses a namespace option.\r
+ * @param {!Object} parent Parent definition\r
+ * @param {boolean=} isList\r
+ * @private\r
+ */\r
+ParserPrototype._parseOption = function(parent, isList) {\r
+    var token = this.tn.next(),\r
+        custom = false;\r
+    if (token === '(') {\r
+        custom = true;\r
+        token = this.tn.next();\r
+    }\r
+    if (!Lang.TYPEREF.test(token))\r
+        // we can allow options of the form google.protobuf.* since they will just get ignored anyways\r
+        // if (!/google\.protobuf\./.test(token)) // FIXME: Why should that not be a valid typeref?\r
+            throw Error("illegal option name: "+token);\r
+    var name = token;\r
+    if (custom) { // (my_method_option).foo, (my_method_option), some_method_option, (foo.my_option).bar\r
+        this.tn.skip(')');\r
+        name = '('+name+')';\r
+        token = this.tn.peek();\r
+        if (Lang.FQTYPEREF.test(token)) {\r
+            name += token;\r
+            this.tn.next();\r
+        }\r
+    }\r
+    this.tn.skip('=');\r
+    this._parseOptionValue(parent, name);\r
+    if (!isList)\r
+        this.tn.skip(";");\r
+};\r
+\r
+/**\r
+ * Sets an option on the specified options object.\r
+ * @param {!Object.<string,*>} options\r
+ * @param {string} name\r
+ * @param {string|number|boolean} value\r
+ * @inner\r
+ */\r
+function setOption(options, name, value) {\r
+    if (typeof options[name] === 'undefined')\r
+        options[name] = value;\r
+    else {\r
+        if (!Array.isArray(options[name]))\r
+            options[name] = [ options[name] ];\r
+        options[name].push(value);\r
+    }\r
+}\r
+\r
+/**\r
+ * Parses an option value.\r
+ * @param {!Object} parent\r
+ * @param {string} name\r
+ * @private\r
+ */\r
+ParserPrototype._parseOptionValue = function(parent, name) {\r
+    var token = this.tn.peek();\r
+    if (token !== '{') { // Plain value\r
+        setOption(parent["options"], name, this._readValue(true));\r
+    } else { // Aggregate options\r
+        this.tn.skip("{");\r
+        while ((token = this.tn.next()) !== '}') {\r
+            if (!Lang.NAME.test(token))\r
+                throw Error("illegal option name: " + name + "." + token);\r
+            if (this.tn.omit(":"))\r
+                setOption(parent["options"], name + "." + token, this._readValue(true));\r
+            else\r
+                this._parseOptionValue(parent, name + "." + token);\r
+        }\r
+    }\r
+};\r
+\r
+/**\r
+ * Parses a service definition.\r
+ * @param {!Object} parent Parent definition\r
+ * @private\r
+ */\r
+ParserPrototype._parseService = function(parent) {\r
+    var token = this.tn.next();\r
+    if (!Lang.NAME.test(token))\r
+        throw Error("illegal service name at line "+this.tn.line+": "+token);\r
+    var name = token;\r
+    var svc = {\r
+        "name": name,\r
+        "rpc": {},\r
+        "options": {}\r
+    };\r
+    this.tn.skip("{");\r
+    while ((token = this.tn.next()) !== '}') {\r
+        if (token === "option")\r
+            this._parseOption(svc);\r
+        else if (token === 'rpc')\r
+            this._parseServiceRPC(svc);\r
+        else\r
+            throw Error("illegal service token: "+token);\r
+    }\r
+    this.tn.omit(";");\r
+    parent["services"].push(svc);\r
+};\r
+\r
+/**\r
+ * Parses a RPC service definition of the form ['rpc', name, (request), 'returns', (response)].\r
+ * @param {!Object} svc Service definition\r
+ * @private\r
+ */\r
+ParserPrototype._parseServiceRPC = function(svc) {\r
+    var type = "rpc",\r
+        token = this.tn.next();\r
+    if (!Lang.NAME.test(token))\r
+        throw Error("illegal rpc service method name: "+token);\r
+    var name = token;\r
+    var method = {\r
+        "request": null,\r
+        "response": null,\r
+        "request_stream": false,\r
+        "response_stream": false,\r
+        "options": {}\r
+    };\r
+    this.tn.skip("(");\r
+    token = this.tn.next();\r
+    if (token.toLowerCase() === "stream") {\r
+      method["request_stream"] = true;\r
+      token = this.tn.next();\r
+    }\r
+    if (!Lang.TYPEREF.test(token))\r
+        throw Error("illegal rpc service request type: "+token);\r
+    method["request"] = token;\r
+    this.tn.skip(")");\r
+    token = this.tn.next();\r
+    if (token.toLowerCase() !== "returns")\r
+        throw Error("illegal rpc service request type delimiter: "+token);\r
+    this.tn.skip("(");\r
+    token = this.tn.next();\r
+    if (token.toLowerCase() === "stream") {\r
+      method["response_stream"] = true;\r
+      token = this.tn.next();\r
+    }\r
+    method["response"] = token;\r
+    this.tn.skip(")");\r
+    token = this.tn.peek();\r
+    if (token === '{') {\r
+        this.tn.next();\r
+        while ((token = this.tn.next()) !== '}') {\r
+            if (token === 'option')\r
+                this._parseOption(method);\r
+            else\r
+                throw Error("illegal rpc service token: " + token);\r
+        }\r
+        this.tn.omit(";");\r
+    } else\r
+        this.tn.skip(";");\r
+    if (typeof svc[type] === 'undefined')\r
+        svc[type] = {};\r
+    svc[type][name] = method;\r
+};\r
+\r
+/**\r
+ * Parses a message definition.\r
+ * @param {!Object} parent Parent definition\r
+ * @param {!Object=} fld Field definition if this is a group\r
+ * @returns {!Object}\r
+ * @private\r
+ */\r
+ParserPrototype._parseMessage = function(parent, fld) {\r
+    var isGroup = !!fld,\r
+        token = this.tn.next();\r
+    var msg = {\r
+        "name": "",\r
+        "fields": [],\r
+        "enums": [],\r
+        "messages": [],\r
+        "options": {},\r
+        "services": [],\r
+        "oneofs": {}\r
+        // "extensions": undefined\r
+    };\r
+    if (!Lang.NAME.test(token))\r
+        throw Error("illegal "+(isGroup ? "group" : "message")+" name: "+token);\r
+    msg["name"] = token;\r
+    if (isGroup) {\r
+        this.tn.skip("=");\r
+        fld["id"] = mkId(this.tn.next());\r
+        msg["isGroup"] = true;\r
+    }\r
+    token = this.tn.peek();\r
+    if (token === '[' && fld)\r
+        this._parseFieldOptions(fld);\r
+    this.tn.skip("{");\r
+    while ((token = this.tn.next()) !== '}') {\r
+        if (Lang.RULE.test(token))\r
+            this._parseMessageField(msg, token);\r
+        else if (token === "oneof")\r
+            this._parseMessageOneOf(msg);\r
+        else if (token === "enum")\r
+            this._parseEnum(msg);\r
+        else if (token === "message")\r
+            this._parseMessage(msg);\r
+        else if (token === "option")\r
+            this._parseOption(msg);\r
+        else if (token === "service")\r
+            this._parseService(msg);\r
+        else if (token === "extensions")\r
+            if (msg.hasOwnProperty("extensions")) {\r
+                msg["extensions"] = msg["extensions"].concat(this._parseExtensionRanges())\r
+            } else {\r
+                msg["extensions"] = this._parseExtensionRanges();\r
+            }\r
+        else if (token === "reserved")\r
+            this._parseIgnored(); // TODO\r
+        else if (token === "extend")\r
+            this._parseExtend(msg);\r
+        else if (Lang.TYPEREF.test(token)) {\r
+            if (!this.proto3)\r
+                throw Error("illegal field rule: "+token);\r
+            this._parseMessageField(msg, "optional", token);\r
+        } else\r
+            throw Error("illegal message token: "+token);\r
+    }\r
+    this.tn.omit(";");\r
+    parent["messages"].push(msg);\r
+    return msg;\r
+};\r
+\r
+/**\r
+ * Parses an ignored statement.\r
+ * @private\r
+ */\r
+ParserPrototype._parseIgnored = function() {\r
+    while (this.tn.peek() !== ';')\r
+        this.tn.next();\r
+    this.tn.skip(";");\r
+};\r
+\r
+/**\r
+ * Parses a message field.\r
+ * @param {!Object} msg Message definition\r
+ * @param {string} rule Field rule\r
+ * @param {string=} type Field type if already known (never known for maps)\r
+ * @returns {!Object} Field descriptor\r
+ * @private\r
+ */\r
+ParserPrototype._parseMessageField = function(msg, rule, type) {\r
+    if (!Lang.RULE.test(rule))\r
+        throw Error("illegal message field rule: "+rule);\r
+    var fld = {\r
+        "rule": rule,\r
+        "type": "",\r
+        "name": "",\r
+        "options": {},\r
+        "id": 0\r
+    };\r
+    var token;\r
+    if (rule === "map") {\r
+\r
+        if (type)\r
+            throw Error("illegal type: " + type);\r
+        this.tn.skip('<');\r
+        token = this.tn.next();\r
+        if (!Lang.TYPE.test(token) && !Lang.TYPEREF.test(token))\r
+            throw Error("illegal message field type: " + token);\r
+        fld["keytype"] = token;\r
+        this.tn.skip(',');\r
+        token = this.tn.next();\r
+        if (!Lang.TYPE.test(token) && !Lang.TYPEREF.test(token))\r
+            throw Error("illegal message field: " + token);\r
+        fld["type"] = token;\r
+        this.tn.skip('>');\r
+        token = this.tn.next();\r
+        if (!Lang.NAME.test(token))\r
+            throw Error("illegal message field name: " + token);\r
+        fld["name"] = token;\r
+        this.tn.skip("=");\r
+        fld["id"] = mkId(this.tn.next());\r
+        token = this.tn.peek();\r
+        if (token === '[')\r
+            this._parseFieldOptions(fld);\r
+        this.tn.skip(";");\r
+\r
+    } else {\r
+\r
+        type = typeof type !== 'undefined' ? type : this.tn.next();\r
+\r
+        if (type === "group") {\r
+\r
+            // "A [legacy] group simply combines a nested message type and a field into a single declaration. In your\r
+            // code, you can treat this message just as if it had a Result type field called result (the latter name is\r
+            // converted to lower-case so that it does not conflict with the former)."\r
+            var grp = this._parseMessage(msg, fld);\r
+            if (!/^[A-Z]/.test(grp["name"]))\r
+                throw Error('illegal group name: '+grp["name"]);\r
+            fld["type"] = grp["name"];\r
+            fld["name"] = grp["name"].toLowerCase();\r
+            this.tn.omit(";");\r
+\r
+        } else {\r
+\r
+            if (!Lang.TYPE.test(type) && !Lang.TYPEREF.test(type))\r
+                throw Error("illegal message field type: " + type);\r
+            fld["type"] = type;\r
+            token = this.tn.next();\r
+            if (!Lang.NAME.test(token))\r
+                throw Error("illegal message field name: " + token);\r
+            fld["name"] = token;\r
+            this.tn.skip("=");\r
+            fld["id"] = mkId(this.tn.next());\r
+            token = this.tn.peek();\r
+            if (token === "[")\r
+                this._parseFieldOptions(fld);\r
+            this.tn.skip(";");\r
+\r
+        }\r
+    }\r
+    msg["fields"].push(fld);\r
+    return fld;\r
+};\r
+\r
+/**\r
+ * Parses a message oneof.\r
+ * @param {!Object} msg Message definition\r
+ * @private\r
+ */\r
+ParserPrototype._parseMessageOneOf = function(msg) {\r
+    var token = this.tn.next();\r
+    if (!Lang.NAME.test(token))\r
+        throw Error("illegal oneof name: "+token);\r
+    var name = token,\r
+        fld;\r
+    var fields = [];\r
+    this.tn.skip("{");\r
+    while ((token = this.tn.next()) !== "}") {\r
+        fld = this._parseMessageField(msg, "optional", token);\r
+        fld["oneof"] = name;\r
+        fields.push(fld["id"]);\r
+    }\r
+    this.tn.omit(";");\r
+    msg["oneofs"][name] = fields;\r
+};\r
+\r
+/**\r
+ * Parses a set of field option definitions.\r
+ * @param {!Object} fld Field definition\r
+ * @private\r
+ */\r
+ParserPrototype._parseFieldOptions = function(fld) {\r
+    this.tn.skip("[");\r
+    var token,\r
+        first = true;\r
+    while ((token = this.tn.peek()) !== ']') {\r
+        if (!first)\r
+            this.tn.skip(",");\r
+        this._parseOption(fld, true);\r
+        first = false;\r
+    }\r
+    this.tn.next();\r
+};\r
+\r
+/**\r
+ * Parses an enum.\r
+ * @param {!Object} msg Message definition\r
+ * @private\r
+ */\r
+ParserPrototype._parseEnum = function(msg) {\r
+    var enm = {\r
+        "name": "",\r
+        "values": [],\r
+        "options": {}\r
+    };\r
+    var token = this.tn.next();\r
+    if (!Lang.NAME.test(token))\r
+        throw Error("illegal name: "+token);\r
+    enm["name"] = token;\r
+    this.tn.skip("{");\r
+    while ((token = this.tn.next()) !== '}') {\r
+        if (token === "option")\r
+            this._parseOption(enm);\r
+        else {\r
+            if (!Lang.NAME.test(token))\r
+                throw Error("illegal name: "+token);\r
+            this.tn.skip("=");\r
+            var val = {\r
+                "name": token,\r
+                "id": mkId(this.tn.next(), true)\r
+            };\r
+            token = this.tn.peek();\r
+            if (token === "[")\r
+                this._parseFieldOptions({ "options": {} });\r
+            this.tn.skip(";");\r
+            enm["values"].push(val);\r
+        }\r
+    }\r
+    this.tn.omit(";");\r
+    msg["enums"].push(enm);\r
+};\r
+\r
+/**\r
+ * Parses extension / reserved ranges.\r
+ * @returns {!Array.<!Array.<number>>}\r
+ * @private\r
+ */\r
+ParserPrototype._parseExtensionRanges = function() {\r
+    var ranges = [];\r
+    var token,\r
+        range,\r
+        value;\r
+    do {\r
+        range = [];\r
+        while (true) {\r
+            token = this.tn.next();\r
+            switch (token) {\r
+                case "min":\r
+                    value = ProtoBuf.ID_MIN;\r
+                    break;\r
+                case "max":\r
+                    value = ProtoBuf.ID_MAX;\r
+                    break;\r
+                default:\r
+                    value = mkNumber(token);\r
+                    break;\r
+            }\r
+            range.push(value);\r
+            if (range.length === 2)\r
+                break;\r
+            if (this.tn.peek() !== "to") {\r
+                range.push(value);\r
+                break;\r
+            }\r
+            this.tn.next();\r
+        }\r
+        ranges.push(range);\r
+    } while (this.tn.omit(","));\r
+    this.tn.skip(";");\r
+    return ranges;\r
+};\r
+\r
+/**\r
+ * Parses an extend block.\r
+ * @param {!Object} parent Parent object\r
+ * @private\r
+ */\r
+ParserPrototype._parseExtend = function(parent) {\r
+    var token = this.tn.next();\r
+    if (!Lang.TYPEREF.test(token))\r
+        throw Error("illegal extend reference: "+token);\r
+    var ext = {\r
+        "ref": token,\r
+        "fields": []\r
+    };\r
+    this.tn.skip("{");\r
+    while ((token = this.tn.next()) !== '}') {\r
+        if (Lang.RULE.test(token))\r
+            this._parseMessageField(ext, token);\r
+        else if (Lang.TYPEREF.test(token)) {\r
+            if (!this.proto3)\r
+                throw Error("illegal field rule: "+token);\r
+            this._parseMessageField(ext, "optional", token);\r
+        } else\r
+            throw Error("illegal extend token: "+token);\r
+    }\r
+    this.tn.omit(";");\r
+    parent["messages"].push(ext);\r
+    return ext;\r
+};\r
+\r
+// ----- General -----\r
+\r
+/**\r
+ * Returns a string representation of this parser.\r
+ * @returns {string}\r
+ */\r
+ParserPrototype.toString = function() {\r
+    return "Parser at line "+this.tn.line;\r
+};\r