cpp_file.cc revision fbaaef999ba563838ebd00874ed8a1c01fbf286d
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// Protocol Buffers - Google's data interchange format
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// Copyright 2008 Google Inc.  All rights reserved.
35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// http://code.google.com/p/protobuf/
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// Redistribution and use in source and binary forms, with or without
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// modification, are permitted provided that the following conditions are
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// met:
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//     * Redistributions of source code must retain the above copyright
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// notice, this list of conditions and the following disclaimer.
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//     * Redistributions in binary form must reproduce the above
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// copyright notice, this list of conditions and the following disclaimer
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// in the documentation and/or other materials provided with the
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// distribution.
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//     * Neither the name of Google Inc. nor the names of its
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// contributors may be used to endorse or promote products derived from
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// this software without specific prior written permission.
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project// Author: kenton@google.com (Kenton Varda)
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//  Based on original Protocol Buffers design by
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project//  Sanjay Ghemawat, Jeff Dean, and others.
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/compiler/cpp/cpp_file.h>
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/compiler/cpp/cpp_enum.h>
375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/compiler/cpp/cpp_service.h>
385cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen#include <google/protobuf/compiler/cpp/cpp_extension.h>
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/compiler/cpp/cpp_helpers.h>
405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/compiler/cpp/cpp_message.h>
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/io/printer.h>
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/descriptor.pb.h>
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <google/protobuf/stubs/strutil.h>
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectnamespace google {
4636f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpurenamespace protobuf {
4736f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpurenamespace compiler {
4836f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpurenamespace cpp {
4936f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure
5036f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure// ===================================================================
5136f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure
5236f43cc4b0ce38007c29d573f251ec594d95b180Nitin ShivpureFileGenerator::FileGenerator(const FileDescriptor* file,
5336f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure                             const string& dllexport_decl)
5436f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure  : file_(file),
5536f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    message_generators_(
5636f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure      new scoped_ptr<MessageGenerator>[file->message_type_count()]),
5736f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    enum_generators_(
5836f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure      new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
5936f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    service_generators_(
6036f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure      new scoped_ptr<ServiceGenerator>[file->service_count()]),
6136f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    extension_generators_(
6236f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure      new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
6336f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    dllexport_decl_(dllexport_decl) {
6436f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure
6536f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure  for (int i = 0; i < file->message_type_count(); i++) {
6636f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    message_generators_[i].reset(
6736f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure      new MessageGenerator(file->message_type(i), dllexport_decl));
6836f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure  }
6936f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure
7036f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure  for (int i = 0; i < file->enum_type_count(); i++) {
7136f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    enum_generators_[i].reset(
7236f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure      new EnumGenerator(file->enum_type(i), dllexport_decl));
7336f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure  }
7436f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure
7536f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure  for (int i = 0; i < file->service_count(); i++) {
7636f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure    service_generators_[i].reset(
7736f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure      new ServiceGenerator(file->service(i), dllexport_decl));
7836f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure  }
7936f43cc4b0ce38007c29d573f251ec594d95b180Nitin Shivpure
805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file->extension_count(); i++) {
815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    extension_generators_[i].reset(
825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      new ExtensionGenerator(file->extension(i), dllexport_decl));
835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  SplitStringUsing(file_->package(), ".", &package_parts_);
865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjectFileGenerator::~FileGenerator() {}
895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid FileGenerator::GenerateHeader(io::Printer* printer) {
915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  string filename_identifier = FilenameIdentifier(file_->name());
925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Generate top of header.
945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n"
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n"
1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <string>\n"
1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n",
1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "filename_identifier", filename_identifier);
1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <google/protobuf/stubs/common.h>\n"
1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n");
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Verify the protobuf library header version is compatible with the protoc
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // version before going any further.
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#error This file was generated by a newer version of protoc which is\n"
1135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#error incompatible with your Protocol Buffer headers.  Please update\n"
1145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#error your headers.\n"
1155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#endif\n"
1165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
1175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#error This file was generated by an older version of protoc which is\n"
1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#error incompatible with your Protocol Buffer headers.  Please\n"
1195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#error regenerate this file with a newer version of protoc.\n"
1205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#endif\n"
1215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n",
1225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "min_header_version",
1235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
1245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
1255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // OK, it's now safe to #include other files.
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <google/protobuf/generated_message_util.h>\n"
1295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <google/protobuf/repeated_field.h>\n"
1305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <google/protobuf/extension_set.h>\n");
1315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (HasDescriptorMethods(file_)) {
1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "#include <google/protobuf/generated_message_reflection.h>\n");
1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (file_->service_count() > 0) {
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print(
1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "#include <google/protobuf/service.h>\n");
1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->dependency_count(); i++) {
1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "#include \"$dependency$.pb.h\"\n",
1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "dependency", StripProto(file_->dependency(i)->name()));
1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Open namespace.
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  GenerateNamespaceOpeners(printer);
1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile
1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // functions, so that we can declare them to be friends of each class.
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n"
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "// Internal implementation detail -- do not call these.\n"
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "void $dllexport_decl$ $adddescriptorsname$();\n",
1575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "dllexport_decl", dllexport_decl_);
1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Note that we don't put dllexport_decl on these because they are only
1625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // called by the .pb.cc file in which they are defined.
1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "void $assigndescriptorsname$();\n"
1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "void $shutdownfilename$();\n"
1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n",
1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "shutdownfilename", GlobalShutdownFileName(file_->name()));
1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Generate forward declarations of classes.
1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateForwardDeclaration(printer);
1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print("\n");
1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Generate enum definitions.
1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateEnumDefinitions(printer);
1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->enum_type_count(); i++) {
1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    enum_generators_[i]->GenerateDefinition(printer);
1825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(kThickSeparator);
1855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print("\n");
1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Generate class definitions.
1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
1895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (i > 0) {
1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print("\n");
1915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print(kThinSeparator);
1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print("\n");
1935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateClassDefinition(printer);
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print("\n");
1985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(kThickSeparator);
1995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print("\n");
2005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (HasDescriptorMethods(file_)) {
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Generate service definitions.
2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->service_count(); i++) {
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (i > 0) {
2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        printer->Print("\n");
2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        printer->Print(kThinSeparator);
2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        printer->Print("\n");
2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      service_generators_[i]->GenerateDeclarations(printer);
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print("\n");
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(kThickSeparator);
214e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati    printer->Print("\n");
2155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Declare extension identifiers.
2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->extension_count(); i++) {
2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    extension_generators_[i]->GenerateDeclaration(printer);
2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print("\n");
2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(kThickSeparator);
2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print("\n");
2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Generate class inline methods.
2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (i > 0) {
2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print(kThinSeparator);
2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print("\n");
2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateInlineMethods(printer);
2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Close up namespace.
2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  GenerateNamespaceClosers(printer);
2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Emit GetEnumDescriptor specializations into google::protobuf namespace:
2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (HasDescriptorMethods(file_)) {
2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // The SWIG conditional is to avoid a null-pointer dereference
2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    //   namespace X { void Y<Z::W>(); }
2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // which appears in GetEnumDescriptor() specializations.
2445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "\n"
2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "#ifndef SWIG\n"
2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "namespace google {\nnamespace protobuf {\n"
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "\n");
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->message_type_count(); i++) {
2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->enum_type_count(); i++) {
2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "\n"
2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "}  // namespace google\n}  // namespace protobuf\n"
2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "#endif  // SWIG\n"
2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "\n");
2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#endif  // PROTOBUF_$filename_identifier$__INCLUDED\n",
2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "filename_identifier", filename_identifier);
2655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
2665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid FileGenerator::GenerateSource(io::Printer* printer) {
2685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
2695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
2705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n"
2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // The generated code calls accessors that might be deprecated. We don't
2725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // want the compiler to warn in generated code.
2735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
2745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include \"$basename$.pb.h\"\n"
2755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <google/protobuf/stubs/once.h>\n"
2775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <google/protobuf/io/coded_stream.h>\n"
2785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "#include <google/protobuf/wire_format_lite_inl.h>\n",
2795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "basename", StripProto(file_->name()));
2805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (HasDescriptorMethods(file_)) {
2825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
2835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "#include <google/protobuf/descriptor.h>\n"
2845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "#include <google/protobuf/reflection_ops.h>\n"
2855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "#include <google/protobuf/wire_format.h>\n");
2865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
2875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  GenerateNamespaceOpeners(printer);
2895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
2905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (HasDescriptorMethods(file_)) {
2915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
2925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n"
2935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "namespace {\n"
2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n");
2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->message_type_count(); i++) {
2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      message_generators_[i]->GenerateDescriptorDeclarations(printer);
2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
2985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->enum_type_count(); i++) {
2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print(
3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "name", ClassName(file_->enum_type(i), false));
3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->service_count(); i++) {
3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print(
3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "name", file_->service(i)->name());
3075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n"
3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "}  // namespace\n"
3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n");
3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Define our externally-visible BuildDescriptors() function.  (For the lite
3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // library, all this does is initialize default instances.)
3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  GenerateBuildDescriptors(printer);
3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Generate enums.
3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->enum_type_count(); i++) {
3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    enum_generators_[i]->GenerateMethods(printer);
3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Generate classes.
3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print("\n");
3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(kThickSeparator);
3285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print("\n");
3295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateClassMethods(printer);
3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (HasDescriptorMethods(file_)) {
3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Generate services.
3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->service_count(); i++) {
3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (i == 0) printer->Print("\n");
3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print(kThickSeparator);
3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print("\n");
3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      service_generators_[i]->GenerateImplementation(printer);
3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Define extensions.
3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->extension_count(); i++) {
3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    extension_generators_[i]->GenerateDefinition(printer);
3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  GenerateNamespaceClosers(printer);
3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // AddDescriptors() is a file-level procedure which adds the encoded
3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // FileDescriptorProto for this .proto file to the global DescriptorPool
3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // for generated files (DescriptorPool::generated_pool()).  It always runs
3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // at static initialization time, so all files will be registered before
3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // main() starts.  This procedure also constructs default instances and
3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // registers extensions.
3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  //
3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Its sibling, AssignDescriptors(), actually pulls the compiled
3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // FileDescriptor from the DescriptorPool and uses it to populate all of
3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // the global variables which store pointers to the descriptor objects.
3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // It also constructs the reflection objects.  It is called the first time
3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // anyone calls descriptor() or GetReflection() on one of the types defined
3635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // in the file.
3645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
3665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // and we only use AddDescriptors() to allocate default instances.
3675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (HasDescriptorMethods(file_)) {
3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n"
3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "void $assigndescriptorsname$() {\n",
3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Indent();
3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Make sure the file has found its way into the pool.  If a descriptor
3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // is requested *during* static init then AddDescriptors() may not have
3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // been called yet, so we call it manually.  Note that it's fine if
3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // AddDescriptors() is called multiple times.
3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "$adddescriptorsname$();\n",
3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Get the file's descriptor from the pool.
3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "const ::google::protobuf::FileDescriptor* file =\n"
3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "  ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "    \"$filename$\");\n"
3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      // being unused when compiling an empty .proto file.
3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "GOOGLE_CHECK(file != NULL);\n",
3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "filename", file_->name());
3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Go through all the stuff defined in this file and generated code to
3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // assign the global descriptor pointers based on the file descriptor.
3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->message_type_count(); i++) {
3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      message_generators_[i]->GenerateDescriptorInitializer(printer, i);
3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->enum_type_count(); i++) {
3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->service_count(); i++) {
4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      service_generators_[i]->GenerateDescriptorInitializer(printer, i);
4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Outdent();
4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "}\n"
4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n");
4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // ---------------------------------------------------------------
4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // protobuf_AssignDescriptorsOnce():  The first time it is called, calls
4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // AssignDescriptors().  All later times, waits for the first call to
4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // complete and then returns.
4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "namespace {\n"
4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n"
4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "inline void protobuf_AssignDescriptorsOnce() {\n"
4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "                 &$assigndescriptorsname$);\n"
4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "}\n"
4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n",
4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // protobuf_RegisterTypes():  Calls
4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // MessageFactory::InternalRegisterGeneratedType() for each message type.
4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "void protobuf_RegisterTypes(const ::std::string&) {\n"
4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "  protobuf_AssignDescriptorsOnce();\n");
4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Indent();
4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_->message_type_count(); i++) {
4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      message_generators_[i]->GenerateTypeRegistrations(printer);
4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Outdent();
4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
4385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "}\n"
4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "\n"
4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "}  // namespace\n");
4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // -----------------------------------------------------------------
4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // ShutdownFile():  Deletes descriptors, default instances, etc. on shutdown.
4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n"
4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "void $shutdownfilename$() {\n",
4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "shutdownfilename", GlobalShutdownFileName(file_->name()));
4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Indent();
4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateShutdownCode(printer);
4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Outdent();
4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "}\n");
4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // -----------------------------------------------------------------
4615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
4625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Now generate the AddDescriptors() function.
4635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n"
4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "void $adddescriptorsname$() {\n"
4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // We don't need any special synchronization here because this code is
4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // called at static init time before any threads exist.
4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "  static bool already_here = false;\n"
4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "  if (already_here) return;\n"
4705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "  already_here = true;\n"
4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n",
4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Indent();
475e85eb5a7c3ea7eaca09cbb33920435d809b4dd3dNitin Shivpure
4765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Call the AddDescriptors() methods for all of our dependencies, to make
4775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // sure they get added first.
4785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->dependency_count(); i++) {
4795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    const FileDescriptor* dependency = file_->dependency(i);
4805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Print the namespace prefix for the dependency.
4815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    vector<string> dependency_package_parts;
4825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
4835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print("::");
4845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < dependency_package_parts.size(); i++) {
4855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print("$name$::",
4865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                     "name", dependency_package_parts[i]);
4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Call its AddDescriptors function.
4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "$name$();\n",
4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "name", GlobalAddDescriptorsName(dependency->name()));
4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
49484c63f1c985a30173fdf419167a3b85ba77a6d5bSharvil Nanavati  if (HasDescriptorMethods(file_)) {
49584c63f1c985a30173fdf419167a3b85ba77a6d5bSharvil Nanavati    // Embed the descriptor.  We simply serialize the entire FileDescriptorProto
4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // and embed it as a string literal, which is parsed and built into real
4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // descriptors at initialization time.
4985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    FileDescriptorProto file_proto;
4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    file_->CopyTo(&file_proto);
5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    string file_data;
5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    file_proto.SerializeToString(&file_data);
5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    // Only write 40 bytes per line.
5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    static const int kBytesPerLine = 40;
5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      printer->Print("\n  \"$data$\"",
5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        "data", CEscape(file_data.substr(i, kBytesPerLine)));
5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      ", $size$);\n",
5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "size", SimpleItoa(file_data.size()));
5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5165cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen    // Call MessageFactory::InternalRegisterGeneratedFile().
5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print(
5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "  \"$filename$\", &protobuf_RegisterTypes);\n",
5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      "filename", file_->name());
5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // Allocate and initialize default instances.  This can't be done lazily
5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // since default instances are returned by simple accessors and are used with
5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  // extensions.  Speaking of which, we also register extensions at this time.
5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->extension_count(); i++) {
5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    extension_generators_[i]->GenerateRegistration(printer);
5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = 0; i < file_->message_type_count(); i++) {
5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "shutdownfilename", GlobalShutdownFileName(file_->name()));
5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Outdent();
5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  printer->Print(
5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "}\n"
5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n"
5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "// Force AddDescriptors() to be called at static initialization time.\n"
5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "struct StaticDescriptorInitializer_$filename$ {\n"
5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "  StaticDescriptorInitializer_$filename$() {\n"
548e85eb5a7c3ea7eaca09cbb33920435d809b4dd3dNitin Shivpure    "    $adddescriptorsname$();\n"
549e85eb5a7c3ea7eaca09cbb33920435d809b4dd3dNitin Shivpure    "  }\n"
5505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "} static_descriptor_initializer_$filename$_;\n"
5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "\n",
5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    "filename", FilenameIdentifier(file_->name()));
5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (package_parts_.size() > 0) printer->Print("\n");
5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
559e85eb5a7c3ea7eaca09cbb33920435d809b4dd3dNitin Shivpure  for (int i = 0; i < package_parts_.size(); i++) {
560e85eb5a7c3ea7eaca09cbb33920435d809b4dd3dNitin Shivpure    printer->Print("namespace $part$ {\n",
561e85eb5a7c3ea7eaca09cbb33920435d809b4dd3dNitin Shivpure                   "part", package_parts_[i]);
5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  if (package_parts_.size() > 0) printer->Print("\n");
5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  for (int i = package_parts_.size() - 1; i >= 0; i--) {
5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    printer->Print("}  // namespace $part$\n",
5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                   "part", package_parts_[i]);
5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
5725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}
5735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}  // namespace cpp
5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}  // namespace compiler
5765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}  // namespace protobuf
5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}  // namespace google
5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project