15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_file.h>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_enum.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_service.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_extension.h>
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_helpers.h>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_message.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/cpp/cpp_field.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/printer.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace compiler {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace cpp {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileGenerator::FileGenerator(const FileDescriptor* file,
54ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                             const Options& options)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : file_(file),
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new scoped_ptr<MessageGenerator>[file->message_type_count()]),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum_generators_(
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_generators_(
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new scoped_ptr<ServiceGenerator>[file->service_count()]),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_generators_(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    options_(options) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file->message_type_count(); i++) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i].reset(
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      new MessageGenerator(file->message_type(i), options));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file->enum_type_count(); i++) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum_generators_[i].reset(
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      new EnumGenerator(file->enum_type(i), options));
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file->service_count(); i++) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service_generators_[i].reset(
78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      new ServiceGenerator(file->service(i), options));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file->extension_count(); i++) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_generators_[i].reset(
83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      new ExtensionGenerator(file->extension(i), options));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SplitStringUsing(file_->package(), ".", &package_parts_);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileGenerator::~FileGenerator() {}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::GenerateHeader(io::Printer* printer) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string filename_identifier = FilenameIdentifier(file_->name());
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate top of header.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// source: $filename$\n"
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <string>\n"
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n",
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "filename", file_->name(),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "filename_identifier", filename_identifier);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <google/protobuf/stubs/common.h>\n"
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n");
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the protobuf library header version is compatible with the protoc
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // version before going any further.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#error This file was generated by a newer version of protoc which is\n"
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#error incompatible with your Protocol Buffer headers.  Please update\n"
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#error your headers.\n"
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#endif\n"
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#error This file was generated by an older version of protoc which is\n"
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#error incompatible with your Protocol Buffer headers.  Please\n"
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#error regenerate this file with a newer version of protoc.\n"
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#endif\n"
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n",
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "min_header_version",
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OK, it's now safe to #include other files.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "#include <google/protobuf/generated_message_util.h>\n");
133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (file_->message_type_count() > 0) {
134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (HasDescriptorMethods(file_)) {
135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      printer->Print(
136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        "#include <google/protobuf/message.h>\n");
137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      printer->Print(
139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        "#include <google/protobuf/message_lite.h>\n");
140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  printer->Print(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <google/protobuf/repeated_field.h>\n"
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <google/protobuf/extension_set.h>\n");
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasUnknownFields(file_)) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "#include <google/protobuf/unknown_field_set.h>\n");
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "#include <google/protobuf/generated_enum_reflection.h>\n");
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasGenericServices(file_)) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "#include <google/protobuf/service.h>\n");
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (HasUnknownFields(file_) && file_->message_type_count() > 0) {
162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    printer->Print(
163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "#include <google/protobuf/unknown_field_set.h>\n");
164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->dependency_count(); i++) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "#include \"$dependency$.pb.h\"\n",
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "dependency", StripProto(file_->dependency(i)->name()));
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// @@protoc_insertion_point(includes)\n");
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Open namespace.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateNamespaceOpeners(printer);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functions, so that we can declare them to be friends of each class.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// Internal implementation detail -- do not call these.\n"
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "void $dllexport_decl$ $adddescriptorsname$();\n",
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "dllexport_decl", options_.dllexport_decl);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that we don't put dllexport_decl on these because they are only
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // called by the .pb.cc file in which they are defined.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "void $assigndescriptorsname$();\n"
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "void $shutdownfilename$();\n"
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n",
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "shutdownfilename", GlobalShutdownFileName(file_->name()));
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate forward declarations of classes.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateForwardDeclaration(printer);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print("\n");
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate enum definitions.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateEnumDefinitions(printer);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->enum_type_count(); i++) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum_generators_[i]->GenerateDefinition(printer);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(kThickSeparator);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print("\n");
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate class definitions.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i > 0) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print("\n");
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print(kThinSeparator);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print("\n");
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateClassDefinition(printer);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print("\n");
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(kThickSeparator);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print("\n");
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasGenericServices(file_)) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Generate service definitions.
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->service_count(); i++) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (i > 0) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printer->Print("\n");
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printer->Print(kThinSeparator);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printer->Print("\n");
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service_generators_[i]->GenerateDeclarations(printer);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print("\n");
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(kThickSeparator);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print("\n");
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Declare extension identifiers.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->extension_count(); i++) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_generators_[i]->GenerateDeclaration(printer);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print("\n");
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(kThickSeparator);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print("\n");
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate class inline methods.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i > 0) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print(kThinSeparator);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print("\n");
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateInlineMethods(printer);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// @@protoc_insertion_point(namespace_scope)\n");
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close up namespace.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateNamespaceClosers(printer);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Emit GetEnumDescriptor specializations into google::protobuf namespace:
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasDescriptorMethods(file_)) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The SWIG conditional is to avoid a null-pointer dereference
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   namespace X { void Y<Z::W>(); }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // which appears in GetEnumDescriptor() specializations.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "\n"
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "#ifndef SWIG\n"
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "namespace google {\nnamespace protobuf {\n"
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "\n");
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->message_type_count(); i++) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->enum_type_count(); i++) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "\n"
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "}  // namespace google\n}  // namespace protobuf\n"
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "#endif  // SWIG\n");
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// @@protoc_insertion_point(global_scope)\n"
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n");
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#endif  // PROTOBUF_$filename_identifier$__INCLUDED\n",
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "filename_identifier", filename_identifier);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::GenerateSource(io::Printer* printer) {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "// source: $filename$\n"
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The generated code calls accessors that might be deprecated. We don't
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // want the compiler to warn in generated code.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include \"$basename$.pb.h\"\n"
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <algorithm>\n"    // for swap()
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
318ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "#include <google/protobuf/stubs/common.h>\n"
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <google/protobuf/stubs/once.h>\n"
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <google/protobuf/io/coded_stream.h>\n"
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "#include <google/protobuf/wire_format_lite_inl.h>\n",
322ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "filename", file_->name(),
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "basename", StripProto(file_->name()));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasDescriptorMethods(file_)) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "#include <google/protobuf/descriptor.h>\n"
328ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      "#include <google/protobuf/generated_message_reflection.h>\n"
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "#include <google/protobuf/reflection_ops.h>\n"
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "#include <google/protobuf/wire_format.h>\n");
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// @@protoc_insertion_point(includes)\n");
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateNamespaceOpeners(printer);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasDescriptorMethods(file_)) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n"
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "namespace {\n"
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n");
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->message_type_count(); i++) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message_generators_[i]->GenerateDescriptorDeclarations(printer);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->enum_type_count(); i++) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print(
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "name", ClassName(file_->enum_type(i), false));
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (HasGenericServices(file_)) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int i = 0; i < file_->service_count(); i++) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        printer->Print(
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "name", file_->service(i)->name());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n"
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}  // namespace\n"
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n");
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Define our externally-visible BuildDescriptors() function.  (For the lite
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // library, all this does is initialize default instances.)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateBuildDescriptors(printer);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate enums.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->enum_type_count(); i++) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum_generators_[i]->GenerateMethods(printer);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generate classes.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print("\n");
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(kThickSeparator);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print("\n");
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateClassMethods(printer);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasGenericServices(file_)) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Generate services.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->service_count(); i++) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (i == 0) printer->Print("\n");
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print(kThickSeparator);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print("\n");
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service_generators_[i]->GenerateImplementation(printer);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Define extensions.
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->extension_count(); i++) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_generators_[i]->GenerateDefinition(printer);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// @@protoc_insertion_point(namespace_scope)\n");
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GenerateNamespaceClosers(printer);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// @@protoc_insertion_point(global_scope)\n");
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AddDescriptors() is a file-level procedure which adds the encoded
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FileDescriptorProto for this .proto file to the global DescriptorPool for
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // generated files (DescriptorPool::generated_pool()). It either runs at
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // static initialization time (by default) or when default_instance() is
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called for the first time (in LITE_RUNTIME mode with
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // constructs default instances and registers extensions.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Its sibling, AssignDescriptors(), actually pulls the compiled
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FileDescriptor from the DescriptorPool and uses it to populate all of
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the global variables which store pointers to the descriptor objects.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It also constructs the reflection objects.  It is called the first time
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // anyone calls descriptor() or GetReflection() on one of the types defined
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the file.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and we only use AddDescriptors() to allocate default instances.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasDescriptorMethods(file_)) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n"
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "void $assigndescriptorsname$() {\n",
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Indent();
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the file has found its way into the pool.  If a descriptor
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // is requested *during* static init then AddDescriptors() may not have
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // been called yet, so we call it manually.  Note that it's fine if
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // AddDescriptors() is called multiple times.
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "$adddescriptorsname$();\n",
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get the file's descriptor from the pool.
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "const ::google::protobuf::FileDescriptor* file =\n"
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "    \"$filename$\");\n"
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // being unused when compiling an empty .proto file.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GOOGLE_CHECK(file != NULL);\n",
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "filename", file_->name());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Go through all the stuff defined in this file and generated code to
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // assign the global descriptor pointers based on the file descriptor.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->message_type_count(); i++) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message_generators_[i]->GenerateDescriptorInitializer(printer, i);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->enum_type_count(); i++) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (HasGenericServices(file_)) {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int i = 0; i < file_->service_count(); i++) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        service_generators_[i]->GenerateDescriptorInitializer(printer, i);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Outdent();
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}\n"
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n");
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ---------------------------------------------------------------
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protobuf_AssignDescriptorsOnce():  The first time it is called, calls
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // AssignDescriptors().  All later times, waits for the first call to
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // complete and then returns.
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "namespace {\n"
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n"
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "inline void protobuf_AssignDescriptorsOnce() {\n"
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "                 &$assigndescriptorsname$);\n"
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}\n"
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n",
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protobuf_RegisterTypes():  Calls
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // MessageFactory::InternalRegisterGeneratedType() for each message type.
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "void protobuf_RegisterTypes(const ::std::string&) {\n"
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  protobuf_AssignDescriptorsOnce();\n");
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Indent();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_->message_type_count(); i++) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message_generators_[i]->GenerateTypeRegistrations(printer);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Outdent();
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}\n"
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "\n"
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "}  // namespace\n");
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // -----------------------------------------------------------------
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ShutdownFile():  Deletes descriptors, default instances, etc. on shutdown.
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n"
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "void $shutdownfilename$() {\n",
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "shutdownfilename", GlobalShutdownFileName(file_->name()));
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Indent();
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateShutdownCode(printer);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Outdent();
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n\n");
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // -----------------------------------------------------------------
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now generate the AddDescriptors() function.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrintHandlingOptionalStaticInitializers(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_, printer,
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // With static initializers.
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that we don't need any special synchronization in the following code
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // because it is called at static init time before any threads exist.
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "void $adddescriptorsname$() {\n"
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  static bool already_here = false;\n"
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  if (already_here) return;\n"
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  already_here = true;\n"
534ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
535ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "\n",
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Without.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "void $adddescriptorsname$_impl() {\n"
538ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
539ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "\n",
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Vars.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Indent();
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call the AddDescriptors() methods for all of our dependencies, to make
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sure they get added first.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->dependency_count(); i++) {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FileDescriptor* dependency = file_->dependency(i);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Print the namespace prefix for the dependency.
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vector<string> dependency_package_parts;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print("::");
553ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    for (int j = 0; j < dependency_package_parts.size(); j++) {
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print("$name$::",
555ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                     "name", dependency_package_parts[j]);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Call its AddDescriptors function.
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "$name$();\n",
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "name", GlobalAddDescriptorsName(dependency->name()));
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HasDescriptorMethods(file_)) {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Embed the descriptor.  We simply serialize the entire FileDescriptorProto
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and embed it as a string literal, which is parsed and built into real
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // descriptors at initialization time.
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FileDescriptorProto file_proto;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_->CopyTo(&file_proto);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string file_data;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_proto.SerializeToString(&file_data);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only write 40 bytes per line.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static const int kBytesPerLine = 40;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      printer->Print("\n  \"$data$\"",
579ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                     "data",
580ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                     EscapeTrigraphs(
581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                         CEscape(file_data.substr(i, kBytesPerLine))));
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
584ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        ", $size$);\n",
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "size", SimpleItoa(file_data.size()));
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Call MessageFactory::InternalRegisterGeneratedFile().
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print(
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "  \"$filename$\", &protobuf_RegisterTypes);\n",
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "filename", file_->name());
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocate and initialize default instances.  This can't be done lazily
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since default instances are returned by simple accessors and are used with
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extensions.  Speaking of which, we also register extensions at this time.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->extension_count(); i++) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_generators_[i]->GenerateRegistration(printer);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < file_->message_type_count(); i++) {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "shutdownfilename", GlobalShutdownFileName(file_->name()));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Outdent();
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  printer->Print(
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n"
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "\n");
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrintHandlingOptionalStaticInitializers(
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_, printer,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // With static initializers.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "// Force AddDescriptors() to be called at static initialization time.\n"
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "struct StaticDescriptorInitializer_$filename$ {\n"
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  StaticDescriptorInitializer_$filename$() {\n"
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "    $adddescriptorsname$();\n"
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  }\n"
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "} static_descriptor_initializer_$filename$_;\n",
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Without.
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "void $adddescriptorsname$() {\n"
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "  ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "                 &$adddescriptorsname$_impl);\n"
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "}\n",
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Vars.
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "filename", FilenameIdentifier(file_->name()));
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (package_parts_.size() > 0) printer->Print("\n");
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < package_parts_.size(); i++) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print("namespace $part$ {\n",
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   "part", package_parts_[i]);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (package_parts_.size() > 0) printer->Print("\n");
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = package_parts_.size() - 1; i >= 0; i--) {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    printer->Print("}  // namespace $part$\n",
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   "part", package_parts_[i]);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace cpp
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace compiler
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
658