智慧水务管理系统 - 精河县供水工程综合管理平台

converter.js 14KB

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