cpp_file.cc 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #include <google/protobuf/compiler/cpp/cpp_file.h>
  34. #include <map>
  35. #include <memory>
  36. #include <set>
  37. #include <vector>
  38. #include <google/protobuf/compiler/cpp/cpp_enum.h>
  39. #include <google/protobuf/compiler/cpp/cpp_extension.h>
  40. #include <google/protobuf/compiler/cpp/cpp_field.h>
  41. #include <google/protobuf/compiler/cpp/cpp_helpers.h>
  42. #include <google/protobuf/compiler/cpp/cpp_message.h>
  43. #include <google/protobuf/compiler/cpp/cpp_service.h>
  44. #include <google/protobuf/descriptor.pb.h>
  45. #include <google/protobuf/io/printer.h>
  46. #include <google/protobuf/stubs/strutil.h>
  47. namespace google {
  48. namespace protobuf {
  49. namespace compiler {
  50. namespace cpp {
  51. FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
  52. : file_(file),
  53. options_(options),
  54. scc_analyzer_(options),
  55. enum_generators_owner_(
  56. new std::unique_ptr<EnumGenerator>[file->enum_type_count()]),
  57. service_generators_owner_(
  58. new std::unique_ptr<ServiceGenerator>[file->service_count()]),
  59. extension_generators_owner_(
  60. new std::unique_ptr<ExtensionGenerator>[file->extension_count()]) {
  61. std::vector<const Descriptor*> msgs = FlattenMessagesInFile(file);
  62. for (int i = 0; i < msgs.size(); i++) {
  63. // Deleted in destructor
  64. MessageGenerator* msg_gen =
  65. new MessageGenerator(msgs[i], i, options, &scc_analyzer_);
  66. message_generators_.push_back(msg_gen);
  67. msg_gen->AddGenerators(&enum_generators_, &extension_generators_);
  68. }
  69. for (int i = 0; i < file->enum_type_count(); i++) {
  70. enum_generators_owner_[i].reset(
  71. new EnumGenerator(file->enum_type(i), options));
  72. enum_generators_.push_back(enum_generators_owner_[i].get());
  73. }
  74. for (int i = 0; i < file->service_count(); i++) {
  75. service_generators_owner_[i].reset(
  76. new ServiceGenerator(file->service(i), options));
  77. service_generators_.push_back(service_generators_owner_[i].get());
  78. }
  79. if (HasGenericServices(file_, options_)) {
  80. for (int i = 0; i < service_generators_.size(); i++) {
  81. service_generators_[i]->index_in_metadata_ = i;
  82. }
  83. }
  84. for (int i = 0; i < file->extension_count(); i++) {
  85. extension_generators_owner_[i].reset(
  86. new ExtensionGenerator(file->extension(i), options));
  87. extension_generators_.push_back(extension_generators_owner_[i].get());
  88. }
  89. package_parts_ = Split(file_->package(), ".", true);
  90. }
  91. FileGenerator::~FileGenerator() {
  92. for (int i = 0; i < message_generators_.size(); i++) {
  93. delete message_generators_[i];
  94. }
  95. }
  96. void FileGenerator::GenerateMacroUndefs(io::Printer* printer) {
  97. // Only do this for protobuf's own types. There are some google3 protos using
  98. // macros as field names and the generated code compiles after the macro
  99. // expansion. Undefing these macros actually breaks such code.
  100. if (file_->name() != "google/protobuf/compiler/plugin.proto") {
  101. return;
  102. }
  103. std::vector<string> names_to_undef;
  104. std::vector<const FieldDescriptor*> fields;
  105. ListAllFields(file_, &fields);
  106. for (int i = 0; i < fields.size(); i++) {
  107. const string& name = fields[i]->name();
  108. static const char* kMacroNames[] = {"major", "minor"};
  109. for (int i = 0; i < GOOGLE_ARRAYSIZE(kMacroNames); ++i) {
  110. if (name == kMacroNames[i]) {
  111. names_to_undef.push_back(name);
  112. break;
  113. }
  114. }
  115. }
  116. for (int i = 0; i < names_to_undef.size(); ++i) {
  117. printer->Print(
  118. "#ifdef $name$\n"
  119. "#undef $name$\n"
  120. "#endif\n",
  121. "name", names_to_undef[i]);
  122. }
  123. }
  124. void FileGenerator::GenerateHeader(io::Printer* printer) {
  125. printer->Print(
  126. "// @@protoc_insertion_point(includes)\n");
  127. printer->Print("#define PROTOBUF_INTERNAL_EXPORT_$filename$ $export$\n",
  128. "filename", FileLevelNamespace(file_),
  129. "export", options_.dllexport_decl);
  130. GenerateMacroUndefs(printer);
  131. GenerateGlobalStateFunctionDeclarations(printer);
  132. GenerateForwardDeclarations(printer);
  133. {
  134. NamespaceOpener ns(Namespace(file_), printer);
  135. printer->Print("\n");
  136. GenerateEnumDefinitions(printer);
  137. printer->Print(kThickSeparator);
  138. printer->Print("\n");
  139. GenerateMessageDefinitions(printer);
  140. printer->Print("\n");
  141. printer->Print(kThickSeparator);
  142. printer->Print("\n");
  143. GenerateServiceDefinitions(printer);
  144. GenerateExtensionIdentifiers(printer);
  145. printer->Print("\n");
  146. printer->Print(kThickSeparator);
  147. printer->Print("\n");
  148. GenerateInlineFunctionDefinitions(printer);
  149. printer->Print(
  150. "\n"
  151. "// @@protoc_insertion_point(namespace_scope)\n"
  152. "\n");
  153. }
  154. // We need to specialize some templates in the ::google::protobuf namespace:
  155. GenerateProto2NamespaceEnumSpecializations(printer);
  156. printer->Print(
  157. "\n"
  158. "// @@protoc_insertion_point(global_scope)\n"
  159. "\n");
  160. }
  161. void FileGenerator::GenerateProtoHeader(io::Printer* printer,
  162. const string& info_path) {
  163. if (!options_.proto_h) {
  164. return;
  165. }
  166. string filename_identifier = FilenameIdentifier(file_->name());
  167. GenerateTopHeaderGuard(printer, filename_identifier);
  168. GenerateLibraryIncludes(printer);
  169. for (int i = 0; i < file_->public_dependency_count(); i++) {
  170. const FileDescriptor* dep = file_->public_dependency(i);
  171. const char* extension = ".proto.h";
  172. string dependency = StripProto(dep->name()) + extension;
  173. printer->Print(
  174. "#include \"$dependency$\" // IWYU pragma: export\n",
  175. "dependency", dependency);
  176. }
  177. GenerateMetadataPragma(printer, info_path);
  178. GenerateHeader(printer);
  179. GenerateBottomHeaderGuard(printer, filename_identifier);
  180. }
  181. void FileGenerator::GeneratePBHeader(io::Printer* printer,
  182. const string& info_path) {
  183. string filename_identifier =
  184. FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : ""));
  185. GenerateTopHeaderGuard(printer, filename_identifier);
  186. if (options_.proto_h) {
  187. string target_basename = StripProto(file_->name());
  188. printer->Print("#include \"$basename$.proto.h\" // IWYU pragma: export\n",
  189. "basename", target_basename);
  190. } else {
  191. GenerateLibraryIncludes(printer);
  192. }
  193. GenerateDependencyIncludes(printer);
  194. GenerateMetadataPragma(printer, info_path);
  195. if (!options_.proto_h) {
  196. GenerateHeader(printer);
  197. } else {
  198. // This is unfortunately necessary for some plugins. I don't see why we
  199. // need two of the same insertion points.
  200. // TODO(gerbens) remove this.
  201. printer->Print(
  202. "// @@protoc_insertion_point(includes)\n");
  203. {
  204. NamespaceOpener ns(Namespace(file_), printer);
  205. printer->Print(
  206. "\n"
  207. "// @@protoc_insertion_point(namespace_scope)\n");
  208. }
  209. printer->Print(
  210. "\n"
  211. "// @@protoc_insertion_point(global_scope)\n"
  212. "\n");
  213. }
  214. GenerateBottomHeaderGuard(printer, filename_identifier);
  215. }
  216. void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
  217. string target_basename = StripProto(file_->name());
  218. const bool use_system_include = IsWellKnownMessage(file_);
  219. string header = target_basename + (options_.proto_h ? ".proto.h" : ".pb.h");
  220. printer->Print(
  221. "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
  222. "// source: $filename$\n"
  223. "\n"
  224. "#include $left$$header$$right$\n"
  225. "\n"
  226. "#include <algorithm>\n" // for swap()
  227. "\n"
  228. "#include <google/protobuf/stubs/common.h>\n"
  229. "#include <google/protobuf/stubs/port.h>\n"
  230. "#include <google/protobuf/io/coded_stream.h>\n"
  231. "#include <google/protobuf/wire_format_lite_inl.h>\n",
  232. "filename", file_->name(),
  233. "header", header,
  234. "left", use_system_include ? "<" : "\"",
  235. "right", use_system_include ? ">" : "\"");
  236. // Unknown fields implementation in lite mode uses StringOutputStream
  237. if (!UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
  238. printer->Print(
  239. "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
  240. }
  241. if (HasDescriptorMethods(file_, options_)) {
  242. printer->Print(
  243. "#include <google/protobuf/descriptor.h>\n"
  244. "#include <google/protobuf/generated_message_reflection.h>\n"
  245. "#include <google/protobuf/reflection_ops.h>\n"
  246. "#include <google/protobuf/wire_format.h>\n");
  247. }
  248. if (options_.proto_h) {
  249. // Use the smaller .proto.h files.
  250. for (int i = 0; i < file_->dependency_count(); i++) {
  251. const FileDescriptor* dep = file_->dependency(i);
  252. const char* extension = ".proto.h";
  253. string basename = StripProto(dep->name());
  254. string dependency = basename + extension;
  255. printer->Print(
  256. "#include \"$dependency$\"\n",
  257. "dependency", dependency);
  258. }
  259. }
  260. // TODO(gerbens) Remove this when all code in google is using the same
  261. // proto library. This is a temporary hack to force build errors if
  262. // the proto library is compiled with GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
  263. // and is also linking internal proto2. This is to prevent regressions while
  264. // we work cleaning up the code base. After this is completed and we have
  265. // one proto lib all code uses this should be removed.
  266. printer->Print(
  267. "// This is a temporary google only hack\n"
  268. "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n"
  269. "#include \"third_party/protobuf/version.h\"\n"
  270. "#endif\n");
  271. printer->Print(
  272. "// @@protoc_insertion_point(includes)\n");
  273. }
  274. void FileGenerator::GenerateSourceDefaultInstance(int idx,
  275. io::Printer* printer) {
  276. printer->Print(
  277. "class $classname$DefaultTypeInternal {\n"
  278. " public:\n"
  279. " ::google::protobuf::internal::ExplicitlyConstructed<$classname$>\n"
  280. " _instance;\n",
  281. "classname", message_generators_[idx]->classname_);
  282. printer->Indent();
  283. message_generators_[idx]->GenerateExtraDefaultFields(printer);
  284. printer->Outdent();
  285. printer->Print("} _$classname$_default_instance_;\n", "classname",
  286. message_generators_[idx]->classname_);
  287. }
  288. namespace {
  289. // Generates weak symbol declarations for types that are to be considered weakly
  290. // referenced.
  291. void GenerateInternalForwardDeclarations(
  292. const std::vector<const FieldDescriptor*>& fields, const Options& options,
  293. SCCAnalyzer* scc_analyzer, io::Printer* printer) {
  294. // To ensure determinism and minimize the number of namespace statements,
  295. // we output the forward declarations sorted on namespace and type / function
  296. // name.
  297. std::set<std::pair<string, string> > messages;
  298. std::set<std::pair<string, string> > sccs;
  299. std::set<std::pair<string, string> > inits;
  300. for (int i = 0; i < fields.size(); ++i) {
  301. const FieldDescriptor* field = fields[i];
  302. const Descriptor* msg = field->message_type();
  303. if (msg == nullptr) continue;
  304. bool is_weak = IsImplicitWeakField(field, options, scc_analyzer);
  305. string flns = FileLevelNamespace(msg);
  306. auto scc = scc_analyzer->GetSCC(msg);
  307. string repr = ClassName(scc->GetRepresentative());
  308. string weak_attr;
  309. if (is_weak) {
  310. inits.insert(std::make_pair(flns, "AddDescriptors"));
  311. messages.insert(std::make_pair(Namespace(msg), ClassName(msg)));
  312. weak_attr = " __attribute__((weak))";
  313. }
  314. string dllexport = "PROTOBUF_INTERNAL_EXPORT_" + FileLevelNamespace(msg);
  315. sccs.insert(std::make_pair(flns, "extern " + dllexport + weak_attr +
  316. " ::google::protobuf::internal::SCCInfo<" +
  317. SimpleItoa(scc->children.size()) +
  318. "> scc_info_" + repr + ";\n"));
  319. }
  320. printer->Print("\n");
  321. NamespaceOpener ns(printer);
  322. for (std::set<std::pair<string, string> >::const_iterator it =
  323. messages.begin();
  324. it != messages.end(); ++it) {
  325. ns.ChangeTo(it->first);
  326. printer->Print(
  327. "extern __attribute__((weak)) $classname$DefaultTypeInternal "
  328. "_$classname$_default_instance_;\n",
  329. "classname", it->second);
  330. }
  331. for (std::set<std::pair<string, string> >::const_iterator it = inits.begin();
  332. it != inits.end(); ++it) {
  333. ns.ChangeTo(it->first);
  334. printer->Print("void $name$() __attribute__((weak));\n",
  335. "name", it->second);
  336. }
  337. for (const auto& p : sccs) {
  338. ns.ChangeTo(p.first);
  339. printer->Print(p.second.c_str());
  340. }
  341. }
  342. } // namespace
  343. void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
  344. GenerateSourceIncludes(printer);
  345. // Generate weak declarations. We do this for the whole strongly-connected
  346. // component (SCC), because we have a single InitDefaults* function for the
  347. // SCC.
  348. std::vector<const FieldDescriptor*> fields;
  349. for (const Descriptor* message :
  350. scc_analyzer_.GetSCC(message_generators_[idx]->descriptor_)
  351. ->descriptors) {
  352. ListAllFields(message, &fields);
  353. }
  354. GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_,
  355. printer);
  356. if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) {
  357. NamespaceOpener ns(FileLevelNamespace(file_), printer);
  358. GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer);
  359. }
  360. { // package namespace
  361. NamespaceOpener ns(Namespace(file_), printer);
  362. // Define default instances
  363. GenerateSourceDefaultInstance(idx, printer);
  364. if (options_.lite_implicit_weak_fields) {
  365. printer->Print("void $classname$_ReferenceStrong() {}\n", "classname",
  366. message_generators_[idx]->classname_);
  367. }
  368. // Generate classes.
  369. printer->Print("\n");
  370. message_generators_[idx]->GenerateClassMethods(printer);
  371. printer->Print(
  372. "\n"
  373. "// @@protoc_insertion_point(namespace_scope)\n");
  374. } // end package namespace
  375. printer->Print(
  376. "namespace google {\nnamespace protobuf {\n");
  377. message_generators_[idx]->GenerateSourceInProto2Namespace(printer);
  378. printer->Print(
  379. "} // namespace protobuf\n} // namespace google\n");
  380. printer->Print(
  381. "\n"
  382. "// @@protoc_insertion_point(global_scope)\n");
  383. }
  384. void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
  385. GenerateSourceIncludes(printer);
  386. {
  387. NamespaceOpener ns(FileLevelNamespace(file_), printer);
  388. GenerateTables(printer);
  389. // Define the code to initialize reflection. This code uses a global
  390. // constructor to register reflection data with the runtime pre-main.
  391. if (HasDescriptorMethods(file_, options_)) {
  392. GenerateReflectionInitializationCode(printer);
  393. }
  394. }
  395. NamespaceOpener ns(Namespace(file_), printer);
  396. // Generate enums.
  397. for (int i = 0; i < enum_generators_.size(); i++) {
  398. enum_generators_[i]->GenerateMethods(i, printer);
  399. }
  400. // Define extensions.
  401. for (int i = 0; i < extension_generators_.size(); i++) {
  402. extension_generators_[i]->GenerateDefinition(printer);
  403. }
  404. if (HasGenericServices(file_, options_)) {
  405. // Generate services.
  406. for (int i = 0; i < service_generators_.size(); i++) {
  407. if (i == 0) printer->Print("\n");
  408. printer->Print(kThickSeparator);
  409. printer->Print("\n");
  410. service_generators_[i]->GenerateImplementation(printer);
  411. }
  412. }
  413. }
  414. void FileGenerator::GenerateSource(io::Printer* printer) {
  415. GenerateSourceIncludes(printer);
  416. std::vector<const FieldDescriptor*> fields;
  417. ListAllFields(file_, &fields);
  418. GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_,
  419. printer);
  420. {
  421. NamespaceOpener ns(Namespace(file_), printer);
  422. // Define default instances
  423. for (int i = 0; i < message_generators_.size(); i++) {
  424. GenerateSourceDefaultInstance(i, printer);
  425. if (options_.lite_implicit_weak_fields) {
  426. printer->Print("void $classname$_ReferenceStrong() {}\n", "classname",
  427. message_generators_[i]->classname_);
  428. }
  429. }
  430. }
  431. {
  432. NamespaceOpener ns(FileLevelNamespace(file_), printer);
  433. GenerateTables(printer);
  434. // Now generate the InitDefaults for each SCC.
  435. for (int i = 0; i < message_generators_.size(); i++) {
  436. if (IsSCCRepresentative(message_generators_[i]->descriptor_)) {
  437. GenerateInitForSCC(GetSCC(message_generators_[i]->descriptor_),
  438. printer);
  439. }
  440. }
  441. printer->Print("void InitDefaults() {\n");
  442. for (int i = 0; i < message_generators_.size(); i++) {
  443. if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue;
  444. string scc_name = ClassName(message_generators_[i]->descriptor_);
  445. printer->Print(
  446. " ::google::protobuf::internal::InitSCC(&scc_info_$scc_name$.base);\n",
  447. "scc_name", scc_name);
  448. }
  449. printer->Print("}\n\n");
  450. // Define the code to initialize reflection. This code uses a global
  451. // constructor to register reflection data with the runtime pre-main.
  452. if (HasDescriptorMethods(file_, options_)) {
  453. GenerateReflectionInitializationCode(printer);
  454. }
  455. }
  456. {
  457. NamespaceOpener ns(Namespace(file_), printer);
  458. // Actually implement the protos
  459. // Generate enums.
  460. for (int i = 0; i < enum_generators_.size(); i++) {
  461. enum_generators_[i]->GenerateMethods(i, printer);
  462. }
  463. // Generate classes.
  464. for (int i = 0; i < message_generators_.size(); i++) {
  465. printer->Print("\n");
  466. printer->Print(kThickSeparator);
  467. printer->Print("\n");
  468. message_generators_[i]->GenerateClassMethods(printer);
  469. }
  470. if (HasGenericServices(file_, options_)) {
  471. // Generate services.
  472. for (int i = 0; i < service_generators_.size(); i++) {
  473. if (i == 0) printer->Print("\n");
  474. printer->Print(kThickSeparator);
  475. printer->Print("\n");
  476. service_generators_[i]->GenerateImplementation(printer);
  477. }
  478. }
  479. // Define extensions.
  480. for (int i = 0; i < extension_generators_.size(); i++) {
  481. extension_generators_[i]->GenerateDefinition(printer);
  482. }
  483. printer->Print(
  484. "\n"
  485. "// @@protoc_insertion_point(namespace_scope)\n");
  486. }
  487. printer->Print(
  488. "namespace google {\nnamespace protobuf {\n");
  489. for (int i = 0; i < message_generators_.size(); i++) {
  490. message_generators_[i]->GenerateSourceInProto2Namespace(printer);
  491. }
  492. printer->Print(
  493. "} // namespace protobuf\n} // namespace google\n");
  494. printer->Print(
  495. "\n"
  496. "// @@protoc_insertion_point(global_scope)\n");
  497. }
  498. class FileGenerator::ForwardDeclarations {
  499. public:
  500. ~ForwardDeclarations() {
  501. for (std::map<string, ForwardDeclarations*>::iterator
  502. it = namespaces_.begin(),
  503. end = namespaces_.end();
  504. it != end; ++it) {
  505. delete it->second;
  506. }
  507. namespaces_.clear();
  508. }
  509. ForwardDeclarations* AddOrGetNamespace(const string& ns_name) {
  510. ForwardDeclarations*& ns = namespaces_[ns_name];
  511. if (ns == nullptr) {
  512. ns = new ForwardDeclarations;
  513. }
  514. return ns;
  515. }
  516. std::map<string, const Descriptor*>& classes() { return classes_; }
  517. std::map<string, const EnumDescriptor*>& enums() { return enums_; }
  518. void PrintForwardDeclarations(io::Printer* printer,
  519. const Options& options) const {
  520. PrintNestedDeclarations(printer, options);
  521. PrintTopLevelDeclarations(printer, options);
  522. }
  523. private:
  524. void PrintNestedDeclarations(io::Printer* printer,
  525. const Options& options) const {
  526. PrintDeclarationsInsideNamespace(printer, options);
  527. for (std::map<string, ForwardDeclarations *>::const_iterator
  528. it = namespaces_.begin(),
  529. end = namespaces_.end();
  530. it != end; ++it) {
  531. printer->Print("namespace $nsname$ {\n",
  532. "nsname", it->first);
  533. it->second->PrintNestedDeclarations(printer, options);
  534. printer->Print("} // namespace $nsname$\n",
  535. "nsname", it->first);
  536. }
  537. }
  538. void PrintTopLevelDeclarations(io::Printer* printer,
  539. const Options& options) const {
  540. PrintDeclarationsOutsideNamespace(printer, options);
  541. for (std::map<string, ForwardDeclarations *>::const_iterator
  542. it = namespaces_.begin(),
  543. end = namespaces_.end();
  544. it != end; ++it) {
  545. it->second->PrintTopLevelDeclarations(printer, options);
  546. }
  547. }
  548. void PrintDeclarationsInsideNamespace(io::Printer* printer,
  549. const Options& options) const {
  550. for (std::map<string, const EnumDescriptor *>::const_iterator
  551. it = enums_.begin(),
  552. end = enums_.end();
  553. it != end; ++it) {
  554. printer->Print("enum $enumname$ : int;\n", "enumname", it->first);
  555. printer->Annotate("enumname", it->second);
  556. printer->Print("bool $enumname$_IsValid(int value);\n", "enumname",
  557. it->first);
  558. }
  559. for (std::map<string, const Descriptor*>::const_iterator
  560. it = classes_.begin(),
  561. end = classes_.end();
  562. it != end; ++it) {
  563. printer->Print("class $classname$;\n", "classname", it->first);
  564. printer->Annotate("classname", it->second);
  565. printer->Print(
  566. "class $classname$DefaultTypeInternal;\n"
  567. "$dllexport_decl$"
  568. "extern $classname$DefaultTypeInternal "
  569. "_$classname$_default_instance_;\n", // NOLINT
  570. "dllexport_decl",
  571. options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ",
  572. "classname",
  573. it->first);
  574. if (options.lite_implicit_weak_fields) {
  575. printer->Print("void $classname$_ReferenceStrong();\n",
  576. "classname", it->first);
  577. }
  578. }
  579. }
  580. void PrintDeclarationsOutsideNamespace(io::Printer* printer,
  581. const Options& options) const {
  582. if (classes_.size() == 0) return;
  583. printer->Print(
  584. "namespace google {\nnamespace protobuf {\n");
  585. for (std::map<string, const Descriptor*>::const_iterator
  586. it = classes_.begin(),
  587. end = classes_.end();
  588. it != end; ++it) {
  589. const Descriptor* d = it->second;
  590. printer->Print(
  591. "template<> "
  592. "$dllexport_decl$"
  593. "$classname$* Arena::CreateMaybeMessage<$classname$>"
  594. "(Arena*);\n",
  595. "classname", QualifiedClassName(d), "dllexport_decl",
  596. options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ");
  597. }
  598. printer->Print(
  599. "} // namespace protobuf\n} // namespace google\n");
  600. }
  601. std::map<string, ForwardDeclarations*> namespaces_;
  602. std::map<string, const Descriptor*> classes_;
  603. std::map<string, const EnumDescriptor*> enums_;
  604. };
  605. void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
  606. // AddDescriptors() is a file-level procedure which adds the encoded
  607. // FileDescriptorProto for this .proto file to the global DescriptorPool for
  608. // generated files (DescriptorPool::generated_pool()). It ordinarily runs at
  609. // static initialization time, but is not used at all in LITE_RUNTIME mode.
  610. //
  611. // Its sibling, AssignDescriptors(), actually pulls the compiled
  612. // FileDescriptor from the DescriptorPool and uses it to populate all of
  613. // the global variables which store pointers to the descriptor objects.
  614. // It also constructs the reflection objects. It is called the first time
  615. // anyone calls descriptor() or GetReflection() on one of the types defined
  616. // in the file.
  617. if (!message_generators_.empty()) {
  618. printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\n", "size",
  619. SimpleItoa(message_generators_.size()));
  620. }
  621. if (!enum_generators_.empty()) {
  622. printer->Print(
  623. "const ::google::protobuf::EnumDescriptor* "
  624. "file_level_enum_descriptors[$size$];\n",
  625. "size", SimpleItoa(enum_generators_.size()));
  626. }
  627. if (HasGenericServices(file_, options_) && file_->service_count() > 0) {
  628. printer->Print(
  629. "const ::google::protobuf::ServiceDescriptor* "
  630. "file_level_service_descriptors[$size$];\n",
  631. "size", SimpleItoa(file_->service_count()));
  632. }
  633. if (!message_generators_.empty()) {
  634. printer->Print(
  635. "\n"
  636. "const ::google::protobuf::uint32 TableStruct::offsets[] "
  637. "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
  638. printer->Indent();
  639. std::vector<std::pair<size_t, size_t> > pairs;
  640. pairs.reserve(message_generators_.size());
  641. for (int i = 0; i < message_generators_.size(); i++) {
  642. pairs.push_back(message_generators_[i]->GenerateOffsets(printer));
  643. }
  644. printer->Outdent();
  645. printer->Print(
  646. "};\n"
  647. "static const ::google::protobuf::internal::MigrationSchema schemas[] "
  648. "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
  649. printer->Indent();
  650. {
  651. int offset = 0;
  652. for (int i = 0; i < message_generators_.size(); i++) {
  653. message_generators_[i]->GenerateSchema(printer, offset,
  654. pairs[i].second);
  655. offset += pairs[i].first;
  656. }
  657. }
  658. printer->Outdent();
  659. printer->Print(
  660. "};\n"
  661. "\nstatic "
  662. "::google::protobuf::Message const * const file_default_instances[] = {\n");
  663. printer->Indent();
  664. for (int i = 0; i < message_generators_.size(); i++) {
  665. const Descriptor* descriptor = message_generators_[i]->descriptor_;
  666. printer->Print(
  667. "reinterpret_cast<const "
  668. "::google::protobuf::Message*>(&$ns$::_$classname$_default_instance_),\n",
  669. "classname", ClassName(descriptor), "ns", Namespace(descriptor));
  670. }
  671. printer->Outdent();
  672. printer->Print(
  673. "};\n"
  674. "\n");
  675. } else {
  676. // we still need these symbols to exist
  677. printer->Print(
  678. // MSVC doesn't like empty arrays, so we add a dummy.
  679. "const ::google::protobuf::uint32 TableStruct::offsets[1] = {};\n"
  680. "static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n"
  681. "static const ::google::protobuf::Message* const* "
  682. "file_default_instances = NULL;\n"
  683. "\n");
  684. }
  685. // ---------------------------------------------------------------
  686. // protobuf_AssignDescriptorsOnce(): The first time it is called, calls
  687. // AssignDescriptors(). All later times, waits for the first call to
  688. // complete and then returns.
  689. printer->Print(
  690. "void protobuf_AssignDescriptors() {\n"
  691. // Make sure the file has found its way into the pool. If a descriptor
  692. // is requested *during* static init then AddDescriptors() may not have
  693. // been called yet, so we call it manually. Note that it's fine if
  694. // AddDescriptors() is called multiple times.
  695. " AddDescriptors();\n"
  696. " AssignDescriptors(\n"
  697. " \"$filename$\", schemas, file_default_instances, "
  698. "TableStruct::offsets,\n"
  699. " $metadata$, $enum_descriptors$, $service_descriptors$);\n",
  700. "filename", file_->name(), "metadata",
  701. !message_generators_.empty() ? "file_level_metadata" : "NULL",
  702. "enum_descriptors",
  703. !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
  704. "service_descriptors",
  705. HasGenericServices(file_, options_) && file_->service_count() > 0
  706. ? "file_level_service_descriptors"
  707. : "NULL");
  708. printer->Print(
  709. "}\n"
  710. "\n"
  711. "void protobuf_AssignDescriptorsOnce() {\n"
  712. " static ::google::protobuf::internal::once_flag once;\n"
  713. " ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);\n"
  714. "}\n"
  715. "\n",
  716. "filename", file_->name(), "metadata",
  717. !message_generators_.empty() ? "file_level_metadata" : "NULL",
  718. "enum_descriptors",
  719. !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
  720. "service_descriptors",
  721. HasGenericServices(file_, options_) && file_->service_count() > 0
  722. ? "file_level_service_descriptors"
  723. : "NULL");
  724. // Only here because of useless string reference that we don't want in
  725. // protobuf_AssignDescriptorsOnce, because that is called from all the
  726. // GetMetadata member methods.
  727. printer->Print(
  728. "void protobuf_RegisterTypes(const ::std::string&) "
  729. "GOOGLE_PROTOBUF_ATTRIBUTE_COLD;\n"
  730. "void protobuf_RegisterTypes(const ::std::string&) {\n"
  731. " protobuf_AssignDescriptorsOnce();\n");
  732. printer->Indent();
  733. // All normal messages can be done generically
  734. if (!message_generators_.empty()) {
  735. printer->Print(
  736. "::google::protobuf::internal::RegisterAllTypes(file_level_metadata, $size$);\n",
  737. "size", SimpleItoa(message_generators_.size()));
  738. }
  739. printer->Outdent();
  740. printer->Print(
  741. "}\n"
  742. "\n");
  743. // Now generate the AddDescriptors() function.
  744. printer->Print(
  745. "void AddDescriptorsImpl() {\n"
  746. " InitDefaults();\n");
  747. printer->Indent();
  748. // Embed the descriptor. We simply serialize the entire
  749. // FileDescriptorProto
  750. // and embed it as a string literal, which is parsed and built into real
  751. // descriptors at initialization time.
  752. FileDescriptorProto file_proto;
  753. file_->CopyTo(&file_proto);
  754. string file_data;
  755. file_proto.SerializeToString(&file_data);
  756. printer->Print("static const char descriptor[] "
  757. "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) "
  758. "= {\n");
  759. printer->Indent();
  760. if (file_data.size() > 65535) {
  761. // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
  762. // bytes in length". Declare a static array of characters rather than use
  763. // a string literal. Only write 25 bytes per line.
  764. static const int kBytesPerLine = 25;
  765. for (int i = 0; i < file_data.size();) {
  766. for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
  767. printer->Print("'$char$', ", "char",
  768. CEscape(file_data.substr(i, 1)));
  769. }
  770. printer->Print("\n");
  771. }
  772. } else {
  773. // Only write 40 bytes per line.
  774. static const int kBytesPerLine = 40;
  775. for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
  776. printer->Print(" \"$data$\"\n", "data",
  777. EscapeTrigraphs(CEscape(
  778. file_data.substr(i, kBytesPerLine))));
  779. }
  780. }
  781. printer->Outdent();
  782. printer->Print("};\n");
  783. printer->Print(
  784. "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(\n"
  785. " descriptor, $size$);\n",
  786. "size", SimpleItoa(file_data.size()));
  787. // Call MessageFactory::InternalRegisterGeneratedFile().
  788. printer->Print(
  789. "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
  790. " \"$filename$\", &protobuf_RegisterTypes);\n",
  791. "filename", file_->name());
  792. // Call the AddDescriptors() methods for all of our dependencies, to make
  793. // sure they get added first.
  794. for (int i = 0; i < file_->dependency_count(); i++) {
  795. const FileDescriptor* dependency = file_->dependency(i);
  796. // Print the namespace prefix for the dependency.
  797. string file_namespace = FileLevelNamespace(dependency);
  798. // Call its AddDescriptors function.
  799. printer->Print("::$file_namespace$::AddDescriptors();\n", "file_namespace",
  800. file_namespace);
  801. }
  802. printer->Outdent();
  803. printer->Print(
  804. "}\n"
  805. "\n"
  806. "void AddDescriptors() {\n"
  807. " static ::google::protobuf::internal::once_flag once;\n"
  808. " ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);\n"
  809. "}\n");
  810. printer->Print(
  811. "// Force AddDescriptors() to be called at dynamic initialization "
  812. "time.\n"
  813. "struct StaticDescriptorInitializer {\n"
  814. " StaticDescriptorInitializer() {\n"
  815. " AddDescriptors();\n"
  816. " }\n"
  817. "} static_descriptor_initializer;\n");
  818. }
  819. void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) {
  820. const string scc_name = ClassName(scc->GetRepresentative());
  821. // We use static and not anonymous namespace because symbol names are
  822. // substantially shorter.
  823. printer->Print(
  824. "static void InitDefaults$scc_name$() {\n"
  825. " GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n"
  826. , // awkward comma due to macro
  827. "scc_name", scc_name);
  828. printer->Indent();
  829. // First construct all the necessary default instances.
  830. for (int i = 0; i < message_generators_.size(); i++) {
  831. if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
  832. continue;
  833. }
  834. // TODO(gerbens) This requires this function to be friend. Remove
  835. // the need for this.
  836. message_generators_[i]->GenerateFieldDefaultInstances(printer);
  837. printer->Print(
  838. "{\n"
  839. " void* ptr = &$ns$::_$classname$_default_instance_;\n"
  840. " new (ptr) $ns$::$classname$();\n",
  841. "ns", Namespace(message_generators_[i]->descriptor_),
  842. "classname", ClassName(message_generators_[i]->descriptor_));
  843. if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) {
  844. printer->Print(
  845. " ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);\n");
  846. }
  847. printer->Print("}\n");
  848. }
  849. // TODO(gerbens) make default instances be the same as normal instances.
  850. // Default instances differ from normal instances because they have cross
  851. // linked message fields.
  852. for (int i = 0; i < message_generators_.size(); i++) {
  853. if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
  854. continue;
  855. }
  856. printer->Print("$classname$::InitAsDefaultInstance();\n", "classname",
  857. QualifiedClassName(message_generators_[i]->descriptor_));
  858. }
  859. printer->Outdent();
  860. printer->Print("}\n\n");
  861. printer->Print(
  862. "$dllexport_decl$::google::protobuf::internal::SCCInfo<$size$> "
  863. "scc_info_$scc_name$ =\n"
  864. " {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), "
  865. "$size$, InitDefaults$scc_name$}, {",
  866. "size", SimpleItoa(scc->children.size()), "scc_name",
  867. ClassName(scc->GetRepresentative()), "dllexport_decl",
  868. options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
  869. for (const SCC* child : scc->children) {
  870. auto repr = child->GetRepresentative();
  871. printer->Print("\n &$ns$::scc_info_$child$.base,", "ns",
  872. FileLevelNamespace(repr), "child", ClassName(repr));
  873. }
  874. printer->Print("}};\n\n");
  875. }
  876. void FileGenerator::GenerateTables(io::Printer* printer) {
  877. if (options_.table_driven_parsing) {
  878. // TODO(ckennelly): Gate this with the same options flag to enable
  879. // table-driven parsing.
  880. printer->Print(
  881. "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n"
  882. " const TableStruct::entries[] "
  883. "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
  884. printer->Indent();
  885. std::vector<size_t> entries;
  886. size_t count = 0;
  887. for (int i = 0; i < message_generators_.size(); i++) {
  888. size_t value = message_generators_[i]->GenerateParseOffsets(printer);
  889. entries.push_back(value);
  890. count += value;
  891. }
  892. // We need these arrays to exist, and MSVC does not like empty arrays.
  893. if (count == 0) {
  894. printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n");
  895. }
  896. printer->Outdent();
  897. printer->Print(
  898. "};\n"
  899. "\n"
  900. "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n"
  901. " const TableStruct::aux[] "
  902. "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
  903. printer->Indent();
  904. std::vector<size_t> aux_entries;
  905. count = 0;
  906. for (int i = 0; i < message_generators_.size(); i++) {
  907. size_t value = message_generators_[i]->GenerateParseAuxTable(printer);
  908. aux_entries.push_back(value);
  909. count += value;
  910. }
  911. if (count == 0) {
  912. printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
  913. }
  914. printer->Outdent();
  915. printer->Print(
  916. "};\n"
  917. "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n"
  918. " TableStruct::schema[] "
  919. "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
  920. printer->Indent();
  921. size_t offset = 0;
  922. size_t aux_offset = 0;
  923. for (int i = 0; i < message_generators_.size(); i++) {
  924. message_generators_[i]->GenerateParseTable(printer, offset, aux_offset);
  925. offset += entries[i];
  926. aux_offset += aux_entries[i];
  927. }
  928. if (message_generators_.empty()) {
  929. printer->Print("{ NULL, NULL, 0, -1, -1, false },\n");
  930. }
  931. printer->Outdent();
  932. printer->Print(
  933. "};\n"
  934. "\n");
  935. }
  936. if (!message_generators_.empty() && options_.table_driven_serialization) {
  937. printer->Print(
  938. "const ::google::protobuf::internal::FieldMetadata TableStruct::field_metadata[] "
  939. "= {\n");
  940. printer->Indent();
  941. std::vector<int> field_metadata_offsets;
  942. int idx = 0;
  943. for (int i = 0; i < message_generators_.size(); i++) {
  944. field_metadata_offsets.push_back(idx);
  945. idx += message_generators_[i]->GenerateFieldMetadata(printer);
  946. }
  947. field_metadata_offsets.push_back(idx);
  948. printer->Outdent();
  949. printer->Print(
  950. "};\n"
  951. "const ::google::protobuf::internal::SerializationTable "
  952. "TableStruct::serialization_table[] = {\n");
  953. printer->Indent();
  954. // We rely on the order we layout the tables to match the order we
  955. // calculate them with FlattenMessagesInFile, so we check here that
  956. // these match exactly.
  957. std::vector<const Descriptor*> calculated_order =
  958. FlattenMessagesInFile(file_);
  959. GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size());
  960. for (int i = 0; i < message_generators_.size(); i++) {
  961. GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_);
  962. printer->Print(
  963. "{$num_fields$, TableStruct::field_metadata + $index$},\n",
  964. "classname", message_generators_[i]->classname_, "num_fields",
  965. SimpleItoa(field_metadata_offsets[i + 1] - field_metadata_offsets[i]),
  966. "index", SimpleItoa(field_metadata_offsets[i]));
  967. }
  968. printer->Outdent();
  969. printer->Print(
  970. "};\n"
  971. "\n");
  972. }
  973. }
  974. void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
  975. ForwardDeclarations decls;
  976. FillForwardDeclarations(&decls);
  977. decls.PrintForwardDeclarations(printer, options_);
  978. }
  979. void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) {
  980. for (int i = 0; i < package_parts_.size(); i++) {
  981. decls = decls->AddOrGetNamespace(package_parts_[i]);
  982. }
  983. // Generate enum definitions.
  984. for (int i = 0; i < enum_generators_.size(); i++) {
  985. enum_generators_[i]->FillForwardDeclaration(&decls->enums());
  986. }
  987. // Generate forward declarations of classes.
  988. for (int i = 0; i < message_generators_.size(); i++) {
  989. message_generators_[i]->FillMessageForwardDeclarations(
  990. &decls->classes());
  991. }
  992. }
  993. void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
  994. const string& filename_identifier) {
  995. // Generate top of header.
  996. printer->Print(
  997. "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
  998. "// source: $filename$\n"
  999. "\n"
  1000. "#ifndef PROTOBUF_INCLUDED_$filename_identifier$\n"
  1001. "#define PROTOBUF_INCLUDED_$filename_identifier$\n"
  1002. "\n"
  1003. "#include <string>\n",
  1004. "filename", file_->name(), "filename_identifier", filename_identifier);
  1005. printer->Print("\n");
  1006. }
  1007. void FileGenerator::GenerateBottomHeaderGuard(
  1008. io::Printer* printer, const string& filename_identifier) {
  1009. printer->Print(
  1010. "#endif // PROTOBUF_INCLUDED_$filename_identifier$\n",
  1011. "filename_identifier", filename_identifier);
  1012. }
  1013. void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
  1014. if (UsingImplicitWeakFields(file_, options_)) {
  1015. printer->Print("#include <google/protobuf/implicit_weak_message.h>\n");
  1016. }
  1017. printer->Print(
  1018. "#include <google/protobuf/stubs/common.h>\n"
  1019. "\n");
  1020. // Verify the protobuf library header version is compatible with the protoc
  1021. // version before going any further.
  1022. printer->Print(
  1023. "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
  1024. "#error This file was generated by a newer version of protoc which is\n"
  1025. "#error incompatible with your Protocol Buffer headers. Please update\n"
  1026. "#error your headers.\n"
  1027. "#endif\n"
  1028. "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
  1029. "#error This file was generated by an older version of protoc which is\n"
  1030. "#error incompatible with your Protocol Buffer headers. Please\n"
  1031. "#error regenerate this file with a newer version of protoc.\n"
  1032. "#endif\n"
  1033. "\n",
  1034. "min_header_version",
  1035. SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
  1036. "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
  1037. // OK, it's now safe to #include other files.
  1038. printer->Print(
  1039. "#include <google/protobuf/io/coded_stream.h>\n"
  1040. "#include <google/protobuf/arena.h>\n"
  1041. "#include <google/protobuf/arenastring.h>\n"
  1042. "#include <google/protobuf/generated_message_table_driven.h>\n"
  1043. "#include <google/protobuf/generated_message_util.h>\n"
  1044. "#include <google/protobuf/inlined_string_field.h>\n");
  1045. if (HasDescriptorMethods(file_, options_)) {
  1046. printer->Print(
  1047. "#include <google/protobuf/metadata.h>\n");
  1048. } else {
  1049. printer->Print(
  1050. "#include <google/protobuf/metadata_lite.h>\n");
  1051. }
  1052. if (!message_generators_.empty()) {
  1053. if (HasDescriptorMethods(file_, options_)) {
  1054. printer->Print(
  1055. "#include <google/protobuf/message.h>\n");
  1056. } else {
  1057. printer->Print(
  1058. "#include <google/protobuf/message_lite.h>\n");
  1059. }
  1060. }
  1061. printer->Print(
  1062. "#include <google/protobuf/repeated_field.h>"
  1063. " // IWYU pragma: export\n"
  1064. "#include <google/protobuf/extension_set.h>"
  1065. " // IWYU pragma: export\n");
  1066. if (HasMapFields(file_)) {
  1067. printer->Print(
  1068. "#include <google/protobuf/map.h>"
  1069. " // IWYU pragma: export\n");
  1070. if (HasDescriptorMethods(file_, options_)) {
  1071. printer->Print("#include <google/protobuf/map_entry.h>\n");
  1072. printer->Print("#include <google/protobuf/map_field_inl.h>\n");
  1073. } else {
  1074. printer->Print("#include <google/protobuf/map_entry_lite.h>\n");
  1075. printer->Print("#include <google/protobuf/map_field_lite.h>\n");
  1076. }
  1077. }
  1078. if (HasEnumDefinitions(file_)) {
  1079. if (HasDescriptorMethods(file_, options_)) {
  1080. printer->Print(
  1081. "#include <google/protobuf/generated_enum_reflection.h>\n");
  1082. } else {
  1083. printer->Print(
  1084. "#include <google/protobuf/generated_enum_util.h>\n");
  1085. }
  1086. }
  1087. if (HasGenericServices(file_, options_)) {
  1088. printer->Print(
  1089. "#include <google/protobuf/service.h>\n");
  1090. }
  1091. if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
  1092. printer->Print(
  1093. "#include <google/protobuf/unknown_field_set.h>\n");
  1094. }
  1095. if (IsAnyMessage(file_)) {
  1096. printer->Print(
  1097. "#include <google/protobuf/any.h>\n");
  1098. }
  1099. }
  1100. void FileGenerator::GenerateMetadataPragma(io::Printer* printer,
  1101. const string& info_path) {
  1102. if (!info_path.empty() && !options_.annotation_pragma_name.empty() &&
  1103. !options_.annotation_guard_name.empty()) {
  1104. printer->Print(
  1105. "#ifdef $guard$\n"
  1106. "#pragma $pragma$ \"$info_path$\"\n"
  1107. "#endif // $guard$\n",
  1108. "guard", options_.annotation_guard_name, "pragma",
  1109. options_.annotation_pragma_name, "info_path", info_path);
  1110. }
  1111. }
  1112. void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
  1113. std::set<string> public_import_names;
  1114. for (int i = 0; i < file_->public_dependency_count(); i++) {
  1115. public_import_names.insert(file_->public_dependency(i)->name());
  1116. }
  1117. for (int i = 0; i < file_->dependency_count(); i++) {
  1118. const bool use_system_include = IsWellKnownMessage(file_->dependency(i));
  1119. const string& name = file_->dependency(i)->name();
  1120. bool public_import = (public_import_names.count(name) != 0);
  1121. string basename = StripProto(name);
  1122. printer->Print(
  1123. "#include $left$$dependency$.pb.h$right$$iwyu$\n",
  1124. "dependency", basename,
  1125. "iwyu", (public_import) ? " // IWYU pragma: export" : "",
  1126. "left", use_system_include ? "<" : "\"",
  1127. "right", use_system_include ? ">" : "\"");
  1128. }
  1129. }
  1130. void FileGenerator::GenerateGlobalStateFunctionDeclarations(
  1131. io::Printer* printer) {
  1132. // Forward-declare the AddDescriptors, InitDefaults because these are called
  1133. // by .pb.cc files depending on this file.
  1134. printer->Print(
  1135. "\n"
  1136. "namespace $file_namespace$ {\n"
  1137. "// Internal implementation detail -- do not use these members.\n"
  1138. "struct $dllexport_decl$TableStruct {\n"
  1139. // These tables describe how to serialize and parse messages. Used
  1140. // for table driven code.
  1141. " static const ::google::protobuf::internal::ParseTableField entries[];\n"
  1142. " static const ::google::protobuf::internal::AuxillaryParseTableField aux[];\n"
  1143. " static const ::google::protobuf::internal::ParseTable schema[$num$];\n"
  1144. " static const ::google::protobuf::internal::FieldMetadata field_metadata[];\n"
  1145. " static const ::google::protobuf::internal::SerializationTable "
  1146. "serialization_table[];\n"
  1147. " static const ::google::protobuf::uint32 offsets[];\n"
  1148. "};\n",
  1149. "file_namespace", FileLevelNamespace(file_), "dllexport_decl",
  1150. options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ",
  1151. "num", SimpleItoa(std::max(size_t(1), message_generators_.size())));
  1152. if (HasDescriptorMethods(file_, options_)) {
  1153. printer->Print(
  1154. "void $dllexport_decl$AddDescriptors();\n", "dllexport_decl",
  1155. options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
  1156. }
  1157. printer->Print(
  1158. "} // namespace $file_namespace$\n",
  1159. "file_namespace", FileLevelNamespace(file_));
  1160. }
  1161. void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) {
  1162. // Generate class definitions.
  1163. for (int i = 0; i < message_generators_.size(); i++) {
  1164. if (i > 0) {
  1165. printer->Print("\n");
  1166. printer->Print(kThinSeparator);
  1167. printer->Print("\n");
  1168. }
  1169. message_generators_[i]->GenerateClassDefinition(printer);
  1170. }
  1171. }
  1172. void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) {
  1173. // Generate enum definitions.
  1174. for (int i = 0; i < enum_generators_.size(); i++) {
  1175. enum_generators_[i]->GenerateDefinition(printer);
  1176. }
  1177. }
  1178. void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
  1179. if (HasGenericServices(file_, options_)) {
  1180. // Generate service definitions.
  1181. for (int i = 0; i < service_generators_.size(); i++) {
  1182. if (i > 0) {
  1183. printer->Print("\n");
  1184. printer->Print(kThinSeparator);
  1185. printer->Print("\n");
  1186. }
  1187. service_generators_[i]->GenerateDeclarations(printer);
  1188. }
  1189. printer->Print("\n");
  1190. printer->Print(kThickSeparator);
  1191. printer->Print("\n");
  1192. }
  1193. }
  1194. void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) {
  1195. // Declare extension identifiers. These are in global scope and so only
  1196. // the global scope extensions.
  1197. for (int i = 0; i < file_->extension_count(); i++) {
  1198. extension_generators_owner_[i]->GenerateDeclaration(printer);
  1199. }
  1200. }
  1201. void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
  1202. // TODO(gerbens) remove pragmas when gcc is no longer used. Current version
  1203. // of gcc fires a bogus error when compiled with strict-aliasing.
  1204. printer->Print(
  1205. "#ifdef __GNUC__\n"
  1206. " #pragma GCC diagnostic push\n"
  1207. " #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n"
  1208. "#endif // __GNUC__\n");
  1209. // Generate class inline methods.
  1210. for (int i = 0; i < message_generators_.size(); i++) {
  1211. if (i > 0) {
  1212. printer->Print(kThinSeparator);
  1213. printer->Print("\n");
  1214. }
  1215. message_generators_[i]->GenerateInlineMethods(printer);
  1216. }
  1217. printer->Print(
  1218. "#ifdef __GNUC__\n"
  1219. " #pragma GCC diagnostic pop\n"
  1220. "#endif // __GNUC__\n");
  1221. for (int i = 0; i < message_generators_.size(); i++) {
  1222. if (i > 0) {
  1223. printer->Print(kThinSeparator);
  1224. printer->Print("\n");
  1225. }
  1226. }
  1227. }
  1228. void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
  1229. io::Printer* printer) {
  1230. // Emit GetEnumDescriptor specializations into google::protobuf namespace:
  1231. if (HasEnumDefinitions(file_)) {
  1232. printer->Print(
  1233. "\n"
  1234. "namespace google {\nnamespace protobuf {\n"
  1235. "\n");
  1236. for (int i = 0; i < enum_generators_.size(); i++) {
  1237. enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
  1238. }
  1239. printer->Print(
  1240. "\n"
  1241. "} // namespace protobuf\n} // namespace google\n");
  1242. }
  1243. }
  1244. } // namespace cpp
  1245. } // namespace compiler
  1246. } // namespace protobuf
  1247. } // namespace google