// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <google/protobuf/compiler/cpp/cpp_file.h>
#include <map>
#include <memory>
#include <set>
#include <vector>

#include <google/protobuf/compiler/cpp/cpp_enum.h>
#include <google/protobuf/compiler/cpp/cpp_extension.h>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/compiler/cpp/cpp_message.h>
#include <google/protobuf/compiler/cpp/cpp_service.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {

FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
    : file_(file),
      options_(options),
      scc_analyzer_(options),
      enum_generators_owner_(
          new std::unique_ptr<EnumGenerator>[file->enum_type_count()]),
      service_generators_owner_(
          new std::unique_ptr<ServiceGenerator>[file->service_count()]),
      extension_generators_owner_(
          new std::unique_ptr<ExtensionGenerator>[file->extension_count()]) {
  std::vector<const Descriptor*> msgs = FlattenMessagesInFile(file);
  for (int i = 0; i < msgs.size(); i++) {
    // Deleted in destructor
    MessageGenerator* msg_gen =
        new MessageGenerator(msgs[i], i, options, &scc_analyzer_);
    message_generators_.push_back(msg_gen);
    msg_gen->AddGenerators(&enum_generators_, &extension_generators_);
  }

  for (int i = 0; i < file->enum_type_count(); i++) {
    enum_generators_owner_[i].reset(
        new EnumGenerator(file->enum_type(i), options));
    enum_generators_.push_back(enum_generators_owner_[i].get());
  }

  for (int i = 0; i < file->service_count(); i++) {
    service_generators_owner_[i].reset(
        new ServiceGenerator(file->service(i), options));
    service_generators_.push_back(service_generators_owner_[i].get());
  }
  if (HasGenericServices(file_, options_)) {
    for (int i = 0; i < service_generators_.size(); i++) {
      service_generators_[i]->index_in_metadata_ = i;
    }
  }

  for (int i = 0; i < file->extension_count(); i++) {
    extension_generators_owner_[i].reset(
        new ExtensionGenerator(file->extension(i), options));
    extension_generators_.push_back(extension_generators_owner_[i].get());
  }


  package_parts_ = Split(file_->package(), ".", true);
}

FileGenerator::~FileGenerator() {
  for (int i = 0; i < message_generators_.size(); i++) {
    delete message_generators_[i];
  }
}

void FileGenerator::GenerateMacroUndefs(io::Printer* printer) {
  // Only do this for protobuf's own types. There are some google3 protos using
  // macros as field names and the generated code compiles after the macro
  // expansion. Undefing these macros actually breaks such code.
  if (file_->name() != "google/protobuf/compiler/plugin.proto") {
    return;
  }
  std::vector<string> names_to_undef;
  std::vector<const FieldDescriptor*> fields;
  ListAllFields(file_, &fields);
  for (int i = 0; i < fields.size(); i++) {
    const string& name = fields[i]->name();
    static const char* kMacroNames[] = {"major", "minor"};
    for (int i = 0; i < GOOGLE_ARRAYSIZE(kMacroNames); ++i) {
      if (name == kMacroNames[i]) {
        names_to_undef.push_back(name);
        break;
      }
    }
  }
  for (int i = 0; i < names_to_undef.size(); ++i) {
    printer->Print(
        "#ifdef $name$\n"
        "#undef $name$\n"
        "#endif\n",
        "name", names_to_undef[i]);
  }
}

void FileGenerator::GenerateHeader(io::Printer* printer) {
  printer->Print(
    "// @@protoc_insertion_point(includes)\n");

  printer->Print("#define PROTOBUF_INTERNAL_EXPORT_$filename$ $export$\n",
                 "filename", FileLevelNamespace(file_),
                 "export", options_.dllexport_decl);
  GenerateMacroUndefs(printer);

  GenerateGlobalStateFunctionDeclarations(printer);

  GenerateForwardDeclarations(printer);

  {
    NamespaceOpener ns(Namespace(file_), printer);

    printer->Print("\n");

    GenerateEnumDefinitions(printer);

    printer->Print(kThickSeparator);
    printer->Print("\n");

    GenerateMessageDefinitions(printer);

    printer->Print("\n");
    printer->Print(kThickSeparator);
    printer->Print("\n");

    GenerateServiceDefinitions(printer);

    GenerateExtensionIdentifiers(printer);

    printer->Print("\n");
    printer->Print(kThickSeparator);
    printer->Print("\n");

    GenerateInlineFunctionDefinitions(printer);

    printer->Print(
      "\n"
      "// @@protoc_insertion_point(namespace_scope)\n"
      "\n");
  }

  // We need to specialize some templates in the ::google::protobuf namespace:
  GenerateProto2NamespaceEnumSpecializations(printer);

  printer->Print(
    "\n"
    "// @@protoc_insertion_point(global_scope)\n"
    "\n");
}

void FileGenerator::GenerateProtoHeader(io::Printer* printer,
                                        const string& info_path) {
  if (!options_.proto_h) {
    return;
  }

  string filename_identifier = FilenameIdentifier(file_->name());
  GenerateTopHeaderGuard(printer, filename_identifier);


  GenerateLibraryIncludes(printer);

  for (int i = 0; i < file_->public_dependency_count(); i++) {
    const FileDescriptor* dep = file_->public_dependency(i);
    const char* extension = ".proto.h";
    string dependency = StripProto(dep->name()) + extension;
    printer->Print(
      "#include \"$dependency$\"  // IWYU pragma: export\n",
      "dependency", dependency);
  }

  GenerateMetadataPragma(printer, info_path);

  GenerateHeader(printer);

  GenerateBottomHeaderGuard(printer, filename_identifier);
}

