idl_util.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. /**
  2. * Tencent is pleased to support the open source community by making Tars available.
  3. *
  4. * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
  5. *
  6. * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  7. * in compliance with the License. You may obtain a copy of the License at
  8. *
  9. * https://opensource.org/licenses/BSD-3-Clause
  10. *
  11. * Unless required by applicable law or agreed to in writing, software distributed
  12. * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  13. * CONDITIONS OF ANY KIND, either express or implied. See the License for the
  14. * specific language governing permissions and limitations under the License.
  15. */
  16. #include "code_generator.h"
  17. string CodeGenerator::toFunctionName(const TypeIdPtr& pPtr, const string& sAction)
  18. {
  19. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
  20. if (bPtr)
  21. {
  22. switch (bPtr->kind())
  23. {
  24. case Builtin::KindBool : return sAction + "Boolean";
  25. case Builtin::KindString : return sAction + "String";
  26. case Builtin::KindByte : return sAction + "Int8";
  27. case Builtin::KindShort : return sAction + (bPtr->isUnsigned() ? "UInt8" : "Int16");
  28. case Builtin::KindInt : return sAction + (bPtr->isUnsigned() ? "UInt16" : "Int32");
  29. case Builtin::KindLong : return sAction + (bPtr->isUnsigned() ? "UInt32" : "Int64");
  30. case Builtin::KindFloat : return sAction + "Float";
  31. case Builtin::KindDouble : return sAction + "Double";
  32. default : assert(false);
  33. }
  34. }
  35. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
  36. if (vPtr)
  37. {
  38. BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
  39. if (vbPtr && vbPtr->kind() == Builtin::KindByte)
  40. {
  41. return sAction + "Bytes";
  42. }
  43. return sAction + "List";
  44. }
  45. StructPtr sPtr = StructPtr::dynamicCast(pPtr->getTypePtr());
  46. if (sPtr)
  47. {
  48. return sAction + "Struct";
  49. }
  50. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
  51. if (ePtr)
  52. {
  53. return sAction + "Int32";
  54. }
  55. MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
  56. if (mPtr)
  57. {
  58. return sAction + "Map";
  59. }
  60. return "";
  61. }
  62. string CodeGenerator::toObjectString(const TypeIdPtr &pPtr)
  63. {
  64. string nameId = pPtr->getId();
  65. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
  66. if (vPtr)
  67. {
  68. return nameId + ".toObject()";
  69. }
  70. StructPtr sPtr = StructPtr::dynamicCast(pPtr->getTypePtr());
  71. if (sPtr)
  72. {
  73. return nameId + ".toObject()";
  74. }
  75. MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
  76. if (mPtr)
  77. {
  78. return nameId + ".toObject()";
  79. }
  80. return nameId;
  81. }
  82. string CodeGenerator::representArgument(const TypePtr& pPtr) const
  83. {
  84. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
  85. if (bPtr)
  86. {
  87. if (bPtr->kind() == Builtin::KindLong && _iLongType != CodeGenerator::Number)
  88. {
  89. stringstream str;
  90. str << ", " << _iLongType;
  91. return str.str();
  92. }
  93. if (_bStringBinaryEncoding && bPtr->kind() == Builtin::KindString)
  94. {
  95. return ", 1";
  96. }
  97. }
  98. return "";
  99. }
  100. string CodeGenerator::getClassName(const TypePtr& pPtr)
  101. {
  102. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
  103. if (bPtr)
  104. {
  105. switch (bPtr->kind())
  106. {
  107. case Builtin::KindBool : return "bool";
  108. case Builtin::KindString : return "string";
  109. case Builtin::KindByte : return "char";
  110. case Builtin::KindShort : return "short";
  111. case Builtin::KindInt : return "int32";
  112. case Builtin::KindLong : return "int64";
  113. case Builtin::KindFloat : return "float";
  114. case Builtin::KindDouble : return "double";
  115. default : assert(false);
  116. }
  117. }
  118. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
  119. if (vPtr)
  120. {
  121. return "list(" + getClassName(vPtr->getTypePtr()) + ")";
  122. }
  123. StructPtr sPtr = StructPtr::dynamicCast(pPtr);
  124. if (sPtr)
  125. {
  126. vector<string> vecNames = TC_Common::sepstr<string>(sPtr->getSid(), "::");
  127. assert(vecNames.size() == 2);
  128. return vecNames[0] + "." + vecNames[1];
  129. }
  130. MapPtr mPtr = MapPtr::dynamicCast(pPtr);
  131. if (mPtr)
  132. {
  133. return "map(" + getClassName(mPtr->getLeftTypePtr()) + ", " + getClassName(mPtr->getRightTypePtr()) + ")";
  134. }
  135. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
  136. if (ePtr)
  137. {
  138. return "int32";
  139. }
  140. return "void";
  141. }
  142. string CodeGenerator::getDataType(const TypePtr& pPtr, const bool &bCastEnumAsAny)
  143. {
  144. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
  145. if (bPtr)
  146. {
  147. switch (bPtr->kind())
  148. {
  149. case Builtin::KindBool : return IDL_NAMESPACE_STR + "Stream.Boolean";
  150. case Builtin::KindString : return IDL_NAMESPACE_STR + "Stream.String";
  151. case Builtin::KindByte : return IDL_NAMESPACE_STR + "Stream.Int8";
  152. case Builtin::KindShort : return IDL_NAMESPACE_STR + "Stream.Int16";
  153. case Builtin::KindInt : return IDL_NAMESPACE_STR + "Stream.Int32";
  154. case Builtin::KindLong : return IDL_NAMESPACE_STR + "Stream.Int64";
  155. case Builtin::KindFloat : return IDL_NAMESPACE_STR + "Stream.Float";
  156. case Builtin::KindDouble : return IDL_NAMESPACE_STR + "Stream.Double";
  157. default : assert(false);
  158. }
  159. }
  160. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
  161. if (vPtr)
  162. {
  163. BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
  164. if (vbPtr && vbPtr->kind() == Builtin::KindByte)
  165. {
  166. return IDL_NAMESPACE_STR + "Stream.BinBuffer";
  167. }
  168. return IDL_NAMESPACE_STR + "Stream.List(" + getDataType(vPtr->getTypePtr(), bCastEnumAsAny) + representArgument(vPtr->getTypePtr()) + ")";
  169. }
  170. StructPtr sPtr = StructPtr::dynamicCast(pPtr);
  171. if (sPtr)
  172. {
  173. vector<string> vecNames = TC_Common::sepstr<string>(sPtr->getSid(), "::");
  174. assert(vecNames.size() == 2);
  175. return findName(vecNames[0], vecNames[1]);
  176. }
  177. MapPtr mPtr = MapPtr::dynamicCast(pPtr);
  178. if (mPtr)
  179. {
  180. string sLeft = representArgument(mPtr->getLeftTypePtr());
  181. string sRight = representArgument(mPtr->getRightTypePtr());
  182. if (sLeft.empty() && !sRight.empty())
  183. {
  184. sLeft = ", 0";
  185. }
  186. return IDL_NAMESPACE_STR + "Stream.Map(" + getDataType(mPtr->getLeftTypePtr(), bCastEnumAsAny) + ", " +
  187. getDataType(mPtr->getRightTypePtr(), bCastEnumAsAny) + sLeft + sRight + ")";
  188. }
  189. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
  190. if (ePtr)
  191. {
  192. vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
  193. assert(vecNames.size() == 2);
  194. string suffix = bCastEnumAsAny ? " as any" : "";
  195. return findName(vecNames[0], vecNames[1]) + suffix;
  196. }
  197. assert(false);
  198. return "";
  199. }
  200. string CodeGenerator::getTsType(const TypePtr &pPtr, const bool bStream, const bool bBase)
  201. {
  202. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
  203. if (bPtr)
  204. {
  205. switch (bPtr->kind())
  206. {
  207. case Builtin::KindBool : return "boolean";
  208. case Builtin::KindString : return _bStringBinaryEncoding ? "Buffer" : "string";
  209. case Builtin::KindByte : return "number";
  210. case Builtin::KindShort : return "number";
  211. case Builtin::KindInt : return "number";
  212. case Builtin::KindFloat : return "number";
  213. case Builtin::KindDouble : return "number";
  214. case Builtin::KindLong :
  215. {
  216. switch (_iLongType)
  217. {
  218. case CodeGenerator::Number : return "number";
  219. case CodeGenerator::String : return "string";
  220. case CodeGenerator::BigInt : return "bigint";
  221. default : assert(false);
  222. }
  223. }
  224. default : assert(false);
  225. }
  226. }
  227. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
  228. if (vPtr)
  229. {
  230. BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
  231. if (vbPtr && vbPtr->kind() == Builtin::KindByte)
  232. {
  233. return bStream ? (IDL_NAMESPACE_STR + "Stream.BinBuffer") : "Buffer";
  234. }
  235. return (bStream ? (IDL_NAMESPACE_STR + "Stream.List") : "Array") + string("<") + getTsType(vPtr->getTypePtr(), bStream, bBase) + string(">");
  236. }
  237. StructPtr sPtr = StructPtr::dynamicCast(pPtr);
  238. if (sPtr)
  239. {
  240. vector<string> vecNames = TC_Common::sepstr<string>(sPtr->getSid(), "::");
  241. assert(vecNames.size() == 2);
  242. return findName(vecNames[0], vecNames[1], bBase) + (bStream ? "" : ".Object");
  243. }
  244. MapPtr mPtr = MapPtr::dynamicCast(pPtr);
  245. if (mPtr)
  246. {
  247. if (bStream)
  248. {
  249. // In current version (20190311) of the streaming library,
  250. // TypeScript cannot infer enum type over conditional type correctly.
  251. // So use `HeroMap` instead of `Map` to solve this problem.
  252. EnumPtr keyTypePtr = EnumPtr::dynamicCast(mPtr->getLeftTypePtr());
  253. string mapName = keyTypePtr ? "HeroMap" : "Map";
  254. return IDL_NAMESPACE_STR + "Stream." + mapName + "<" + getTsType(mPtr->getLeftTypePtr(), bStream) + ", " + getTsType(mPtr->getRightTypePtr(), bStream, bBase) + ">";
  255. }
  256. else
  257. {
  258. const string& sLeftType = getTsType(mPtr->getLeftTypePtr(), bStream, bBase);
  259. const string& sRightType = getTsType(mPtr->getRightTypePtr(), bStream, bBase);
  260. if (isSimple(mPtr->getLeftTypePtr()))
  261. {
  262. const string& recordKeyType = sLeftType == "number" ? "number" : "string";
  263. return "Record<" + recordKeyType + ", " + sRightType + ">";
  264. }
  265. else
  266. {
  267. return "";
  268. }
  269. }
  270. }
  271. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
  272. if (ePtr)
  273. {
  274. vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
  275. assert(vecNames.size() == 2);
  276. return findName(vecNames[0], vecNames[1], bBase);
  277. }
  278. assert(false);
  279. return "";
  280. }
  281. bool CodeGenerator::isSimple(const TypePtr & pPtr) const
  282. {
  283. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
  284. if (bPtr)
  285. {
  286. return true;
  287. }
  288. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
  289. if (ePtr)
  290. {
  291. return true;
  292. }
  293. return false;
  294. }
  295. bool CodeGenerator::isBinBuffer(const TypePtr & pPtr) const
  296. {
  297. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
  298. if (vPtr)
  299. {
  300. BuiltinPtr vbPtr = BuiltinPtr::dynamicCast(vPtr->getTypePtr());
  301. if (vbPtr && vbPtr->kind() == Builtin::KindByte)
  302. {
  303. return true;
  304. }
  305. }
  306. return false;
  307. }
  308. string CodeGenerator::getDefault(const TypeIdPtr & pPtr, const string &sDefault, const string& sNamespace, const bool &bGlobal, const bool &bCastEnumAsAny)
  309. {
  310. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
  311. if (bPtr)
  312. {
  313. switch (bPtr->kind())
  314. {
  315. case Builtin::KindBool :
  316. return sDefault.empty() ? "false" : sDefault;
  317. case Builtin::KindString :
  318. {
  319. if (_bStringBinaryEncoding)
  320. {
  321. return IDL_NAMESPACE_STR + "Stream.BinBuffer.from(\"" + TC_Common::replace(sDefault, "\"", "\\\"") + "\").toNodeBufferUnSafe()";
  322. }
  323. else
  324. {
  325. return "\"" + TC_Common::replace(sDefault, "\"", "\\\"") + "\"";
  326. }
  327. }
  328. case Builtin::KindByte : // [[fallthrough]]
  329. case Builtin::KindShort : // [[fallthrough]]
  330. case Builtin::KindInt : // [[fallthrough]]
  331. case Builtin::KindLong :
  332. {
  333. string sTemp = TC_Common::trim(sDefault);
  334. if (sTemp.empty())
  335. {
  336. sTemp = "0";
  337. }
  338. else
  339. {
  340. if (TC_Common::tostr(TC_Common::strto<long>(sTemp)) != sTemp)
  341. {
  342. // lookup in the enum when it is a enum
  343. vector<string> vecNames = TC_Common::sepstr<string>(sDefault, "::");
  344. if (vecNames.size() == 2)
  345. {
  346. sTemp = findName(vecNames[0], vecNames[1]);
  347. }
  348. else
  349. {
  350. sTemp = findName(sNamespace, sDefault);
  351. }
  352. }
  353. }
  354. if (sTemp.empty())
  355. {
  356. sTemp = "0";
  357. }
  358. if (bPtr->kind() == Builtin::KindLong)
  359. {
  360. switch (_iLongType)
  361. {
  362. case CodeGenerator::String:
  363. {
  364. sTemp = "\"" + sTemp + "\"";
  365. break;
  366. }
  367. case CodeGenerator::BigInt:
  368. {
  369. sTemp = sTemp + "n";
  370. break;
  371. }
  372. }
  373. }
  374. return sTemp;
  375. }
  376. case Builtin::KindFloat : // [[fallthrough]]
  377. case Builtin::KindDouble :
  378. return sDefault.empty()?"0.0":sDefault;
  379. default :
  380. assert(false);
  381. }
  382. }
  383. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
  384. if (ePtr)
  385. {
  386. if (sDefault.empty())
  387. {
  388. vector<TypeIdPtr>& eMember = ePtr->getAllMemberPtr();
  389. if (eMember.size() > 0)
  390. {
  391. vector<string> vecNames = TC_Common::sepstr<string>(ePtr->getSid(), "::");
  392. string sModule = findName(vecNames[0], eMember[0]->getId());
  393. return sModule;
  394. }
  395. }
  396. if (!TC_Common::isdigit(sDefault))
  397. {
  398. string s1 = sNamespace;
  399. string s2 = sDefault;
  400. string::size_type index = sDefault.find("::");
  401. if (index != string::npos)
  402. {
  403. s1 = sDefault.substr(0, index);
  404. s2 = sDefault.substr(index + 2);
  405. }
  406. string sModule = findName(s1, s2);
  407. assert(!sModule.empty());
  408. return sModule;
  409. }
  410. return sDefault;
  411. }
  412. if (bGlobal)
  413. {
  414. return "new " + getDataType(pPtr->getTypePtr(), bCastEnumAsAny);
  415. }
  416. return sDefault;
  417. }