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