void FileGenerator::GeneratePBHeader(io::Printer* printer,
                                     const string& info_path) {
  string filename_identifier =
      FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : ""));
  GenerateTopHeaderGuard(printer, filename_identifier);

  if (options_.proto_h) {
    string target_basename = StripProto(file_->name());
    printer->Print("#include \"$basename$.proto.h\"  // IWYU pragma: export\n",
                   "basename", target_basename);
  } else {
    GenerateLibraryIncludes(printer);
  }

  GenerateDependencyIncludes(printer);
  GenerateMetadataPragma(printer, info_path);

  if (!options_.proto_h) {
    GenerateHeader(printer);
  } else {
    // This is unfortunately necessary for some plugins. I don't see why we
    // need two of the same insertion points.
    // TODO(gerbens) remove this.
    printer->Print(
      "// @@protoc_insertion_point(includes)\n");
    {
      NamespaceOpener ns(Namespace(file_), printer);
      printer->Print(
        "\n"
        "// @@protoc_insertion_point(namespace_scope)\n");
    }
    printer->Print(
      "\n"
      "// @@protoc_insertion_point(global_scope)\n"
      "\n");
  }

  GenerateBottomHeaderGuard(printer, filename_identifier);
}

void FileGenerator::GenerateSourceIncludes(io::Printer* printer) {
  string target_basename = StripProto(file_->name());
  const bool use_system_include = IsWellKnownMessage(file_);

  string header = target_basename + (options_.proto_h ? ".proto.h" : ".pb.h");
  printer->Print(
    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
    "// source: $filename$\n"
    "\n"
    "#include $left$$header$$right$\n"
    "\n"
    "#include <algorithm>\n"    // for swap()
    "\n"
    "#include <google/protobuf/stubs/common.h>\n"
    "#include <google/protobuf/stubs/port.h>\n"
    "#include <google/protobuf/io/coded_stream.h>\n"
    "#include <google/protobuf/wire_format_lite_inl.h>\n",
    "filename", file_->name(),
    "header", header,
    "left", use_system_include ? "<" : "\"",
    "right", use_system_include ? ">" : "\"");

  // Unknown fields implementation in lite mode uses StringOutputStream
  if (!UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
    printer->Print(
      "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
  }

  if (HasDescriptorMethods(file_, options_)) {
    printer->Print(
      "#include <google/protobuf/descriptor.h>\n"
      "#include <google/protobuf/generated_message_reflection.h>\n"
      "#include <google/protobuf/reflection_ops.h>\n"
      "#include <google/protobuf/wire_format.h>\n");
  }

  if (options_.proto_h) {
    // Use the smaller .proto.h files.
    for (int i = 0; i < file_->dependency_count(); i++) {
      const FileDescriptor* dep = file_->dependency(i);
      const char* extension = ".proto.h";
      string basename = StripProto(dep->name());
      string dependency = basename + extension;
      printer->Print(
          "#include \"$dependency$\"\n",
          "dependency", dependency);
    }
  }

  // TODO(gerbens) Remove this when all code in google is using the same
  // proto library. This is a temporary hack to force build errors if
  // the proto library is compiled with GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS
  // and is also linking internal proto2. This is to prevent regressions while
  // we work cleaning up the code base. After this is completed and we have
  // one proto lib all code uses this should be removed.
  printer->Print(
    "// This is a temporary google only hack\n"
    "#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS\n"
    "#include \"third_party/protobuf/version.h\"\n"
    "#endif\n");

  printer->Print(
    "// @@protoc_insertion_point(includes)\n");
}

void FileGenerator::GenerateSourceDefaultInstance(int idx,
                                                  io::Printer* printer) {
  printer->Print(
      "class $classname$DefaultTypeInternal {\n"
      " public:\n"
      "  ::google::protobuf::internal::ExplicitlyConstructed<$classname$>\n"
      "      _instance;\n",
      "classname", message_generators_[idx]->classname_);
  printer->Indent();
  message_generators_[idx]->GenerateExtraDefaultFields(printer);
  printer->Outdent();
  printer->Print("} _$classname$_default_instance_;\n", "classname",
                 message_generators_[idx]->classname_);
}

namespace {

// Generates weak symbol declarations for types that are to be considered weakly
// referenced.
void GenerateInternalForwardDeclarations(
    const std::vector<const FieldDescriptor*>& fields, const Options& options,
    SCCAnalyzer* scc_analyzer, io::Printer* printer) {
  // To ensure determinism and minimize the number of namespace statements,
  // we output the forward declarations sorted on namespace and type / function
  // name.
  std::set<std::pair<string, string> > messages;
  std::set<std::pair<string, string> > sccs;
  std::set<std::pair<string, string> > inits;
  for (int i = 0; i < fields.size(); ++i) {
    const FieldDescriptor* field = fields[i];
    const Descriptor* msg = field->message_type();
    if (msg == nullptr) continue;
    bool is_weak = IsImplicitWeakField(field, options, scc_analyzer);
    string flns = FileLevelNamespace(msg);
    auto scc = scc_analyzer->GetSCC(msg);
    string repr = ClassName(scc->GetRepresentative());
    string weak_attr;
    if (is_weak) {
      inits.insert(std::make_pair(flns, "AddDescriptors"));
      messages.insert(std::make_pair(Namespace(msg), ClassName(msg)));
      weak_attr = " __attribute__((weak))";
    }
    string dllexport = "PROTOBUF_INTERNAL_EXPORT_" + FileLevelNamespace(msg);
    sccs.insert(std::make_pair(flns, "extern " + dllexport + weak_attr +
                                     " ::google::protobuf::internal::SCCInfo<" +
                                     SimpleItoa(scc->children.size()) +
                                     "> scc_info_" + repr + ";\n"));
  }

  printer->Print("\n");
  NamespaceOpener ns(printer);
  for (std::set<std::pair<string, string> >::const_iterator it =
           messages.begin();
       it != messages.end(); ++it) {
    ns.ChangeTo(it->first);
    printer->Print(
        "extern __attribute__((weak)) $classname$DefaultTypeInternal "
        "_$classname$_default_instance_;\n",
        "classname", it->second);
  }
  for (std::set<std::pair<string, string> >::const_iterator it = inits.begin();
       it != inits.end(); ++it) {
    ns.ChangeTo(it->first);
    printer->Print("void $name$() __attribute__((weak));\n",
                   "name", it->second);
  }
  for (const auto& p : sccs) {
    ns.ChangeTo(p.first);
    printer->Print(p.second.c_str());
  }
}

}  // namespace

void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* printer) {
  GenerateSourceIncludes(printer);

  // Generate weak declarations. We do this for the whole strongly-connected
  // component (SCC), because we have a single InitDefaults* function for the
  // SCC.
  std::vector<const FieldDescriptor*> fields;
  for (const Descriptor* message :
       scc_analyzer_.GetSCC(message_generators_[idx]->descriptor_)
           ->descriptors) {
    ListAllFields(message, &fields);
  }
  GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_,
                                      printer);

  if (IsSCCRepresentative(message_generators_[idx]->descriptor_)) {
    NamespaceOpener ns(FileLevelNamespace(file_), printer);
    GenerateInitForSCC(GetSCC(message_generators_[idx]->descriptor_), printer);
  }

  {  // package namespace
    NamespaceOpener ns(Namespace(file_), printer);

    // Define default instances
    GenerateSourceDefaultInstance(idx, printer);
    if (options_.lite_implicit_weak_fields) {
      printer->Print("void $classname$_ReferenceStrong() {}\n", "classname",
                     message_generators_[idx]->classname_);
    }

    // Generate classes.
    printer->Print("\n");
    message_generators_[idx]->GenerateClassMethods(printer);

    printer->Print(
        "\n"
        "// @@protoc_insertion_point(namespace_scope)\n");
  }  // end package namespace

  printer->Print(
      "namespace google {\nnamespace protobuf {\n");
  message_generators_[idx]->GenerateSourceInProto2Namespace(printer);
  printer->Print(
      "}  // namespace protobuf\n}  // namespace google\n");

  printer->Print(
      "\n"
      "// @@protoc_insertion_point(global_scope)\n");
}

