gen_server.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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::generatePing(const NamespacePtr &nPtr, const InterfacePtr &pPtr)
  18. {
  19. ostringstream str;
  20. str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << TC_Common::lower(IDL_NAMESPACE_STR) << "_ping$RE = function (_ret) {" << endl;
  21. INC_TAB;
  22. str << TAB << "if (this.getRequestVersion() === " << PROTOCOL_SIMPLE << " || this.getRequestVersion() === " << PROTOCOL_COMPLEX << ") {" << endl;
  23. INC_TAB;
  24. str << TAB << "var " << PROTOCOL_VAR << " = new " << IDL_NAMESPACE_STR << "Stream.UniAttribute();" << endl;
  25. str << TAB << PROTOCOL_VAR << "." << PROTOCOL_VAR << "Version = this.getRequestVersion();" << endl;
  26. str << TAB << PROTOCOL_VAR << ".writeInt32(\"\", _ret);" << endl << endl;
  27. str << TAB << "this.doResponse(" << PROTOCOL_VAR << ".encode());" << endl;
  28. DEL_TAB;
  29. str << TAB << "} else {" << endl;
  30. INC_TAB;
  31. str << TAB << "var os = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "OutputStream();" << endl;
  32. str << TAB << "os.writeInt32(0, _ret);" << endl << endl;
  33. str << TAB << "this.doResponse(os.getBinBuffer());" << endl;
  34. DEL_TAB;
  35. str << TAB << "}" << endl;
  36. DEL_TAB;
  37. str << TAB << "};" << endl << endl;
  38. str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype.__" << TC_Common::lower(IDL_NAMESPACE_STR) << "_ping = function (current) {" << endl;
  39. INC_TAB;
  40. str << TAB << "__" << nPtr->getId() << "_" << pPtr->getId() << "$" << TC_Common::lower(IDL_NAMESPACE_STR) << "_ping$RE.call(current, 0);" << endl << endl;
  41. str << TAB << "return " << IDL_NAMESPACE_STR << "Error.SUCCESS;" << endl;
  42. DEL_TAB;
  43. str << TAB << "};" << endl;
  44. return str.str();
  45. }
  46. string CodeGenerator::generateAsync(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr)
  47. {
  48. ostringstream str;
  49. string sParams = "";
  50. if (oPtr->getReturnPtr()->getTypePtr())
  51. {
  52. sParams += "_ret";
  53. // push the symbol into dependent list
  54. getDataType(oPtr->getReturnPtr()->getTypePtr());
  55. }
  56. vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr();
  57. for (size_t i = 0; i < vParamDecl.size(); i++)
  58. {
  59. if (!vParamDecl[i]->isOut()) continue;
  60. sParams += (sParams.empty()?"":", ") + vParamDecl[i]->getTypeIdPtr()->getId();
  61. }
  62. str << TAB << "var __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$RE = function (" << sParams << ") {" << endl;
  63. INC_TAB;
  64. if (sParams.empty())
  65. {
  66. str << TAB << "this.doResponse(new " << IDL_NAMESPACE_STR << "Stream.BinBuffer());" << endl;
  67. DEL_TAB;
  68. str << TAB << "};" << endl;
  69. return str.str();
  70. }
  71. str << TAB << "if (this.getRequestVersion() === " << PROTOCOL_SIMPLE << " || this.getRequestVersion() === " << PROTOCOL_COMPLEX << ") {" << endl;
  72. INC_TAB;
  73. str << TAB << "var " << PROTOCOL_VAR << " = new " << IDL_NAMESPACE_STR << "Stream.UniAttribute();" << endl;
  74. str << TAB << PROTOCOL_VAR << "." << PROTOCOL_VAR << "Version = this.getRequestVersion();" << endl;
  75. if (oPtr->getReturnPtr()->getTypePtr())
  76. {
  77. str << TAB << PROTOCOL_VAR << "." << toFunctionName(oPtr->getReturnPtr(), "write") << "(\"\", _ret"
  78. << representArgument(oPtr->getReturnPtr()->getTypePtr()) << ");" << endl;
  79. }
  80. for (size_t i = 0; i < vParamDecl.size(); i++)
  81. {
  82. if (!vParamDecl[i]->isOut()) continue;
  83. str << TAB << PROTOCOL_VAR << "." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "(\""
  84. << vParamDecl[i]->getTypeIdPtr()->getId() << "\", " << vParamDecl[i]->getTypeIdPtr()->getId()
  85. << representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ");" << endl;
  86. }
  87. str << endl;
  88. str << TAB << "this.doResponse(" << PROTOCOL_VAR << ".encode());" << endl;
  89. DEL_TAB;
  90. //// ========= 增加对 JSON_VERSION 支持
  91. str << TAB << "} else if (this.getRequestVersion() === " << PROTOCOL_JSON << ") {" << endl;
  92. INC_TAB;
  93. str << TAB << "var _data_ = {};" << endl;
  94. if (oPtr->getReturnPtr()->getTypePtr())
  95. {
  96. str << TAB << "_data_[\"tars_ret\"] = _ret;" << endl;
  97. }
  98. for (size_t i = 0; i < vParamDecl.size(); i++)
  99. {
  100. if (!vParamDecl[i]->isOut())
  101. continue;
  102. str << TAB << "_data_[\"" << vParamDecl[i]->getTypeIdPtr()->getId() << "\"] = " << vParamDecl[i]->getTypeIdPtr()->getId()
  103. << ".toObject ? " << vParamDecl[i]->getTypeIdPtr()->getId() << ".toObject() : "
  104. << vParamDecl[i]->getTypeIdPtr()->getId() << ";" << endl;
  105. }
  106. str << endl;
  107. str << TAB << " this.doResponse(new TarsStream.BinBuffer(Buffer.from(JSON.stringify(_data_))));" << endl;
  108. DEL_TAB;
  109. //// =========
  110. str << TAB << "} else {" << endl;
  111. INC_TAB;
  112. str << TAB << "var os = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "OutputStream();" << endl;
  113. if (oPtr->getReturnPtr()->getTypePtr())
  114. {
  115. str << TAB << "os." << toFunctionName(oPtr->getReturnPtr(), "write") << "(0, _ret"
  116. << representArgument(oPtr->getReturnPtr()->getTypePtr()) << ");" << endl;
  117. }
  118. for (size_t i = 0; i < vParamDecl.size(); i++)
  119. {
  120. if (!vParamDecl[i]->isOut()) continue;
  121. str << TAB << "os." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "write") << "("
  122. << (i + 1) << ", " << vParamDecl[i]->getTypeIdPtr()->getId()
  123. << representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) << ");" << endl;
  124. }
  125. str << endl;
  126. str << TAB << "this.doResponse(os.getBinBuffer());" << endl;
  127. DEL_TAB;
  128. str << TAB << "}" << endl;
  129. DEL_TAB;
  130. str << TAB << "};" << endl;
  131. return str.str();
  132. }
  133. string CodeGenerator::generateDispatch(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr)
  134. {
  135. ostringstream str;
  136. vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr();
  137. str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype.__" << oPtr->getId() << " = function (current" << (vParamDecl.size() != 0 ? ", binBuffer" : "") << ") {" << endl;
  138. INC_TAB;
  139. ostringstream dstr;
  140. for (size_t i = 0; i < vParamDecl.size(); i++)
  141. {
  142. dstr << TAB << "var " << vParamDecl[i]->getTypeIdPtr()->getId() << " = null;" << endl;
  143. }
  144. if (vParamDecl.size() != 0)
  145. {
  146. dstr << endl;
  147. }
  148. dstr << TAB << "if (current.getRequestVersion() === " << PROTOCOL_SIMPLE << " || current.getRequestVersion() === " << PROTOCOL_COMPLEX << ") {" << endl;
  149. INC_TAB;
  150. dstr << TAB << "var " << PROTOCOL_VAR << " = new " << IDL_NAMESPACE_STR << "Stream.UniAttribute();" << endl;
  151. dstr << TAB << PROTOCOL_VAR << "." << PROTOCOL_VAR << "Version = current.getRequestVersion();" << endl;
  152. dstr << TAB << PROTOCOL_VAR << ".decode(binBuffer);" << endl;
  153. for (size_t i = 0; i < vParamDecl.size(); i++)
  154. {
  155. dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
  156. << " = " << PROTOCOL_VAR << "." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "read")
  157. << "(\"" << vParamDecl[i]->getTypeIdPtr()->getId() << "\"";
  158. if (!isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()) && !isBinBuffer(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
  159. {
  160. dstr << ", " << getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  161. }
  162. if (vParamDecl[i]->isOut())
  163. {
  164. dstr << ", " << getDefault(vParamDecl[i]->getTypeIdPtr(), "", nPtr->getId(), true)
  165. << representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  166. }
  167. dstr << ");" << endl;
  168. }
  169. DEL_TAB;
  170. //// ========= 增加对 JSON_VERSION 支持
  171. dstr << TAB << "} else if (current.getRequestVersion() === " << PROTOCOL_JSON << ") {" << endl;
  172. INC_TAB;
  173. dstr << TAB << "var _data_ = JSON.parse(binBuffer.toNodeBuffer());" << endl;
  174. for (size_t i = 0; i < vParamDecl.size(); i++)
  175. {
  176. if (vParamDecl[i]->isOut())
  177. {
  178. //_data_.rsp ? rsp.readFromObject(_data_.rsp) : rsp;
  179. StructPtr sPtr = StructPtr::dynamicCast(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  180. VectorPtr vPtr = VectorPtr::dynamicCast(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  181. MapPtr mPtr = MapPtr::dynamicCast(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  182. if (sPtr || vPtr || mPtr)
  183. {
  184. dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
  185. << " = " << getDefault(vParamDecl[i]->getTypeIdPtr(), "", nPtr->getId(), true)
  186. << ";" << endl;
  187. dstr << TAB << "_data_." << vParamDecl[i]->getTypeIdPtr()->getId() << " ? " << vParamDecl[i]->getTypeIdPtr()->getId() << ".readFromObject("
  188. << "_data_." << vParamDecl[i]->getTypeIdPtr()->getId() << ") : " << vParamDecl[i]->getTypeIdPtr()->getId()
  189. << ";" << endl;
  190. }
  191. else
  192. {
  193. dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
  194. << " = _data_." << vParamDecl[i]->getTypeIdPtr()->getId() << " || " << getDefault(vParamDecl[i]->getTypeIdPtr(), "", nPtr->getId(), true)
  195. << ";" << endl;
  196. }
  197. }
  198. else
  199. {
  200. StructPtr sPtr = StructPtr::dynamicCast(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  201. VectorPtr vPtr = VectorPtr::dynamicCast(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  202. MapPtr mPtr = MapPtr::dynamicCast(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  203. if (sPtr || vPtr || mPtr)
  204. {
  205. dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
  206. << " = " << getDefault(vParamDecl[i]->getTypeIdPtr(), "", nPtr->getId(), true)
  207. << ";" << endl;
  208. dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId() << ".readFromObject("
  209. << "_data_." << vParamDecl[i]->getTypeIdPtr()->getId() << ")"
  210. << ";" << endl;
  211. }
  212. else
  213. {
  214. dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
  215. << " = _data_." << vParamDecl[i]->getTypeIdPtr()->getId()
  216. << ";" << endl;
  217. }
  218. }
  219. }
  220. DEL_TAB;
  221. //// =========
  222. dstr << TAB << "} else {" << endl;
  223. INC_TAB;
  224. dstr << TAB << "var is = new " << IDL_NAMESPACE_STR << "Stream." << IDL_TYPE << "InputStream(binBuffer);" << endl;
  225. string sParams = "";
  226. for (size_t i = 0; i < vParamDecl.size(); i++)
  227. {
  228. sParams += ", " + vParamDecl[i]->getTypeIdPtr()->getId();
  229. dstr << TAB << vParamDecl[i]->getTypeIdPtr()->getId()
  230. << " = is." << toFunctionName(vParamDecl[i]->getTypeIdPtr(), "read") << "("
  231. << (i + 1) << ", " << (vParamDecl[i]->isOut() ? "false" : "true") << ", ";
  232. if (isSimple(vParamDecl[i]->getTypeIdPtr()->getTypePtr()))
  233. {
  234. dstr << getDefault(vParamDecl[i]->getTypeIdPtr(), vParamDecl[i]->getTypeIdPtr()->def(), nPtr->getId())
  235. << representArgument(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  236. }
  237. else
  238. {
  239. dstr << getDataType(vParamDecl[i]->getTypeIdPtr()->getTypePtr());
  240. }
  241. dstr << ");" << endl;
  242. }
  243. DEL_TAB;
  244. dstr << TAB << "}" << endl << endl;
  245. if (!sParams.empty())
  246. {
  247. str << dstr.str();
  248. }
  249. str << TAB << "current.sendResponse = __" << nPtr->getId() << "_" << pPtr->getId() << "$" << oPtr->getId() << "$RE;" << endl << endl;
  250. str << TAB << "this." << oPtr->getId() << "(current" << sParams << ");" << endl << endl;
  251. str << TAB << "return " << IDL_NAMESPACE_STR << "Error.SUCCESS;" << endl;
  252. DEL_TAB;
  253. str << TAB << "};" << endl;
  254. return str.str();
  255. }
  256. string CodeGenerator::generateJSServer(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr)
  257. {
  258. ostringstream str;
  259. str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype." << oPtr->getId() << " = function () {" << endl;
  260. INC_TAB;
  261. str << TAB << "assert.fail(\"" << oPtr->getId() << " function not implemented\");" << endl;
  262. DEL_TAB;
  263. str << TAB << "};" << endl;
  264. return str.str();
  265. }
  266. string CodeGenerator::generateJSServer(const InterfacePtr &pPtr, const NamespacePtr &nPtr)
  267. {
  268. ostringstream str;
  269. vector<OperationPtr> & vOperation = pPtr->getAllOperationPtr();
  270. // generate the implementation class
  271. str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp = function () { " << endl;
  272. INC_TAB;
  273. str << TAB << "this._name = undefined;" << endl;
  274. str << TAB << "this._worker = undefined;" << endl;
  275. DEL_TAB;
  276. str << TAB << "};" << endl << endl;
  277. // generate the initialize function
  278. str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype.initialize = function () {};" << endl << endl;
  279. // generate the dispatch function
  280. str << TAB << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype.onDispatch = function (current, funcName, binBuffer) { " << endl;
  281. INC_TAB;
  282. str << TAB << "if (\"__\" + funcName in this) {" << endl;
  283. INC_TAB;
  284. str << TAB << "return this[\"__\" + funcName](current, binBuffer);" << endl;
  285. DEL_TAB;
  286. str << TAB << "} else {" << endl;
  287. INC_TAB;
  288. str << TAB << "return " << IDL_NAMESPACE_STR << "Error.SERVER.FUNC_NOT_FOUND;" << endl;
  289. DEL_TAB;
  290. str << TAB << "}" << endl;
  291. DEL_TAB;
  292. str << TAB << "};" << endl << endl;
  293. // generate the ping function
  294. str << generatePing(nPtr, pPtr) << endl;
  295. // generate functions
  296. for (size_t i = 0; i < vOperation.size(); i++)
  297. {
  298. str << generateJSServer(nPtr, pPtr, vOperation[i]) << endl;
  299. str << generateAsync(nPtr, pPtr, vOperation[i]) << endl;
  300. str << generateDispatch(nPtr, pPtr, vOperation[i]) << endl;
  301. }
  302. str << endl;
  303. return str.str();
  304. }
  305. string CodeGenerator::generateJSServer(const NamespacePtr &pPtr, bool &bNeedStream, bool &bNeedRpc, bool &bNeedAssert)
  306. {
  307. ostringstream str;
  308. vector<InterfacePtr> & is = pPtr->getAllInterfacePtr();
  309. for (size_t i = 0; i < is.size(); i++)
  310. {
  311. str << generateJSServer(is[i], pPtr) << endl;
  312. }
  313. if (is.size() != 0)
  314. {
  315. bNeedRpc = true;
  316. bNeedStream = true;
  317. bNeedAssert = true;
  318. }
  319. return str.str();
  320. }
  321. bool CodeGenerator::generateJSServer(const ContextPtr &pPtr)
  322. {
  323. vector<NamespacePtr> namespaces = pPtr->getNamespaces();
  324. ostringstream istr;
  325. set<string> setNamespace;
  326. for(size_t i = 0; i < namespaces.size(); i++)
  327. {
  328. if (setNamespace.count(namespaces[i]->getId()) == 0)
  329. {
  330. istr << TAB << "var " << namespaces[i]->getId() << " = " << namespaces[i]->getId() << " || {};" << endl;
  331. istr << TAB << "module.exports." << namespaces[i]->getId() << " = " << namespaces[i]->getId() << ";" << endl << endl;
  332. setNamespace.insert(namespaces[i]->getId());
  333. }
  334. }
  335. // generate server classes with encoders and decoders
  336. ostringstream estr;
  337. bool bNeedAssert = false;
  338. bool bNeedStream = false;
  339. bool bQuickFunc = false;
  340. for(size_t i = 0; i < namespaces.size(); i++)
  341. {
  342. estr << generateJS(namespaces[i], bNeedStream, bNeedAssert, bQuickFunc);
  343. }
  344. bool bNeedRpc = false;
  345. for(size_t i = 0; i < namespaces.size(); i++)
  346. {
  347. estr << generateJSServer(namespaces[i], bNeedStream, bNeedRpc, bNeedAssert) << endl;
  348. }
  349. if (estr.str().empty())
  350. {
  351. return false;
  352. }
  353. // generate module imports
  354. ostringstream ostr;
  355. if (bNeedAssert)
  356. {
  357. ostr << TAB << "var assert = require(\"assert\");" << endl;
  358. }
  359. if (bNeedStream)
  360. {
  361. ostr << TAB << "var " << IDL_NAMESPACE_STR << "Stream = require(\"" << _sStreamPath << "\");" << endl;
  362. }
  363. if (bNeedRpc)
  364. {
  365. ostr << TAB << "var " << IDL_NAMESPACE_STR << "Error = require(\"" << _sRpcPath << "\").error;" << endl;
  366. }
  367. for (map<string, ImportFile>::iterator it = _mapFiles.begin(); it != _mapFiles.end(); it++)
  368. {
  369. if (it->second.sModule.empty()) continue;
  370. if (estr.str().find(it->second.sModule + ".") == string::npos) continue;
  371. ostr << TAB << "var " << it->second.sModule << " = require(\"" << it->second.sFile << "\");" << endl;
  372. }
  373. if (bQuickFunc)
  374. {
  375. ostr << endl;
  376. ostr << TAB << "var _hasOwnProperty = Object.prototype.hasOwnProperty;" << endl;
  377. }
  378. ostringstream str;
  379. str << printHeaderRemark("Server");
  380. str << DISABLE_ESLINT << endl;
  381. str << endl;
  382. str << "\"use strict\";" << endl << endl;
  383. str << ostr.str() << endl;
  384. str << istr.str();
  385. str << estr.str() << endl;
  386. string sFileName = TC_File::excludeFileExt(_sToPath + TC_File::extractFileName(pPtr->getFileName())) + ".js";
  387. TC_File::makeDirRecursive(_sToPath);
  388. makeUTF8File(sFileName, str.str());
  389. return true;
  390. }