Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / node_modules / protobufjs / cli / pbjs / targets / proto.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 var description = "Plain .proto descriptor";\r
17 \r
18 var ProtoBuf = require(__dirname+"/../../../index.js"),\r
19     util = require("../util.js");\r
20 \r
21 /**\r
22  * pbjs target: Plain .proto descriptor\r
23  * @exports pbjs/targets/proto\r
24  * @function\r
25  * @param {!ProtoBuf.Builder} builder Builder\r
26  * @param {!Object.<string,*>=} options Options\r
27  * @returns {string}\r
28  */\r
29 var proto = module.exports = function(builder, options) {\r
30     options = options || {};\r
31     builder.resolveAll();\r
32 \r
33     // Set the pointer to the lowest common namespace (with options)\r
34     var ptr = builder.ns;\r
35     while (ptr.children.length === 1 && Object.keys(ptr.options).length === 0 && ptr.children[0].className === "Namespace")\r
36         ptr = ptr.children[0];\r
37 \r
38     var out = [];\r
39 \r
40     function trim() {\r
41         out[out.length-1] = out[out.length-1].replace(/\n{2,}$/, "\n");\r
42     }\r
43 \r
44     // Builds a set of top level options\r
45     function buildOptions(opt, indent) {\r
46         var keys;\r
47         if ((keys = Object.keys(opt)).length === 0)\r
48             return;\r
49         keys.forEach(function(key) {\r
50             if (!options.min)\r
51                 out.push(indent);\r
52             out.push("option ", key, options.min ? "=" : " = ", value(opt[key]), options.min ? ";" : ";\n");\r
53         });\r
54         if (!options.min)\r
55             out[out.length-1] += "\n";\r
56     }\r
57 \r
58     // Builds everything within a namespace\r
59     function buildNamespace(ns, indent) {\r
60         ns.getChildren(ProtoBuf.Reflect.Enum).forEach(function(enm) {\r
61             buildEnum(enm, indent);\r
62         });\r
63         ns.getChildren(ProtoBuf.Reflect.Message).forEach(function(msg) {\r
64             if (!msg.isGroup) // legacy groups are build within the respective field\r
65                 buildMessage(msg, indent);\r
66         });\r
67         var exts = util.groupExtensions(ns);\r
68         if (exts !== null) {\r
69             Object.keys(exts).forEach(function(extFqn) {\r
70                 var extMsg = ns.resolve(extFqn),\r
71                     extFields = exts[extFqn];\r
72                 if (!options.min)\r
73                     out.push(indent);\r
74                 out.push("extend ", ns.qn(extMsg), options.min ? "{" : " {\n");\r
75                 extFields.forEach(function(extField) {\r
76                     buildMessageField(ns, extField, indent+"    ", false);\r
77                 });\r
78                 if (!options.min)\r
79                     out.push(indent);\r
80                 out.push(options.min ? "}" : "}\n\n");\r
81             });\r
82         }\r
83         ns.getChildren(ProtoBuf.Reflect.Service).forEach(function(svc) {\r
84             buildService(svc, indent);\r
85         });\r
86         ns.getChildren(ProtoBuf.Reflect.Namespace).forEach(function(innerNs) {\r
87             if (innerNs.className !== "Namespace")\r
88                 return;\r
89             if (!options.min)\r
90                 out.push(indent);\r
91             out.push("message ", innerNs.name, options.min ? "{" : " {\n");\r
92             buildNamespace(innerNs, indent+"    ");\r
93             if (!options.min)\r
94                 out.push(indent);\r
95             out.push(options.min ? "}" : "}\n");\r
96         });\r
97         trim();\r
98     }\r
99 \r
100     // Builds a message\r
101     function buildMessage(msg, indent) {\r
102         if (!msg.isGroup) {\r
103             if (!options.min)\r
104                 out.push(indent);\r
105             out.push("message ", msg.name);\r
106         }\r
107         out.push(options.min ? "{" : " {\n");\r
108         buildOptions(msg.options, indent+"    ");\r
109         var n = 0, oneofFields = [];\r
110         msg.getChildren(ProtoBuf.Reflect.Message.OneOf).forEach(function(oneof) {\r
111             if (!options.min)\r
112                 out.push(indent, "    ");\r
113             out.push("oneof ", oneof.name, options.min ? "{" : " {\n");\r
114             oneof.fields.forEach(function(fld) {\r
115                 buildMessageField(msg, fld, indent+"        ", true);\r
116                 oneofFields.push(fld);\r
117             });\r
118             if (!options.min)\r
119                 out.push(indent, "    ");\r
120             out.push(options.min ? "}" : "}\n");\r
121         });\r
122         msg.getChildren(ProtoBuf.Reflect.Message.Field).forEach(function(fld) {\r
123             if (fld instanceof ProtoBuf.Reflect.Message.ExtensionField)\r
124                 return;\r
125             if (oneofFields.indexOf(fld) >= 0)\r
126                 return;\r
127             buildMessageField(msg, fld, indent+"    ", false);\r
128             n++;\r
129         });\r
130         if (n > 0 && !options.min)\r
131             out[out.length-1] += "\n";\r
132         if (msg.extensions) { // array of ranges\r
133             if (!options.min)\r
134                 out.push(indent, "    ");\r
135             out.push("extensions ");\r
136             msg.extensions.forEach(function(range, index) {\r
137                 if (index > 0)\r
138                     out.push(options.min ? "," : ", ");\r
139                 out.push(value(range[0]));\r
140                 if (range[1] !== range[0])\r
141                     out.push(" to ", range[1] === ProtoBuf.ID_MAX ? "max" : value(range[1]));\r
142             });\r
143             out.push(options.min ? ";" : ";\n\n");\r
144         }\r
145         buildNamespace(msg, indent+"    ");\r
146         if (!options.min)\r
147             out.push(indent);\r
148         out.push(options.min ? "}" : "}\n\n");\r
149     }\r
150 \r
151     // Builds a message field\r
152     function buildMessageField(msg, fld, indent, isOneOf) {\r
153         var isGroup = false;\r
154         if (!options.min)\r
155             out.push(indent);\r
156         if (!isOneOf)\r
157             out.push(fld.required ? "required " : (fld.repeated ? "repeated " : "optional "));\r
158         if (fld.resolvedType !== null) {\r
159             if (fld.resolvedType instanceof ProtoBuf.Reflect.Message && fld.resolvedType.isGroup) {\r
160                 // inline legacy groups\r
161                 out.push("group ");\r
162                 isGroup = true;\r
163             }\r
164             out.push(msg.qn(fld.resolvedType));\r
165         } else\r
166             out.push(fld.type['name']);\r
167         if (!isGroup)\r
168             out.push(" ", fld instanceof ProtoBuf.Reflect.Message.ExtensionField ? fld.name.substring(fld.name.lastIndexOf(".")+1) : fld.name);\r
169         out.push(options.min ? "=" : " = ", fld.id);\r
170         if (isGroup) // inline\r
171             buildMessage(fld.resolvedType, indent);\r
172         else {\r
173             var keys = Object.keys(fld.options);\r
174             if (keys.length > 0) {\r
175                 out.push(options.min ? "[" : " [");\r
176                 var n = 0;\r
177                 keys.forEach(function (key) {\r
178                     if (n > 0)\r
179                         out.push(options.min ? "," : ", ");\r
180                     out.push(key, options.min ? "=" : " = ",\r
181                         // BEWARE: Monkey patch for string enum defaults\r
182                         key === "default" && fld.type === ProtoBuf.TYPES["enum"] && typeof fld.options[key] === 'string' ? fld.options[key] : value(fld.options[key])\r
183                     );\r
184                     n++;\r
185                 });\r
186                 out.push("]");\r
187             }\r
188             out.push(options.min ? ";" : ";\n");\r
189         }\r
190     }\r
191 \r
192     // Builds an enum\r
193     function buildEnum(enm, indent) {\r
194         if (!options.min)\r
195             out.push(indent);\r
196         out.push("enum ", enm.name, options.min ? "{" : " {\n");\r
197         buildOptions(enm.options, indent+"    ");\r
198         enm.getChildren(ProtoBuf.Reflect.Enum.Value).forEach(function(val) {\r
199             if (!options.min)\r
200                 out.push(indent, "    ");\r
201             out.push(val.name, options.min ? "=" : " = ", val.id, options.min? ";" : ";\n");\r
202         });\r
203         if (!options.min)\r
204             out.push(indent);\r
205         out.push(options.min ? "}" : "}\n\n");\r
206     }\r
207 \r
208     // Builds a service\r
209     function buildService(svc, indent) {\r
210         if (!options.min)\r
211             out.push(indent);\r
212         out.push("service ", svc.name, options.min ? "{" : " {\n");\r
213         buildOptions(svc.options, indent+"    ");\r
214         svc.getChildren(ProtoBuf.Reflect.Service.RPCMethod).forEach(function(rpc) {\r
215             if (!options.min)\r
216                 out.push(indent+"    ");\r
217             out.push("rpc ", rpc.name, "(", svc.qn(rpc.resolvedRequestType), ") returns(", svc.qn(rpc.resolvedResponseType), ")");\r
218             var keys = Object.keys(rpc.options);\r
219             if (keys.length === 0) {\r
220                 out.push(options.min ? ";" : ";\n")\r
221             } else {\r
222                 out.push(options.min ? "{" : " {\n");\r
223                 buildOptions(rpc.options, indent+"        ");\r
224                 trim();\r
225                 if (!options.min)\r
226                     out.push(indent+"    ");\r
227                 out.push(options.min ? "}" : "}\n");\r
228             }\r
229             if (!options.min)\r
230                 out[out.length-1] += "\n";\r
231         });\r
232         trim();\r
233         out.push(options.min ? "}" : "}\n");\r
234     }\r
235 \r
236     // Start by building the package namespace\r
237     var pkg = ptr.fqn().substring(1);\r
238     if (pkg !== "")\r
239         out.push("package ", pkg, options.min ? ";" : ";\n\n");\r
240     buildOptions(ptr.options, "");\r
241     buildNamespace(ptr, "");\r
242     return out.join('');\r
243 };\r
244 \r
245 /**\r
246  * Module description.\r
247  * @type {string}\r
248  */\r
249 proto.description = description;\r
250 \r
251 /**\r
252  * Converts a JavaScript value to a .proto value.\r
253  * @param {*} v Value\r
254  * @returns {string} Dot proto value\r
255  */\r
256 function value(v) {\r
257     switch (typeof v) {\r
258         case 'boolean':\r
259             return v ? 'true' : 'false';\r
260         case 'number':\r
261             return v.toString();\r
262         case 'string':\r
263             return '"'+v.replace(/"/g, '\\"')+'"';\r
264         default:\r
265             throw new Error("illegal value type: "+typeof(v));\r
266     }\r
267 }\r