void FileGenerator::GenerateGlobalSource(io::Printer* printer) {
  GenerateSourceIncludes(printer);

  {
    NamespaceOpener ns(FileLevelNamespace(file_), printer);
    GenerateTables(printer);

    // Define the code to initialize reflection. This code uses a global
    // constructor to register reflection data with the runtime pre-main.
    if (HasDescriptorMethods(file_, options_)) {
      GenerateReflectionInitializationCode(printer);
    }
  }

  NamespaceOpener ns(Namespace(file_), printer);

  // Generate enums.
  for (int i = 0; i < enum_generators_.size(); i++) {
    enum_generators_[i]->GenerateMethods(i, printer);
  }

  // Define extensions.
  for (int i = 0; i < extension_generators_.size(); i++) {
    extension_generators_[i]->GenerateDefinition(printer);
  }

  if (HasGenericServices(file_, options_)) {
    // Generate services.
    for (int i = 0; i < service_generators_.size(); i++) {
      if (i == 0) printer->Print("\n");
      printer->Print(kThickSeparator);
      printer->Print("\n");
      service_generators_[i]->GenerateImplementation(printer);
    }
  }
}

void FileGenerator::GenerateSource(io::Printer* printer) {
  GenerateSourceIncludes(printer);
  std::vector<const FieldDescriptor*> fields;
  ListAllFields(file_, &fields);
  GenerateInternalForwardDeclarations(fields, options_, &scc_analyzer_,
                                      printer);

  {
    NamespaceOpener ns(Namespace(file_), printer);

    // Define default instances
    for (int i = 0; i < message_generators_.size(); i++) {
      GenerateSourceDefaultInstance(i, printer);
      if (options_.lite_implicit_weak_fields) {
        printer->Print("void $classname$_ReferenceStrong() {}\n", "classname",
                       message_generators_[i]->classname_);
      }
    }
  }

  {
    NamespaceOpener ns(FileLevelNamespace(file_), printer);
    GenerateTables(printer);

    // Now generate the InitDefaults for each SCC.
    for (int i = 0; i < message_generators_.size(); i++) {
      if (IsSCCRepresentative(message_generators_[i]->descriptor_)) {
        GenerateInitForSCC(GetSCC(message_generators_[i]->descriptor_),
                           printer);
      }
    }

    printer->Print("void InitDefaults() {\n");
    for (int i = 0; i < message_generators_.size(); i++) {
      if (!IsSCCRepresentative(message_generators_[i]->descriptor_)) continue;
      string scc_name = ClassName(message_generators_[i]->descriptor_);
      printer->Print(
          "  ::google::protobuf::internal::InitSCC(&scc_info_$scc_name$.base);\n",
          "scc_name", scc_name);
    }
    printer->Print("}\n\n");

    // Define the code to initialize reflection. This code uses a global
    // constructor to register reflection data with the runtime pre-main.
    if (HasDescriptorMethods(file_, options_)) {
      GenerateReflectionInitializationCode(printer);
    }
  }


  {
    NamespaceOpener ns(Namespace(file_), printer);

    // Actually implement the protos

    // Generate enums.
    for (int i = 0; i < enum_generators_.size(); i++) {
      enum_generators_[i]->GenerateMethods(i, printer);
    }

    // Generate classes.
    for (int i = 0; i < message_generators_.size(); i++) {
      printer->Print("\n");
      printer->Print(kThickSeparator);
      printer->Print("\n");
      message_generators_[i]->GenerateClassMethods(printer);
    }

    if (HasGenericServices(file_, options_)) {
      // Generate services.
      for (int i = 0; i < service_generators_.size(); i++) {
        if (i == 0) printer->Print("\n");
        printer->Print(kThickSeparator);
        printer->Print("\n");
        service_generators_[i]->GenerateImplementation(printer);
      }
    }

    // Define extensions.
    for (int i = 0; i < extension_generators_.size(); i++) {
      extension_generators_[i]->GenerateDefinition(printer);
    }

    printer->Print(
      "\n"
      "// @@protoc_insertion_point(namespace_scope)\n");
  }

  printer->Print(
      "namespace google {\nnamespace protobuf {\n");
  for (int i = 0; i < message_generators_.size(); i++) {
    message_generators_[i]->GenerateSourceInProto2Namespace(printer);
  }
  printer->Print(
      "}  // namespace protobuf\n}  // namespace google\n");

  printer->Print(
    "\n"
    "// @@protoc_insertion_point(global_scope)\n");
}

