messagedefinitionprinter.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. * MIT License
  3. *
  4. * Copyright (c) 2019 Alexey Edelev <semlanik@gmail.com>, Tatyana Borisova <tanusshhka@mail.ru>
  5. *
  6. * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy of this
  9. * software and associated documentation files (the "Software"), to deal in the Software
  10. * without restriction, including without limitation the rights to use, copy, modify,
  11. * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
  12. * to permit persons to whom the Software is furnished to do so, subject to the following
  13. * conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in all copies
  16. * or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  19. * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  20. * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  21. * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  22. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "messagedefinitionprinter.h"
  26. #include <google/protobuf/descriptor.h>
  27. #include "generatoroptions.h"
  28. using namespace QtProtobuf::generator;
  29. using namespace ::google::protobuf;
  30. MessageDefinitionPrinter::MessageDefinitionPrinter(const Descriptor *message, const std::shared_ptr<::google::protobuf::io::Printer> &printer) :
  31. DescriptorPrinterBase<Descriptor>(message, printer)
  32. {
  33. mTypeMap = common::produceMessageTypeMap(message, nullptr);
  34. }
  35. void MessageDefinitionPrinter::printRegisterBody()
  36. {
  37. mPrinter->Print(mTypeMap,
  38. Templates::ManualRegistrationComplexTypeDefinition);
  39. Indent();
  40. if (GeneratorOptions::instance().hasQml()) {
  41. mPrinter->Print(mTypeMap, Templates::RegisterQmlListPropertyMetaTypeTemplate);
  42. mPrinter->Print(mTypeMap, Templates::QmlRegisterTypeTemplate);
  43. }
  44. common::iterateMessageFields(mDescriptor, [this](const FieldDescriptor *field, const PropertyMap &propertyMap) {
  45. if (field->type() == FieldDescriptor::TYPE_ENUM
  46. && common::isLocalEnum(field->enum_type(), mDescriptor)) {
  47. mPrinter->Print(propertyMap, Templates::RegisterLocalEnumTemplate);
  48. } else if (field->is_map()) {
  49. mPrinter->Print(propertyMap, Templates::RegisterMapTemplate);
  50. }
  51. });
  52. Outdent();
  53. mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
  54. }
  55. void MessageDefinitionPrinter::printFieldsOrdering() {
  56. mPrinter->Print({{"type", mName}}, Templates::FieldsOrderingContainerTemplate);
  57. Indent();
  58. for (int i = 0; i < mDescriptor->field_count(); i++) {
  59. const FieldDescriptor *field = mDescriptor->field(i);
  60. if (i != 0) {
  61. mPrinter->Print("\n,");
  62. }
  63. //property_number is incremented by 1 because user properties stating from 1.
  64. //Property with index 0 is "objectName"
  65. mPrinter->Print({{"field_number", std::to_string(field->number())},
  66. {"property_number", std::to_string(i + 1)}}, Templates::FieldOrderTemplate);
  67. }
  68. Outdent();
  69. mPrinter->Print(Templates::SemicolonBlockEnclosureTemplate);
  70. mPrinter->Print("\n");
  71. }
  72. void MessageDefinitionPrinter::printConstructors() {
  73. for (int i = 0; i <= mDescriptor->field_count(); i++) {
  74. mPrinter->Print(mTypeMap, Templates::ProtoConstructorDefinitionBeginTemplate);
  75. printConstructor(i);
  76. mPrinter->Print(mTypeMap, Templates::ProtoConstructorDefinitionEndTemplate);
  77. printInitializationList(i);
  78. mPrinter->Print(Templates::ConstructorContentTemplate);
  79. }
  80. }
  81. void MessageDefinitionPrinter::printConstructor(int fieldCount)
  82. {
  83. for (int i = 0; i < fieldCount; i++) {
  84. const FieldDescriptor *field = mDescriptor->field(i);
  85. const char *parameterTemplate = Templates::ConstructorParameterTemplate;
  86. FieldDescriptor::Type fieldType = field->type();
  87. if (field->is_repeated() && !field->is_map()) {
  88. parameterTemplate = Templates::ConstructorRepeatedParameterTemplate;
  89. } else if(fieldType == FieldDescriptor::TYPE_BYTES
  90. || fieldType == FieldDescriptor::TYPE_STRING
  91. || fieldType == FieldDescriptor::TYPE_MESSAGE
  92. || field->is_map()) {
  93. parameterTemplate = Templates::ConstructorMessageParameterTemplate;
  94. }
  95. mPrinter->Print(common::producePropertyMap(field, mDescriptor), parameterTemplate);
  96. }
  97. }
  98. void MessageDefinitionPrinter::printInitializationList(int fieldCount)
  99. {
  100. for (int i = 0; i < mDescriptor->field_count(); i++) {
  101. const FieldDescriptor *field = mDescriptor->field(i);
  102. auto propertyMap = common::producePropertyMap(field, mDescriptor);
  103. propertyMap["initializer"] = "";
  104. if (!field->is_repeated() && !field->is_map()) {
  105. switch (field->type()) {
  106. case FieldDescriptor::TYPE_DOUBLE:
  107. case FieldDescriptor::TYPE_FLOAT:
  108. propertyMap["initializer"] = "0.0";
  109. break;
  110. case FieldDescriptor::TYPE_FIXED32:
  111. case FieldDescriptor::TYPE_FIXED64:
  112. case FieldDescriptor::TYPE_INT32:
  113. case FieldDescriptor::TYPE_INT64:
  114. case FieldDescriptor::TYPE_SINT32:
  115. case FieldDescriptor::TYPE_SINT64:
  116. case FieldDescriptor::TYPE_UINT32:
  117. case FieldDescriptor::TYPE_UINT64:
  118. propertyMap["initializer"] = "0";
  119. break;
  120. case FieldDescriptor::TYPE_BOOL:
  121. propertyMap["initializer"] = "false";
  122. break;
  123. case FieldDescriptor::TYPE_ENUM:
  124. propertyMap["initializer"] = propertyMap["scope_type"] + "::" + field->enum_type()->value(0)->name();
  125. break;
  126. default:
  127. break;
  128. }
  129. }
  130. if (field->type() == FieldDescriptor::TYPE_MESSAGE
  131. && !field->is_map() && !field->is_repeated()) {
  132. if (i < fieldCount) {
  133. mPrinter->Print(propertyMap, Templates::MessagePropertyInitializerTemplate);
  134. } else {
  135. mPrinter->Print(propertyMap, Templates::MessagePropertyDefaultInitializerTemplate);
  136. }
  137. } else {
  138. if (i < fieldCount) {
  139. mPrinter->Print(propertyMap, Templates::PropertyInitializerTemplate);
  140. } else {
  141. if (!propertyMap["initializer"].empty()) {
  142. mPrinter->Print(propertyMap, Templates::PropertyDefaultInitializerTemplate);
  143. }
  144. }
  145. }
  146. }
  147. }
  148. void MessageDefinitionPrinter::printCopyFunctionality()
  149. {
  150. assert(mDescriptor != nullptr);
  151. const char *constructorTemplate = Templates::CopyConstructorDefinitionTemplate;
  152. const char *assignmentOperatorTemplate = Templates::AssignmentOperatorDefinitionTemplate;
  153. if (mDescriptor->field_count() <= 0) {
  154. constructorTemplate = Templates::EmptyCopyConstructorDefinitionTemplate;
  155. assignmentOperatorTemplate = Templates::EmptyAssignmentOperatorDefinitionTemplate;
  156. }
  157. mPrinter->Print({{"classname", mName}},
  158. constructorTemplate);
  159. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
  160. if (field->type() == FieldDescriptor::TYPE_MESSAGE
  161. && !field->is_map() && !field->is_repeated()) {
  162. mPrinter->Print(propertyMap, Templates::MessagePropertyDefaultInitializerTemplate);
  163. }
  164. });
  165. mPrinter->Print("\n{\n");
  166. Indent();
  167. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
  168. if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
  169. mPrinter->Print(propertyMap, Templates::CopyComplexFieldTemplate);
  170. } else {
  171. mPrinter->Print(propertyMap, Templates::CopyFieldTemplate);
  172. }
  173. });
  174. Outdent();
  175. mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
  176. mPrinter->Print({{"classname", mName}}, assignmentOperatorTemplate);
  177. Indent();
  178. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
  179. if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
  180. mPrinter->Print(propertyMap, Templates::CopyComplexFieldTemplate);
  181. } else {
  182. mPrinter->Print(propertyMap, Templates::CopyFieldTemplate);
  183. }
  184. });
  185. mPrinter->Print(Templates::AssignmentOperatorReturnTemplate);
  186. Outdent();
  187. mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
  188. }
  189. void MessageDefinitionPrinter::printMoveSemantic()
  190. {
  191. assert(mDescriptor != nullptr);
  192. const char *constructorTemplate = Templates::MoveConstructorDefinitionTemplate;
  193. const char *assignmentOperatorTemplate = Templates::MoveAssignmentOperatorDefinitionTemplate;
  194. if (mDescriptor->field_count() <= 0) {
  195. constructorTemplate = Templates::EmptyMoveConstructorDefinitionTemplate;
  196. assignmentOperatorTemplate = Templates::EmptyMoveAssignmentOperatorDefinitionTemplate;
  197. }
  198. mPrinter->Print({{"classname", mName}},
  199. constructorTemplate);
  200. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
  201. if (field->type() == FieldDescriptor::TYPE_MESSAGE
  202. && !field->is_map() && !field->is_repeated()) {
  203. mPrinter->Print(propertyMap, Templates::MessagePropertyDefaultInitializerTemplate);
  204. }
  205. });
  206. mPrinter->Print("\n{\n");
  207. Indent();
  208. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
  209. if (field->type() == FieldDescriptor::TYPE_MESSAGE
  210. || field->type() == FieldDescriptor::TYPE_STRING
  211. || field->type() == FieldDescriptor::TYPE_BYTES
  212. || field->is_repeated()) {
  213. if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
  214. mPrinter->Print(propertyMap, Templates::MoveMessageFieldTemplate);
  215. } else {
  216. mPrinter->Print(propertyMap, Templates::MoveComplexFieldConstructorTemplate);
  217. }
  218. } else {
  219. if (field->type() != FieldDescriptor::TYPE_ENUM) {
  220. mPrinter->Print(propertyMap, Templates::MoveFieldTemplate);
  221. }
  222. else {
  223. mPrinter->Print(propertyMap, Templates::EnumMoveFieldTemplate);
  224. }
  225. }
  226. });
  227. Outdent();
  228. mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
  229. mPrinter->Print({{"classname", mName}}, assignmentOperatorTemplate);
  230. Indent();
  231. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, const PropertyMap &propertyMap) {
  232. if (field->type() == FieldDescriptor::TYPE_MESSAGE
  233. || field->type() == FieldDescriptor::TYPE_STRING
  234. || field->type() == FieldDescriptor::TYPE_BYTES
  235. || field->is_repeated()) {
  236. if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
  237. mPrinter->Print(propertyMap, Templates::MoveMessageFieldTemplate);
  238. } else {
  239. mPrinter->Print(propertyMap, Templates::MoveComplexFieldTemplate);
  240. }
  241. } else {
  242. if (field->type() != FieldDescriptor::TYPE_ENUM) {
  243. mPrinter->Print(propertyMap, Templates::MoveFieldTemplate);
  244. }
  245. else {
  246. mPrinter->Print(propertyMap, Templates::EnumMoveFieldTemplate);
  247. }
  248. }
  249. });
  250. mPrinter->Print(Templates::AssignmentOperatorReturnTemplate);
  251. Outdent();
  252. mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
  253. }
  254. void MessageDefinitionPrinter::printComparisonOperators()
  255. {
  256. assert(mDescriptor != nullptr);
  257. if (mDescriptor->field_count() <= 0) {
  258. mPrinter->Print({{"classname", mName}}, Templates::EmptyEqualOperatorDefinitionTemplate);
  259. mPrinter->Print({{"classname", mName}}, Templates::NotEqualOperatorDefinitionTemplate);
  260. return;
  261. }
  262. mPrinter->Print({{"classname", mName}}, Templates::EqualOperatorDefinitionTemplate);
  263. bool isFirst = true;
  264. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
  265. if (!isFirst) {
  266. mPrinter->Print("\n&& ");
  267. } else {
  268. Indent();
  269. Indent();
  270. isFirst = false;
  271. }
  272. if (field->type() == FieldDescriptor::TYPE_MESSAGE
  273. && !field->is_map() && !field->is_repeated()) {
  274. mPrinter->Print(propertyMap, Templates::EqualOperatorMessagePropertyTemplate);
  275. } else {
  276. mPrinter->Print(propertyMap, Templates::EqualOperatorPropertyTemplate);
  277. }
  278. });
  279. //Only if at least one field "copied"
  280. if (!isFirst) {
  281. Outdent();
  282. Outdent();
  283. }
  284. mPrinter->Print(";\n");
  285. mPrinter->Print(Templates::SimpleBlockEnclosureTemplate);
  286. mPrinter->Print({{"classname", mName}}, Templates::NotEqualOperatorDefinitionTemplate);
  287. }
  288. void MessageDefinitionPrinter::printGetters()
  289. {
  290. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
  291. if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map() && !field->is_repeated()) {
  292. mPrinter->Print(propertyMap, Templates::GetterPrivateMessageDefinitionTemplate);
  293. mPrinter->Print(propertyMap, Templates::GetterMessageDefinitionTemplate);
  294. }
  295. if (field->is_repeated()) {
  296. if (field->type() == FieldDescriptor::TYPE_MESSAGE && !field->is_map()
  297. && GeneratorOptions::instance().hasQml()) {
  298. mPrinter->Print(propertyMap, Templates::GetterQmlListDefinitionTemplate);
  299. }
  300. }
  301. });
  302. common::iterateMessageFields(mDescriptor, [&](const FieldDescriptor *field, PropertyMap &propertyMap) {
  303. switch (field->type()) {
  304. case FieldDescriptor::TYPE_MESSAGE:
  305. if (!field->is_map() && !field->is_repeated()) {
  306. mPrinter->Print(propertyMap, Templates::SetterPrivateTemplateDefinitionMessageType);
  307. mPrinter->Print(propertyMap, Templates::SetterTemplateDefinitionMessageType);
  308. } else {
  309. mPrinter->Print(propertyMap, Templates::SetterTemplateDefinitionComplexType);
  310. }
  311. break;
  312. case FieldDescriptor::FieldDescriptor::TYPE_STRING:
  313. case FieldDescriptor::FieldDescriptor::TYPE_BYTES:
  314. mPrinter->Print(propertyMap, Templates::SetterTemplateDefinitionComplexType);
  315. break;
  316. default:
  317. break;
  318. }
  319. });
  320. }
  321. void MessageDefinitionPrinter::printDestructor()
  322. {
  323. mPrinter->Print({{"classname", mName}}, Templates::RegistrarTemplate);
  324. mPrinter->Print({{"classname", mName}}, "$classname$::~$classname$()\n"
  325. "{}\n\n");
  326. }