tars2cs.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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 "tars2cs.h"
  17. #include "util/tc_md5.h"
  18. #include "util/tc_file.h"
  19. #include "util/tc_common.h"
  20. #include <string>
  21. #include <string.h>
  22. #define TARS_PACKAGE "Wup.Tars"
  23. #define TAB g_parse->getTab()
  24. #define INC_TAB g_parse->incTab()
  25. #define DEL_TAB g_parse->delTab()
  26. //////////////////////////////////////////////////////////////////////////////////
  27. string Tars2Cs::toTypeInit(const TypePtr &pPtr) const
  28. {
  29. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
  30. if (bPtr)
  31. {
  32. switch (bPtr->kind())
  33. {
  34. case Builtin::KindBool: return "false;";
  35. case Builtin::KindByte: return "0;";
  36. case Builtin::KindShort: return "0;";
  37. case Builtin::KindInt: return "0;";
  38. case Builtin::KindLong: return "0L;";
  39. case Builtin::KindFloat: return "0.0f;";
  40. case Builtin::KindDouble: return "0.0;";
  41. case Builtin::KindString: return "\"\";";
  42. default: return "";
  43. }
  44. }
  45. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
  46. if (vPtr)
  47. {
  48. string sType;
  49. size_t iPosBegin, iPosEnd;
  50. sType = tostr(vPtr->getTypePtr());
  51. if ((iPosBegin = sType.find("<")) != string::npos && (iPosEnd = sType.rfind(">")) != string::npos)
  52. {
  53. sType = sType.substr(0, iPosBegin) + sType.substr(iPosEnd+1);
  54. }
  55. sType = tars::TC_Common::replace(sType, "[]" , "[1]");
  56. return "(" + tostr(vPtr->getTypePtr()) + "[]) new " + sType + "[1];";;
  57. }
  58. MapPtr mPtr = MapPtr::dynamicCast(pPtr);
  59. if (mPtr) return "new " + tostrMap(mPtr, true) + "();";
  60. StructPtr sPtr = StructPtr::dynamicCast(pPtr);
  61. if (sPtr) return "new " + tostrStruct(sPtr) + "();";
  62. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
  63. if (ePtr) return "0;";
  64. return "";
  65. }
  66. string Tars2Cs::toObjStr(const TypePtr &pPtr) const
  67. {
  68. string sType = tostr(pPtr);
  69. if (sType == "bool") return "bool";
  70. if (sType == "byte") return "byte";
  71. if (sType == "short" ) return "short";
  72. if (sType == "int" ) return "int";
  73. if (sType == "long" ) return "long";
  74. if (sType == "float" ) return "float";
  75. if (sType == "double" ) return "double";
  76. return sType;
  77. }
  78. string Tars2Cs::tostr(const TypePtr &pPtr) const
  79. {
  80. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
  81. if (bPtr) return tostrBuiltin(bPtr);
  82. VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
  83. if (vPtr) return tostrVector(vPtr);
  84. MapPtr mPtr = MapPtr::dynamicCast(pPtr);
  85. if (mPtr) return tostrMap(mPtr);
  86. StructPtr sPtr = StructPtr::dynamicCast(pPtr);
  87. if (sPtr) return tostrStruct(sPtr);
  88. EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
  89. if (ePtr) return tostrEnum(ePtr);
  90. if (!pPtr) return "void";
  91. assert(false);
  92. return "";
  93. }
  94. /*******************************BuiltinPtr********************************/
  95. string Tars2Cs::tostrBuiltin(const BuiltinPtr &pPtr) const
  96. {
  97. string s;
  98. switch (pPtr->kind())
  99. {
  100. case Builtin::KindBool: s = "bool"; break;
  101. case Builtin::KindByte: s = "byte"; break;
  102. case Builtin::KindShort: s = "short"; break;
  103. case Builtin::KindInt: s = "int"; break;
  104. case Builtin::KindLong: s = "long"; break;
  105. case Builtin::KindFloat: s = "float"; break;
  106. case Builtin::KindDouble: s = "double"; break;
  107. case Builtin::KindString: s = "string"; break;
  108. case Builtin::KindVector: s = "System.Collections.Generic.List"; break;
  109. case Builtin::KindMap: s = "System.Collections.Generic.Dictionary"; break;
  110. default: assert(false); break;
  111. }
  112. return s;
  113. }
  114. string Tars2Cs::tostrVector(const VectorPtr &pPtr) const
  115. {
  116. string s = "System.Collections.Generic.List" + string("<") + toObjStr(pPtr->getTypePtr()) + ">";
  117. return s;
  118. }
  119. string Tars2Cs::tostrMap(const MapPtr &pPtr, bool bNew) const
  120. {
  121. string s;
  122. if (!bNew)
  123. {
  124. s = "System.Collections.Generic.Dictionary";
  125. }
  126. else
  127. {
  128. s = "System.Collections.Generic.Dictionary";
  129. }
  130. s += string("<") + toObjStr(pPtr->getLeftTypePtr()) + ", " + toObjStr(pPtr->getRightTypePtr()) + ">";
  131. return s;
  132. }
  133. string Tars2Cs::tostrStruct(const StructPtr &pPtr) const
  134. {
  135. return tars::TC_Common::replace(pPtr->getSid(), "::", ".").substr(tars::TC_Common::replace(pPtr->getSid(), "::", ".").find(".")+1);
  136. }
  137. string Tars2Cs::tostrEnum(const EnumPtr &pPtr) const
  138. {
  139. return "int";
  140. }
  141. /******************************StructPtr***************************************/
  142. string Tars2Cs::generateCs(const StructPtr &pPtr, const NamespacePtr &nPtr) const
  143. {
  144. ostringstream s;
  145. s << g_parse->printHeaderRemark();
  146. vector<string> key = pPtr->getKey();
  147. vector<TypeIdPtr>& member = pPtr->getAllMemberPtr();
  148. s << TAB << "using System;"<<endl;
  149. s << TAB << "namespace "<< nPtr->getId()<< endl;
  150. s << "{"<<endl;
  151. INC_TAB;
  152. s << endl;
  153. s << TAB << "public sealed class " << pPtr->getId() << " : " TARS_PACKAGE ".TarsStruct"<< endl;
  154. s << TAB << "{" << endl;
  155. INC_TAB;
  156. for (size_t i = 0; i < member.size(); i++)
  157. {
  158. string sDefault;
  159. if (member[i]->hasDefault())
  160. {
  161. BuiltinPtr bPtr = BuiltinPtr::dynamicCast(member[i]->getTypePtr());
  162. if (bPtr && bPtr->kind() == Builtin::KindString)
  163. {
  164. sDefault = tars::TC_Common::replace(member[i]->def(), "\"", "\\\"");
  165. sDefault = " = \"" + sDefault + "\"";
  166. }
  167. else
  168. {
  169. sDefault = " = " + member[i]->def();
  170. }
  171. s << TAB << tostr(member[i]->getTypePtr()) << " _" << member[i]->getId() << sDefault << ";" << endl;
  172. s << TAB << "public " << tostr(member[i]->getTypePtr()) << " " << member[i]->getId() << endl;
  173. s << TAB << "{" << endl;
  174. INC_TAB;
  175. s << TAB << "get" << endl;
  176. s << TAB << "{" << endl;
  177. INC_TAB;
  178. s << TAB << " return _" << member[i]->getId() << ";" << endl;
  179. DEL_TAB;
  180. s << TAB << "}" << endl;
  181. s << TAB << "set" << endl;
  182. s << TAB << "{" << endl;
  183. INC_TAB;
  184. s << TAB << "_" << member[i]->getId() << " = value; " << endl;
  185. DEL_TAB;
  186. s << TAB << "}" << endl;
  187. DEL_TAB;
  188. s << TAB << "}" << endl;
  189. }
  190. else
  191. {
  192. sDefault = " {get; set;} ";
  193. s << TAB << "public " << tostr(member[i]->getTypePtr()) << " " << member[i]->getId() << sDefault << endl;
  194. }
  195. s << endl;
  196. }
  197. //writeTo()
  198. s << TAB << "public override void WriteTo(" TARS_PACKAGE ".TarsOutputStream _os)" << endl;
  199. s << TAB << "{" << endl;
  200. INC_TAB;
  201. for (size_t i = 0; i < member.size(); i++)
  202. {
  203. s << TAB << "_os.Write(" << member[i]->getId()
  204. << ", " << member[i]->getTag() << ");" << endl;
  205. }
  206. DEL_TAB;
  207. s << TAB << "}" << endl;
  208. s << endl;
  209. //readFrom()
  210. s << TAB << "public override void ReadFrom(" TARS_PACKAGE ".TarsInputStream _is)" << endl;
  211. s << TAB << "{" << endl;
  212. INC_TAB;
  213. for (size_t i = 0; i < member.size(); i++)
  214. {
  215. s << TAB << member[i]->getId() << " = (" + tostr(member[i]->getTypePtr()) + ")"
  216. << " _is.Read(" << member[i]->getId() << ", " << member[i]->getTag() << ", "
  217. << (member[i]->isRequire() ? "true" : "false") << ");" << endl << endl;
  218. }
  219. DEL_TAB;
  220. s << TAB << "}" << endl;
  221. s << endl;
  222. //display()
  223. s << TAB << "public override void Display(System.Text.StringBuilder _os, int _level)" << endl;
  224. s << TAB << "{" << endl;
  225. INC_TAB;
  226. s << TAB << TARS_PACKAGE ".TarsDisplayer _ds = new " TARS_PACKAGE ".TarsDisplayer(_os, _level);" << endl;
  227. for (size_t i = 0; i < member.size(); i++)
  228. {
  229. s << TAB << "_ds.Display(" << member[i]->getId() << ", \"" << member[i]->getId() << "\");" << endl;
  230. }
  231. DEL_TAB;
  232. s << TAB << "}" << endl;
  233. s << endl;
  234. DEL_TAB;
  235. s << TAB << "}" << endl;
  236. DEL_TAB;
  237. s << TAB << "}" << endl;
  238. s << endl;
  239. string fileCs = getFilePath(nPtr->getId()) + pPtr->getId() + ".cs";
  240. tars::TC_File::makeDirRecursive(getFilePath(nPtr->getId()));
  241. tars::TC_File::save2file(fileCs, s.str());
  242. return s.str();
  243. }
  244. /******************************ConstPtr***************************************/
  245. void Tars2Cs::generateCs(const vector<EnumPtr> &es,const vector<ConstPtr> &cs,const NamespacePtr &nPtr) const
  246. {
  247. if (es.size()==0 && cs.size()==0)
  248. {
  249. return;
  250. }
  251. ostringstream s;
  252. s << g_parse->printHeaderRemark();
  253. s << TAB << "using System;"<<endl;
  254. s << TAB << "namespace " << nPtr->getId()<< endl;
  255. s << "{"<<endl;
  256. INC_TAB;
  257. if (cs.size()>0)
  258. {
  259. s << TAB << "class Const " << endl;
  260. s << TAB << "{" << endl;
  261. INC_TAB;
  262. for (size_t i = 0; i < cs.size(); i++)
  263. {
  264. if (cs[i]->getConstGrammarPtr()->t == ConstGrammar::STRING)
  265. {
  266. string tmp = tars::TC_Common::replace(cs[i]->getConstGrammarPtr()->v, "\"", "\\\"");
  267. s << TAB << "public const "<< tostr(cs[i]->getTypeIdPtr()->getTypePtr()) << " "<<cs[i]->getTypeIdPtr()->getId()<< " = \""
  268. << tmp << "\";"<< endl;
  269. }
  270. else if (tostr(cs[i]->getTypeIdPtr()->getTypePtr()) == "long")
  271. {
  272. s << TAB << "public const "<< tostr(cs[i]->getTypeIdPtr()->getTypePtr()) << " "<<cs[i]->getTypeIdPtr()->getId()<< " = "
  273. << cs[i]->getConstGrammarPtr()->v << "L;" << endl;
  274. }
  275. else
  276. {
  277. s << TAB << "public const "<< tostr(cs[i]->getTypeIdPtr()->getTypePtr()) <<" "<<cs[i]->getTypeIdPtr()->getId()<< " = "
  278. << cs[i]->getConstGrammarPtr()->v << ";" << endl;
  279. }
  280. }
  281. DEL_TAB;
  282. s << TAB << "}" << endl;
  283. }
  284. if (es.size()>0)
  285. {
  286. for (size_t i = 0; i < es.size(); i++)
  287. {
  288. s << TAB << "public enum "<<es[i]->getId()<<endl;
  289. s<< TAB <<"{"<<endl;
  290. INC_TAB;
  291. vector<TypeIdPtr>& member = es[i]->getAllMemberPtr();
  292. for (size_t i = 0; i < member.size(); i++)
  293. {
  294. s << TAB << member[i]->getId();
  295. if(member[i]->hasDefault())
  296. {
  297. s << " = " << member[i]->def();
  298. }
  299. s <<","<<endl;
  300. }
  301. DEL_TAB;
  302. s<< TAB <<"}"<<endl;
  303. }
  304. }
  305. DEL_TAB;
  306. s << TAB << "}" << endl;
  307. string fileCs = getFilePath(nPtr->getId()) + nPtr->getId()+"_const.cs";
  308. tars::TC_File::makeDirRecursive(getFilePath(nPtr->getId()));
  309. tars::TC_File::save2file(fileCs, s.str());
  310. return;
  311. }
  312. /******************************NamespacePtr***************************************/
  313. void Tars2Cs::generateCs(const NamespacePtr &pPtr) const
  314. {
  315. vector<StructPtr> &ss = pPtr->getAllStructPtr();
  316. vector<EnumPtr> &es = pPtr->getAllEnumPtr();
  317. vector<ConstPtr> &cs = pPtr->getAllConstPtr();
  318. for (size_t i = 0; i < ss.size(); i++)
  319. {
  320. generateCs(ss[i], pPtr);
  321. }
  322. generateCs(es,cs,pPtr);
  323. return;
  324. }
  325. void Tars2Cs::generateCs(const ContextPtr &pPtr) const
  326. {
  327. ostringstream s;
  328. vector<NamespacePtr> namespaces = pPtr->getNamespaces();
  329. for (size_t i = 0; i < namespaces.size(); i++)
  330. {
  331. generateCs(namespaces[i]);
  332. }
  333. }
  334. void Tars2Cs::createFile(const string &file)
  335. {
  336. std::vector<ContextPtr> contexts = g_parse->getContexts();
  337. for (size_t i = 0; i < contexts.size(); i++)
  338. {
  339. if (file == contexts[i]->getFileName())
  340. {
  341. generateCs(contexts[i]);
  342. }
  343. }
  344. }
  345. void Tars2Cs::setBaseDir(const string &dir)
  346. {
  347. _baseDir = dir;
  348. }
  349. void Tars2Cs::setBasePackage(const string &prefix)
  350. {
  351. _packagePrefix = prefix;
  352. if (_packagePrefix.length() != 0 && _packagePrefix.substr(_packagePrefix.length()-1, 1) != ".")
  353. {
  354. _packagePrefix += ".";
  355. }
  356. }
  357. string Tars2Cs::getFilePath(const string &ns) const
  358. {
  359. return _baseDir + FILE_SEP + tars::TC_Common::replace(_packagePrefix, ".", FILE_SEP) + FILE_SEP + ns + FILE_SEP;
  360. }