PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/src/google/protobuf/compiler/cpp/cpp_file.cc

http://protobuf.googlecode.com/
C++ | 652 lines | 443 code | 92 blank | 117 comment | 58 complexity | c9d8d49ebd2e0e498c9c36e945d24018 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  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 <google/protobuf/compiler/cpp/cpp_enum.h>
  35. #include <google/protobuf/compiler/cpp/cpp_service.h>
  36. #include <google/protobuf/compiler/cpp/cpp_extension.h>
  37. #include <google/protobuf/compiler/cpp/cpp_helpers.h>
  38. #include <google/protobuf/compiler/cpp/cpp_message.h>
  39. #include <google/protobuf/compiler/cpp/cpp_field.h>
  40. #include <google/protobuf/io/printer.h>
  41. #include <google/protobuf/descriptor.pb.h>
  42. #include <google/protobuf/stubs/strutil.h>
  43. namespace google {
  44. namespace protobuf {
  45. namespace compiler {
  46. namespace cpp {
  47. // ===================================================================
  48. FileGenerator::FileGenerator(const FileDescriptor* file,
  49. const Options& options)
  50. : file_(file),
  51. message_generators_(
  52. new scoped_ptr<MessageGenerator>[file->message_type_count()]),
  53. enum_generators_(
  54. new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
  55. service_generators_(
  56. new scoped_ptr<ServiceGenerator>[file->service_count()]),
  57. extension_generators_(
  58. new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
  59. options_(options) {
  60. for (int i = 0; i < file->message_type_count(); i++) {
  61. message_generators_[i].reset(
  62. new MessageGenerator(file->message_type(i), options));
  63. }
  64. for (int i = 0; i < file->enum_type_count(); i++) {
  65. enum_generators_[i].reset(
  66. new EnumGenerator(file->enum_type(i), options));
  67. }
  68. for (int i = 0; i < file->service_count(); i++) {
  69. service_generators_[i].reset(
  70. new ServiceGenerator(file->service(i), options));
  71. }
  72. for (int i = 0; i < file->extension_count(); i++) {
  73. extension_generators_[i].reset(
  74. new ExtensionGenerator(file->extension(i), options));
  75. }
  76. SplitStringUsing(file_->package(), ".", &package_parts_);
  77. }
  78. FileGenerator::~FileGenerator() {}
  79. void FileGenerator::GenerateHeader(io::Printer* printer) {
  80. string filename_identifier = FilenameIdentifier(file_->name());
  81. // Generate top of header.
  82. printer->Print(
  83. "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
  84. "// source: $filename$\n"
  85. "\n"
  86. "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
  87. "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
  88. "\n"
  89. "#include <string>\n"
  90. "\n",
  91. "filename", file_->name(),
  92. "filename_identifier", filename_identifier);
  93. printer->Print(
  94. "#include <google/protobuf/stubs/common.h>\n"
  95. "\n");
  96. // Verify the protobuf library header version is compatible with the protoc
  97. // version before going any further.
  98. printer->Print(
  99. "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
  100. "#error This file was generated by a newer version of protoc which is\n"
  101. "#error incompatible with your Protocol Buffer headers. Please update\n"
  102. "#error your headers.\n"
  103. "#endif\n"
  104. "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
  105. "#error This file was generated by an older version of protoc which is\n"
  106. "#error incompatible with your Protocol Buffer headers. Please\n"
  107. "#error regenerate this file with a newer version of protoc.\n"
  108. "#endif\n"
  109. "\n",
  110. "min_header_version",
  111. SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
  112. "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
  113. // OK, it's now safe to #include other files.
  114. printer->Print(
  115. "#include <google/protobuf/generated_message_util.h>\n");
  116. if (file_->message_type_count() > 0) {
  117. if (HasDescriptorMethods(file_)) {
  118. printer->Print(
  119. "#include <google/protobuf/message.h>\n");
  120. } else {
  121. printer->Print(
  122. "#include <google/protobuf/message_lite.h>\n");
  123. }
  124. }
  125. printer->Print(
  126. "#include <google/protobuf/repeated_field.h>\n"
  127. "#include <google/protobuf/extension_set.h>\n");
  128. if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) {
  129. printer->Print(
  130. "#include <google/protobuf/generated_enum_reflection.h>\n");
  131. }
  132. if (HasGenericServices(file_)) {
  133. printer->Print(
  134. "#include <google/protobuf/service.h>\n");
  135. }
  136. if (HasUnknownFields(file_) && file_->message_type_count() > 0) {
  137. printer->Print(
  138. "#include <google/protobuf/unknown_field_set.h>\n");
  139. }
  140. for (int i = 0; i < file_->dependency_count(); i++) {
  141. printer->Print(
  142. "#include \"$dependency$.pb.h\"\n",
  143. "dependency", StripProto(file_->dependency(i)->name()));
  144. }
  145. printer->Print(
  146. "// @@protoc_insertion_point(includes)\n");
  147. // Open namespace.
  148. GenerateNamespaceOpeners(printer);
  149. // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile
  150. // functions, so that we can declare them to be friends of each class.
  151. printer->Print(
  152. "\n"
  153. "// Internal implementation detail -- do not call these.\n"
  154. "void $dllexport_decl$ $adddescriptorsname$();\n",
  155. "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
  156. "dllexport_decl", options_.dllexport_decl);
  157. printer->Print(
  158. // Note that we don't put dllexport_decl on these because they are only
  159. // called by the .pb.cc file in which they are defined.
  160. "void $assigndescriptorsname$();\n"
  161. "void $shutdownfilename$();\n"
  162. "\n",
  163. "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
  164. "shutdownfilename", GlobalShutdownFileName(file_->name()));
  165. // Generate forward declarations of classes.
  166. for (int i = 0; i < file_->message_type_count(); i++) {
  167. message_generators_[i]->GenerateForwardDeclaration(printer);
  168. }
  169. printer->Print("\n");
  170. // Generate enum definitions.
  171. for (int i = 0; i < file_->message_type_count(); i++) {
  172. message_generators_[i]->GenerateEnumDefinitions(printer);
  173. }
  174. for (int i = 0; i < file_->enum_type_count(); i++) {
  175. enum_generators_[i]->GenerateDefinition(printer);
  176. }
  177. printer->Print(kThickSeparator);
  178. printer->Print("\n");
  179. // Generate class definitions.
  180. for (int i = 0; i < file_->message_type_count(); i++) {
  181. if (i > 0) {
  182. printer->Print("\n");
  183. printer->Print(kThinSeparator);
  184. printer->Print("\n");
  185. }
  186. message_generators_[i]->GenerateClassDefinition(printer);
  187. }
  188. printer->Print("\n");
  189. printer->Print(kThickSeparator);
  190. printer->Print("\n");
  191. if (HasGenericServices(file_)) {
  192. // Generate service definitions.
  193. for (int i = 0; i < file_->service_count(); i++) {
  194. if (i > 0) {
  195. printer->Print("\n");
  196. printer->Print(kThinSeparator);
  197. printer->Print("\n");
  198. }
  199. service_generators_[i]->GenerateDeclarations(printer);
  200. }
  201. printer->Print("\n");
  202. printer->Print(kThickSeparator);
  203. printer->Print("\n");
  204. }
  205. // Declare extension identifiers.
  206. for (int i = 0; i < file_->extension_count(); i++) {
  207. extension_generators_[i]->GenerateDeclaration(printer);
  208. }
  209. printer->Print("\n");
  210. printer->Print(kThickSeparator);
  211. printer->Print("\n");
  212. // Generate class inline methods.
  213. for (int i = 0; i < file_->message_type_count(); i++) {
  214. if (i > 0) {
  215. printer->Print(kThinSeparator);
  216. printer->Print("\n");
  217. }
  218. message_generators_[i]->GenerateInlineMethods(printer);
  219. }
  220. printer->Print(
  221. "\n"
  222. "// @@protoc_insertion_point(namespace_scope)\n");
  223. // Close up namespace.
  224. GenerateNamespaceClosers(printer);
  225. // Emit GetEnumDescriptor specializations into google::protobuf namespace:
  226. if (HasDescriptorMethods(file_)) {
  227. // The SWIG conditional is to avoid a null-pointer dereference
  228. // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
  229. // namespace X { void Y<Z::W>(); }
  230. // which appears in GetEnumDescriptor() specializations.
  231. printer->Print(
  232. "\n"
  233. "#ifndef SWIG\n"
  234. "namespace google {\nnamespace protobuf {\n"
  235. "\n");
  236. for (int i = 0; i < file_->message_type_count(); i++) {
  237. message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
  238. }
  239. for (int i = 0; i < file_->enum_type_count(); i++) {
  240. enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
  241. }
  242. printer->Print(
  243. "\n"
  244. "} // namespace google\n} // namespace protobuf\n"
  245. "#endif // SWIG\n");
  246. }
  247. printer->Print(
  248. "\n"
  249. "// @@protoc_insertion_point(global_scope)\n"
  250. "\n");
  251. printer->Print(
  252. "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
  253. "filename_identifier", filename_identifier);
  254. }
  255. void FileGenerator::GenerateSource(io::Printer* printer) {
  256. printer->Print(
  257. "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
  258. "// source: $filename$\n"
  259. "\n"
  260. // The generated code calls accessors that might be deprecated. We don't
  261. // want the compiler to warn in generated code.
  262. "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
  263. "#include \"$basename$.pb.h\"\n"
  264. "\n"
  265. "#include <algorithm>\n" // for swap()
  266. "\n"
  267. "#include <google/protobuf/stubs/common.h>\n"
  268. "#include <google/protobuf/stubs/once.h>\n"
  269. "#include <google/protobuf/io/coded_stream.h>\n"
  270. "#include <google/protobuf/wire_format_lite_inl.h>\n",
  271. "filename", file_->name(),
  272. "basename", StripProto(file_->name()));
  273. if (HasDescriptorMethods(file_)) {
  274. printer->Print(
  275. "#include <google/protobuf/descriptor.h>\n"
  276. "#include <google/protobuf/generated_message_reflection.h>\n"
  277. "#include <google/protobuf/reflection_ops.h>\n"
  278. "#include <google/protobuf/wire_format.h>\n");
  279. }
  280. printer->Print(
  281. "// @@protoc_insertion_point(includes)\n");
  282. GenerateNamespaceOpeners(printer);
  283. if (HasDescriptorMethods(file_)) {
  284. printer->Print(
  285. "\n"
  286. "namespace {\n"
  287. "\n");
  288. for (int i = 0; i < file_->message_type_count(); i++) {
  289. message_generators_[i]->GenerateDescriptorDeclarations(printer);
  290. }
  291. for (int i = 0; i < file_->enum_type_count(); i++) {
  292. printer->Print(
  293. "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
  294. "name", ClassName(file_->enum_type(i), false));
  295. }
  296. if (HasGenericServices(file_)) {
  297. for (int i = 0; i < file_->service_count(); i++) {
  298. printer->Print(
  299. "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
  300. "name", file_->service(i)->name());
  301. }
  302. }
  303. printer->Print(
  304. "\n"
  305. "} // namespace\n"
  306. "\n");
  307. }
  308. // Define our externally-visible BuildDescriptors() function. (For the lite
  309. // library, all this does is initialize default instances.)
  310. GenerateBuildDescriptors(printer);
  311. // Generate enums.
  312. for (int i = 0; i < file_->enum_type_count(); i++) {
  313. enum_generators_[i]->GenerateMethods(printer);
  314. }
  315. // Generate classes.
  316. for (int i = 0; i < file_->message_type_count(); i++) {
  317. printer->Print("\n");
  318. printer->Print(kThickSeparator);
  319. printer->Print("\n");
  320. message_generators_[i]->GenerateClassMethods(printer);
  321. }
  322. if (HasGenericServices(file_)) {
  323. // Generate services.
  324. for (int i = 0; i < file_->service_count(); i++) {
  325. if (i == 0) printer->Print("\n");
  326. printer->Print(kThickSeparator);
  327. printer->Print("\n");
  328. service_generators_[i]->GenerateImplementation(printer);
  329. }
  330. }
  331. // Define extensions.
  332. for (int i = 0; i < file_->extension_count(); i++) {
  333. extension_generators_[i]->GenerateDefinition(printer);
  334. }
  335. printer->Print(
  336. "\n"
  337. "// @@protoc_insertion_point(namespace_scope)\n");
  338. GenerateNamespaceClosers(printer);
  339. printer->Print(
  340. "\n"
  341. "// @@protoc_insertion_point(global_scope)\n");
  342. }
  343. void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
  344. // AddDescriptors() is a file-level procedure which adds the encoded
  345. // FileDescriptorProto for this .proto file to the global DescriptorPool for
  346. // generated files (DescriptorPool::generated_pool()). It either runs at
  347. // static initialization time (by default) or when default_instance() is
  348. // called for the first time (in LITE_RUNTIME mode with
  349. // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
  350. // constructs default instances and registers extensions.
  351. //
  352. // Its sibling, AssignDescriptors(), actually pulls the compiled
  353. // FileDescriptor from the DescriptorPool and uses it to populate all of
  354. // the global variables which store pointers to the descriptor objects.
  355. // It also constructs the reflection objects. It is called the first time
  356. // anyone calls descriptor() or GetReflection() on one of the types defined
  357. // in the file.
  358. // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
  359. // and we only use AddDescriptors() to allocate default instances.
  360. if (HasDescriptorMethods(file_)) {
  361. printer->Print(
  362. "\n"
  363. "void $assigndescriptorsname$() {\n",
  364. "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
  365. printer->Indent();
  366. // Make sure the file has found its way into the pool. If a descriptor
  367. // is requested *during* static init then AddDescriptors() may not have
  368. // been called yet, so we call it manually. Note that it's fine if
  369. // AddDescriptors() is called multiple times.
  370. printer->Print(
  371. "$adddescriptorsname$();\n",
  372. "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
  373. // Get the file's descriptor from the pool.
  374. printer->Print(
  375. "const ::google::protobuf::FileDescriptor* file =\n"
  376. " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
  377. " \"$filename$\");\n"
  378. // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
  379. // being unused when compiling an empty .proto file.
  380. "GOOGLE_CHECK(file != NULL);\n",
  381. "filename", file_->name());
  382. // Go through all the stuff defined in this file and generated code to
  383. // assign the global descriptor pointers based on the file descriptor.
  384. for (int i = 0; i < file_->message_type_count(); i++) {
  385. message_generators_[i]->GenerateDescriptorInitializer(printer, i);
  386. }
  387. for (int i = 0; i < file_->enum_type_count(); i++) {
  388. enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
  389. }
  390. if (HasGenericServices(file_)) {
  391. for (int i = 0; i < file_->service_count(); i++) {
  392. service_generators_[i]->GenerateDescriptorInitializer(printer, i);
  393. }
  394. }
  395. printer->Outdent();
  396. printer->Print(
  397. "}\n"
  398. "\n");
  399. // ---------------------------------------------------------------
  400. // protobuf_AssignDescriptorsOnce(): The first time it is called, calls
  401. // AssignDescriptors(). All later times, waits for the first call to
  402. // complete and then returns.
  403. printer->Print(
  404. "namespace {\n"
  405. "\n"
  406. "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
  407. "inline void protobuf_AssignDescriptorsOnce() {\n"
  408. " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
  409. " &$assigndescriptorsname$);\n"
  410. "}\n"
  411. "\n",
  412. "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
  413. // protobuf_RegisterTypes(): Calls
  414. // MessageFactory::InternalRegisterGeneratedType() for each message type.
  415. printer->Print(
  416. "void protobuf_RegisterTypes(const ::std::string&) {\n"
  417. " protobuf_AssignDescriptorsOnce();\n");
  418. printer->Indent();
  419. for (int i = 0; i < file_->message_type_count(); i++) {
  420. message_generators_[i]->GenerateTypeRegistrations(printer);
  421. }
  422. printer->Outdent();
  423. printer->Print(
  424. "}\n"
  425. "\n"
  426. "} // namespace\n");
  427. }
  428. // -----------------------------------------------------------------
  429. // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown.
  430. printer->Print(
  431. "\n"
  432. "void $shutdownfilename$() {\n",
  433. "shutdownfilename", GlobalShutdownFileName(file_->name()));
  434. printer->Indent();
  435. for (int i = 0; i < file_->message_type_count(); i++) {
  436. message_generators_[i]->GenerateShutdownCode(printer);
  437. }
  438. printer->Outdent();
  439. printer->Print(
  440. "}\n\n");
  441. // -----------------------------------------------------------------
  442. // Now generate the AddDescriptors() function.
  443. PrintHandlingOptionalStaticInitializers(
  444. file_, printer,
  445. // With static initializers.
  446. // Note that we don't need any special synchronization in the following code
  447. // because it is called at static init time before any threads exist.
  448. "void $adddescriptorsname$() {\n"
  449. " static bool already_here = false;\n"
  450. " if (already_here) return;\n"
  451. " already_here = true;\n"
  452. " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
  453. "\n",
  454. // Without.
  455. "void $adddescriptorsname$_impl() {\n"
  456. " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
  457. "\n",
  458. // Vars.
  459. "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
  460. printer->Indent();
  461. // Call the AddDescriptors() methods for all of our dependencies, to make
  462. // sure they get added first.
  463. for (int i = 0; i < file_->dependency_count(); i++) {
  464. const FileDescriptor* dependency = file_->dependency(i);
  465. // Print the namespace prefix for the dependency.
  466. vector<string> dependency_package_parts;
  467. SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
  468. printer->Print("::");
  469. for (int j = 0; j < dependency_package_parts.size(); j++) {
  470. printer->Print("$name$::",
  471. "name", dependency_package_parts[j]);
  472. }
  473. // Call its AddDescriptors function.
  474. printer->Print(
  475. "$name$();\n",
  476. "name", GlobalAddDescriptorsName(dependency->name()));
  477. }
  478. if (HasDescriptorMethods(file_)) {
  479. // Embed the descriptor. We simply serialize the entire FileDescriptorProto
  480. // and embed it as a string literal, which is parsed and built into real
  481. // descriptors at initialization time.
  482. FileDescriptorProto file_proto;
  483. file_->CopyTo(&file_proto);
  484. string file_data;
  485. file_proto.SerializeToString(&file_data);
  486. printer->Print(
  487. "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
  488. // Only write 40 bytes per line.
  489. static const int kBytesPerLine = 40;
  490. for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
  491. printer->Print("\n \"$data$\"",
  492. "data",
  493. EscapeTrigraphs(
  494. CEscape(file_data.substr(i, kBytesPerLine))));
  495. }
  496. printer->Print(
  497. ", $size$);\n",
  498. "size", SimpleItoa(file_data.size()));
  499. // Call MessageFactory::InternalRegisterGeneratedFile().
  500. printer->Print(
  501. "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
  502. " \"$filename$\", &protobuf_RegisterTypes);\n",
  503. "filename", file_->name());
  504. }
  505. // Allocate and initialize default instances. This can't be done lazily
  506. // since default instances are returned by simple accessors and are used with
  507. // extensions. Speaking of which, we also register extensions at this time.
  508. for (int i = 0; i < file_->message_type_count(); i++) {
  509. message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
  510. }
  511. for (int i = 0; i < file_->extension_count(); i++) {
  512. extension_generators_[i]->GenerateRegistration(printer);
  513. }
  514. for (int i = 0; i < file_->message_type_count(); i++) {
  515. message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
  516. }
  517. printer->Print(
  518. "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
  519. "shutdownfilename", GlobalShutdownFileName(file_->name()));
  520. printer->Outdent();
  521. printer->Print(
  522. "}\n"
  523. "\n");
  524. PrintHandlingOptionalStaticInitializers(
  525. file_, printer,
  526. // With static initializers.
  527. "// Force AddDescriptors() to be called at static initialization time.\n"
  528. "struct StaticDescriptorInitializer_$filename$ {\n"
  529. " StaticDescriptorInitializer_$filename$() {\n"
  530. " $adddescriptorsname$();\n"
  531. " }\n"
  532. "} static_descriptor_initializer_$filename$_;\n",
  533. // Without.
  534. "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
  535. "void $adddescriptorsname$() {\n"
  536. " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
  537. " &$adddescriptorsname$_impl);\n"
  538. "}\n",
  539. // Vars.
  540. "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
  541. "filename", FilenameIdentifier(file_->name()));
  542. }
  543. void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
  544. if (package_parts_.size() > 0) printer->Print("\n");
  545. for (int i = 0; i < package_parts_.size(); i++) {
  546. printer->Print("namespace $part$ {\n",
  547. "part", package_parts_[i]);
  548. }
  549. }
  550. void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
  551. if (package_parts_.size() > 0) printer->Print("\n");
  552. for (int i = package_parts_.size() - 1; i >= 0; i--) {
  553. printer->Print("} // namespace $part$\n",
  554. "part", package_parts_[i]);
  555. }
  556. }
  557. } // namespace cpp
  558. } // namespace compiler
  559. } // namespace protobuf
  560. } // namespace google