class FileGenerator::ForwardDeclarations {
 public:
  ~ForwardDeclarations() {
    for (std::map<string, ForwardDeclarations*>::iterator
             it = namespaces_.begin(),
             end = namespaces_.end();
         it != end; ++it) {
      delete it->second;
    }
    namespaces_.clear();
  }

  ForwardDeclarations* AddOrGetNamespace(const string& ns_name) {
    ForwardDeclarations*& ns = namespaces_[ns_name];
    if (ns == nullptr) {
      ns = new ForwardDeclarations;
    }
    return ns;
  }

  std::map<string, const Descriptor*>& classes() { return classes_; }
  std::map<string, const EnumDescriptor*>& enums() { return enums_; }

  void PrintForwardDeclarations(io::Printer* printer,
                                const Options& options) const {
    PrintNestedDeclarations(printer, options);
    PrintTopLevelDeclarations(printer, options);
  }


 private:
  void PrintNestedDeclarations(io::Printer* printer,
                               const Options& options) const {
    PrintDeclarationsInsideNamespace(printer, options);
    for (std::map<string, ForwardDeclarations *>::const_iterator
             it = namespaces_.begin(),
             end = namespaces_.end();
         it != end; ++it) {
      printer->Print("namespace $nsname$ {\n",
                     "nsname", it->first);
      it->second->PrintNestedDeclarations(printer, options);
      printer->Print("}  // namespace $nsname$\n",
                     "nsname", it->first);
    }
  }

  void PrintTopLevelDeclarations(io::Printer* printer,
                                 const Options& options) const {
    PrintDeclarationsOutsideNamespace(printer, options);
    for (std::map<string, ForwardDeclarations *>::const_iterator
             it = namespaces_.begin(),
             end = namespaces_.end();
         it != end; ++it) {
      it->second->PrintTopLevelDeclarations(printer, options);
    }
  }

  void PrintDeclarationsInsideNamespace(io::Printer* printer,
                                        const Options& options) const {
    for (std::map<string, const EnumDescriptor *>::const_iterator
             it = enums_.begin(),
             end = enums_.end();
         it != end; ++it) {
      printer->Print("enum $enumname$ : int;\n", "enumname", it->first);
      printer->Annotate("enumname", it->second);
      printer->Print("bool $enumname$_IsValid(int value);\n", "enumname",
                     it->first);
    }
    for (std::map<string, const Descriptor*>::const_iterator
             it = classes_.begin(),
             end = classes_.end();
         it != end; ++it) {
      printer->Print("class $classname$;\n", "classname", it->first);
      printer->Annotate("classname", it->second);

      printer->Print(
          "class $classname$DefaultTypeInternal;\n"
          "$dllexport_decl$"
          "extern $classname$DefaultTypeInternal "
          "_$classname$_default_instance_;\n",  // NOLINT
          "dllexport_decl",
          options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ",
          "classname",
          it->first);
      if (options.lite_implicit_weak_fields) {
        printer->Print("void $classname$_ReferenceStrong();\n",
                       "classname", it->first);
      }
    }
  }

  void PrintDeclarationsOutsideNamespace(io::Printer* printer,
                                         const Options& options) const {
    if (classes_.size() == 0) return;

    printer->Print(
        "namespace google {\nnamespace protobuf {\n");
    for (std::map<string, const Descriptor*>::const_iterator
             it = classes_.begin(),
             end = classes_.end();
         it != end; ++it) {
      const Descriptor* d = it->second;
      printer->Print(
          "template<> "
          "$dllexport_decl$"
          "$classname$* Arena::CreateMaybeMessage<$classname$>"
          "(Arena*);\n",
          "classname", QualifiedClassName(d), "dllexport_decl",
          options.dllexport_decl.empty() ? "" : options.dllexport_decl + " ");
    }
    printer->Print(
        "}  // namespace protobuf\n}  // namespace google\n");
  }

  std::map<string, ForwardDeclarations*> namespaces_;
  std::map<string, const Descriptor*> classes_;
  std::map<string, const EnumDescriptor*> enums_;
};

