1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_file.h>
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_enum.h>
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_service.h>
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_extension.h>
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_helpers.h>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/cpp/cpp_message.h>
41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/compiler/cpp/cpp_field.h>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h>
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace cpp {
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ===================================================================
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileGenerator::FileGenerator(const FileDescriptor* file,
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                             const string& dllexport_decl)
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  : file_(file),
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_(
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new scoped_ptr<MessageGenerator>[file->message_type_count()]),
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_(
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new scoped_ptr<EnumGenerator>[file->enum_type_count()]),
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    service_generators_(
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new scoped_ptr<ServiceGenerator>[file->service_count()]),
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_(
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    dllexport_decl_(dllexport_decl) {
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file->message_type_count(); i++) {
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i].reset(
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new MessageGenerator(file->message_type(i), dllexport_decl));
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file->enum_type_count(); i++) {
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i].reset(
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new EnumGenerator(file->enum_type(i), dllexport_decl));
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file->service_count(); i++) {
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    service_generators_[i].reset(
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new ServiceGenerator(file->service(i), dllexport_decl));
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file->extension_count(); i++) {
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i].reset(
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new ExtensionGenerator(file->extension(i), dllexport_decl));
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  SplitStringUsing(file_->package(), ".", &package_parts_);
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileGenerator::~FileGenerator() {}
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileGenerator::GenerateHeader(io::Printer* printer) {
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string filename_identifier = FilenameIdentifier(file_->name());
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate top of header.
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// source: $filename$\n"
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <string>\n"
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "filename", file_->name(),
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "filename_identifier", filename_identifier);
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <google/protobuf/stubs/common.h>\n"
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n");
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Verify the protobuf library header version is compatible with the protoc
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // version before going any further.
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#error This file was generated by a newer version of protoc which is\n"
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#error incompatible with your Protocol Buffer headers.  Please update\n"
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#error your headers.\n"
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#endif\n"
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#error This file was generated by an older version of protoc which is\n"
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#error incompatible with your Protocol Buffer headers.  Please\n"
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#error regenerate this file with a newer version of protoc.\n"
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#endif\n"
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "min_header_version",
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // OK, it's now safe to #include other files.
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <google/protobuf/generated_message_util.h>\n"
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <google/protobuf/repeated_field.h>\n"
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <google/protobuf/extension_set.h>\n");
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(file_)) {
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "#include <google/protobuf/generated_message_reflection.h>\n");
138d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
140d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (HasGenericServices(file_)) {
141d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer->Print(
142d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "#include <google/protobuf/service.h>\n");
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
145d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->dependency_count(); i++) {
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "#include \"$dependency$.pb.h\"\n",
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "dependency", StripProto(file_->dependency(i)->name()));
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
152d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
153d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(includes)\n");
154d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Open namespace.
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateNamespaceOpeners(printer);
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // functions, so that we can declare them to be friends of each class.
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// Internal implementation detail -- do not call these.\n"
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $dllexport_decl$ $adddescriptorsname$();\n",
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "dllexport_decl", dllexport_decl_);
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Note that we don't put dllexport_decl on these because they are only
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // called by the .pb.cc file in which they are defined.
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $assigndescriptorsname$();\n"
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $shutdownfilename$();\n"
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "shutdownfilename", GlobalShutdownFileName(file_->name()));
175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate forward declarations of classes.
177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateForwardDeclaration(printer);
179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate enum definitions.
184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateEnumDefinitions(printer);
186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->enum_type_count(); i++) {
188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateDefinition(printer);
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(kThickSeparator);
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate class definitions.
195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (i > 0) {
197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(kThinSeparator);
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateClassDefinition(printer);
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(kThickSeparator);
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
208d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (HasGenericServices(file_)) {
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate service definitions.
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->service_count(); i++) {
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i > 0) {
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print("\n");
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print(kThinSeparator);
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        printer->Print("\n");
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      service_generators_[i]->GenerateDeclarations(printer);
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThickSeparator);
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Declare extension identifiers.
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->extension_count(); i++) {
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateDeclaration(printer);
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(kThickSeparator);
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print("\n");
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate class inline methods.
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (i > 0) {
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(kThinSeparator);
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateInlineMethods(printer);
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
242d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
243d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n"
244d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(namespace_scope)\n");
245d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Close up namespace.
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateNamespaceClosers(printer);
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Emit GetEnumDescriptor specializations into google::protobuf namespace:
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(file_)) {
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // The SWIG conditional is to avoid a null-pointer dereference
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    //   namespace X { void Y<Z::W>(); }
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // which appears in GetEnumDescriptor() specializations.
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "\n"
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "#ifndef SWIG\n"
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "namespace google {\nnamespace protobuf {\n"
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "\n");
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->message_type_count(); i++) {
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->enum_type_count(); i++) {
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "\n"
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "}  // namespace google\n}  // namespace protobuf\n"
269d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "#endif  // SWIG\n");
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n"
274d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(global_scope)\n"
275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n");
276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#endif  // PROTOBUF_$filename_identifier$__INCLUDED\n",
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "filename_identifier", filename_identifier);
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileGenerator::GenerateSource(io::Printer* printer) {
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // The generated code calls accessors that might be deprecated. We don't
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // want the compiler to warn in generated code.
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include \"$basename$.pb.h\"\n"
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <google/protobuf/stubs/once.h>\n"
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <google/protobuf/io/coded_stream.h>\n"
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "#include <google/protobuf/wire_format_lite_inl.h>\n",
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "basename", StripProto(file_->name()));
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(file_)) {
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "#include <google/protobuf/descriptor.h>\n"
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "#include <google/protobuf/reflection_ops.h>\n"
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "#include <google/protobuf/wire_format.h>\n");
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
303d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
304d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(includes)\n");
305d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateNamespaceOpeners(printer);
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(file_)) {
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "namespace {\n"
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->message_type_count(); i++) {
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_generators_[i]->GenerateDescriptorDeclarations(printer);
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->enum_type_count(); i++) {
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "name", ClassName(file_->enum_type(i), false));
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
321d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    if (HasGenericServices(file_)) {
323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      for (int i = 0; i < file_->service_count(); i++) {
324d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        printer->Print(
325d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
326d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          "name", file_->service(i)->name());
327d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}  // namespace\n"
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Define our externally-visible BuildDescriptors() function.  (For the lite
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // library, all this does is initialize default instances.)
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateBuildDescriptors(printer);
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate enums.
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->enum_type_count(); i++) {
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    enum_generators_[i]->GenerateMethods(printer);
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Generate classes.
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(kThickSeparator);
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("\n");
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateClassMethods(printer);
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
353d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (HasGenericServices(file_)) {
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Generate services.
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->service_count(); i++) {
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (i == 0) printer->Print("\n");
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print(kThickSeparator);
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n");
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      service_generators_[i]->GenerateImplementation(printer);
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Define extensions.
364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->extension_count(); i++) {
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateDefinition(printer);
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
368d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
369d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n"
370d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(namespace_scope)\n");
371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GenerateNamespaceClosers(printer);
373d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n"
376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "// @@protoc_insertion_point(global_scope)\n");
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // AddDescriptors() is a file-level procedure which adds the encoded
381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // FileDescriptorProto for this .proto file to the global DescriptorPool
382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // for generated files (DescriptorPool::generated_pool()).  It always runs
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // at static initialization time, so all files will be registered before
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // main() starts.  This procedure also constructs default instances and
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // registers extensions.
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Its sibling, AssignDescriptors(), actually pulls the compiled
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // FileDescriptor from the DescriptorPool and uses it to populate all of
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // the global variables which store pointers to the descriptor objects.
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // It also constructs the reflection objects.  It is called the first time
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // anyone calls descriptor() or GetReflection() on one of the types defined
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // in the file.
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // and we only use AddDescriptors() to allocate default instances.
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(file_)) {
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void $assigndescriptorsname$() {\n",
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Make sure the file has found its way into the pool.  If a descriptor
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // is requested *during* static init then AddDescriptors() may not have
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // been called yet, so we call it manually.  Note that it's fine if
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // AddDescriptors() is called multiple times.
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$adddescriptorsname$();\n",
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Get the file's descriptor from the pool.
412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "const ::google::protobuf::FileDescriptor* file =\n"
414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "    \"$filename$\");\n"
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      // being unused when compiling an empty .proto file.
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "GOOGLE_CHECK(file != NULL);\n",
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "filename", file_->name());
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Go through all the stuff defined in this file and generated code to
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // assign the global descriptor pointers based on the file descriptor.
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->message_type_count(); i++) {
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_generators_[i]->GenerateDescriptorInitializer(printer, i);
425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->enum_type_count(); i++) {
427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
429d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    if (HasGenericServices(file_)) {
430d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      for (int i = 0; i < file_->service_count(); i++) {
431d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        service_generators_[i]->GenerateDescriptorInitializer(printer, i);
432d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n");
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // ---------------------------------------------------------------
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // protobuf_AssignDescriptorsOnce():  The first time it is called, calls
443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // AssignDescriptors().  All later times, waits for the first call to
444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // complete and then returns.
445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "namespace {\n"
447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "inline void protobuf_AssignDescriptorsOnce() {\n"
450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "                 &$assigndescriptorsname$);\n"
452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n",
454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // protobuf_RegisterTypes():  Calls
457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // MessageFactory::InternalRegisterGeneratedType() for each message type.
458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "void protobuf_RegisterTypes(const ::std::string&) {\n"
460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  protobuf_AssignDescriptorsOnce();\n");
461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Indent();
462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_->message_type_count(); i++) {
464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_generators_[i]->GenerateTypeRegistrations(printer);
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Outdent();
468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}\n"
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "}  // namespace\n");
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // -----------------------------------------------------------------
475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // ShutdownFile():  Deletes descriptors, default instances, etc. on shutdown.
477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $shutdownfilename$() {\n",
480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "shutdownfilename", GlobalShutdownFileName(file_->name()));
481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateShutdownCode(printer);
485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n");
490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // -----------------------------------------------------------------
492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Now generate the AddDescriptors() function.
494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "void $adddescriptorsname$() {\n"
497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // We don't need any special synchronization here because this code is
498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // called at static init time before any threads exist.
499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  static bool already_here = false;\n"
500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  if (already_here) return;\n"
501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  already_here = true;\n"
502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Indent();
506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Call the AddDescriptors() methods for all of our dependencies, to make
508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // sure they get added first.
509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->dependency_count(); i++) {
510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FileDescriptor* dependency = file_->dependency(i);
511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Print the namespace prefix for the dependency.
512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    vector<string> dependency_package_parts;
513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    SplitStringUsing(dependency->package(), ".", &dependency_package_parts);
514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("::");
515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < dependency_package_parts.size(); i++) {
516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("$name$::",
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                     "name", dependency_package_parts[i]);
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Call its AddDescriptors function.
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$name$();\n",
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name", GlobalAddDescriptorsName(dependency->name()));
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (HasDescriptorMethods(file_)) {
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Embed the descriptor.  We simply serialize the entire FileDescriptorProto
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // and embed it as a string literal, which is parsed and built into real
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // descriptors at initialization time.
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FileDescriptorProto file_proto;
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    file_->CopyTo(&file_proto);
531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string file_data;
532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    file_proto.SerializeToString(&file_data);
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Only write 40 bytes per line.
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    static const int kBytesPerLine = 40;
539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      printer->Print("\n  \"$data$\"",
541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "data", CEscape(file_data.substr(i, kBytesPerLine)));
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ", $size$);\n",
545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "size", SimpleItoa(file_data.size()));
546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Call MessageFactory::InternalRegisterGeneratedFile().
548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  \"$filename$\", &protobuf_RegisterTypes);\n",
551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "filename", file_->name());
552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Allocate and initialize default instances.  This can't be done lazily
555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // since default instances are returned by simple accessors and are used with
556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // extensions.  Speaking of which, we also register extensions at this time.
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->extension_count(); i++) {
561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension_generators_[i]->GenerateRegistration(printer);
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); i++) {
564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "shutdownfilename", GlobalShutdownFileName(file_->name()));
570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Outdent();
572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "}\n"
575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n"
576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "// Force AddDescriptors() to be called at static initialization time.\n"
577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "struct StaticDescriptorInitializer_$filename$ {\n"
578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  StaticDescriptorInitializer_$filename$() {\n"
579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "    $adddescriptorsname$();\n"
580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "  }\n"
581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "} static_descriptor_initializer_$filename$_;\n"
582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "\n",
583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    "filename", FilenameIdentifier(file_->name()));
585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (package_parts_.size() > 0) printer->Print("\n");
589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < package_parts_.size(); i++) {
591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("namespace $part$ {\n",
592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   "part", package_parts_[i]);
593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (package_parts_.size() > 0) printer->Print("\n");
598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = package_parts_.size() - 1; i >= 0; i--) {
600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print("}  // namespace $part$\n",
601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                   "part", package_parts_[i]);
602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace cpp
606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
609