printer.h 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734
  1. /*
  2. Copyright (c) 2020 Sogou, Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. #ifndef __RPC_PRINTER_H__
  14. #define __RPC_PRINTER_H__
  15. #include <string>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <unordered_map>
  19. #include "descriptor.h"
  20. #include "thrift/rpc_thrift_enum.h"
  21. static inline std::string join_package_names(const std::vector<std::string>& package)
  22. {
  23. std::string ret = package[0];
  24. for (size_t i = 1; i < package.size(); i++)
  25. {
  26. ret.append("::");
  27. ret.append(package[i]);
  28. }
  29. return ret;
  30. }
  31. static inline std::string change_include_prefix(const std::string& param)
  32. {
  33. size_t pos = param.find('.');
  34. if (pos == std::string::npos)
  35. return param;
  36. std::string ret = param.substr(0, pos);
  37. ret.append("::");
  38. ret.append(param.substr(pos + 1, param.length() - 1 - pos));
  39. return ret;
  40. }
  41. static inline std::string make_thrift_package_prefix(const std::vector<std::string>& package,
  42. const std::string& service,
  43. const std::string& param)
  44. {
  45. if (package.size() == 0)
  46. return service + "::" + param;
  47. std::string package_str = join_package_names(package);
  48. return "::" + package_str + "::" + service + "::" + param;
  49. }
  50. static inline std::string make_package_prefix(const std::vector<std::string>& package,
  51. const std::string& param)
  52. {
  53. size_t pos = param.find('.');
  54. if (pos != std::string::npos)
  55. return change_include_prefix(param);
  56. if (package.size() == 0)
  57. return param;
  58. std::string package_str = join_package_names(package);
  59. return "::" + package_str + "::" + param;
  60. }
  61. static inline std::string make_srpc_service_prefix(const std::vector<std::string>& package,
  62. const std::string& service, char sp)
  63. {
  64. std::string name;
  65. for (const std::string& p : package)
  66. {
  67. name.append(p);
  68. name.push_back(sp);
  69. }
  70. name.append(service);
  71. return name;
  72. }
  73. static inline std::string make_trpc_service_prefix(const std::vector<std::string>& package,
  74. const std::string& service)
  75. {
  76. if (package.size() == 0)
  77. return service;
  78. std::string package_prefix = package[0] + ".";
  79. for (size_t i = 1; i < package.size(); i++)
  80. package_prefix = package_prefix + package[i] + ".";
  81. return package_prefix + service;
  82. }
  83. static inline std::string make_trpc_method_prefix(const std::vector<std::string>& package,
  84. const std::string& service,
  85. const std::string& method)
  86. {
  87. std::string method_prefix = "/";
  88. for (size_t i = 0; i < package.size(); i++)
  89. method_prefix = method_prefix + package[i] + ".";
  90. return method_prefix + service + "/" + method;
  91. }
  92. static inline bool is_simple_type(int8_t data_type)
  93. {
  94. return data_type == srpc::TDT_BOOL
  95. || data_type == srpc::TDT_I08
  96. || data_type == srpc::TDT_I16
  97. || data_type == srpc::TDT_I32
  98. || data_type == srpc::TDT_I64
  99. || data_type == srpc::TDT_U64
  100. || data_type == srpc::TDT_DOUBLE;
  101. }
  102. static inline void fill_thrift_sync_params(const rpc_descriptor& rpc, std::string& return_type, std::string& handler_params, std::string& send_params)
  103. {
  104. return_type = "void";
  105. handler_params.clear();
  106. send_params.clear();
  107. if (!rpc.resp_params.empty())
  108. {
  109. const auto &param = rpc.resp_params[0];
  110. if (param.field_id == 0)
  111. {
  112. if (is_simple_type(param.data_type))
  113. return_type = param.type_name;
  114. else
  115. {
  116. handler_params += param.type_name;
  117. handler_params += "& _return";
  118. }
  119. }
  120. }
  121. for (const auto &param : rpc.req_params)
  122. {
  123. if (!handler_params.empty())
  124. handler_params += ", ";
  125. if (!send_params.empty())
  126. send_params += ", ";
  127. handler_params += "const ";
  128. handler_params += param.type_name;
  129. send_params += "const ";
  130. send_params += param.type_name;
  131. if (!is_simple_type(param.data_type))
  132. {
  133. handler_params += "&";
  134. send_params += "&";
  135. }
  136. handler_params += " ";
  137. handler_params += param.var_name;
  138. send_params += " ";
  139. send_params += param.var_name;
  140. }
  141. }
  142. static inline void fill_thrift_async_params(const rpc_descriptor& rpc, std::string& return_type, std::string& handler_params)
  143. {
  144. return_type.clear();
  145. handler_params.clear();
  146. if (!rpc.resp_params.empty())
  147. {
  148. const auto &param = rpc.resp_params[0];
  149. if (param.field_id == 0)
  150. {
  151. if (is_simple_type(param.data_type))
  152. return_type += "response->result = ";
  153. else
  154. handler_params += "response->result";
  155. }
  156. }
  157. for (const auto &param : rpc.req_params)
  158. {
  159. if (!handler_params.empty())
  160. handler_params += ", ";
  161. handler_params += "request->";
  162. handler_params += param.var_name;
  163. }
  164. }
  165. static void output_descriptor(int& i, FILE *f, const std::string& type_name, size_t& cur, const idl_info& info)
  166. {
  167. int8_t data_type;
  168. size_t st = cur;
  169. std::string key_arg = "void";
  170. std::string val_arg = "void";
  171. for (; cur < type_name.size(); cur++)
  172. {
  173. if (type_name[cur] == ',' || type_name[cur] == '>' || type_name[cur] == '<')
  174. break;
  175. }
  176. auto cpptype = SGenUtil::strip(type_name.substr(st, cur - st));
  177. if (info.typedef_mapping.find(cpptype) != info.typedef_mapping.end())
  178. {
  179. size_t offset = 0;
  180. output_descriptor(i,f,info.typedef_mapping.at(cpptype),offset,info);
  181. return;
  182. }
  183. std::string ret;
  184. if (cpptype == "bool")
  185. data_type = srpc::TDT_BOOL;
  186. else if (cpptype == "int8_t")
  187. data_type = srpc::TDT_I08;
  188. else if (cpptype == "int16_t")
  189. data_type = srpc::TDT_I16;
  190. else if (cpptype == "int32_t")
  191. data_type = srpc::TDT_I32;
  192. else if (cpptype == "int64_t")
  193. data_type = srpc::TDT_I64;
  194. else if (cpptype == "uint64_t")
  195. data_type = srpc::TDT_U64;
  196. else if (cpptype == "double")
  197. data_type = srpc::TDT_DOUBLE;
  198. else if (cpptype == "std::string")
  199. data_type = srpc::TDT_STRING;
  200. else if (cpptype == "std::map" && cur < type_name.size() && type_name[cur] == '<')
  201. {
  202. data_type = srpc::TDT_MAP;
  203. output_descriptor(i, f, type_name, ++cur, info);
  204. key_arg = "subtype_" + std::to_string(i);
  205. output_descriptor(i, f, type_name, ++cur, info);
  206. val_arg = "subtype_" + std::to_string(i);
  207. cpptype = SGenUtil::strip(type_name.substr(st, ++cur - st));
  208. }
  209. else if (cpptype == "std::set" && cur < type_name.size() && type_name[cur] == '<')
  210. {
  211. data_type = srpc::TDT_SET;
  212. output_descriptor(i, f, type_name, ++cur, info);
  213. val_arg = "subtype_" + std::to_string(i);
  214. cpptype = SGenUtil::strip(type_name.substr(st, ++cur - st));
  215. }
  216. else if (cpptype == "std::vector" && cur < type_name.size() && type_name[cur] == '<')
  217. {
  218. data_type = srpc::TDT_LIST;
  219. output_descriptor(i, f, type_name, ++cur, info);
  220. val_arg = "subtype_" + std::to_string(i);
  221. cpptype = SGenUtil::strip(type_name.substr(st, ++cur - st));
  222. }
  223. else
  224. data_type = srpc::TDT_STRUCT;
  225. fprintf(f, "\t\tusing subtype_%d = srpc::ThriftDescriptorImpl<%s, %d, %s, %s>;\n",
  226. ++i, cpptype.c_str(), data_type, key_arg.c_str(), val_arg.c_str());
  227. }
  228. class Printer
  229. {
  230. public:
  231. bool open(std::string out_file)
  232. {
  233. this->out_file = fopen(out_file.c_str(), "w");
  234. return this->out_file;
  235. }
  236. void close()
  237. {
  238. fclose(this->out_file);
  239. }
  240. void print_thrift_include(const idl_info& cur_info)
  241. {
  242. fprintf(this->out_file, "%s", this->thrift_include_format.c_str());
  243. for (const auto& sub_info : cur_info.include_list)
  244. fprintf(this->out_file, "#include \"%s.h\"\n", sub_info.file_name.c_str());
  245. //if (cur_info.package_name.length())
  246. for (size_t i = 0; i < cur_info.package_name.size(); i++)
  247. {
  248. fprintf(this->out_file, this->namespace_package_start_format.c_str(),
  249. cur_info.package_name[i].c_str());
  250. }
  251. }
  252. void print_thrift_struct_declaration(const idl_info& cur_info)
  253. {
  254. fprintf(this->out_file,"\n");
  255. for (const auto& desc : cur_info.desc_list)
  256. {
  257. if (desc.block_type == "struct")
  258. fprintf(this->out_file,"class %s;\n",desc.block_name.c_str());
  259. }
  260. fprintf(this->out_file,"\n");
  261. }
  262. void print_thrift_typedef(const idl_info& cur_info)
  263. {
  264. fprintf(this->out_file,"\n");
  265. for (const auto& t : cur_info.typedef_list)
  266. {
  267. fprintf(this->out_file,"typedef %s %s;\n",t.old_type_name.c_str(),t.new_type_name.c_str());
  268. }
  269. fprintf(this->out_file,"\n");
  270. }
  271. void print_thrift_include_enum(const std::string& name, const std::vector<std::string>& enum_lines)
  272. {
  273. fprintf(this->out_file, "\nenum %s {\n", name.c_str());
  274. for (const auto& line : enum_lines)
  275. fprintf(this->out_file, "\t%s,\n", line.c_str());
  276. fprintf(this->out_file, "};\n");
  277. }
  278. void print_rpc_thrift_struct_class(const std::string& class_name, const std::vector<rpc_param>& class_params,const idl_info& info)
  279. {
  280. fprintf(this->out_file, thrift_struct_class_begin_format.c_str(), class_name.c_str());
  281. for (const auto& ele : class_params)
  282. {
  283. if (ele.default_value.empty())
  284. fprintf(this->out_file, "\t%s %s;\n", ele.type_name.c_str(), ele.var_name.c_str());
  285. else
  286. fprintf(this->out_file, "\t%s %s = %s;\n",
  287. ele.type_name.c_str(), ele.var_name.c_str(), ele.default_value.c_str());
  288. }
  289. fprintf(this->out_file, "%s", thrift_struct_class_isset_begin_format.c_str());
  290. for (const auto& ele : class_params)
  291. {
  292. if (ele.required_state != srpc::THRIFT_STRUCT_FIELD_REQUIRED)
  293. {
  294. if (!ele.default_value.empty())
  295. fprintf(this->out_file, "\t\tbool %s = true;\n", ele.var_name.c_str());
  296. else
  297. fprintf(this->out_file, "\t\tbool %s = false;\n", ele.var_name.c_str());
  298. }
  299. }
  300. fprintf(this->out_file, thrift_struct_class_isset_end_format.c_str(), class_name.c_str());
  301. for (const auto& ele : class_params)
  302. {
  303. std::string type = ele.type_name;
  304. if (!is_simple_type(ele.data_type))
  305. type += '&';
  306. if (ele.required_state == srpc::THRIFT_STRUCT_FIELD_REQUIRED)
  307. fprintf(this->out_file, thrift_struct_class_set_required_format.c_str(),
  308. ele.var_name.c_str(), type.c_str(), ele.var_name.c_str());
  309. else
  310. fprintf(this->out_file, thrift_struct_class_set_optional_format.c_str(),
  311. ele.var_name.c_str(), type.c_str(), ele.var_name.c_str(), ele.var_name.c_str());
  312. }
  313. fprintf(this->out_file, thrift_struct_class_operator_equal_begin_format.c_str(), class_name.c_str());
  314. for (const auto& ele : class_params)
  315. {
  316. if (ele.required_state == srpc::THRIFT_STRUCT_FIELD_REQUIRED)
  317. fprintf(this->out_file, thrift_struct_class_operator_equal_required_format.c_str(),
  318. ele.var_name.c_str(), ele.var_name.c_str());
  319. else
  320. fprintf(this->out_file, thrift_struct_class_operator_equal_optional_format.c_str(),
  321. ele.var_name.c_str(), ele.var_name.c_str(), ele.var_name.c_str(),
  322. ele.var_name.c_str(), ele.var_name.c_str());
  323. }
  324. fprintf(this->out_file, "%s", thrift_struct_class_operator_equal_end_format.c_str());
  325. fprintf(this->out_file, thrift_struct_class_elements_start_format.c_str(),
  326. class_name.c_str(), class_name.c_str(),
  327. class_name.c_str(), class_name.c_str(),
  328. class_name.c_str(), class_name.c_str(),
  329. class_name.c_str(), class_name.c_str(),
  330. class_name.c_str(), class_name.c_str(), class_name.c_str());
  331. for (const auto& ele : class_params)
  332. {
  333. if (is_simple_type(ele.data_type))
  334. {
  335. if (ele.default_value.empty())
  336. fprintf(this->out_file, "\t\tthis->%s = 0;\n", ele.var_name.c_str());
  337. }
  338. }
  339. fprintf(this->out_file, thrift_struct_class_constructor_end_format.c_str(),
  340. class_name.c_str(), class_name.c_str());
  341. fprintf(this->out_file, thrift_struct_element_impl_begin_format.c_str(),
  342. class_name.c_str(), class_name.c_str());
  343. int i = 0;
  344. for (const auto& ele : class_params)
  345. {
  346. size_t cur = 0;
  347. output_descriptor(i, this->out_file, ele.type_name, cur, info);
  348. std::string p_isset = "0";
  349. if (ele.required_state != srpc::THRIFT_STRUCT_FIELD_REQUIRED)
  350. p_isset = "(const char *)(&st->__isset." + ele.var_name + ") - base";
  351. fprintf(this->out_file, "\t\telements->push_back({subtype_%d::get_instance(), \"%s\", %s, (const char *)(&st->%s) - base, %d, %d});\n",
  352. i, ele.var_name.c_str(), p_isset.c_str(), ele.var_name.c_str(), ele.field_id, ele.required_state);
  353. }
  354. fprintf(this->out_file, thrift_struct_class_end_format.c_str(), class_name.c_str());
  355. }
  356. void print_srpc_include(const std::string& prefix, const std::vector<std::string>& package)
  357. {
  358. fprintf(this->out_file, this->srpc_include_format.c_str(), prefix.c_str(),
  359. this->is_thrift ? "thrift" : "pb");
  360. for (size_t i = 0; i < package.size(); i++)
  361. fprintf(this->out_file, this->namespace_package_start_format.c_str(),
  362. package[i].c_str());
  363. }
  364. void print_server_file_include(const std::string& prefix)
  365. {
  366. fprintf(this->out_file, this->srpc_file_include_format.c_str(), prefix.c_str());
  367. fprintf(this->out_file, "%s", this->using_namespace_sogou_format.c_str());
  368. fprintf(this->out_file, "%s", this->wait_group_declaration_format.c_str());
  369. }
  370. void print_client_file_include(const std::string& prefix)
  371. {
  372. fprintf(this->out_file, this->srpc_file_include_format.c_str(), prefix.c_str());
  373. fprintf(this->out_file, "%s", this->using_namespace_sogou_format.c_str());
  374. fprintf(this->out_file, "%s", this->wait_group_declaration_format.c_str());
  375. }
  376. void print_server_comment()
  377. {
  378. fprintf(this->out_file, "%s", this->server_comment_format.c_str());
  379. }
  380. void print_client_comment()
  381. {
  382. fprintf(this->out_file, "%s", this->client_comment_format.c_str());
  383. }
  384. void print_client_define_done(const std::string& method,
  385. const std::string& response)
  386. {
  387. std::string resp = change_include_prefix(response);
  388. fprintf(this->out_file, client_define_done_format.c_str(),
  389. method.c_str(), resp.c_str());
  390. }
  391. /*
  392. void print_client_define_task(const std::string& package, const std::string& method,
  393. const std::string& request, const std::string& response)
  394. {
  395. std::string req = make_package_prefix(package, request);
  396. std::string resp = make_package_prefix(package, response);
  397. fprintf(this->out_file, client_define_task_format.c_str(),
  398. method.c_str(), req.c_str(), resp.c_str());
  399. }
  400. void print_server_method(const std::string& package, const std::string& method,
  401. const std::string& request, const std::string& response,
  402. const std::string& service)
  403. {
  404. std::string req = make_package_prefix(package, request);
  405. std::string resp = make_package_prefix(package, response);
  406. fprintf(this->out_file, this->server_method_format.c_str(),
  407. method.c_str(), req.c_str(), resp.c_str(),
  408. service.c_str(), method.c_str(),
  409. req.c_str(), resp.c_str(),
  410. method.c_str());
  411. }
  412. */
  413. void print_server_class_impl(const std::vector<std::string>& package,
  414. const std::string& service)
  415. {
  416. std::string base_service = make_package_prefix(package, service);
  417. fprintf(this->out_file, this->print_server_class_impl_format.c_str(),
  418. service.c_str(), base_service.c_str());
  419. }
  420. void print_server_impl_method(const std::vector<std::string>& package,
  421. const std::string& service, const std::string& method,
  422. const std::string& request, const std::string& response)
  423. {
  424. std::string req;
  425. std::string resp;
  426. if (this->is_thrift)
  427. {
  428. req = make_thrift_package_prefix(package, service, request);
  429. resp = make_thrift_package_prefix(package, service, response);
  430. }
  431. else
  432. {
  433. req = make_package_prefix(package, request);
  434. resp = make_package_prefix(package, response);
  435. }
  436. fprintf(this->out_file, this->server_impl_method_format.c_str(),
  437. method.c_str(), req.c_str(), resp.c_str());
  438. }
  439. void print_server_class_impl_end()
  440. {
  441. fprintf(this->out_file, "};");
  442. }
  443. void print_server_main_begin()
  444. {
  445. fprintf(this->out_file, "%s", this->server_main_begin_format.c_str());
  446. if (!this->is_thrift)
  447. fprintf(this->out_file, "%s", this->main_pb_version_format.c_str());
  448. }
  449. void print_server_main_address()
  450. {
  451. if (this->is_thrift)
  452. fprintf(this->out_file, this->server_main_ip_port_format.c_str(), "Thrift");
  453. else
  454. fprintf(this->out_file, this->server_main_ip_port_format.c_str(), "SRPC");
  455. }
  456. void print_server_main_method(const std::string& service)
  457. {
  458. std::string service_lower = service;
  459. std::transform(service_lower.begin(), service_lower.end(),
  460. service_lower.begin(), ::tolower);
  461. fprintf(this->out_file, this->server_main_method_format.c_str(),
  462. service.c_str(), service_lower.c_str(), service_lower.c_str());
  463. }
  464. void print_server_main_end()
  465. {
  466. fprintf(this->out_file, "%s", this->server_main_end_format.c_str());
  467. }
  468. void print_server_main_return()
  469. {
  470. if (!this->is_thrift)
  471. fprintf(this->out_file, "%s", this->main_pb_shutdown_format.c_str());
  472. fprintf(this->out_file, "%s", this->main_end_return_format.c_str());
  473. }
  474. void print_server_class_thrift(const std::string& service, const std::vector<rpc_descriptor>& rpcs)
  475. {
  476. std::string return_type;
  477. std::string handler_params;
  478. std::string send_params;
  479. fprintf(this->out_file, "%s", this->server_class_constructor_format.c_str());
  480. for (const auto& rpc : rpcs)
  481. {
  482. fill_thrift_sync_params(rpc, return_type, handler_params, send_params);
  483. fprintf(this->out_file, this->server_class_method_declaration_thrift_handler_format.c_str(),
  484. return_type.c_str(), rpc.method_name.c_str(), handler_params.c_str());
  485. }
  486. fprintf(this->out_file, "\npublic:\n");
  487. for (const auto& rpc : rpcs)
  488. {
  489. fill_thrift_async_params(rpc, return_type, handler_params);
  490. fprintf(this->out_file, this->server_class_method_declaration_thrift_format.c_str(),
  491. rpc.method_name.c_str(), rpc.request_name.c_str(), rpc.response_name.c_str());
  492. }
  493. fprintf(this->out_file, "%s", this->server_class_end_format.c_str());
  494. }
  495. void print_server_methods_thrift(const std::string& service, const std::vector<rpc_descriptor>& rpcs)
  496. {
  497. std::string return_type;
  498. std::string handler_params;
  499. std::string send_params;
  500. for (const auto& rpc : rpcs)
  501. {
  502. fill_thrift_sync_params(rpc, return_type, handler_params, send_params);
  503. fprintf(this->out_file, this->server_class_method_implementation_thrift_handler_format.c_str(),
  504. return_type.c_str(), rpc.method_name.c_str(), handler_params.c_str(),
  505. return_type == "void" ? " " : " return 0; ");
  506. }
  507. for (const auto& rpc : rpcs)
  508. {
  509. fill_thrift_async_params(rpc, return_type, handler_params);
  510. fprintf(this->out_file, this->server_class_method_implementation_thrift_format.c_str(),
  511. rpc.method_name.c_str(), rpc.request_name.c_str(), rpc.response_name.c_str(),
  512. return_type.c_str(), rpc.method_name.c_str(), handler_params.c_str());
  513. }
  514. }
  515. void print_server_class(const std::string& service,
  516. const std::vector<rpc_descriptor>& rpcs)
  517. {
  518. fprintf(this->out_file, "%s", this->server_class_constructor_format.c_str());
  519. for (const auto& rpc : rpcs)
  520. {
  521. std::string req = change_include_prefix(rpc.request_name);
  522. std::string resp = change_include_prefix(rpc.response_name);
  523. fprintf(this->out_file, this->server_class_method_format.c_str(),
  524. rpc.method_name.c_str(), req.c_str(),
  525. resp.c_str());
  526. }
  527. fprintf(this->out_file, "%s", this->server_class_end_format.c_str());
  528. }
  529. void print_server_methods(const std::string& service, const std::vector<rpc_descriptor>& rpcs)
  530. {
  531. for (const auto& rpc : rpcs)
  532. {
  533. fprintf(this->out_file, this->server_methods_format.c_str(),
  534. service.c_str(), service.c_str(),
  535. rpc.method_name.c_str(), rpc.method_name.c_str(),
  536. rpc.method_name.c_str());
  537. }
  538. }
  539. void print_client_class(const std::string& type,
  540. const std::string& service,
  541. const std::vector<rpc_descriptor>& rpcs)
  542. {
  543. fprintf(this->out_file, this->client_class_constructor_start_format.c_str(),
  544. type.c_str(), type.c_str());
  545. if (this->is_thrift)
  546. {
  547. std::string return_type;
  548. std::string handler_params;
  549. std::string send_params;
  550. std::string recv_params;
  551. for (const auto& rpc : rpcs)
  552. {
  553. fill_thrift_sync_params(rpc, return_type, handler_params, send_params);
  554. if (return_type != "void")
  555. recv_params.clear();
  556. else if (!rpc.resp_params.empty() && rpc.resp_params[0].field_id == 0)
  557. recv_params = rpc.resp_params[0].type_name + "& _return";
  558. else
  559. recv_params.clear();
  560. fprintf(this->out_file,
  561. this->client_class_construct_methods_thrift_format.c_str(),
  562. return_type.c_str(), rpc.method_name.c_str(), handler_params.c_str(),
  563. rpc.method_name.c_str(), send_params.c_str(),
  564. return_type.c_str(), rpc.method_name.c_str(), recv_params.c_str());
  565. }
  566. fprintf(this->out_file, "%s", this->client_class_get_last_thrift_format.c_str());
  567. fprintf(this->out_file, "public:\n");
  568. }
  569. for (const auto& rpc : rpcs)
  570. {
  571. std::string req = change_include_prefix(rpc.request_name);
  572. std::string resp = change_include_prefix(rpc.response_name);
  573. fprintf(this->out_file,
  574. this->client_class_construct_methods_format.c_str(),
  575. rpc.method_name.c_str(), req.c_str(), rpc.method_name.c_str(),
  576. rpc.method_name.c_str(), req.c_str(), resp.c_str(),
  577. resp.c_str(), rpc.method_name.c_str(), req.c_str());
  578. }
  579. fprintf(this->out_file, this->client_class_constructor_format.c_str(),
  580. type.c_str(), type.c_str());
  581. for (const auto& rpc : rpcs)
  582. {
  583. fprintf(this->out_file,
  584. this->client_class_create_methods_format.c_str(),
  585. type.c_str(), rpc.method_name.c_str(), rpc.method_name.c_str());
  586. //type.c_str(), rpc.method_name.c_str(), rpc.request_name.c_str(), rpc.method_name.c_str());
  587. }
  588. if (this->is_thrift)
  589. {
  590. fprintf(this->out_file, "%s", client_class_private_get_thrift_format.c_str());
  591. for (const auto& rpc : rpcs)
  592. {
  593. std::string resp = change_include_prefix(rpc.response_name);
  594. fprintf(this->out_file,
  595. this->client_class_get_rpc_thread_resp_thrift_format.c_str(),
  596. resp.c_str(), rpc.method_name.c_str());
  597. }
  598. }
  599. fprintf(this->out_file, this->client_class_constructor_end_format.c_str(),
  600. service.c_str());
  601. }
  602. void print_implement_comments()
  603. {
  604. fprintf(this->out_file, "\n///// implements detials /////\n");
  605. }
  606. void print_server_constructor(const std::string& service, const std::vector<rpc_descriptor>& rpcs)
  607. {
  608. fprintf(this->out_file, this->server_constructor_method_format.c_str(),
  609. service.c_str());
  610. for (const auto& rpc : rpcs)
  611. {
  612. fprintf(this->out_file, this->server_constructor_add_method_format.c_str(),
  613. rpc.method_name.c_str(), rpc.method_name.c_str());
  614. }
  615. fprintf(this->out_file, "}\n");
  616. }
  617. void print_client_constructor(const std::string& type, const std::string& service,
  618. const std::vector<std::string>& package)
  619. {
  620. bool is_srpc_thrift = (this->is_thrift && (type == "SRPC" || type == "SRPCHttp"));
  621. const char *method_ip = is_srpc_thrift ? client_constructor_methods_ip_srpc_thrift_format.c_str() : "";
  622. const char *method_params = is_srpc_thrift ? client_constructor_methods_params_srpc_thrift_format.c_str() : "";
  623. std::string full_service = service;
  624. if (type == "TRPC")
  625. full_service = make_trpc_service_prefix(package, service);
  626. else if (type == "SRPC" || type == "BRPC" || type == "TRPCHttp")
  627. full_service = make_srpc_service_prefix(package, service, '.');
  628. else if (type == "SRPCHttp")
  629. full_service = make_srpc_service_prefix(package, service, '/');
  630. fprintf(this->out_file, this->client_constructor_methods_format.c_str(),
  631. type.c_str(), type.c_str(),
  632. type.c_str(), full_service.c_str(),
  633. method_ip, type.c_str(),
  634. type.c_str(), type.c_str(),
  635. type.c_str(), full_service.c_str(),
  636. method_params, type.c_str());
  637. }
  638. void print_client_methods(const std::string& type,
  639. const std::string& service,
  640. const std::vector<rpc_descriptor>& rpcs,
  641. const std::vector<std::string>& package)
  642. {
  643. for (const auto& rpc : rpcs)
  644. {
  645. std::string req = change_include_prefix(rpc.request_name);
  646. std::string resp = change_include_prefix(rpc.response_name);
  647. if (type == "TRPC")
  648. {
  649. std::string full_method = make_trpc_method_prefix(package,
  650. service,
  651. rpc.method_name);
  652. fprintf(this->out_file, this->client_method_trpc_format.c_str(),
  653. type.c_str(), rpc.method_name.c_str(),
  654. req.c_str(), rpc.method_name.c_str(),
  655. full_method.c_str(),
  656. type.c_str(), rpc.method_name.c_str(),
  657. req.c_str(), resp.c_str(), rpc.method_name.c_str(),
  658. resp.c_str(), type.c_str(),
  659. rpc.method_name.c_str(), req.c_str(),
  660. resp.c_str(), resp.c_str(), full_method.c_str(),
  661. resp.c_str());
  662. }
  663. else if (type == "TRPCHttp")
  664. {
  665. fprintf(this->out_file, this->client_method_trpc_format.c_str(),
  666. type.c_str(), rpc.method_name.c_str(),
  667. req.c_str(), rpc.method_name.c_str(),
  668. rpc.method_name.c_str(),
  669. type.c_str(), rpc.method_name.c_str(),
  670. req.c_str(), resp.c_str(), rpc.method_name.c_str(),
  671. resp.c_str(), type.c_str(),
  672. rpc.method_name.c_str(), req.c_str(),
  673. resp.c_str(), resp.c_str(), rpc.method_name.c_str(),
  674. resp.c_str());
  675. }
  676. else
  677. {
  678. fprintf(this->out_file, this->client_method_format.c_str(),
  679. type.c_str(), rpc.method_name.c_str(),
  680. req.c_str(), rpc.method_name.c_str(),
  681. rpc.method_name.c_str(),
  682. type.c_str(), rpc.method_name.c_str(),
  683. req.c_str(), resp.c_str(), rpc.method_name.c_str(),
  684. resp.c_str(), type.c_str(),
  685. rpc.method_name.c_str(), req.c_str(),
  686. resp.c_str(), resp.c_str(), rpc.method_name.c_str(),
  687. resp.c_str());
  688. }
  689. }
  690. if (this->is_thrift)
  691. {
  692. std::string return_type;
  693. std::string handler_params;
  694. std::string send_params;
  695. std::string recv_params;
  696. for (const auto& rpc : rpcs)
  697. {
  698. std::string req = change_include_prefix(rpc.request_name);
  699. std::string resp = change_include_prefix(rpc.response_name);
  700. std::string last_return;
  701. fill_thrift_sync_params(rpc, return_type, handler_params, send_params);
  702. if (return_type != "void")
  703. last_return = "return __thrift__sync__resp.result";
  704. else if (!rpc.resp_params.empty() && rpc.resp_params[0].field_id == 0)
  705. last_return = "_return = std::move(__thrift__sync__resp.result)";
  706. else
  707. last_return = "(void)__thrift__sync__resp";
  708. fprintf(this->out_file,
  709. this->client_method_thrift_begin_format.c_str(),
  710. resp.c_str(), type.c_str(), rpc.method_name.c_str(), resp.c_str(),
  711. return_type.c_str(), type.c_str(), rpc.method_name.c_str(), handler_params.c_str(),
  712. req.c_str(), resp.c_str());
  713. for (const auto &param : rpc.req_params)
  714. fprintf(this->out_file, "\t__thrift__sync__req.%s = %s;\n", param.var_name.c_str(), param.var_name.c_str());
  715. fprintf(this->out_file,
  716. this->client_method_thrift_end_format.c_str(),
  717. rpc.method_name.c_str(), type.c_str(), last_return.c_str(),
  718. type.c_str(), rpc.method_name.c_str(), send_params.c_str(), req.c_str());
  719. for (const auto &param : rpc.req_params)
  720. fprintf(this->out_file, "\t__thrift__sync__req.%s = %s;\n", param.var_name.c_str(), param.var_name.c_str());
  721. if (return_type != "void")
  722. {
  723. last_return = "return std::move(res.result);";
  724. recv_params.clear();
  725. }
  726. else if (!rpc.resp_params.empty() && rpc.resp_params[0].field_id == 0)
  727. {
  728. last_return = "_return = std::move(res.result)";
  729. recv_params = rpc.resp_params[0].type_name + "& _return";
  730. }
  731. else
  732. {
  733. last_return = "(void)res";
  734. recv_params.clear();
  735. }
  736. fprintf(this->out_file,
  737. this->cilent_method_thrift_send_end_format.c_str(),
  738. resp.c_str(), rpc.method_name.c_str(), resp.c_str(), rpc.method_name.c_str(),
  739. return_type.c_str(), type.c_str(), rpc.method_name.c_str(), recv_params.c_str(),
  740. rpc.method_name.c_str(), last_return.c_str());
  741. }
  742. fprintf(this->out_file, this->client_method_get_last_thrift_format.c_str(),
  743. type.c_str(), type.c_str(), type.c_str());
  744. }
  745. }
  746. void print_client_create_task(const std::string& type, const std::string& service,
  747. const std::vector<rpc_descriptor>& rpcs,
  748. const std::vector<std::string>& package)
  749. {
  750. for (const auto& rpc : rpcs)
  751. {
  752. if (type == "TRPC")
  753. {
  754. std::string full_method = make_trpc_method_prefix(package,
  755. service,
  756. rpc.method_name);
  757. fprintf(this->out_file, this->client_create_task_trpc_format.c_str(),
  758. type.c_str(), type.c_str(), rpc.method_name.c_str(),
  759. rpc.method_name.c_str(), full_method.c_str());
  760. }
  761. else if (type == "TRPCHttp")
  762. {
  763. fprintf(this->out_file, this->client_create_task_trpc_format.c_str(),
  764. type.c_str(), type.c_str(), rpc.method_name.c_str(),
  765. rpc.method_name.c_str(), rpc.method_name.c_str());
  766. }
  767. else
  768. {
  769. fprintf(this->out_file, this->client_create_task_format.c_str(),
  770. type.c_str(), type.c_str(), rpc.method_name.c_str(),
  771. rpc.method_name.c_str(), rpc.method_name.c_str());
  772. }
  773. }
  774. }
  775. void print_service_namespace(const std::string& service)
  776. {
  777. fprintf(this->out_file, this->namespace_service_start_format.c_str(),
  778. service.c_str());
  779. }
  780. void print_service_namespace_end(const std::string& service)
  781. {
  782. fprintf(this->out_file, this->namespace_service_end_format.c_str(),
  783. service.c_str());
  784. }
  785. void print_create_client_controller(const std::string& service,
  786. const std::vector<rpc_descriptor>& rpcs)
  787. {
  788. for (const auto& rpc : rpcs)
  789. {
  790. this->print_create_method_controller(service, rpc.method_name);
  791. }
  792. }
  793. void print_create_method_controller(const std::string& service, const std::string& method)
  794. {
  795. std::string method_lower = method;
  796. std::transform(method_lower.begin(), method_lower.end(),
  797. method_lower.begin(), ::tolower);
  798. fprintf(this->out_file, this->namespace_method_task_format.c_str(),
  799. //create_method_cntl(stub)
  800. method.c_str(), method_lower.c_str(),
  801. service.c_str(), method.c_str(),
  802. method.c_str(), method.c_str());
  803. }
  804. void print_client_done_method(const std::vector<std::string>& package,
  805. const std::string& service,
  806. const std::string& method,
  807. const std::string& response)
  808. {
  809. std::string method_lower = method;
  810. std::transform(method_lower.begin(), method_lower.end(),
  811. method_lower.begin(), ::tolower);
  812. std::string resp;
  813. if (this->is_thrift)
  814. resp = make_thrift_package_prefix(package, service, response);
  815. else
  816. resp = make_package_prefix(package, response);
  817. fprintf(this->out_file, this->client_done_format.c_str(),
  818. method_lower.c_str(), resp.c_str(),
  819. service.c_str(), method.c_str());
  820. }
  821. void print_client_main_begin()
  822. {
  823. fprintf(this->out_file, "%s", this->client_main_begin_format.c_str());
  824. if (!this->is_thrift)
  825. fprintf(this->out_file, "%s", this->main_pb_version_format.c_str());
  826. }
  827. void print_client_main_address()
  828. {
  829. fprintf(this->out_file, "%s", this->client_main_ip_port_format.c_str());
  830. }
  831. void print_client_main_service(const std::string& type,
  832. const std::vector<std::string>& package,
  833. const std::string& service,
  834. const std::string& suffix)
  835. {
  836. //std::string service_lower = service;
  837. //std::transform(service_lower.begin(), service_lower.end(),
  838. // service_lower.begin(), ::tolower);
  839. std::string base_service = make_package_prefix(package, service);
  840. fprintf(this->out_file, this->client_main_service_format.c_str(),
  841. base_service.c_str(), type.c_str(), suffix.c_str());
  842. }
  843. void print_client_main_method_call(const std::vector<std::string>& package,
  844. const std::string& service,
  845. const std::string& method,
  846. const std::string& request,
  847. const std::string& suffix)
  848. {
  849. std::string method_lower = method;
  850. std::transform(method_lower.begin(), method_lower.end(),
  851. method_lower.begin(), ::tolower);
  852. std::string req;
  853. if (this->is_thrift)
  854. req = make_thrift_package_prefix(package, service, request);
  855. else
  856. req = make_package_prefix(package, request);
  857. fprintf(this->out_file, this->client_main_method_call_format.c_str(),
  858. req.c_str(), method_lower.c_str(), method_lower.c_str(),
  859. suffix.c_str(), method.c_str(), method_lower.c_str(),
  860. method_lower.c_str());
  861. }
  862. /*
  863. void print_client_main_create_task(const std::string& package, const std::string& service,
  864. const std::string& method, const std::string& request)
  865. {
  866. std::string method_lower = method;
  867. std::transform(method_lower.begin(), method_lower.end(),
  868. method_lower.begin(), ::tolower);
  869. std::string req = make_package_prefix(package, request);
  870. fprintf(this->out_file, this->client_main_create_task_format.c_str(),
  871. req.c_str(), method_lower.c_str(), service.c_str(),
  872. method.c_str(), method_lower.c_str(), method.c_str(),
  873. method_lower.c_str(), method_lower.c_str(),
  874. method_lower.c_str(), method_lower.c_str());
  875. }
  876. */
  877. void print_client_main_end()
  878. {
  879. fprintf(this->out_file, "%s", this->client_main_end_format.c_str());
  880. if (!this->is_thrift)
  881. fprintf(this->out_file, "%s", this->main_pb_shutdown_format.c_str());
  882. fprintf(this->out_file, "%s", this->main_end_return_format.c_str());
  883. }
  884. void print_end(const std::vector<std::string>& package)
  885. {
  886. for (size_t i = package.size() - 1; i != (size_t)-1; i--)
  887. fprintf(this->out_file, namespace_package_end_format.c_str(),
  888. package[i].c_str());
  889. // fprintf(this->out_file, "} // namespace srpc\n");
  890. }
  891. void print_empty_line()
  892. {
  893. fprintf(this->out_file, "\n");
  894. }
  895. Printer(bool is_thrift) { this->is_thrift = is_thrift; }
  896. protected:
  897. FILE *out_file;
  898. bool is_thrift;
  899. private:
  900. std::string thrift_include_format = R"(#pragma once
  901. #include "srpc/rpc_thrift_idl.h"
  902. )";
  903. std::string srpc_include_format = R"(#pragma once
  904. #include <stdio.h>
  905. #include <string>
  906. #include "srpc/rpc_define.h"
  907. #include "%s.%s.h"
  908. )";
  909. std::string thrift_include_package_format = R"(
  910. namespace %s
  911. {
  912. )";
  913. std::string srpc_include_package_format = R"(
  914. using namespace %s;
  915. )";
  916. std::string srpc_file_include_format = R"(#include "%s.srpc.h"
  917. #include "workflow/WFFacilities.h"
  918. )";
  919. std::string using_namespace_sogou_format = R"(
  920. using namespace srpc;
  921. )";
  922. std::string wait_group_declaration_format = R"(
  923. static WFFacilities::WaitGroup wait_group(1);
  924. void sig_handler(int signo)
  925. {
  926. wait_group.done();
  927. }
  928. )";
  929. /*
  930. std::string namespace_total_start_format = R"(
  931. namespace srpc
  932. {
  933. )";
  934. */
  935. std::string namespace_package_start_format = R"(
  936. namespace %s
  937. {
  938. )";
  939. std::string namespace_package_end_format = R"(} // end namespace %s
  940. )";
  941. std::string server_comment_format = R"(
  942. /*
  943. * Server codes
  944. * Generated by SRPC
  945. */
  946. )";
  947. std::string client_comment_format = R"(
  948. /*
  949. * Client codes
  950. * Generated by SRPC
  951. */
  952. )";
  953. std::string client_define_done_format = R"(
  954. using %sDone = std::function<void (%s *, srpc::RPCContext *)>;)";
  955. std::string client_define_task_format = R"(using %sTask = srpc::RPCClientTask<%s, %s>;
  956. )";
  957. std::string server_context_format = R"(
  958. using %sContext = srpc::RPCContext<%s, %s>;
  959. )";
  960. std::string server_controller_format = R"(
  961. class Server%sCntl : public srpc::%sCntl
  962. {
  963. public:
  964. // must implement this in server codes
  965. void %s(%s *request, %s *response);
  966. Server%sCntl(srpc::RPCTask *task)
  967. : %sCntl(task)
  968. {}
  969. };
  970. )";
  971. std::string client_controller_format = R"(
  972. class Client%sCntl;
  973. typedef std::function<void (Client%sCntl *, %s *)> %sDone;
  974. class Client%sCntl : public srpc::%sCntl
  975. {
  976. public:
  977. Client%sCntl(srpc::RPCTask *task)
  978. : %sCntl(task)
  979. {}
  980. void %s(%sDone done, SeriesWork *series)
  981. {
  982. this->done = std::move(done);
  983. if (series != NULL)
  984. {
  985. this->set_series(series);
  986. series->push_back(this->get_task());
  987. }
  988. this->service->call_method("%s", this);
  989. }
  990. %sDone done;
  991. };
  992. )";
  993. std::string server_method_format = R"(
  994. void %s(srpc::RPCTask *task, %s *request, %s *response);
  995. static inline void %s%s(srpc::RPCTask *task, \
  996. rpc_buf_t *req_buf, rpc_buf_t *resp_buf)
  997. {
  998. %s pb_req;
  999. %s pb_resp;
  1000. pb_req.ParseFromArray(req_buf->buf, req_buf->len);
  1001. %s(task, &pb_req, &pb_resp);
  1002. resp_buf->buf = malloc(pb_resp.ByteSizeLong());
  1003. resp_buf->len = pb_resp.ByteSizeLong();
  1004. pb_resp.SerializeToArray(resp_buf->buf, resp_buf->len);
  1005. }
  1006. )";
  1007. std::string server_class_constructor_format = R"(
  1008. class Service : public srpc::RPCService
  1009. {
  1010. public:
  1011. // please implement these methods in server.cc
  1012. )";
  1013. std::string server_class_end_format = R"(
  1014. public:
  1015. Service();
  1016. };
  1017. )";
  1018. std::string server_class_method_format = R"(
  1019. virtual void %s(%s *request, %s *response,
  1020. srpc::RPCContext *ctx) = 0;
  1021. )";
  1022. std::string server_class_method_declaration_thrift_format = R"(
  1023. virtual void %s(%s *request, %s *response,
  1024. srpc::RPCContext *ctx);
  1025. )";
  1026. std::string server_class_method_implementation_thrift_format = R"(
  1027. inline void Service::%s(%s *request, %s *response, srpc::RPCContext *ctx)
  1028. {
  1029. %sthis->%s(%s);
  1030. }
  1031. )";
  1032. std::string server_class_method_declaration_thrift_handler_format = R"(
  1033. virtual %s %s(%s);
  1034. )";
  1035. std::string server_class_method_implementation_thrift_handler_format = R"(
  1036. inline %s Service::%s(%s) {%s}
  1037. )";
  1038. std::string server_class_construct_method_format = R"(
  1039. void %s%s(srpc::RPCTask *task);
  1040. )";
  1041. std::string server_constructor_method_format = R"(
  1042. inline Service::Service(): srpc::RPCService("%s")
  1043. {)";
  1044. std::string server_constructor_add_method_format = R"(
  1045. this->srpc::RPCService::add_method("%s",
  1046. [this](srpc::RPCWorker& worker) ->int {
  1047. return ServiceRPCCallImpl(this, worker, &Service::%s);
  1048. });
  1049. )";
  1050. std::string server_methods_format = R"(
  1051. void %s::%s%s(srpc::RPCTask *task)
  1052. {
  1053. Server%sCntl cntl(task);
  1054. srpc::RPCService::parse_from_buffer(task, cntl.get_input(), true);
  1055. cntl.%s(cntl.get_req(), cntl.get_resp());
  1056. srpc::RPCService::serialize_to_buffer(task, cntl.get_output(), false);
  1057. }
  1058. )";
  1059. std::string client_class_constructor_start_format = R"(
  1060. class %sClient : public srpc::%sClient
  1061. {
  1062. public:)";
  1063. std::string client_constructor_methods_format = R"(
  1064. inline %sClient::%sClient(const char *host, unsigned short port):
  1065. srpc::%sClient("%s")
  1066. {
  1067. struct srpc::RPCClientParams params = srpc::RPC_CLIENT_PARAMS_DEFAULT;
  1068. %s
  1069. params.host = host;
  1070. params.port = port;
  1071. this->srpc::%sClient::init(&params);
  1072. }
  1073. inline %sClient::%sClient(const struct srpc::RPCClientParams *params):
  1074. srpc::%sClient("%s")
  1075. {
  1076. const struct srpc::RPCClientParams *temp = params;
  1077. struct srpc::RPCClientParams temp_params;
  1078. %s
  1079. this->srpc::%sClient::init(temp);
  1080. }
  1081. )";
  1082. std::string client_constructor_methods_ip_srpc_thrift_format = R"(
  1083. params.task_params.data_type = srpc::RPCDataThrift;
  1084. )";
  1085. std::string client_constructor_methods_params_srpc_thrift_format = R"(
  1086. if (params->task_params.data_type == srpc::RPCDataUndefined)
  1087. {
  1088. temp_params = *temp;
  1089. temp_params.task_params.data_type = srpc::RPCDataThrift;
  1090. temp = &temp_params;
  1091. }
  1092. )";
  1093. std::string client_class_constructor_ip_port_format = R"(
  1094. %sClient(const char *host, unsigned short port) :
  1095. srpc::RPCService("%s")
  1096. {
  1097. this->params.service_params.host = host;
  1098. this->params.service_params.port = port;
  1099. this->register_compress_type(srpc::RPCCompressGzip);
  1100. )";
  1101. std::string client_class_functions = R"(
  1102. const struct srpc::RPCClientParams *get_params()
  1103. {
  1104. return &this->params;
  1105. }
  1106. )";
  1107. std::string client_class_variables = R"(
  1108. struct srpc::RPCClientParams params;
  1109. )";
  1110. std::string tab_right_braket = R"(
  1111. }
  1112. )";
  1113. std::string client_class_done_format = R"(
  1114. %sDone %s_done;
  1115. )";
  1116. std::string client_class_construct_methods_thrift_format = R"(
  1117. %s %s(%s);
  1118. void send_%s(%s);
  1119. %s recv_%s(%s);
  1120. )";
  1121. std::string client_class_get_last_thrift_format = R"(
  1122. bool thrift_last_sync_success() const;
  1123. const srpc::RPCSyncContext& thrift_last_sync_ctx() const;
  1124. )";
  1125. std::string client_class_private_get_thrift_format = R"(
  1126. private:
  1127. static srpc::RPCSyncContext *get_thread_sync_ctx();
  1128. )";
  1129. std::string client_class_get_rpc_thread_resp_thrift_format = R"(
  1130. static srpc::ThriftReceiver<%s> *get_thread_sync_receiver_%s();
  1131. )";
  1132. std::string client_class_construct_methods_format = R"(
  1133. void %s(const %s *req, %sDone done);
  1134. void %s(const %s *req, %s *resp, srpc::RPCSyncContext *sync_ctx);
  1135. WFFuture<std::pair<%s, srpc::RPCSyncContext>> async_%s(const %s *req);
  1136. )";
  1137. std::string client_class_constructor_format = R"(
  1138. public:
  1139. %sClient(const char *host, unsigned short port);
  1140. %sClient(const struct srpc::RPCClientParams *params);
  1141. public:
  1142. )";
  1143. std::string client_class_create_methods_format = R"( srpc::%sClientTask *create_%s_task(%sDone done);
  1144. )";
  1145. //%sClientTask *create_%s_task(%s *req, %sDone done);
  1146. std::string client_class_constructor_end_format = R"(};
  1147. )";
  1148. std::string client_method_format = R"(
  1149. inline void %sClient::%s(const %s *req, %sDone done)
  1150. {
  1151. auto *task = this->create_rpc_client_task("%s", std::move(done));
  1152. task->serialize_input(req);
  1153. task->start();
  1154. }
  1155. inline void %sClient::%s(const %s *req, %s *resp, srpc::RPCSyncContext *sync_ctx)
  1156. {
  1157. auto res = this->async_%s(req).get();
  1158. if (resp && res.second.success)
  1159. *resp = std::move(res.first);
  1160. if (sync_ctx)
  1161. *sync_ctx = std::move(res.second);
  1162. }
  1163. inline WFFuture<std::pair<%s, srpc::RPCSyncContext>> %sClient::async_%s(const %s *req)
  1164. {
  1165. using RESULT = std::pair<%s, srpc::RPCSyncContext>;
  1166. auto *pr = new WFPromise<RESULT>();
  1167. auto fr = pr->get_future();
  1168. auto *task = this->create_rpc_client_task<%s>("%s", srpc::RPCAsyncFutureCallback<%s>);
  1169. task->serialize_input(req);
  1170. task->user_data = pr;
  1171. task->start();
  1172. return fr;
  1173. }
  1174. )";
  1175. std::string client_method_trpc_format = R"(
  1176. inline void %sClient::%s(const %s *req, %sDone done)
  1177. {
  1178. auto *task = this->create_rpc_client_task("%s", std::move(done));
  1179. if (this->params.callee_timeout >= 0)
  1180. task->get_req()->set_callee_timeout(this->params.callee_timeout);
  1181. if (!this->params.caller.empty())
  1182. task->get_req()->set_caller_name(this->params.caller);
  1183. task->serialize_input(req);
  1184. task->start();
  1185. }
  1186. inline void %sClient::%s(const %s *req, %s *resp, srpc::RPCSyncContext *sync_ctx)
  1187. {
  1188. auto res = this->async_%s(req).get();
  1189. if (resp && res.second.success)
  1190. *resp = std::move(res.first);
  1191. if (sync_ctx)
  1192. *sync_ctx = std::move(res.second);
  1193. }
  1194. inline WFFuture<std::pair<%s, srpc::RPCSyncContext>> %sClient::async_%s(const %s *req)
  1195. {
  1196. using RESULT = std::pair<%s, srpc::RPCSyncContext>;
  1197. auto *pr = new WFPromise<RESULT>();
  1198. auto fr = pr->get_future();
  1199. auto *task = this->create_rpc_client_task<%s>("%s", srpc::RPCAsyncFutureCallback<%s>);
  1200. if (this->params.callee_timeout >= 0)
  1201. task->get_req()->set_callee_timeout(this->params.callee_timeout);
  1202. if (!this->params.caller.empty())
  1203. task->get_req()->set_caller_name(this->params.caller);
  1204. task->serialize_input(req);
  1205. task->user_data = pr;
  1206. task->start();
  1207. return fr;
  1208. }
  1209. )";
  1210. std::string client_method_thrift_begin_format = R"(
  1211. inline srpc::ThriftReceiver<%s> *%sClient::get_thread_sync_receiver_%s()
  1212. {
  1213. static thread_local srpc::ThriftReceiver<%s> receiver;
  1214. return &receiver;
  1215. }
  1216. inline %s %sClient::%s(%s)
  1217. {
  1218. %s __thrift__sync__req;
  1219. %s __thrift__sync__resp;
  1220. )";
  1221. std::string client_method_thrift_end_format = R"(
  1222. this->%s(&__thrift__sync__req, &__thrift__sync__resp, %sClient::get_thread_sync_ctx());
  1223. %s;
  1224. }
  1225. inline void %sClient::send_%s(%s)
  1226. {
  1227. %s __thrift__sync__req;
  1228. )";
  1229. std::string cilent_method_thrift_send_end_format = R"(
  1230. auto *task = this->create_rpc_client_task<%s>("%s", srpc::ThriftSendCallback<%s>);
  1231. task->serialize_input(&__thrift__sync__req);
  1232. task->user_data = get_thread_sync_receiver_%s();
  1233. task->start();
  1234. }
  1235. inline %s %sClient::recv_%s(%s)
  1236. {
  1237. int cookie = 0;
  1238. auto *receiver = get_thread_sync_receiver_%s();
  1239. std::unique_lock<std::mutex> lock(receiver->mutex);
  1240. if (!receiver->is_done)
  1241. {
  1242. cookie = WFGlobal::sync_operation_begin();
  1243. while (!receiver->is_done)
  1244. receiver->cond.wait(lock);
  1245. }
  1246. receiver->is_done = false;
  1247. *get_thread_sync_ctx() = std::move(receiver->ctx);
  1248. auto res = std::move(receiver->output);
  1249. lock.unlock();
  1250. WFGlobal::sync_operation_end(cookie);
  1251. %s;
  1252. }
  1253. )";
  1254. std::string client_method_get_last_thrift_format = R"(
  1255. inline srpc::RPCSyncContext *%sClient::get_thread_sync_ctx()
  1256. {
  1257. static thread_local srpc::RPCSyncContext thread_sync_ctx;
  1258. return &thread_sync_ctx;
  1259. }
  1260. inline bool %sClient::thrift_last_sync_success() const
  1261. {
  1262. return get_thread_sync_ctx()->success;
  1263. }
  1264. inline const srpc::RPCSyncContext& %sClient::thrift_last_sync_ctx() const
  1265. {
  1266. return *get_thread_sync_ctx();
  1267. }
  1268. )";
  1269. std::string client_create_task_format = R"(
  1270. inline srpc::%sClientTask *%sClient::create_%s_task(%sDone done)
  1271. {
  1272. return this->create_rpc_client_task("%s", std::move(done));
  1273. }
  1274. )";
  1275. std::string client_create_task_trpc_format = R"(
  1276. inline srpc::%sClientTask *%sClient::create_%s_task(%sDone done)
  1277. {
  1278. auto *task = this->create_rpc_client_task("%s", std::move(done));
  1279. if (!this->params.caller.empty())
  1280. task->get_req()->set_caller_name(this->params.caller);
  1281. return task;
  1282. }
  1283. )";
  1284. /*
  1285. inline %sClientTask *%sClient::create_%s_task(%s *req, %sDone done)
  1286. {
  1287. auto *task = this->create_rpc_client_task("%s", std::move(done));
  1288. task->serialize_input(req);
  1289. return task;
  1290. }*/
  1291. std::string namespace_service_start_format = R"(
  1292. namespace %s
  1293. {
  1294. )";
  1295. std::string namespace_service_end_format = R"(
  1296. } // end namespace %s
  1297. )";
  1298. std::string namespace_method_task_format = R"(
  1299. static Client%sCntl *create_%s_cntl(%sClient *stub)
  1300. {
  1301. rpc_callback_t cb = std::bind(&%sClient::%sCallback,
  1302. stub, std::placeholders::_1);
  1303. auto *task = new ComplexRPCClientTask(stub->get_params(), std::move(cb));
  1304. if (task->get_error())
  1305. {
  1306. errno = task->get_error();
  1307. delete task;
  1308. return NULL;
  1309. }
  1310. Client%sCntl *cntl = new Client%sCntl(task);
  1311. cntl->set_service(stub);
  1312. task->set_controller(cntl);
  1313. return cntl;
  1314. }
  1315. )";
  1316. std::string print_server_class_impl_format = R"(
  1317. class %sServiceImpl : public %s::Service
  1318. {
  1319. public:
  1320. )";
  1321. std::string server_impl_method_format = R"(
  1322. void %s(%s *request, %s *response, srpc::RPCContext *ctx) override
  1323. {
  1324. // TODO: fill server logic here
  1325. }
  1326. )";
  1327. std::string server_main_begin_format = R"(
  1328. int main()
  1329. {)";
  1330. std::string server_main_ip_port_format = R"(
  1331. unsigned short port = 1412;
  1332. %sServer server;
  1333. )";
  1334. std::string server_main_method_format = R"(
  1335. %sServiceImpl %s_impl;
  1336. server.add_service(&%s_impl);
  1337. )";
  1338. std::string server_main_end_format = R"(
  1339. server.start(port);
  1340. wait_group.wait();
  1341. server.stop();)";
  1342. std::string client_done_format = R"(
  1343. static void %s_done(%s *response, srpc::RPCContext *context)
  1344. {
  1345. }
  1346. )";
  1347. std::string main_pb_version_format = R"(
  1348. GOOGLE_PROTOBUF_VERIFY_VERSION;)";
  1349. std::string client_main_begin_format = R"(
  1350. int main()
  1351. {)";
  1352. std::string client_main_ip_port_format = R"(
  1353. const char *ip = "127.0.0.1";
  1354. unsigned short port = 1412;
  1355. )";
  1356. std::string client_main_service_format = R"(
  1357. %s::%sClient client%s(ip, port);
  1358. )";
  1359. std::string client_main_method_call_format = R"(
  1360. // example for RPC method call
  1361. %s %s_req;
  1362. //%s_req.set_message("Hello, srpc!");
  1363. client%s.%s(&%s_req, %s_done);
  1364. )";
  1365. /*
  1366. std::string client_main_create_task_format = R"(
  1367. // example for creating RPC task
  1368. %s %s_req;
  1369. srpc::RPC%s::%sTask *%s_task = client.create_%s_task(%s_done);
  1370. %s_task->serialize_input(&%s_req);
  1371. %s_task->start();
  1372. )";
  1373. */
  1374. std::string client_main_end_format = R"(
  1375. wait_group.wait();)";
  1376. std::string main_pb_shutdown_format = R"(
  1377. google::protobuf::ShutdownProtobufLibrary();)";
  1378. std::string main_end_return_format = R"(
  1379. return 0;
  1380. }
  1381. )";
  1382. std::string thrift_struct_class_begin_format = R"(
  1383. class %s : public srpc::ThriftIDLMessage
  1384. {
  1385. public:
  1386. )";
  1387. std::string thrift_struct_class_constructor_end_format = R"(
  1388. this->elements = srpc::ThriftElementsImpl<%s>::get_elements_instance();
  1389. this->descriptor = srpc::ThriftDescriptorImpl<%s, srpc::TDT_STRUCT, void, void>::get_instance();
  1390. }
  1391. )";
  1392. std::string thrift_struct_class_end_format = R"(
  1393. }
  1394. friend class srpc::ThriftElementsImpl<%s>;
  1395. };
  1396. )";
  1397. std::string thrift_struct_element_impl_begin_format = R"(
  1398. private:
  1399. static void StaticElementsImpl(std::list<srpc::struct_element> *elements)
  1400. {
  1401. const %s *st = (const %s *)0;
  1402. const char *base = (const char *)st;
  1403. (void)base;
  1404. )";
  1405. std::string thrift_struct_class_set_required_format = R"(
  1406. void __set_%s(const %s val)
  1407. {
  1408. this->%s = val;
  1409. }
  1410. )";
  1411. std::string thrift_struct_class_set_optional_format = R"(
  1412. void __set_%s(const %s val)
  1413. {
  1414. this->%s = val;
  1415. this->__isset.%s = true;
  1416. }
  1417. )";
  1418. std::string thrift_struct_class_isset_begin_format = R"(
  1419. public:
  1420. struct ISSET
  1421. {
  1422. )";
  1423. std::string thrift_struct_class_isset_end_format = R"(
  1424. } __isset;
  1425. )";
  1426. std::string thrift_struct_class_operator_equal_begin_format = R"(
  1427. bool operator == (const %s& rhs) const
  1428. {
  1429. )";
  1430. std::string thrift_struct_class_operator_equal_required_format = R"(
  1431. if (!(this->%s == rhs.%s))
  1432. return false;
  1433. )";
  1434. std::string thrift_struct_class_operator_equal_optional_format = R"(
  1435. if (this->__isset.%s != rhs.__isset.%s)
  1436. return false;
  1437. else if (this->__isset.%s && !(this->%s == rhs.%s))
  1438. return false;
  1439. )";
  1440. std::string thrift_struct_class_operator_equal_end_format = R"(
  1441. return true;
  1442. }
  1443. )";
  1444. std::string thrift_struct_class_elements_start_format = R"(
  1445. bool operator != (const %s& rhs) const
  1446. {
  1447. return !(*this == rhs);
  1448. }
  1449. bool operator < (const %s & ) const;
  1450. %s(const %s&) = default;
  1451. %s(%s&&) = default;
  1452. %s& operator= (const %s&) = default;
  1453. %s& operator= (%s&&) = default;
  1454. %s()
  1455. {
  1456. )";
  1457. };
  1458. #endif