void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
  // AddDescriptors() is a file-level procedure which adds the encoded
  // FileDescriptorProto for this .proto file to the global DescriptorPool for
  // generated files (DescriptorPool::generated_pool()). It ordinarily runs at
  // static initialization time, but is not used at all in LITE_RUNTIME mode.
  //
  // Its sibling, AssignDescriptors(), actually pulls the compiled
  // FileDescriptor from the DescriptorPool and uses it to populate all of
  // the global variables which store pointers to the descriptor objects.
  // It also constructs the reflection objects.  It is called the first time
  // anyone calls descriptor() or GetReflection() on one of the types defined
  // in the file.

  if (!message_generators_.empty()) {
    printer->Print("::google::protobuf::Metadata file_level_metadata[$size$];\n", "size",
                   SimpleItoa(message_generators_.size()));
  }
  if (!enum_generators_.empty()) {
    printer->Print(
        "const ::google::protobuf::EnumDescriptor* "
        "file_level_enum_descriptors[$size$];\n",
        "size", SimpleItoa(enum_generators_.size()));
  }
  if (HasGenericServices(file_, options_) && file_->service_count() > 0) {
    printer->Print(
        "const ::google::protobuf::ServiceDescriptor* "
        "file_level_service_descriptors[$size$];\n",
        "size", SimpleItoa(file_->service_count()));
  }

  if (!message_generators_.empty()) {
    printer->Print(
        "\n"
        "const ::google::protobuf::uint32 TableStruct::offsets[] "
        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
    printer->Indent();
    std::vector<std::pair<size_t, size_t> > pairs;
    pairs.reserve(message_generators_.size());
    for (int i = 0; i < message_generators_.size(); i++) {
      pairs.push_back(message_generators_[i]->GenerateOffsets(printer));
    }
    printer->Outdent();
    printer->Print(
        "};\n"
        "static const ::google::protobuf::internal::MigrationSchema schemas[] "
        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
    printer->Indent();
    {
      int offset = 0;
      for (int i = 0; i < message_generators_.size(); i++) {
        message_generators_[i]->GenerateSchema(printer, offset,
                                               pairs[i].second);
        offset += pairs[i].first;
      }
    }
    printer->Outdent();
    printer->Print(
        "};\n"
        "\nstatic "
        "::google::protobuf::Message const * const file_default_instances[] = {\n");
    printer->Indent();
    for (int i = 0; i < message_generators_.size(); i++) {
      const Descriptor* descriptor = message_generators_[i]->descriptor_;
      printer->Print(
          "reinterpret_cast<const "
          "::google::protobuf::Message*>(&$ns$::_$classname$_default_instance_),\n",
          "classname", ClassName(descriptor), "ns", Namespace(descriptor));
    }
    printer->Outdent();
    printer->Print(
        "};\n"
        "\n");
  } else {
    // we still need these symbols to exist
    printer->Print(
        // MSVC doesn't like empty arrays, so we add a dummy.
        "const ::google::protobuf::uint32 TableStruct::offsets[1] = {};\n"
        "static const ::google::protobuf::internal::MigrationSchema* schemas = NULL;\n"
        "static const ::google::protobuf::Message* const* "
        "file_default_instances = NULL;\n"
        "\n");
  }

  // ---------------------------------------------------------------

  // protobuf_AssignDescriptorsOnce():  The first time it is called, calls
  // AssignDescriptors().  All later times, waits for the first call to
  // complete and then returns.
    printer->Print(
        "void protobuf_AssignDescriptors() {\n"
        // Make sure the file has found its way into the pool.  If a descriptor
        // is requested *during* static init then AddDescriptors() may not have
        // been called yet, so we call it manually.  Note that it's fine if
        // AddDescriptors() is called multiple times.
        "  AddDescriptors();\n"
        "  AssignDescriptors(\n"
        "      \"$filename$\", schemas, file_default_instances, "
        "TableStruct::offsets,\n"
        "      $metadata$, $enum_descriptors$, $service_descriptors$);\n",
        "filename", file_->name(), "metadata",
        !message_generators_.empty() ? "file_level_metadata" : "NULL",
        "enum_descriptors",
        !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
        "service_descriptors",
        HasGenericServices(file_, options_) && file_->service_count() > 0
            ? "file_level_service_descriptors"
            : "NULL");
    printer->Print(
        "}\n"
        "\n"
        "void protobuf_AssignDescriptorsOnce() {\n"
        "  static ::google::protobuf::internal::once_flag once;\n"
        "  ::google::protobuf::internal::call_once(once, protobuf_AssignDescriptors);\n"
        "}\n"
        "\n",
        "filename", file_->name(), "metadata",
        !message_generators_.empty() ? "file_level_metadata" : "NULL",
        "enum_descriptors",
        !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL",
        "service_descriptors",
        HasGenericServices(file_, options_) && file_->service_count() > 0
            ? "file_level_service_descriptors"
            : "NULL");

    // Only here because of useless string reference that we don't want in
    // protobuf_AssignDescriptorsOnce, because that is called from all the
    // GetMetadata member methods.
    printer->Print(
        "void protobuf_RegisterTypes(const ::std::string&) "
        "GOOGLE_PROTOBUF_ATTRIBUTE_COLD;\n"
        "void protobuf_RegisterTypes(const ::std::string&) {\n"
        "  protobuf_AssignDescriptorsOnce();\n");
    printer->Indent();

    // All normal messages can be done generically
    if (!message_generators_.empty()) {
      printer->Print(
        "::google::protobuf::internal::RegisterAllTypes(file_level_metadata, $size$);\n",
        "size", SimpleItoa(message_generators_.size()));
    }

    printer->Outdent();
    printer->Print(
        "}\n"
        "\n");

    // Now generate the AddDescriptors() function.
    printer->Print(
        "void AddDescriptorsImpl() {\n"
        "  InitDefaults();\n");
    printer->Indent();

    // Embed the descriptor.  We simply serialize the entire
    // FileDescriptorProto
    // and embed it as a string literal, which is parsed and built into real
    // descriptors at initialization time.
    FileDescriptorProto file_proto;
    file_->CopyTo(&file_proto);
    string file_data;
    file_proto.SerializeToString(&file_data);

    printer->Print("static const char descriptor[] "
                   "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) "
                   "= {\n");
    printer->Indent();

    if (file_data.size() > 65535) {
      // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
      // bytes in length". Declare a static array of characters rather than use
      // a string literal. Only write 25 bytes per line.
      static const int kBytesPerLine = 25;
      for (int i = 0; i < file_data.size();) {
        for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
          printer->Print("'$char$', ", "char",
                         CEscape(file_data.substr(i, 1)));
        }
        printer->Print("\n");
      }
    } else {
      // Only write 40 bytes per line.
      static const int kBytesPerLine = 40;
      for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
        printer->Print("  \"$data$\"\n", "data",
                       EscapeTrigraphs(CEscape(
                           file_data.substr(i, kBytesPerLine))));
      }
    }

    printer->Outdent();
    printer->Print("};\n");
    printer->Print(
        "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(\n"
        "    descriptor, $size$);\n",
        "size", SimpleItoa(file_data.size()));

    // Call MessageFactory::InternalRegisterGeneratedFile().
    printer->Print(
      "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
      "  \"$filename$\", &protobuf_RegisterTypes);\n",
      "filename", file_->name());

  // Call the AddDescriptors() methods for all of our dependencies, to make
  // sure they get added first.
  for (int i = 0; i < file_->dependency_count(); i++) {
    const FileDescriptor* dependency = file_->dependency(i);
    // Print the namespace prefix for the dependency.
    string file_namespace = FileLevelNamespace(dependency);
    // Call its AddDescriptors function.
    printer->Print("::$file_namespace$::AddDescriptors();\n", "file_namespace",
                   file_namespace);
  }

  printer->Outdent();
  printer->Print(
      "}\n"
      "\n"
      "void AddDescriptors() {\n"
        "  static ::google::protobuf::internal::once_flag once;\n"
        "  ::google::protobuf::internal::call_once(once, AddDescriptorsImpl);\n"
      "}\n");

    printer->Print(
        "// Force AddDescriptors() to be called at dynamic initialization "
        "time.\n"
        "struct StaticDescriptorInitializer {\n"
        "  StaticDescriptorInitializer() {\n"
        "    AddDescriptors();\n"
        "  }\n"
        "} static_descriptor_initializer;\n");
}

