Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / protobufjs / src / converter.js
1 "use strict";
2 /**
3  * Runtime message from/to plain object converters.
4  * @namespace
5  */
6 var converter = exports;
7
8 var Enum = require("./enum"),
9     util = require("./util");
10
11 /**
12  * Generates a partial value fromObject conveter.
13  * @param {Codegen} gen Codegen instance
14  * @param {Field} field Reflected field
15  * @param {number} fieldIndex Field index
16  * @param {string} prop Property reference
17  * @returns {Codegen} Codegen instance
18  * @ignore
19  */
20 function genValuePartial_fromObject(gen, field, fieldIndex, prop) {
21     /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
22     if (field.resolvedType) {
23         if (field.resolvedType instanceof Enum) { gen
24             ("switch(d%s){", prop);
25             for (var values = field.resolvedType.values, keys = Object.keys(values), i = 0; i < keys.length; ++i) {
26                 if (field.repeated && values[keys[i]] === field.typeDefault) gen
27                 ("default:");
28                 gen
29                 ("case%j:", keys[i])
30                 ("case %i:", values[keys[i]])
31                     ("m%s=%j", prop, values[keys[i]])
32                     ("break");
33             } gen
34             ("}");
35         } else gen
36             ("if(typeof d%s!==\"object\")", prop)
37                 ("throw TypeError(%j)", field.fullName + ": object expected")
38             ("m%s=types[%i].fromObject(d%s)", prop, fieldIndex, prop);
39     } else {
40         var isUnsigned = false;
41         switch (field.type) {
42             case "double":
43             case "float": gen
44                 ("m%s=Number(d%s)", prop, prop); // also catches "NaN", "Infinity"
45                 break;
46             case "uint32":
47             case "fixed32": gen
48                 ("m%s=d%s>>>0", prop, prop);
49                 break;
50             case "int32":
51             case "sint32":
52             case "sfixed32": gen
53                 ("m%s=d%s|0", prop, prop);
54                 break;
55             case "uint64":
56                 isUnsigned = true;
57                 // eslint-disable-line no-fallthrough
58             case "int64":
59             case "sint64":
60             case "fixed64":
61             case "sfixed64": gen
62                 ("if(util.Long)")
63                     ("(m%s=util.Long.fromValue(d%s)).unsigned=%j", prop, prop, isUnsigned)
64                 ("else if(typeof d%s===\"string\")", prop)
65                     ("m%s=parseInt(d%s,10)", prop, prop)
66                 ("else if(typeof d%s===\"number\")", prop)
67                     ("m%s=d%s", prop, prop)
68                 ("else if(typeof d%s===\"object\")", prop)
69                     ("m%s=new util.LongBits(d%s.low>>>0,d%s.high>>>0).toNumber(%s)", prop, prop, prop, isUnsigned ? "true" : "");
70                 break;
71             case "bytes": gen
72                 ("if(typeof d%s===\"string\")", prop)
73                     ("util.base64.decode(d%s,m%s=util.newBuffer(util.base64.length(d%s)),0)", prop, prop, prop)
74                 ("else if(d%s.length)", prop)
75                     ("m%s=d%s", prop, prop);
76                 break;
77             case "string": gen
78                 ("m%s=String(d%s)", prop, prop);
79                 break;
80             case "bool": gen
81                 ("m%s=Boolean(d%s)", prop, prop);
82                 break;
83             /* default: gen
84                 ("m%s=d%s", prop, prop);
85                 break; */
86         }
87     }
88     return gen;
89     /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
90 }
91
92 /**
93  * Generates a plain object to runtime message converter specific to the specified message type.
94  * @param {Type} mtype Message type
95  * @returns {Codegen} Codegen instance
96  */
97 converter.fromObject = function fromObject(mtype) {
98     /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
99     var fields = mtype.fieldsArray;
100     var gen = util.codegen(["d"], mtype.name + "$fromObject")
101     ("if(d instanceof this.ctor)")
102         ("return d");
103     if (!fields.length) return gen
104     ("return new this.ctor");
105     gen
106     ("var m=new this.ctor");
107     for (var i = 0; i < fields.length; ++i) {
108         var field  = fields[i].resolve(),
109             prop   = util.safeProp(field.name);
110
111         // Map fields
112         if (field.map) { gen
113     ("if(d%s){", prop)
114         ("if(typeof d%s!==\"object\")", prop)
115             ("throw TypeError(%j)", field.fullName + ": object expected")
116         ("m%s={}", prop)
117         ("for(var ks=Object.keys(d%s),i=0;i<ks.length;++i){", prop);
118             genValuePartial_fromObject(gen, field, /* not sorted */ i, prop + "[ks[i]]")
119         ("}")
120     ("}");
121
122         // Repeated fields
123         } else if (field.repeated) { gen
124     ("if(d%s){", prop)
125         ("if(!Array.isArray(d%s))", prop)
126             ("throw TypeError(%j)", field.fullName + ": array expected")
127         ("m%s=[]", prop)
128         ("for(var i=0;i<d%s.length;++i){", prop);
129             genValuePartial_fromObject(gen, field, /* not sorted */ i, prop + "[i]")
130         ("}")
131     ("}");
132
133         // Non-repeated fields
134         } else {
135             if (!(field.resolvedType instanceof Enum)) gen // no need to test for null/undefined if an enum (uses switch)
136     ("if(d%s!=null){", prop); // !== undefined && !== null
137         genValuePartial_fromObject(gen, field, /* not sorted */ i, prop);
138             if (!(field.resolvedType instanceof Enum)) gen
139     ("}");
140         }
141     } return gen
142     ("return m");
143     /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
144 };
145
146 /**
147  * Generates a partial value toObject converter.
148  * @param {Codegen} gen Codegen instance
149  * @param {Field} field Reflected field
150  * @param {number} fieldIndex Field index
151  * @param {string} prop Property reference
152  * @returns {Codegen} Codegen instance
153  * @ignore
154  */
155 function genValuePartial_toObject(gen, field, fieldIndex, prop) {
156     /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
157     if (field.resolvedType) {
158         if (field.resolvedType instanceof Enum) gen
159             ("d%s=o.enums===String?types[%i].values[m%s]:m%s", prop, fieldIndex, prop, prop);
160         else gen
161             ("d%s=types[%i].toObject(m%s,o)", prop, fieldIndex, prop);
162     } else {
163         var isUnsigned = false;
164         switch (field.type) {
165             case "double":
166             case "float": gen
167             ("d%s=o.json&&!isFinite(m%s)?String(m%s):m%s", prop, prop, prop, prop);
168                 break;
169             case "uint64":
170                 isUnsigned = true;
171                 // eslint-disable-line no-fallthrough
172             case "int64":
173             case "sint64":
174             case "fixed64":
175             case "sfixed64": gen
176             ("if(typeof m%s===\"number\")", prop)
177                 ("d%s=o.longs===String?String(m%s):m%s", prop, prop, prop)
178             ("else") // Long-like
179                 ("d%s=o.longs===String?util.Long.prototype.toString.call(m%s):o.longs===Number?new util.LongBits(m%s.low>>>0,m%s.high>>>0).toNumber(%s):m%s", prop, prop, prop, prop, isUnsigned ? "true": "", prop);
180                 break;
181             case "bytes": gen
182             ("d%s=o.bytes===String?util.base64.encode(m%s,0,m%s.length):o.bytes===Array?Array.prototype.slice.call(m%s):m%s", prop, prop, prop, prop, prop);
183                 break;
184             default: gen
185             ("d%s=m%s", prop, prop);
186                 break;
187         }
188     }
189     return gen;
190     /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
191 }
192
193 /**
194  * Generates a runtime message to plain object converter specific to the specified message type.
195  * @param {Type} mtype Message type
196  * @returns {Codegen} Codegen instance
197  */
198 converter.toObject = function toObject(mtype) {
199     /* eslint-disable no-unexpected-multiline, block-scoped-var, no-redeclare */
200     var fields = mtype.fieldsArray.slice().sort(util.compareFieldsById);
201     if (!fields.length)
202         return util.codegen()("return {}");
203     var gen = util.codegen(["m", "o"], mtype.name + "$toObject")
204     ("if(!o)")
205         ("o={}")
206     ("var d={}");
207
208     var repeatedFields = [],
209         mapFields = [],
210         normalFields = [],
211         i = 0;
212     for (; i < fields.length; ++i)
213         if (!fields[i].partOf)
214             ( fields[i].resolve().repeated ? repeatedFields
215             : fields[i].map ? mapFields
216             : normalFields).push(fields[i]);
217
218     if (repeatedFields.length) { gen
219     ("if(o.arrays||o.defaults){");
220         for (i = 0; i < repeatedFields.length; ++i) gen
221         ("d%s=[]", util.safeProp(repeatedFields[i].name));
222         gen
223     ("}");
224     }
225
226     if (mapFields.length) { gen
227     ("if(o.objects||o.defaults){");
228         for (i = 0; i < mapFields.length; ++i) gen
229         ("d%s={}", util.safeProp(mapFields[i].name));
230         gen
231     ("}");
232     }
233
234     if (normalFields.length) { gen
235     ("if(o.defaults){");
236         for (i = 0; i < normalFields.length; ++i) {
237             var field = normalFields[i],
238                 prop  = util.safeProp(field.name);
239             if (field.resolvedType instanceof Enum) gen
240         ("d%s=o.enums===String?%j:%j", prop, field.resolvedType.valuesById[field.typeDefault], field.typeDefault);
241             else if (field.long) gen
242         ("if(util.Long){")
243             ("var n=new util.Long(%i,%i,%j)", field.typeDefault.low, field.typeDefault.high, field.typeDefault.unsigned)
244             ("d%s=o.longs===String?n.toString():o.longs===Number?n.toNumber():n", prop)
245         ("}else")
246             ("d%s=o.longs===String?%j:%i", prop, field.typeDefault.toString(), field.typeDefault.toNumber());
247             else if (field.bytes) {
248                 var arrayDefault = "[" + Array.prototype.slice.call(field.typeDefault).join(",") + "]";
249                 gen
250         ("if(o.bytes===String)d%s=%j", prop, String.fromCharCode.apply(String, field.typeDefault))
251         ("else{")
252             ("d%s=%s", prop, arrayDefault)
253             ("if(o.bytes!==Array)d%s=util.newBuffer(d%s)", prop, prop)
254         ("}");
255             } else gen
256         ("d%s=%j", prop, field.typeDefault); // also messages (=null)
257         } gen
258     ("}");
259     }
260     var hasKs2 = false;
261     for (i = 0; i < fields.length; ++i) {
262         var field = fields[i],
263             index = mtype._fieldsArray.indexOf(field),
264             prop  = util.safeProp(field.name);
265         if (field.map) {
266             if (!hasKs2) { hasKs2 = true; gen
267     ("var ks2");
268             } gen
269     ("if(m%s&&(ks2=Object.keys(m%s)).length){", prop, prop)
270         ("d%s={}", prop)
271         ("for(var j=0;j<ks2.length;++j){");
272             genValuePartial_toObject(gen, field, /* sorted */ index, prop + "[ks2[j]]")
273         ("}");
274         } else if (field.repeated) { gen
275     ("if(m%s&&m%s.length){", prop, prop)
276         ("d%s=[]", prop)
277         ("for(var j=0;j<m%s.length;++j){", prop);
278             genValuePartial_toObject(gen, field, /* sorted */ index, prop + "[j]")
279         ("}");
280         } else { gen
281     ("if(m%s!=null&&m.hasOwnProperty(%j)){", prop, field.name); // !== undefined && !== null
282         genValuePartial_toObject(gen, field, /* sorted */ index, prop);
283         if (field.partOf) gen
284         ("if(o.oneofs)")
285             ("d%s=%j", util.safeProp(field.partOf.name), field.name);
286         }
287         gen
288     ("}");
289     }
290     return gen
291     ("return d");
292     /* eslint-enable no-unexpected-multiline, block-scoped-var, no-redeclare */
293 };