Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc / node_modules / protobufjs / cli / pbjs / targets / json.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 JSON 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 JSON descriptor\r
23  * @exports pbjs/targets/json\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 json = 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     // Start by building the package namespace\r
39     var pkg = ptr.fqn().substring(1),\r
40         out = {\r
41             "package": pkg !== "" ? pkg : null\r
42         };\r
43     buildNamespace(ptr, out);\r
44     return JSON.stringify(out, null, options.min ? 0 : 4);\r
45 };\r
46 \r
47 /**\r
48  * Module description.\r
49  * @type {string}\r
50  */\r
51 json.description = description;\r
52 \r
53 /**\r
54  * Builds all structures in a namespace.\r
55  * @param {!ProtoBuf.Reflect.Namespace} ns Namespace to build\r
56  * @param {!Object.<string,*>} out Extended output object\r
57  */\r
58 function buildNamespace(ns, out) {\r
59     var messages, enums, services;\r
60     util.extend(out, {\r
61         "syntax"   : ns.syntax   || 'proto2',\r
62         "options"  : out.options || {},\r
63         "messages" : messages = [],\r
64         "enums"    : enums    = [],\r
65         "services" : services = []\r
66     });\r
67     if (!(ns instanceof ProtoBuf.Reflect.Message))\r
68         out['isNamespace'] = true;\r
69     util.extend(out["options"], buildOptions(ns.options));\r
70     ns.getChildren(ProtoBuf.Reflect.Enum).forEach(function(enm) {\r
71         enums.push(buildEnum(enm));\r
72     });\r
73     if (enums.length === 0)\r
74         delete out["enums"];\r
75     ns.getChildren(ProtoBuf.Reflect.Message).forEach(function(msg) {\r
76         messages.push(buildMessage(msg));\r
77     });\r
78     ns.getChildren(ProtoBuf.Reflect.Service).forEach(function(svc) {\r
79         services.push(buildService(svc));\r
80     });\r
81     if (services.length === 0)\r
82         delete out["services"];\r
83     Array.prototype.push.apply(messages, buildExtensions(ns));\r
84     ns.getChildren(ProtoBuf.Reflect.Namespace).forEach(function(innerNs) {\r
85         if (innerNs.className !== "Namespace")\r
86             return;\r
87         var emptyMessage = {\r
88             "name": innerNs.name,\r
89             "fields": []\r
90         };\r
91         buildNamespace(innerNs, emptyMessage);\r
92         messages.push(emptyMessage);\r
93     });\r
94     if (messages.length === 0)\r
95         delete out["messages"];\r
96     if (Object.keys(out["options"]).length === 0)\r
97         delete out["options"];\r
98 }\r
99 \r
100 /**\r
101  * Builds extensions declared in the specified namespace.\r
102  * @param {!ProtoBuf.Reflect.Namespace} ns Namespace\r
103  * @returns {!Array.<!*>}\r
104  */\r
105 function buildExtensions(ns) {\r
106     var exts = util.groupExtensions(ns);\r
107     if (exts === null)\r
108         return [];\r
109     var messages = [];\r
110     Object.keys(exts).forEach(function(extFqn) {\r
111         var extMsg = ns.resolve(extFqn),\r
112             extFields = exts[extFqn];\r
113         var fields, ext = {\r
114             "ref"    : ns.qn(extMsg),\r
115             "fields" : fields = []\r
116         };\r
117         extFields.forEach(function(extField) {\r
118             fields.push(buildMessageField(extField));\r
119         });\r
120         messages.push(ext);\r
121     });\r
122     return messages;\r
123 }\r
124 \r
125 /**\r
126  * Builds block-level options.\r
127  * @param {!Object.<string,*>} options Options\r
128  * @returns {!Object.<string,*>}\r
129  */\r
130 function buildOptions(options) {\r
131     Object.keys(options = options || {}).forEach(function(key) {\r
132         var val = options[key];\r
133         switch (typeof val) {\r
134             case 'string':\r
135             case 'number':\r
136             case 'boolean':\r
137             case 'object':\r
138                 break;\r
139             default:\r
140                 throw Error("Illegal option type: "+typeof(val));\r
141         }\r
142     });\r
143     return options;\r
144 }\r
145 \r
146 /**\r
147  * Builds a message.\r
148  * @param {!ProtoBuf.Reflect.Message} msg Message\r
149  * @returns {!*}\r
150  */\r
151 function buildMessage(msg) {\r
152     var fields, oneofs;\r
153     var out = {\r
154         "name"     : msg.name,\r
155         "syntax"   : msg.syntax || 'proto2',\r
156         "options"  : {},\r
157         "fields"   : fields   = [],\r
158         "oneofs"   : oneofs   = {}\r
159     };\r
160     msg.getChildren(ProtoBuf.Reflect.Message.Field).forEach(function(fld) {\r
161         if (fld instanceof ProtoBuf.Reflect.Message.ExtensionField)\r
162             return;\r
163         fields.push(buildMessageField(fld));\r
164     });\r
165     msg.getChildren(ProtoBuf.Reflect.Message.OneOf).forEach(function(oneof) {\r
166         oneofs[oneof.name] = buildMessageOneof(oneof);\r
167     });\r
168     if (msg.extensions)\r
169         out["extensions"] = msg.extensions;\r
170     if (Object.keys(oneofs).length === 0)\r
171         delete out["oneofs"];\r
172     buildNamespace(msg, out);\r
173     return out;\r
174 }\r
175 \r
176 /**\r
177  * Builds a message field.\r
178  * @param {!ProtoBuf.Reflect.Message.Field} fld Message field\r
179  * @returns {!*}\r
180  */\r
181 function buildMessageField(fld) {\r
182     return {\r
183         "rule"    : fld.map ? "map" : (fld.repeated ? "repeated" : (fld.required ? "required" : "optional")),\r
184         "type"    : fld.resolvedType ? fld.parent.qn(fld.resolvedType) : fld.type['name'],\r
185         "keytype" : (typeof(fld.keyType) === 'string') ? fld.keyType : (fld.keyType !== null ? fld.keyType.name : undefined),\r
186         "name"    : fld instanceof ProtoBuf.Reflect.Message.ExtensionField ? fld.name.substring(fld.name.lastIndexOf(".")+1): fld.name,\r
187         "id"      : fld.id,\r
188         "options" : Object.keys(fld.options).length > 0 ? buildOptions(fld.options) : undefined,\r
189         "oneof"   : fld.oneof ? fld.oneof.name : undefined\r
190     };\r
191 }\r
192 \r
193 /**\r
194  * Builds a message oneof.\r
195  * @param {!ProtoBuf.Reflect.message.OneOf} oneof Message oneof\r
196  * @returns {!Array.<!*>}\r
197  */\r
198 function buildMessageOneof(oneof) {\r
199     var out = [];\r
200     oneof.fields.forEach(function(fld) {\r
201         out.push(fld.id);\r
202     });\r
203     return out;\r
204 }\r
205 \r
206 /**\r
207  * Builds an enum.\r
208  * @param {!ProtoBuf.Reflect.Enum} enm Enum\r
209  * @returns {!*}\r
210  */\r
211 function buildEnum(enm) {\r
212     var values;\r
213     var out = {\r
214         "name"    : enm.name,\r
215         "syntax"  : enm.syntax || 'proto2',\r
216         "values"  : values = []\r
217     };\r
218     enm.getChildren(ProtoBuf.Reflect.Enum.Value).forEach(function(val) {\r
219         values.push(buildEnumValue(val));\r
220     });\r
221     if (Object.keys(enm.options).length > 0)\r
222         out["options"] = buildOptions(enm.options);\r
223     return out;\r
224 }\r
225 \r
226 /**\r
227  * Builds an enum value.\r
228  * @param {!ProtoBuf.Reflect.Enum.Value} val Enum value\r
229  * @returns {!*}\r
230  */\r
231 function buildEnumValue(val) {\r
232     return {\r
233         "name"    : val.name,\r
234         "id"      : val.id\r
235     };\r
236 }\r
237 \r
238 /**\r
239  * Builds a service.\r
240  * @param {!ProtoBuf.Reflect.Service} svc Service\r
241  * @returns {!*}\r
242  */\r
243 function buildService(svc) {\r
244     var rpc;\r
245     var out = {\r
246         "name": svc.name,\r
247         "options": buildOptions(svc.options),\r
248         "rpc": rpc = {}\r
249     };\r
250     svc.getChildren(ProtoBuf.Reflect.Service.RPCMethod).forEach(function(mtd) {\r
251         rpc[mtd.name] = {\r
252             "request": svc.qn(mtd.resolvedRequestType),\r
253             "request_stream": mtd.requestStream,\r
254             "response": svc.qn(mtd.resolvedResponseType),\r
255             "response_stream": mtd.responseStream,\r
256             "options": buildOptions(mtd.options)\r
257         };\r
258     });\r
259     return out;\r
260 }\r