void FileGenerator::GenerateInitForSCC(const SCC* scc, io::Printer* printer) {
  const string scc_name = ClassName(scc->GetRepresentative());
  // We use static and not anonymous namespace because symbol names are
  // substantially shorter.
  printer->Print(
      "static void InitDefaults$scc_name$() {\n"
      "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n"
      ,  // awkward comma due to macro
      "scc_name", scc_name);

  printer->Indent();


  // First construct all the necessary default instances.
  for (int i = 0; i < message_generators_.size(); i++) {
    if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
      continue;
    }
    // TODO(gerbens) This requires this function to be friend. Remove
    // the need for this.
    message_generators_[i]->GenerateFieldDefaultInstances(printer);
    printer->Print(
        "{\n"
        "  void* ptr = &$ns$::_$classname$_default_instance_;\n"
        "  new (ptr) $ns$::$classname$();\n",
        "ns", Namespace(message_generators_[i]->descriptor_),
        "classname", ClassName(message_generators_[i]->descriptor_));
    if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) {
      printer->Print(
          "  ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);\n");
    }
    printer->Print("}\n");
  }

  // TODO(gerbens) make default instances be the same as normal instances.
  // Default instances differ from normal instances because they have cross
  // linked message fields.
  for (int i = 0; i < message_generators_.size(); i++) {
    if (scc_analyzer_.GetSCC(message_generators_[i]->descriptor_) != scc) {
      continue;
    }
    printer->Print("$classname$::InitAsDefaultInstance();\n", "classname",
                   QualifiedClassName(message_generators_[i]->descriptor_));
  }
  printer->Outdent();
  printer->Print("}\n\n");

  printer->Print(
      "$dllexport_decl$::google::protobuf::internal::SCCInfo<$size$> "
      "scc_info_$scc_name$ =\n"
      "    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), "
      "$size$, InitDefaults$scc_name$}, {",
      "size", SimpleItoa(scc->children.size()), "scc_name",
      ClassName(scc->GetRepresentative()), "dllexport_decl",
      options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
  for (const SCC* child : scc->children) {
    auto repr = child->GetRepresentative();
    printer->Print("\n      &$ns$::scc_info_$child$.base,", "ns",
                   FileLevelNamespace(repr), "child", ClassName(repr));
  }
  printer->Print("}};\n\n");
}

