1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/
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
31a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson//#PY25 compatible generated code for GAE.
32a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Copyright 2007 Google Inc. All Rights Reserved.
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: robinson@google.com (Will Robinson)
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This module outputs pure-Python protocol message classes that will
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// largely be constructed at runtime via the metaclass in reflection.py.
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// In other words, our job is basically to output a Python equivalent
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// of the C++ *Descriptor objects, and fix up all circular references
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// within these objects.
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Note that the runtime performance of protocol message classes created in
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this way is expected to be lousy.  The plan is to create an alternate
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// generator that outputs a Python/C extension module that lets
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// performance-minded Python code leverage the fast C++ implementation
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// directly.
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
47b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/hash.h>
48d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <limits>
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <map>
50a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <memory>
51b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#ifndef _SHARED_PTR_H
52b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/shared_ptr.h>
53b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#endif
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <string>
55b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <utility>
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector>
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/python/python_generator.h>
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
61b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/logging.h>
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h>
63a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/stubs/stringprintf.h>
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h>
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h>
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream.h>
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/substitute.h>
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace python {
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a copy of |filename| with any trailing ".protodevel" or ".proto
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// suffix stripped.
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc.
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring StripProto(const string& filename) {
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char* suffix = HasSuffixString(filename, ".protodevel")
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ? ".protodevel" : ".proto";
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return StripSuffixString(filename, suffix);
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the Python module name expected for a given .proto filename.
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ModuleName(const string& filename) {
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string basename = StripProto(filename);
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  StripString(&basename, "-", '_');
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  StripString(&basename, "/", '.');
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return basename + "_pb2";
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
96b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Returns the alias we assign to the module of the given .proto filename
97b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// when importing. See testPackageInitializationImport in
98b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// google/protobuf/python/reflection_test.py
99b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// to see why we need the alias.
100b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstring ModuleAlias(const string& filename) {
101b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  string module_name = ModuleName(filename);
102b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // We can't have dots in the module name, so we replace each with _dot_.
103b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // But that could lead to a collision between a.b and a_dot_b, so we also
104b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // duplicate each underscore.
105b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  GlobalReplaceSubstring("_", "__", &module_name);
106b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  GlobalReplaceSubstring(".", "_dot_", &module_name);
107b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  return module_name;
108b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
109b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
110b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
111b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Returns an import statement of form "from X.Y.Z import T" for the given
112b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// .proto filename.
113b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstring ModuleImportStatement(const string& filename) {
114b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  string module_name = ModuleName(filename);
115b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  int last_dot_pos = module_name.rfind('.');
116b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  if (last_dot_pos == string::npos) {
117b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    // NOTE(petya): this is not tested as it would require a protocol buffer
118b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    // outside of any package, and I don't think that is easily achievable.
119b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    return "import " + module_name;
120b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  } else {
121b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    return "from " + module_name.substr(0, last_dot_pos) + " import " +
122b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer        module_name.substr(last_dot_pos + 1);
123b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
124b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
125b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
126b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the name of all containing types for descriptor,
128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in order from outermost to innermost, followed by descriptor's
129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// own name.  Each name is separated by |separator|.
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate <typename DescriptorT>
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                   const string& separator) {
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = descriptor.name();
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (const Descriptor* current = descriptor.containing_type();
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       current != NULL; current = current->containing_type()) {
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name = current->name() + separator + name;
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Name of the class attribute where we store the Python
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// descriptor.Descriptor instance for the generated class.
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Must stay consistent with the _DESCRIPTOR_KEY constant
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in proto2/public/reflection.py.
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char kDescriptorKey[] = "DESCRIPTOR";
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
149a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Does the file have top-level enums?
150a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsoninline bool HasTopLevelEnums(const FileDescriptor *file) {
151a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  return file->enum_type_count() > 0;
152a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
153a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
154a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
155d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Should we generate generic services for this file?
156d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleinline bool HasGenericServices(const FileDescriptor *file) {
157d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return file->service_count() > 0 &&
158d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville         file->options().py_generic_services();
159d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
160d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
161d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints the common boilerplate needed at the top of every .py
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// file output by this generator.
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid PrintTopBoilerplate(
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) {
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(robinson): Allow parameterization of Python version?
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
169a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "# source: $filename$\n"
170a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))"  //##PY25
171a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "\n",
172a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "filename", file->name());
173a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (HasTopLevelEnums(file)) {
174a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer->Print(
175a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "from google.protobuf.internal import enum_type_wrapper\n");
176a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
177a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
178a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "from google.protobuf import descriptor as _descriptor\n"
179a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "from google.protobuf import message as _message\n"
180a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "from google.protobuf import reflection as _reflection\n"
181a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "from google.protobuf import symbol_database as "
182a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "_symbol_database\n");
183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (HasGenericServices(file)) {
184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer->Print(
185a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "from google.protobuf import service as _service\n"
186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "from google.protobuf import service_reflection\n");
187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Avoid circular imports if this module is descriptor_pb2.
190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!descriptor_proto) {
191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "from google.protobuf import descriptor_pb2\n");
193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
194d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
195a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "# @@protoc_insertion_point(imports)\n\n"
196a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "_sym_db = _symbol_database.Default()\n");
197d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print("\n\n");
198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a Python literal giving the default value for a field.
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// If the field specifies no explicit default value, we'll return
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the default default value for the field type (zero for numbers,
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// empty string for strings, empty list for repeated fields, and
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// None for non-repeated, composite fields).
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(robinson): Unify with code from
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// //compiler/cpp/internal/primitive_field.cc
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// //compiler/cpp/internal/enum_field.cc
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// //compiler/cpp/internal/string_field.cc
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring StringifyDefaultValue(const FieldDescriptor& field) {
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (field.is_repeated()) {
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return "[]";
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (field.cpp_type()) {
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT32:
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_int32());
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT32:
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_uint32());
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT64:
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_int64());
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT64:
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_uint64());
225d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    case FieldDescriptor::CPPTYPE_DOUBLE: {
226d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      double value = field.default_value_double();
227d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (value == numeric_limits<double>::infinity()) {
228d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
229d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // a numeric literal that is too big for a double will become infinity.
230d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "1e10000";
231d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value == -numeric_limits<double>::infinity()) {
232d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // See above.
233d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "-1e10000";
234d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value != value) {
235d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // infinity * 0 = nan
236d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "(1e10000 * 0)";
237d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
238b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer        return "float(" + SimpleDtoa(value) + ")";
239d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
240d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
241d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    case FieldDescriptor::CPPTYPE_FLOAT: {
242d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      float value = field.default_value_float();
243d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (value == numeric_limits<float>::infinity()) {
244d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
245d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // a numeric literal that is too big for a double will become infinity.
246d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "1e10000";
247d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value == -numeric_limits<float>::infinity()) {
248d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // See above.
249d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "-1e10000";
250d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value != value) {
251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // infinity - infinity = nan
252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "(1e10000 * 0)";
253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
254b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer        return "float(" + SimpleFtoa(value) + ")";
255d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
256d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_BOOL:
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return field.default_value_bool() ? "True" : "False";
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_ENUM:
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_enum()->number());
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_STRING:
262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson//##!PY25      return "b\"" + CEscape(field.default_value_string()) +
263a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson//##!PY25             (field.type() != FieldDescriptor::TYPE_STRING ? "\"" :
264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson//##!PY25               "\".decode('utf-8')");
265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      return "_b(\"" + CEscape(field.default_value_string()) +  //##PY25
266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson             (field.type() != FieldDescriptor::TYPE_STRING ? "\")" :  //##PY25
267a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson               "\").decode('utf-8')");  //##PY25
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_MESSAGE:
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return "None";
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // (We could add a default case above but then we wouldn't get the nice
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // compiler warning when a new type is added.)
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Not reached.";
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "";
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
277b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstring StringifySyntax(FileDescriptor::Syntax syntax) {
278b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  switch (syntax) {
279b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    case FileDescriptor::SYNTAX_PROTO2:
280b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      return "proto2";
281b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    case FileDescriptor::SYNTAX_PROTO3:
282b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      return "proto3";
283b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    case FileDescriptor::SYNTAX_UNKNOWN:
284b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    default:
285b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports proto2 "
286b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                    "and proto3 syntax.";
287b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      return "";
288b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
289b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerator::Generator() : file_(NULL) {
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerator::~Generator() {
299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Generator::Generate(const FileDescriptor* file,
302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         const string& parameter,
303a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                         GeneratorContext* context,
304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         string* error) const {
305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Completely serialize all Generate() calls on this instance.  The
307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // thread-safety constraints of the CodeGenerator interface aren't clear so
308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // just be as conservative as possible.  It's easier to relax this later if
309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // we need to, but I doubt it will be an issue.
310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  The proper thing to do would be to allocate any state on
311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   the stack and use that, so that the Generator class itself does not need
312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   to have any mutable members.  Then it is implicitly thread-safe.
313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  MutexLock lock(&mutex_);
314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  file_ = file;
315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string module_name = ModuleName(file->name());
316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string filename = module_name;
317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  StripString(&filename, ".", '/');
318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  filename += ".py";
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
320d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  FileDescriptorProto fdp;
321d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  file_->CopyTo(&fdp);
322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  fdp.SerializeToString(&file_descriptor_serialized_);
323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
325b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK(output.get());
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  io::Printer printer(output.get(), '$');
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_ = &printer;
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
331a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  PrintImports();
332d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintFileDescriptor();
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintTopLevelEnums();
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintTopLevelExtensions();
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintAllNestedEnumsInFile();
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintMessageDescriptors();
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FixForeignFieldsInDescriptors();
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintMessages();
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We have to fix up the extensions after the message classes themselves,
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // since they need to call static RegisterExtension() methods on these
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // classes.
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FixForeignFieldsInExtensions();
343a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Descriptor options may have custom extensions. These custom options
344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // can only be successfully parsed after we register corresponding
345a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // extensions. Therefore we parse all options again here to recognize
346a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // custom options that may be unknown when we define the descriptors.
347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  FixAllDescriptorOptions();
348d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (HasGenericServices(file)) {
349d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    PrintServices();
350d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
351d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
352d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer.Print(
353d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "# @@protoc_insertion_point(module_scope)\n");
354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return !printer.failed();
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints Python imports for all modules imported by |file|.
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintImports() const {
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->dependency_count(); ++i) {
361b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    const string& filename = file_->dependency(i)->name();
362b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    string import_statement = ModuleImportStatement(filename);
363b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    string module_alias = ModuleAlias(filename);
364b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    printer_->Print("$statement$ as $alias$\n", "statement",
365b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                    import_statement, "alias", module_alias);
366b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    CopyPublicDependenciesAliases(module_alias, file_->dependency(i));
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
369a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
370a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Print public imports.
371a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < file_->public_dependency_count(); ++i) {
372a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    string module_name = ModuleName(file_->public_dependency(i)->name());
373a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer_->Print("from $module$ import *\n", "module", module_name);
374a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
375a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("\n");
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
378d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Prints the single file descriptor for this file.
379d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid Generator::PrintFileDescriptor() const {
380d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  map<string, string> m;
381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["descriptor_name"] = kDescriptorKey;
382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["name"] = file_->name();
383d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["package"] = file_->package();
384b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  m["syntax"] = StringifySyntax(file_->syntax());
385d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  const char file_descriptor_template[] =
386a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor_name$ = _descriptor.FileDescriptor(\n"
387d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  name='$name$',\n"
388b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      "  package='$package$',\n"
389b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      "  syntax='$syntax$',\n";
390d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(m, file_descriptor_template);
391d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Indent();
392d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(
393a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson//##!PY25      "serialized_pb=b'$value$'\n",
394a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "serialized_pb=_b('$value$')\n",  //##PY25
395d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "value", strings::CHexEscape(file_descriptor_serialized_));
396a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (file_->dependency_count() != 0) {
397a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer_->Print(",\ndependencies=[");
398a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int i = 0; i < file_->dependency_count(); ++i) {
399b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      string module_alias = ModuleAlias(file_->dependency(i)->name());
400b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
401b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                      module_alias);
402a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
403a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer_->Print("]");
404a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
405d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // TODO(falk): Also print options and fix the message_type, enum_type,
407d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  //             service and extension later in the generation.
408d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
409d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Outdent();
410d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(")\n");
411a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
412a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                  kDescriptorKey);
413d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("\n");
414d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
415d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints descriptors and module-level constants for all top-level
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// enums defined in |file|.
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintTopLevelEnums() const {
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vector<pair<string, int> > top_level_enum_values;
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->enum_type_count(); ++i) {
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintEnum(enum_descriptor);
423a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer_->Print("$name$ = "
424a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                    "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)",
425a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                    "name", enum_descriptor.name(),
426a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                    "descriptor_name",
427a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                    ModuleLevelDescriptorName(enum_descriptor));
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int j = 0; j < enum_descriptor.value_count(); ++j) {
431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j);
432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      top_level_enum_values.push_back(
433b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer          std::make_pair(value_descriptor.name(), value_descriptor.number()));
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < top_level_enum_values.size(); ++i) {
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("$name$ = $value$\n",
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                    "name", top_level_enum_values[i].first,
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                    "value", SimpleItoa(top_level_enum_values[i].second));
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints all enums contained in all message types in |file|.
446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintAllNestedEnumsInFile() const {
447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintNestedEnums(*file_->message_type(i));
449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a Python statement assigning the appropriate module-level
453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// enum name to a Python EnumDescriptor object equivalent to
454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// enum_descriptor.
455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
457a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  string module_level_descriptor_name =
458a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      ModuleLevelDescriptorName(enum_descriptor);
459a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["descriptor_name"] = module_level_descriptor_name;
460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = enum_descriptor.name();
461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = enum_descriptor.full_name();
462d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["file"] = kDescriptorKey;
463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char enum_descriptor_template[] =
464a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor_name$ = _descriptor.EnumDescriptor(\n"
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  name='$name$',\n"
466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  full_name='$full_name$',\n"
467d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  filename=None,\n"
468d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  file=$file$,\n"
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  values=[\n";
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  enum_descriptor.options().SerializeToString(&options_string);
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, enum_descriptor_template);
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < enum_descriptor.value_count(); ++i) {
476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintEnumValueDescriptor(*enum_descriptor.value(i));
477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(",\n");
478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("],\n");
481d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("containing_type=None,\n");
482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("options=$options_value$,\n",
483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  "options_value",
484a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                  OptionsValue("EnumOptions", options_string));
485d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  EnumDescriptorProto edp;
486d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintSerializedPbInterval(enum_descriptor, edp);
487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(")\n");
489a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
490a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                  module_level_descriptor_name);
491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Recursively prints enums in nested types within descriptor, then
495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// prints enums contained at the top level in descriptor.
496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintNestedEnums(const Descriptor& descriptor) const {
497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintNestedEnums(*descriptor.nested_type(i));
499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintEnum(*descriptor.enum_type(i));
503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintTopLevelExtensions() const {
507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const bool is_extension = true;
508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->extension_count(); ++i) {
509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& extension_field = *file_->extension(i);
510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string constant_name = extension_field.name() + "_FIELD_NUMBER";
511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    UpperString(&constant_name);
512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("$constant_name$ = $number$\n",
513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "constant_name", constant_name,
514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "number", SimpleItoa(extension_field.number()));
515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("$name$ = ", "name", extension_field.name());
516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldDescriptor(extension_field, is_extension);
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints Python equivalents of all Descriptors in |file|.
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintMessageDescriptors() const {
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintDescriptor(*file_->message_type(i));
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintServices() const {
531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->service_count(); ++i) {
532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintServiceDescriptor(*file_->service(i));
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintServiceClass(*file_->service(i));
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintServiceStub(*file_->service(i));
535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintServiceDescriptor(
540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const ServiceDescriptor& descriptor) const {
541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string service_name = ModuleLevelServiceDescriptorName(descriptor);
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  descriptor.options().SerializeToString(&options_string);
545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
547a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$service_name$ = _descriptor.ServiceDescriptor(\n",
548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "service_name", service_name);
549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = descriptor.name();
552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = descriptor.full_name();
553d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["file"] = kDescriptorKey;
554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["index"] = SimpleItoa(descriptor.index());
555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["options_value"] = OptionsValue("ServiceOptions", options_string);
556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char required_function_arguments[] =
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name='$name$',\n"
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "full_name='$full_name$',\n"
559d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "file=$file$,\n"
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "index=$index$,\n"
561d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "options=$options_value$,\n";
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, required_function_arguments);
563d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
564d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  ServiceDescriptorProto sdp;
565d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintSerializedPbInterval(descriptor, sdp);
566d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
567d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("methods=[\n");
568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.method_count(); ++i) {
569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MethodDescriptor* method = descriptor.method(i);
570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    method->options().SerializeToString(&options_string);
571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m.clear();
573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["name"] = method->name();
574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["full_name"] = method->full_name();
575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["index"] = SimpleItoa(method->index());
576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["serialized_options"] = CEscape(options_string);
577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["options_value"] = OptionsValue("MethodOptions", options_string);
580a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer_->Print("_descriptor.MethodDescriptor(\n");
581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Indent();
582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(
583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        m,
584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "name='$name$',\n"
585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "full_name='$full_name$',\n"
586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "index=$index$,\n"
587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "containing_service=None,\n"
588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "input_type=$input_type$,\n"
589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "output_type=$output_type$,\n"
590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "options=$options_value$,\n");
591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Outdent();
592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("),\n");
593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("])\n\n");
597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
599b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
600b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid Generator::PrintDescriptorKeyAndModuleName(
601b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    const ServiceDescriptor& descriptor) const {
602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
603a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor_key$ = $descriptor_name$,\n",
604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "descriptor_key", kDescriptorKey,
605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
606a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print(
607a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "__module__ = '$module_name$'\n",
608a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "module_name", ModuleName(file_->name()));
609b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
610b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
611b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
612b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  // Print the service.
613b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  printer_->Print("$class_name$ = service_reflection.GeneratedServiceType("
614b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                  "'$class_name$', (_service.Service,), dict(\n",
615b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                  "class_name", descriptor.name());
616b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  printer_->Indent();
617b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  Generator::PrintDescriptorKeyAndModuleName(descriptor);
618a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("))\n\n");
619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Print the service stub.
624a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("$class_name$_Stub = "
625a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                  "service_reflection.GeneratedServiceStubType("
626a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                  "'$class_name$_Stub', ($class_name$,), dict(\n",
627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  "class_name", descriptor.name());
628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
629b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  Generator::PrintDescriptorKeyAndModuleName(descriptor);
630a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("))\n\n");
631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to a Python Descriptor object for message_descriptor.
636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintNestedDescriptors().
638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintNestedDescriptors(message_descriptor);
640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
642a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n",
643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  "descriptor_name",
644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  ModuleLevelDescriptorName(message_descriptor));
645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = message_descriptor.name();
648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = message_descriptor.full_name();
649d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["file"] = kDescriptorKey;
650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char required_function_arguments[] =
651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name='$name$',\n"
652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "full_name='$full_name$',\n"
653d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "filename=None,\n"
654d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "file=$file$,\n"
655d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "containing_type=None,\n";
656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, required_function_arguments);
657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldsInDescriptor(message_descriptor);
658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintExtensionsInDescriptor(message_descriptor);
659d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
660d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Nested types
661d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("nested_types=[");
662d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
663d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const string nested_name = ModuleLevelDescriptorName(
664d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        *message_descriptor.nested_type(i));
665d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer_->Print("$name$, ", "name", nested_name);
666d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
667d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("],\n");
668d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
669d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Enum types
670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("enum_types=[\n");
671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string descriptor_name = ModuleLevelDescriptorName(
674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        *message_descriptor.enum_type(i));
675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(descriptor_name.c_str());
676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(",\n");
677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("],\n");
680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  message_descriptor.options().SerializeToString(&options_string);
682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
683d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "options=$options_value$,\n"
684b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      "is_extendable=$extendable$,\n"
685b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      "syntax='$syntax$'",
686d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "options_value", OptionsValue("MessageOptions", options_string),
687d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "extendable", message_descriptor.extension_range_count() > 0 ?
688b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                      "True" : "False",
689b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer      "syntax", StringifySyntax(message_descriptor.file()->syntax()));
690d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(",\n");
691d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
692d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Extension ranges
693d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("extension_ranges=[");
694d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
695d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor::ExtensionRange* range =
696d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        message_descriptor.extension_range(i);
697d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer_->Print("($start$, $end$), ",
698d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                    "start", SimpleItoa(range->start),
699d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                    "end", SimpleItoa(range->end));
700d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
701d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("],\n");
702a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("oneofs=[\n");
703a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Indent();
704a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) {
705a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const OneofDescriptor* desc = message_descriptor.oneof_decl(i);
706a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    map<string, string> m;
707a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    m["name"] = desc->name();
708a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    m["full_name"] = desc->full_name();
709a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    m["index"] = SimpleItoa(desc->index());
710a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer_->Print(
711a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        m,
712a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "_descriptor.OneofDescriptor(\n"
713a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  name='$name$', full_name='$full_name$',\n"
714a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "  index=$index$, containing_type=None, fields=[]),\n");
715a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
716a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Outdent();
717a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("],\n");
718d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Serialization of proto
719d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  DescriptorProto edp;
720d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintSerializedPbInterval(message_descriptor, edp);
721d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(")\n");
724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints Python Descriptor objects for all nested types contained in
727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// message_descriptor.
728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintDescriptor().
730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintNestedDescriptors(
731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& containing_descriptor) const {
732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintDescriptor(*containing_descriptor.nested_type(i));
734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints all messages in |file|.
738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintMessages() const {
739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
740a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    vector<string> to_register;
741a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    PrintMessage(*file_->message_type(i), "", &to_register);
742a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < to_register.size(); ++j) {
743a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
744a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                      to_register[j]);
745a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a Python class for the given message descriptor.  We defer to the
751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// metaclass to do almost all of the work of actually creating a useful class.
752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The purpose of this function and its many helper functions above is merely
753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to output a Python version of the descriptors, which the metaclass in
754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// reflection.py will use to construct the meat of the class itself.
755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintNestedMessages().
757a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Collect nested message names to_register for the symbol_database.
758a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::PrintMessage(const Descriptor& message_descriptor,
759a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                             const string& prefix,
760a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                             vector<string>* to_register) const {
761a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  string qualified_name(prefix + message_descriptor.name());
762a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  to_register->push_back(qualified_name);
763a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print(
764a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$name$ = _reflection.GeneratedProtocolMessageType('$name$', "
765a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "(_message.Message,), dict(\n",
766a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "name", message_descriptor.name());
767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
768a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
769a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  PrintNestedMessages(message_descriptor, qualified_name + ".", to_register);
770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["descriptor_key"] = kDescriptorKey;
772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
773a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print(m, "$descriptor_key$ = $descriptor_name$,\n");
774a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("__module__ = '$module_name$'\n",
775a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                  "module_name", ModuleName(file_->name()));
776a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
777a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                  "full_name", message_descriptor.full_name());
778a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("))\n");
779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints all nested messages within |containing_descriptor|.
783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintMessage().
784a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::PrintNestedMessages(const Descriptor& containing_descriptor,
785a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                    const string& prefix,
786a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                    vector<string>* to_register) const {
787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
789a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register);
790a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    printer_->Print(",\n");
791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Recursively fixes foreign fields in all nested types in |descriptor|, then
795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// sets the message_type and enum_type of all message and enum fields to point
796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to their respective descriptors.
797d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Args:
798d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   descriptor: descriptor to print fields for.
799d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   containing_descriptor: if descriptor is a nested type, this is its
800d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//       containing type, or NULL if this is a root/top-level type.
801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInDescriptor(
802d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor& descriptor,
803d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor* containing_descriptor) const {
804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
805d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.field_count(); ++i) {
809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& field_descriptor = *descriptor.field(i);
810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
812d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
813d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  FixContainingTypeInDescriptor(descriptor, containing_descriptor);
814d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
815d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
816d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
817d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
818a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
819a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    map<string, string> m;
820a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const OneofDescriptor* oneof = descriptor.oneof_decl(i);
821a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
822a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    m["oneof_name"] = oneof->name();
823a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    for (int j = 0; j < oneof->field_count(); ++j) {
824a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      m["field_name"] = oneof->field(j)->name();
825a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer_->Print(
826a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          m,
827a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n"
828a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "  $descriptor_name$.fields_by_name['$field_name$'])\n");
829a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      printer_->Print(
830a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          m,
831a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = "
832a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          "$descriptor_name$.oneofs_by_name['$oneof_name$']\n");
833a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
834a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
835a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
836a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
837a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
838a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  map<string, string> m;
839a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["descriptor_name"] = kDescriptorKey;
840a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["message_name"] = descriptor.name();
841a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
842a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const char file_descriptor_template[] =
843a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor_name$.message_types_by_name['$message_name$'] = "
844a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$message_descriptor_name$\n";
845a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print(m, file_descriptor_template);
846a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
847a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
848a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::AddEnumToFileDescriptor(
849a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const EnumDescriptor& descriptor) const {
850a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  map<string, string> m;
851a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["descriptor_name"] = kDescriptorKey;
852a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["enum_name"] = descriptor.name();
853a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
854a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const char file_descriptor_template[] =
855a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor_name$.enum_types_by_name['$enum_name$'] = "
856a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$enum_descriptor_name$\n";
857a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print(m, file_descriptor_template);
858a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
859a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
860a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::AddExtensionToFileDescriptor(
861a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor& descriptor) const {
862a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  map<string, string> m;
863a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["descriptor_name"] = kDescriptorKey;
864a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  m["field_name"] = descriptor.name();
865a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  const char file_descriptor_template[] =
866a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor_name$.extensions_by_name['$field_name$'] = "
867a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$field_name$\n";
868a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print(m, file_descriptor_template);
869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sets any necessary message_type and enum_type attributes
872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// for the Python version of |field|.
873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// containing_type may be NULL, in which case this is a module-level field.
875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// python_dict_name is the name of the Python dict where we should
877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// look the field up in the containing type.  (e.g., fields_by_name
878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// or extensions_by_name).  We ignore python_dict_name if containing_type
879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// is NULL.
880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInField(const Descriptor* containing_type,
881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                        const FieldDescriptor& field,
882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                        const string& python_dict_name) const {
883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const string field_referencing_expression = FieldReferencingExpression(
884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      containing_type, field, python_dict_name);
885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["field_ref"] = field_referencing_expression;
887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const Descriptor* foreign_message_type = field.message_type();
888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (foreign_message_type) {
889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const EnumDescriptor* enum_type = field.enum_type();
893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (enum_type) {
894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the module-level expression for the given FieldDescriptor.
900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Only works for fields in the .proto file this Generator is generating for.
901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// containing_type may be NULL, in which case this is a module-level field.
903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// python_dict_name is the name of the Python dict where we should
905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// look the field up in the containing type.  (e.g., fields_by_name
906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// or extensions_by_name).  We ignore python_dict_name if containing_type
907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// is NULL.
908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::FieldReferencingExpression(
909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor* containing_type,
910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& field,
911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string& python_dict_name) const {
912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We should only ever be looking up fields in the current file.
913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The only things we refer to from other files are message descriptors.
914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. "
915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                << file_->name();
916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!containing_type) {
917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return field.name();
918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return strings::Substitute(
920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$0.$1['$2']",
921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ModuleLevelDescriptorName(*containing_type),
922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      python_dict_name, field.name());
923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
925d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Prints containing_type for nested descriptors or enum descriptors.
926d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilletemplate <typename DescriptorT>
927d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid Generator::FixContainingTypeInDescriptor(
928d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const DescriptorT& descriptor,
929d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor* containing_descriptor) const {
930d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (containing_descriptor != NULL) {
931d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const string nested_name = ModuleLevelDescriptorName(descriptor);
932d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const string parent_name = ModuleLevelDescriptorName(
933d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        *containing_descriptor);
934d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer_->Print(
935a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "$nested_name$.containing_type = $parent_name$\n",
936d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "nested_name", nested_name,
937d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "parent_name", parent_name);
938d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
939d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
940d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints statements setting the message_type and enum_type fields in the
942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Python descriptor objects we've already output in ths file.  We must
943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// do this in a separate step due to circular references (otherwise, we'd
944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// just set everything in the initial assignment statements).
945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInDescriptors() const {
946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
947d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
949a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < file_->message_type_count(); ++i) {
950a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    AddMessageToFileDescriptor(*file_->message_type(i));
951a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
952a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < file_->enum_type_count(); ++i) {
953a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    AddEnumToFileDescriptor(*file_->enum_type(i));
954a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
955a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < file_->extension_count(); ++i) {
956a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    AddExtensionToFileDescriptor(*file_->extension(i));
957a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// We need to not only set any necessary message_type fields, but
962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// also need to call RegisterExtension() on each message we're
963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// extending.
964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInExtensions() const {
965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Top-level extensions.
966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->extension_count(); ++i) {
967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInExtension(*file_->extension(i));
968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Nested extensions.
970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInNestedExtensions(*file_->message_type(i));
972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
973a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer_->Print("\n");
974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInExtension(
977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& extension_field) const {
978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK(extension_field.is_extension());
979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // extension_scope() will be NULL for top-level extensions, which is
980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // exactly what FixForeignFieldsInField() wants.
981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FixForeignFieldsInField(extension_field.extension_scope(), extension_field,
982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                          "extensions_by_name");
983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Confusingly, for FieldDescriptors that happen to be extensions,
986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // containing_type() means "extended type."
987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // On the other hand, extension_scope() will give us what we normally
988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // mean by containing_type().
989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["extended_message_class"] = ModuleLevelMessageName(
990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      *extension_field.containing_type());
991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["field"] = FieldReferencingExpression(extension_field.extension_scope(),
992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                          extension_field,
993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                          "extensions_by_name");
994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInNestedExtensions(
998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& descriptor) const {
999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Recursively fix up extensions in all nested types.
1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Fix up extensions directly contained within this type.
1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.extension_count(); ++i) {
1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInExtension(*descriptor.extension(i));
1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a Python expression that instantiates a Python EnumValueDescriptor
1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// object for the given C++ descriptor.
1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintEnumValueDescriptor(
1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const EnumValueDescriptor& descriptor) const {
1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
1014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // More circular references.  ::sigh::
1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
1016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  descriptor.options().SerializeToString(&options_string);
1017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
1018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = descriptor.name();
1019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["index"] = SimpleItoa(descriptor.index());
1020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["number"] = SimpleItoa(descriptor.number());
1021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["options"] = OptionsValue("EnumValueOptions", options_string);
1022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      m,
1024a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "_descriptor.EnumValueDescriptor(\n"
1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  name='$name$', index=$index$, number=$number$,\n"
1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  options=$options$,\n"
1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  type=None)");
1028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1030a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Returns a Python expression that calls descriptor._ParseOptions using
1031a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// the given descriptor class name and serialized options protobuf string.
1032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::OptionsValue(
1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string& class_name, const string& serialized_options) const {
1034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
1035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return "None";
1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string full_class_name = "descriptor_pb2." + class_name;
1038a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson//##!PY25    return "_descriptor._ParseOptions(" + full_class_name + "(), b'"
1039a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson//##!PY25        + CEscape(serialized_options)+ "')";
1040a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    return "_descriptor._ParseOptions(" + full_class_name + "(), _b('"  //##PY25
1041a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        + CEscape(serialized_options)+ "'))";  //##PY25
1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints an expression for a Python FieldDescriptor for |field|.
1046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintFieldDescriptor(
1047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& field, bool is_extension) const {
1048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
1049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.options().SerializeToString(&options_string);
1050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
1051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = field.name();
1052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = field.full_name();
1053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["index"] = SimpleItoa(field.index());
1054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["number"] = SimpleItoa(field.number());
1055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["type"] = SimpleItoa(field.type());
1056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["cpp_type"] = SimpleItoa(field.cpp_type());
1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["label"] = SimpleItoa(field.label());
1058d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["has_default_value"] = field.has_default_value() ? "True" : "False";
1059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["default_value"] = StringifyDefaultValue(field);
1060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["is_extension"] = is_extension ? "True" : "False";
1061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["options"] = OptionsValue("FieldOptions", options_string);
1062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We always set message_type and enum_type to None at this point, and then
1063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // these fields in correctly after all referenced descriptors have been
1064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // defined and/or imported (see FixForeignFieldsInDescriptors()).
1065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char field_descriptor_decl[] =
1066a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    "_descriptor.FieldDescriptor(\n"
1067d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  name='$name$', full_name='$full_name$', index=$index$,\n"
1068d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
1069d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  has_default_value=$has_default_value$, default_value=$default_value$,\n"
1070d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  message_type=None, enum_type=None, containing_type=None,\n"
1071d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  is_extension=$is_extension$, extension_scope=None,\n"
1072d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  options=$options$)";
1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, field_descriptor_decl);
1074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Helper for Print{Fields,Extensions}InDescriptor().
1077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintFieldDescriptorsInDescriptor(
1078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& message_descriptor,
1079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bool is_extension,
1080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string& list_variable_name,
1081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int (Descriptor::*CountFn)() const,
1082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const {
1083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("$list$=[\n", "list", list_variable_name);
1084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
1085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
1086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i),
1087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         is_extension);
1088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(",\n");
1089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
1091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("],\n");
1092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a statement assigning "fields" to a list of Python FieldDescriptors,
1095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// one for each field present in message_descriptor.
1096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintFieldsInDescriptor(
1097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& message_descriptor) const {
1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const bool is_extension = false;
1099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldDescriptorsInDescriptor(
1100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_descriptor, is_extension, "fields",
1101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      &Descriptor::field_count, &Descriptor::field);
1102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a statement assigning "extensions" to a list of Python
1105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FieldDescriptors, one for each extension present in message_descriptor.
1106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintExtensionsInDescriptor(
1107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& message_descriptor) const {
1108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const bool is_extension = true;
1109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldDescriptorsInDescriptor(
1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_descriptor, is_extension, "extensions",
1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      &Descriptor::extension_count, &Descriptor::extension);
1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Generator::GeneratingDescriptorProto() const {
1115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return file_->name() == "google/protobuf/descriptor.proto";
1116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the unique Python module-level identifier given to a descriptor.
1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This name is module-qualified iff the given descriptor describes an
1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// entity that doesn't come from the current file.
1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate <typename DescriptorT>
1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::ModuleLevelDescriptorName(
1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const DescriptorT& descriptor) const {
1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // FIXME(robinson):
1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We currently don't worry about collisions with underscores in the type
1126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // names, so these would collide in nasty ways if found in the same file:
1127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto.ProtoA.ProtoB
1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto_ProtoA.ProtoB  # Underscore instead of period.
1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // As would these:
1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto.ProtoA_.ProtoB
1131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto.ProtoA._ProtoB  # Leading vs. trailing underscore.
1132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // (Contrived, but certainly possible).
1133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //
1134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The C++ implementation doesn't guard against this either.  Leaving
1135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // it for now...
1136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = NamePrefixedWithNestedTypes(descriptor, "_");
1137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UpperString(&name);
1138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Module-private for now.  Easy to make public later; almost impossible
1139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // to make private later.
1140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  name = "_" + name;
1141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We now have the name relative to its own module.  Also qualify with
1142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // the module name iff this descriptor is from a different .proto file.
1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor.file() != file_) {
1144b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    name = ModuleAlias(descriptor.file()->name()) + "." + name;
1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the name of the message class itself, not the descriptor.
1150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Like ModuleLevelDescriptorName(), module-qualifies the name iff
1151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the given descriptor describes an entity that doesn't come from
1152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the current file.
1153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::ModuleLevelMessageName(const Descriptor& descriptor) const {
1154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = NamePrefixedWithNestedTypes(descriptor, ".");
1155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor.file() != file_) {
1156b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    name = ModuleAlias(descriptor.file()->name()) + "." + name;
1157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
1159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the unique Python module-level identifier given to a service
1162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// descriptor.
1163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::ModuleLevelServiceDescriptorName(
1164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const ServiceDescriptor& descriptor) const {
1165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = descriptor.name();
1166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UpperString(&name);
1167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  name = "_" + name;
1168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor.file() != file_) {
1169b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    name = ModuleAlias(descriptor.file()->name()) + "." + name;
1170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
1171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
1172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
1173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
1174d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Prints standard constructor arguments serialized_start and serialized_end.
1175d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Args:
1176d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   descriptor: The cpp descriptor to have a serialized reference.
1177d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   proto: A proto
1178d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Example printer output:
1179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// serialized_start=41,
1180d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// serialized_end=43,
1181d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//
1182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilletemplate <typename DescriptorT, typename DescriptorProtoT>
1183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid Generator::PrintSerializedPbInterval(
1184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const DescriptorT& descriptor, DescriptorProtoT& proto) const {
1185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  descriptor.CopyTo(&proto);
1186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  string sp;
1187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  proto.SerializeToString(&sp);
1188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  int offset = file_descriptor_serialized_.find(sp);
1189d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  GOOGLE_CHECK_GE(offset, 0);
1190d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1191d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("serialized_start=$serialized_start$,\n"
1192d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                  "serialized_end=$serialized_end$,\n",
1193d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                  "serialized_start", SimpleItoa(offset),
1194d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                  "serialized_end", SimpleItoa(offset + sp.size()));
1195d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
1196d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
1197a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonnamespace {
1198a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid PrintDescriptorOptionsFixingCode(const string& descriptor,
1199a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                      const string& options,
1200a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                      io::Printer* printer) {
1201a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase
1202a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // in proto2 python runtime but it couldn't be used here because appengine
1203a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // uses a snapshot version of the library in which the new method is not
1204a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // yet present. After appengine has synced their runtime library, the code
1205a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // below should be cleaned up to use _SetOptions().
1206a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  printer->Print(
1207a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor$.has_options = True\n"
1208a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "$descriptor$._options = $options$\n",
1209a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "descriptor", descriptor, "options", options);
1210a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
1211a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}  // namespace
1212a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1213a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Prints expressions that set the options field of all descriptors.
1214a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::FixAllDescriptorOptions() const {
1215a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Prints an expression that sets the file descriptor's options.
1216a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  string file_options = OptionsValue(
1217a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "FileOptions", file_->options().SerializeAsString());
1218a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (file_options != "None") {
1219a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
1220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Prints expressions that set the options for all top level enums.
1222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < file_->enum_type_count(); ++i) {
1223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
1224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FixOptionsForEnum(enum_descriptor);
1225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Prints expressions that set the options for all top level extensions.
1227a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < file_->extension_count(); ++i) {
1228a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor& field = *file_->extension(i);
1229a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FixOptionsForField(field);
1230a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1231a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Prints expressions that set the options for all messages, nested enums,
1232a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // nested extensions and message fields.
1233a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < file_->message_type_count(); ++i) {
1234a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FixOptionsForMessage(*file_->message_type(i));
1235a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1236a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
1237a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Prints expressions that set the options for an enum descriptor and its
1239a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// value descriptors.
1240a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
1241a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
1242a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  string enum_options = OptionsValue(
1243a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "EnumOptions", enum_descriptor.options().SerializeAsString());
1244a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (enum_options != "None") {
1245a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
1246a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < enum_descriptor.value_count(); ++i) {
1248a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
1249a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    string value_options = OptionsValue(
1250a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        "EnumValueOptions", value_descriptor.options().SerializeAsString());
1251a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (value_options != "None") {
1252a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      PrintDescriptorOptionsFixingCode(
1253a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
1254a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                       value_descriptor.name().c_str()),
1255a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          value_options, printer_);
1256a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1257a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1258a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
1259a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1260a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Prints expressions that set the options for field descriptors (including
1261a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// extensions).
1262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::FixOptionsForField(
1263a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor& field) const {
1264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  string field_options = OptionsValue(
1265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "FieldOptions", field.options().SerializeAsString());
1266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (field_options != "None") {
1267a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    string field_name;
1268a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    if (field.is_extension()) {
1269a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      if (field.extension_scope() == NULL) {
1270a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        // Top level extensions.
1271a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_name = field.name();
1272a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      } else {
1273a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson        field_name = FieldReferencingExpression(
1274a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson            field.extension_scope(), field, "extensions_by_name");
1275a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      }
1276a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    } else {
1277a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      field_name = FieldReferencingExpression(
1278a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson          field.containing_type(), field, "fields_by_name");
1279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    }
1280a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
1281a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1282a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
1283a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1284a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Prints expressions that set the options for a message and all its inner
1285a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// types (nested messages, nested enums, extensions, fields).
1286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
1287a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Nested messages.
1288a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
1289a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FixOptionsForMessage(*descriptor.nested_type(i));
1290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1291a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Enums.
1292a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
1293a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FixOptionsForEnum(*descriptor.enum_type(i));
1294a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1295a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Fields.
1296a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor.field_count(); ++i) {
1297a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor& field = *descriptor.field(i);
1298a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FixOptionsForField(field);
1299a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1300a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Extensions.
1301a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  for (int i = 0; i < descriptor.extension_count(); ++i) {
1302a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    const FieldDescriptor& field = *descriptor.extension(i);
1303a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    FixOptionsForField(field);
1304a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1305a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  // Message option for this message.
1306a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  string message_options = OptionsValue(
1307a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson      "MessageOptions", descriptor.options().SerializeAsString());
1308a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  if (message_options != "None") {
1309a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    string descriptor_name = ModuleLevelDescriptorName(descriptor);
1310a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson    PrintDescriptorOptionsFixingCode(descriptor_name,
1311a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     message_options,
1312a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson                                     printer_);
1313a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson  }
1314a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}
1315a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson
1316b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// If a dependency forwards other files through public dependencies, let's
1317b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// copy over the corresponding module aliases.
1318b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid Generator::CopyPublicDependenciesAliases(
1319b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    const string& copy_from, const FileDescriptor* file) const {
1320b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  for (int i = 0; i < file->public_dependency_count(); ++i) {
1321b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    string module_alias = ModuleAlias(file->public_dependency(i)->name());
1322b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    printer_->Print("$alias$ = $copy_from$.$alias$\n", "alias", module_alias,
1323b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer                    "copy_from", copy_from);
1324b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    CopyPublicDependenciesAliases(copy_from, file->public_dependency(i));
1325b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
1326b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
1327b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
1328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace python
1329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
1330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
1331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
1332