void FileGenerator::GenerateTables(io::Printer* printer) {
  if (options_.table_driven_parsing) {
    // TODO(ckennelly): Gate this with the same options flag to enable
    // table-driven parsing.
    printer->Print(
        "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n"
        "    const TableStruct::entries[] "
        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
    printer->Indent();

    std::vector<size_t> entries;
    size_t count = 0;
    for (int i = 0; i < message_generators_.size(); i++) {
      size_t value = message_generators_[i]->GenerateParseOffsets(printer);
      entries.push_back(value);
      count += value;
    }

    // We need these arrays to exist, and MSVC does not like empty arrays.
    if (count == 0) {
      printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n");
    }

    printer->Outdent();
    printer->Print(
        "};\n"
        "\n"
        "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n"
        "    const TableStruct::aux[] "
        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
    printer->Indent();

    std::vector<size_t> aux_entries;
    count = 0;
    for (int i = 0; i < message_generators_.size(); i++) {
      size_t value = message_generators_[i]->GenerateParseAuxTable(printer);
      aux_entries.push_back(value);
      count += value;
    }

    if (count == 0) {
      printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n");
    }

    printer->Outdent();
    printer->Print(
        "};\n"
        "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n"
        "    TableStruct::schema[] "
        "GOOGLE_PROTOBUF_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {\n");
    printer->Indent();

    size_t offset = 0;
    size_t aux_offset = 0;
    for (int i = 0; i < message_generators_.size(); i++) {
      message_generators_[i]->GenerateParseTable(printer, offset, aux_offset);
      offset += entries[i];
      aux_offset += aux_entries[i];
    }

    if (message_generators_.empty()) {
      printer->Print("{ NULL, NULL, 0, -1, -1, false },\n");
    }

    printer->Outdent();
    printer->Print(
        "};\n"
        "\n");
  }

  if (!message_generators_.empty() && options_.table_driven_serialization) {
    printer->Print(
        "const ::google::protobuf::internal::FieldMetadata TableStruct::field_metadata[] "
        "= {\n");
    printer->Indent();
    std::vector<int> field_metadata_offsets;
    int idx = 0;
    for (int i = 0; i < message_generators_.size(); i++) {
      field_metadata_offsets.push_back(idx);
      idx += message_generators_[i]->GenerateFieldMetadata(printer);
    }
    field_metadata_offsets.push_back(idx);
    printer->Outdent();
    printer->Print(
        "};\n"
        "const ::google::protobuf::internal::SerializationTable "
        "TableStruct::serialization_table[] = {\n");
    printer->Indent();
    // We rely on the order we layout the tables to match the order we
    // calculate them with FlattenMessagesInFile, so we check here that
    // these match exactly.
    std::vector<const Descriptor*> calculated_order =
        FlattenMessagesInFile(file_);
    GOOGLE_CHECK_EQ(calculated_order.size(), message_generators_.size());
    for (int i = 0; i < message_generators_.size(); i++) {
      GOOGLE_CHECK_EQ(calculated_order[i], message_generators_[i]->descriptor_);
      printer->Print(
          "{$num_fields$, TableStruct::field_metadata + $index$},\n",
          "classname", message_generators_[i]->classname_, "num_fields",
          SimpleItoa(field_metadata_offsets[i + 1] - field_metadata_offsets[i]),
          "index", SimpleItoa(field_metadata_offsets[i]));
    }
    printer->Outdent();
    printer->Print(
        "};\n"
        "\n");
  }
}

void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
  ForwardDeclarations decls;
  FillForwardDeclarations(&decls);
  decls.PrintForwardDeclarations(printer, options_);
}

void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) {
  for (int i = 0; i < package_parts_.size(); i++) {
    decls = decls->AddOrGetNamespace(package_parts_[i]);
  }
  // Generate enum definitions.
  for (int i = 0; i < enum_generators_.size(); i++) {
    enum_generators_[i]->FillForwardDeclaration(&decls->enums());
  }
  // Generate forward declarations of classes.
  for (int i = 0; i < message_generators_.size(); i++) {
    message_generators_[i]->FillMessageForwardDeclarations(
        &decls->classes());
  }
}

void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
                                           const string& filename_identifier) {
  // Generate top of header.
  printer->Print(
      "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
      "// source: $filename$\n"
      "\n"
      "#ifndef PROTOBUF_INCLUDED_$filename_identifier$\n"
      "#define PROTOBUF_INCLUDED_$filename_identifier$\n"
      "\n"
      "#include <string>\n",
      "filename", file_->name(), "filename_identifier", filename_identifier);
  printer->Print("\n");
}

void FileGenerator::GenerateBottomHeaderGuard(
    io::Printer* printer, const string& filename_identifier) {
  printer->Print(
    "#endif  // PROTOBUF_INCLUDED_$filename_identifier$\n",
    "filename_identifier", filename_identifier);
}

void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
  if (UsingImplicitWeakFields(file_, options_)) {
    printer->Print("#include <google/protobuf/implicit_weak_message.h>\n");
  }

  printer->Print(
    "#include <google/protobuf/stubs/common.h>\n"
    "\n");

  // Verify the protobuf library header version is compatible with the protoc
  // version before going any further.
  printer->Print(
    "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
    "#error This file was generated by a newer version of protoc which is\n"
    "#error incompatible with your Protocol Buffer headers.  Please update\n"
    "#error your headers.\n"
    "#endif\n"
    "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
    "#error This file was generated by an older version of protoc which is\n"
    "#error incompatible with your Protocol Buffer headers.  Please\n"
    "#error regenerate this file with a newer version of protoc.\n"
    "#endif\n"
    "\n",
    "min_header_version",
      SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
    "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));

  // OK, it's now safe to #include other files.
  printer->Print(
      "#include <google/protobuf/io/coded_stream.h>\n"
      "#include <google/protobuf/arena.h>\n"
      "#include <google/protobuf/arenastring.h>\n"
      "#include <google/protobuf/generated_message_table_driven.h>\n"
      "#include <google/protobuf/generated_message_util.h>\n"
      "#include <google/protobuf/inlined_string_field.h>\n");


  if (HasDescriptorMethods(file_, options_)) {
    printer->Print(
      "#include <google/protobuf/metadata.h>\n");
  } else {
    printer->Print(
      "#include <google/protobuf/metadata_lite.h>\n");
  }

  if (!message_generators_.empty()) {
    if (HasDescriptorMethods(file_, options_)) {
      printer->Print(
        "#include <google/protobuf/message.h>\n");
    } else {
      printer->Print(
        "#include <google/protobuf/message_lite.h>\n");
    }
  }
  printer->Print(
    "#include <google/protobuf/repeated_field.h>"
    "  // IWYU pragma: export\n"
    "#include <google/protobuf/extension_set.h>"
    "  // IWYU pragma: export\n");
  if (HasMapFields(file_)) {
    printer->Print(
        "#include <google/protobuf/map.h>"
        "  // IWYU pragma: export\n");
    if (HasDescriptorMethods(file_, options_)) {
      printer->Print("#include <google/protobuf/map_entry.h>\n");
      printer->Print("#include <google/protobuf/map_field_inl.h>\n");
    } else {
      printer->Print("#include <google/protobuf/map_entry_lite.h>\n");
      printer->Print("#include <google/protobuf/map_field_lite.h>\n");
    }
  }

  if (HasEnumDefinitions(file_)) {
    if (HasDescriptorMethods(file_, options_)) {
      printer->Print(
          "#include <google/protobuf/generated_enum_reflection.h>\n");
    } else {
      printer->Print(
          "#include <google/protobuf/generated_enum_util.h>\n");
    }
  }

  if (HasGenericServices(file_, options_)) {
    printer->Print(
      "#include <google/protobuf/service.h>\n");
  }

  if (UseUnknownFieldSet(file_, options_) && !message_generators_.empty()) {
    printer->Print(
      "#include <google/protobuf/unknown_field_set.h>\n");
  }


  if (IsAnyMessage(file_)) {
    printer->Print(
      "#include <google/protobuf/any.h>\n");
  }
}

void FileGenerator::GenerateMetadataPragma(io::Printer* printer,
                                           const string& info_path) {
  if (!info_path.empty() && !options_.annotation_pragma_name.empty() &&
      !options_.annotation_guard_name.empty()) {
    printer->Print(
        "#ifdef $guard$\n"
        "#pragma $pragma$ \"$info_path$\"\n"
        "#endif  // $guard$\n",
        "guard", options_.annotation_guard_name, "pragma",
        options_.annotation_pragma_name, "info_path", info_path);
  }
}

void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
  std::set<string> public_import_names;
  for (int i = 0; i < file_->public_dependency_count(); i++) {
    public_import_names.insert(file_->public_dependency(i)->name());
  }

  for (int i = 0; i < file_->dependency_count(); i++) {
    const bool use_system_include = IsWellKnownMessage(file_->dependency(i));
    const string& name = file_->dependency(i)->name();
    bool public_import = (public_import_names.count(name) != 0);
    string basename = StripProto(name);


    printer->Print(
      "#include $left$$dependency$.pb.h$right$$iwyu$\n",
      "dependency", basename,
      "iwyu", (public_import) ? "  // IWYU pragma: export" : "",
      "left", use_system_include ? "<" : "\"",
      "right", use_system_include ? ">" : "\"");
  }
}

void FileGenerator::GenerateGlobalStateFunctionDeclarations(
    io::Printer* printer) {
// Forward-declare the AddDescriptors, InitDefaults because these are called
// by .pb.cc files depending on this file.
  printer->Print(
      "\n"
      "namespace $file_namespace$ {\n"
      "// Internal implementation detail -- do not use these members.\n"
      "struct $dllexport_decl$TableStruct {\n"
      // These tables describe how to serialize and parse messages. Used
      // for table driven code.
      "  static const ::google::protobuf::internal::ParseTableField entries[];\n"
      "  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];\n"
      "  static const ::google::protobuf::internal::ParseTable schema[$num$];\n"
      "  static const ::google::protobuf::internal::FieldMetadata field_metadata[];\n"
      "  static const ::google::protobuf::internal::SerializationTable "
      "serialization_table[];\n"
      "  static const ::google::protobuf::uint32 offsets[];\n"
      "};\n",
      "file_namespace", FileLevelNamespace(file_), "dllexport_decl",
      options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ",
      "num", SimpleItoa(std::max(size_t(1), message_generators_.size())));
  if (HasDescriptorMethods(file_, options_)) {
    printer->Print(
        "void $dllexport_decl$AddDescriptors();\n", "dllexport_decl",
        options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
  }
  printer->Print(
      "}  // namespace $file_namespace$\n",
      "file_namespace", FileLevelNamespace(file_));
}

void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) {
  // Generate class definitions.
  for (int i = 0; i < message_generators_.size(); i++) {
    if (i > 0) {
      printer->Print("\n");
      printer->Print(kThinSeparator);
      printer->Print("\n");
    }
    message_generators_[i]->GenerateClassDefinition(printer);
  }
}

void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) {
  // Generate enum definitions.
  for (int i = 0; i < enum_generators_.size(); i++) {
    enum_generators_[i]->GenerateDefinition(printer);
  }
}

void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
  if (HasGenericServices(file_, options_)) {
    // Generate service definitions.
    for (int i = 0; i < service_generators_.size(); i++) {
      if (i > 0) {
        printer->Print("\n");
        printer->Print(kThinSeparator);
        printer->Print("\n");
      }
      service_generators_[i]->GenerateDeclarations(printer);
    }

    printer->Print("\n");
    printer->Print(kThickSeparator);
    printer->Print("\n");
  }
}

void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) {
  // Declare extension identifiers. These are in global scope and so only
  // the global scope extensions.
  for (int i = 0; i < file_->extension_count(); i++) {
    extension_generators_owner_[i]->GenerateDeclaration(printer);
  }
}

void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
  // TODO(gerbens) remove pragmas when gcc is no longer used. Current version
  // of gcc fires a bogus error when compiled with strict-aliasing.
  printer->Print(
    "#ifdef __GNUC__\n"
    "  #pragma GCC diagnostic push\n"
    "  #pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n"
    "#endif  // __GNUC__\n");
  // Generate class inline methods.
  for (int i = 0; i < message_generators_.size(); i++) {
    if (i > 0) {
      printer->Print(kThinSeparator);
      printer->Print("\n");
    }
    message_generators_[i]->GenerateInlineMethods(printer);
  }
  printer->Print(
    "#ifdef __GNUC__\n"
    "  #pragma GCC diagnostic pop\n"
    "#endif  // __GNUC__\n");

  for (int i = 0; i < message_generators_.size(); i++) {
    if (i > 0) {
      printer->Print(kThinSeparator);
      printer->Print("\n");
    }
  }
}

void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
    io::Printer* printer) {
  // Emit GetEnumDescriptor specializations into google::protobuf namespace:
  if (HasEnumDefinitions(file_)) {
    printer->Print(
        "\n"
        "namespace google {\nnamespace protobuf {\n"
        "\n");
    for (int i = 0; i < enum_generators_.size(); i++) {
      enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
    }
    printer->Print(
        "\n"
        "}  // namespace protobuf\n}  // namespace google\n");
  }
}

}  // namespace cpp
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
