1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: robinson@google.com (Will Robinson)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This module outputs pure-Python protocol message classes that will
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// largely be constructed at runtime via the metaclass in reflection.py.
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// In other words, our job is basically to output a Python equivalent
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// of the C++ *Descriptor objects, and fix up all circular references
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// within these objects.
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Note that the runtime performance of protocol message classes created in
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this way is expected to be lousy.  The plan is to create an alternate
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// generator that outputs a Python/C extension module that lets
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// performance-minded Python code leverage the fast C++ implementation
43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// directly.
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
45d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <limits>
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <map>
47d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <utility>
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <string>
49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector>
50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/compiler/python/python_generator.h>
52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h>
53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h>
55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/printer.h>
56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h>
57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream.h>
58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h>
59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/substitute.h>
60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler {
64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace python {
65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace {
67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a copy of |filename| with any trailing ".protodevel" or ".proto
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// suffix stripped.
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc.
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring StripProto(const string& filename) {
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char* suffix = HasSuffixString(filename, ".protodevel")
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ? ".protodevel" : ".proto";
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return StripSuffixString(filename, suffix);
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the Python module name expected for a given .proto filename.
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ModuleName(const string& filename) {
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string basename = StripProto(filename);
81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  StripString(&basename, "-", '_');
82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  StripString(&basename, "/", '.');
83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return basename + "_pb2";
84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the name of all containing types for descriptor,
88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in order from outermost to innermost, followed by descriptor's
89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// own name.  Each name is separated by |separator|.
90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate <typename DescriptorT>
91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                   const string& separator) {
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = descriptor.name();
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (const Descriptor* current = descriptor.containing_type();
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       current != NULL; current = current->containing_type()) {
96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name = current->name() + separator + name;
97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Name of the class attribute where we store the Python
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// descriptor.Descriptor instance for the generated class.
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Must stay consistent with the _DESCRIPTOR_KEY constant
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in proto2/public/reflection.py.
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char kDescriptorKey[] = "DESCRIPTOR";
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Should we generate generic services for this file?
110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleinline bool HasGenericServices(const FileDescriptor *file) {
111d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return file->service_count() > 0 &&
112d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville         file->options().py_generic_services();
113d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints the common boilerplate needed at the top of every .py
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// file output by this generator.
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid PrintTopBoilerplate(
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) {
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(robinson): Allow parameterization of Python version?
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer->Print(
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "\n"
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "from google.protobuf import descriptor\n"
125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "from google.protobuf import message\n"
126d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "from google.protobuf import reflection\n");
127d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (HasGenericServices(file)) {
128d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer->Print(
129d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "from google.protobuf import service\n"
130d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "from google.protobuf import service_reflection\n");
131d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
132d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Avoid circular imports if this module is descriptor_pb2.
134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!descriptor_proto) {
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer->Print(
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "from google.protobuf import descriptor_pb2\n");
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
138d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print(
139d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "# @@protoc_insertion_point(imports)\n");
140d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer->Print("\n\n");
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a Python literal giving the default value for a field.
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// If the field specifies no explicit default value, we'll return
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the default default value for the field type (zero for numbers,
147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// empty string for strings, empty list for repeated fields, and
148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// None for non-repeated, composite fields).
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(robinson): Unify with code from
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// //compiler/cpp/internal/primitive_field.cc
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// //compiler/cpp/internal/enum_field.cc
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// //compiler/cpp/internal/string_field.cc
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring StringifyDefaultValue(const FieldDescriptor& field) {
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (field.is_repeated()) {
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return "[]";
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  switch (field.cpp_type()) {
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT32:
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_int32());
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT32:
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_uint32());
164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_INT64:
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_int64());
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_UINT64:
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_uint64());
168d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    case FieldDescriptor::CPPTYPE_DOUBLE: {
169d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      double value = field.default_value_double();
170d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (value == numeric_limits<double>::infinity()) {
171d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
172d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // a numeric literal that is too big for a double will become infinity.
173d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "1e10000";
174d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value == -numeric_limits<double>::infinity()) {
175d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // See above.
176d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "-1e10000";
177d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value != value) {
178d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // infinity * 0 = nan
179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "(1e10000 * 0)";
180d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
181d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return SimpleDtoa(value);
182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    case FieldDescriptor::CPPTYPE_FLOAT: {
185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      float value = field.default_value_float();
186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (value == numeric_limits<float>::infinity()) {
187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // a numeric literal that is too big for a double will become infinity.
189d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "1e10000";
190d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value == -numeric_limits<float>::infinity()) {
191d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // See above.
192d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "-1e10000";
193d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else if (value != value) {
194d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        // infinity - infinity = nan
195d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return "(1e10000 * 0)";
196d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
197d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        return SimpleFtoa(value);
198d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
199d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_BOOL:
201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return field.default_value_bool() ? "True" : "False";
202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_ENUM:
203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return SimpleItoa(field.default_value_enum()->number());
204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_STRING:
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      if (field.type() == FieldDescriptor::TYPE_STRING) {
206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return "unicode(\"" + CEscape(field.default_value_string()) +
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            "\", \"utf-8\")";
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      } else {
209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        return "\"" + CEscape(field.default_value_string()) + "\"";
210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      }
211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    case FieldDescriptor::CPPTYPE_MESSAGE:
212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      return "None";
213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // (We could add a default case above but then we wouldn't get the nice
215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // compiler warning when a new type is added.)
216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_LOG(FATAL) << "Not reached.";
217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return "";
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerator::Generator() : file_(NULL) {
226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGenerator::~Generator() {
229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Generator::Generate(const FileDescriptor* file,
232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         const string& parameter,
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         OutputDirectory* output_directory,
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         string* error) const {
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Completely serialize all Generate() calls on this instance.  The
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // thread-safety constraints of the CodeGenerator interface aren't clear so
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // just be as conservative as possible.  It's easier to relax this later if
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // we need to, but I doubt it will be an issue.
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(kenton):  The proper thing to do would be to allocate any state on
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   the stack and use that, so that the Generator class itself does not need
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   to have any mutable members.  Then it is implicitly thread-safe.
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  MutexLock lock(&mutex_);
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  file_ = file;
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string module_name = ModuleName(file->name());
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string filename = module_name;
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  StripString(&filename, ".", '/');
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  filename += ".py";
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
250d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  FileDescriptorProto fdp;
251d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  file_->CopyTo(&fdp);
252d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  fdp.SerializeToString(&file_descriptor_serialized_);
253d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  scoped_ptr<io::ZeroCopyOutputStream> output(output_directory->Open(filename));
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK(output.get());
257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  io::Printer printer(output.get(), '$');
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_ = &printer;
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
261d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintFileDescriptor();
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintTopLevelEnums();
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintTopLevelExtensions();
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintAllNestedEnumsInFile();
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintMessageDescriptors();
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We have to print the imports after the descriptors, so that mutually
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // recursive protos in separate files can successfully reference each other.
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintImports();
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FixForeignFieldsInDescriptors();
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintMessages();
271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We have to fix up the extensions after the message classes themselves,
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // since they need to call static RegisterExtension() methods on these
273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // classes.
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FixForeignFieldsInExtensions();
275d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (HasGenericServices(file)) {
276d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    PrintServices();
277d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
278d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
279d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer.Print(
280d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "# @@protoc_insertion_point(module_scope)\n");
281d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return !printer.failed();
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints Python imports for all modules imported by |file|.
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintImports() const {
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->dependency_count(); ++i) {
288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string module_name = ModuleName(file_->dependency(i)->name());
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("import $module$\n", "module",
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                    module_name);
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
295d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Prints the single file descriptor for this file.
296d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid Generator::PrintFileDescriptor() const {
297d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  map<string, string> m;
298d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["descriptor_name"] = kDescriptorKey;
299d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["name"] = file_->name();
300d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["package"] = file_->package();
301d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  const char file_descriptor_template[] =
302d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "$descriptor_name$ = descriptor.FileDescriptor(\n"
303d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  name='$name$',\n"
304d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  package='$package$',\n";
305d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(m, file_descriptor_template);
306d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Indent();
307d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(
308d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "serialized_pb='$value$'",
309d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "value", strings::CHexEscape(file_descriptor_serialized_));
310d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
311d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // TODO(falk): Also print options and fix the message_type, enum_type,
312d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  //             service and extension later in the generation.
313d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
314d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Outdent();
315d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(")\n");
316d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("\n");
317d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
318d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints descriptors and module-level constants for all top-level
320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// enums defined in |file|.
321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintTopLevelEnums() const {
322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  vector<pair<string, int> > top_level_enum_values;
323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->enum_type_count(); ++i) {
324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintEnum(enum_descriptor);
326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    for (int j = 0; j < enum_descriptor.value_count(); ++j) {
329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j);
330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      top_level_enum_values.push_back(
331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville          make_pair(value_descriptor.name(), value_descriptor.number()));
332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < top_level_enum_values.size(); ++i) {
336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("$name$ = $value$\n",
337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                    "name", top_level_enum_values[i].first,
338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                    "value", SimpleItoa(top_level_enum_values[i].second));
339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints all enums contained in all message types in |file|.
344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintAllNestedEnumsInFile() const {
345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintNestedEnums(*file_->message_type(i));
347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a Python statement assigning the appropriate module-level
351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// enum name to a Python EnumDescriptor object equivalent to
352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// enum_descriptor.
353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor);
356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = enum_descriptor.name();
357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = enum_descriptor.full_name();
358d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["file"] = kDescriptorKey;
359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char enum_descriptor_template[] =
360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$descriptor_name$ = descriptor.EnumDescriptor(\n"
361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  name='$name$',\n"
362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  full_name='$full_name$',\n"
363d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  filename=None,\n"
364d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  file=$file$,\n"
365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  values=[\n";
366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  enum_descriptor.options().SerializeToString(&options_string);
368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, enum_descriptor_template);
369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < enum_descriptor.value_count(); ++i) {
372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintEnumValueDescriptor(*enum_descriptor.value(i));
373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(",\n");
374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("],\n");
377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("containing_type=None,\n");
378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("options=$options_value$,\n",
379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  "options_value",
380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  OptionsValue("EnumOptions", CEscape(options_string)));
381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  EnumDescriptorProto edp;
382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintSerializedPbInterval(enum_descriptor, edp);
383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(")\n");
385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Recursively prints enums in nested types within descriptor, then
389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// prints enums contained at the top level in descriptor.
390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintNestedEnums(const Descriptor& descriptor) const {
391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintNestedEnums(*descriptor.nested_type(i));
393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintEnum(*descriptor.enum_type(i));
397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintTopLevelExtensions() const {
401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const bool is_extension = true;
402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->extension_count(); ++i) {
403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& extension_field = *file_->extension(i);
404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string constant_name = extension_field.name() + "_FIELD_NUMBER";
405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    UpperString(&constant_name);
406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("$constant_name$ = $number$\n",
407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "constant_name", constant_name,
408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "number", SimpleItoa(extension_field.number()));
409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("$name$ = ", "name", extension_field.name());
410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldDescriptor(extension_field, is_extension);
411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints Python equivalents of all Descriptors in |file|.
417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintMessageDescriptors() const {
418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintDescriptor(*file_->message_type(i));
420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintServices() const {
425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->service_count(); ++i) {
426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintServiceDescriptor(*file_->service(i));
427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintServiceClass(*file_->service(i));
428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintServiceStub(*file_->service(i));
429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintServiceDescriptor(
434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const ServiceDescriptor& descriptor) const {
435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string service_name = ModuleLevelServiceDescriptorName(descriptor);
437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  descriptor.options().SerializeToString(&options_string);
439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$service_name$ = descriptor.ServiceDescriptor(\n",
442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "service_name", service_name);
443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = descriptor.name();
446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = descriptor.full_name();
447d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["file"] = kDescriptorKey;
448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["index"] = SimpleItoa(descriptor.index());
449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["options_value"] = OptionsValue("ServiceOptions", options_string);
450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char required_function_arguments[] =
451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name='$name$',\n"
452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "full_name='$full_name$',\n"
453d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "file=$file$,\n"
454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "index=$index$,\n"
455d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "options=$options_value$,\n";
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, required_function_arguments);
457d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
458d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  ServiceDescriptorProto sdp;
459d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintSerializedPbInterval(descriptor, sdp);
460d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
461d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("methods=[\n");
462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.method_count(); ++i) {
463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MethodDescriptor* method = descriptor.method(i);
464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string options_string;
465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    method->options().SerializeToString(&options_string);
466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m.clear();
468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["name"] = method->name();
469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["full_name"] = method->full_name();
470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["index"] = SimpleItoa(method->index());
471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["serialized_options"] = CEscape(options_string);
472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["options_value"] = OptionsValue("MethodOptions", options_string);
475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("descriptor.MethodDescriptor(\n");
476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Indent();
477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(
478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        m,
479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "name='$name$',\n"
480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "full_name='$full_name$',\n"
481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "index=$index$,\n"
482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "containing_service=None,\n"
483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "input_type=$input_type$,\n"
484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "output_type=$output_type$,\n"
485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        "options=$options_value$,\n");
486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Outdent();
487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("),\n");
488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("])\n\n");
492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Print the service.
496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("class $class_name$(service.Service):\n",
497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  "class_name", descriptor.name());
498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "__metaclass__ = service_reflection.GeneratedServiceType\n"
501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$descriptor_key$ = $descriptor_name$\n",
502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "descriptor_key", kDescriptorKey,
503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Print the service stub.
509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("class $class_name$_Stub($class_name$):\n",
510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  "class_name", descriptor.name());
511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "__metaclass__ = service_reflection.GeneratedServiceStubType\n"
514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$descriptor_key$ = $descriptor_name$\n",
515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "descriptor_key", kDescriptorKey,
516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to a Python Descriptor object for message_descriptor.
522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintNestedDescriptors().
524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintNestedDescriptors(message_descriptor);
526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("$descriptor_name$ = descriptor.Descriptor(\n",
529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  "descriptor_name",
530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  ModuleLevelDescriptorName(message_descriptor));
531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = message_descriptor.name();
534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = message_descriptor.full_name();
535d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["file"] = kDescriptorKey;
536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char required_function_arguments[] =
537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "name='$name$',\n"
538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "full_name='$full_name$',\n"
539d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "filename=None,\n"
540d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "file=$file$,\n"
541d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "containing_type=None,\n";
542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, required_function_arguments);
543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldsInDescriptor(message_descriptor);
544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintExtensionsInDescriptor(message_descriptor);
545d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
546d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Nested types
547d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("nested_types=[");
548d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
549d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const string nested_name = ModuleLevelDescriptorName(
550d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        *message_descriptor.nested_type(i));
551d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer_->Print("$name$, ", "name", nested_name);
552d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
553d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("],\n");
554d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
555d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Enum types
556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("enum_types=[\n");
557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string descriptor_name = ModuleLevelDescriptorName(
560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        *message_descriptor.enum_type(i));
561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(descriptor_name.c_str());
562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(",\n");
563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("],\n");
566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  message_descriptor.options().SerializeToString(&options_string);
568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
569d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "options=$options_value$,\n"
570d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "is_extendable=$extendable$",
571d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "options_value", OptionsValue("MessageOptions", options_string),
572d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "extendable", message_descriptor.extension_range_count() > 0 ?
573d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                      "True" : "False");
574d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(",\n");
575d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
576d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Extension ranges
577d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("extension_ranges=[");
578d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
579d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor::ExtensionRange* range =
580d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        message_descriptor.extension_range(i);
581d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer_->Print("($start$, $end$), ",
582d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                    "start", SimpleItoa(range->start),
583d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                    "end", SimpleItoa(range->end));
584d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
585d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("],\n");
586d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
587d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Serialization of proto
588d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  DescriptorProto edp;
589d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  PrintSerializedPbInterval(message_descriptor, edp);
590d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(")\n");
593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints Python Descriptor objects for all nested types contained in
596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// message_descriptor.
597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintDescriptor().
599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintNestedDescriptors(
600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& containing_descriptor) const {
601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintDescriptor(*containing_descriptor.nested_type(i));
603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints all messages in |file|.
607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintMessages() const {
608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintMessage(*file_->message_type(i));
610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a Python class for the given message descriptor.  We defer to the
615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// metaclass to do almost all of the work of actually creating a useful class.
616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The purpose of this function and its many helper functions above is merely
617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to output a Python version of the descriptors, which the metaclass in
618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// reflection.py will use to construct the meat of the class itself.
619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintNestedMessages().
621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintMessage(
622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& message_descriptor) const {
623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("class $name$(message.Message):\n", "name",
624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                  message_descriptor.name());
625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("__metaclass__ = reflection.GeneratedProtocolMessageType\n");
627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintNestedMessages(message_descriptor);
628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["descriptor_key"] = kDescriptorKey;
630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n");
632d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
633d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print(
634d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "\n"
635d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "# @@protoc_insertion_point(class_scope:$full_name$)\n",
636d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "full_name", message_descriptor.full_name());
637d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints all nested messages within |containing_descriptor|.
642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Mutually recursive with PrintMessage().
643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintNestedMessages(
644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& containing_descriptor) const {
645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print("\n");
647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintMessage(*containing_descriptor.nested_type(i));
648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Recursively fixes foreign fields in all nested types in |descriptor|, then
652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// sets the message_type and enum_type of all message and enum fields to point
653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to their respective descriptors.
654d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Args:
655d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   descriptor: descriptor to print fields for.
656d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   containing_descriptor: if descriptor is a nested type, this is its
657d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//       containing type, or NULL if this is a root/top-level type.
658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInDescriptor(
659d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor& descriptor,
660d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor* containing_descriptor) const {
661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
662d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.field_count(); ++i) {
666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& field_descriptor = *descriptor.field(i);
667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
669d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
670d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  FixContainingTypeInDescriptor(descriptor, containing_descriptor);
671d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
672d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
673d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
674d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sets any necessary message_type and enum_type attributes
678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// for the Python version of |field|.
679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// containing_type may be NULL, in which case this is a module-level field.
681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// python_dict_name is the name of the Python dict where we should
683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// look the field up in the containing type.  (e.g., fields_by_name
684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// or extensions_by_name).  We ignore python_dict_name if containing_type
685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// is NULL.
686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInField(const Descriptor* containing_type,
687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                        const FieldDescriptor& field,
688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                        const string& python_dict_name) const {
689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const string field_referencing_expression = FieldReferencingExpression(
690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      containing_type, field, python_dict_name);
691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["field_ref"] = field_referencing_expression;
693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const Descriptor* foreign_message_type = field.message_type();
694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (foreign_message_type) {
695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const EnumDescriptor* enum_type = field.enum_type();
699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (enum_type) {
700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the module-level expression for the given FieldDescriptor.
706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Only works for fields in the .proto file this Generator is generating for.
707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// containing_type may be NULL, in which case this is a module-level field.
709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// python_dict_name is the name of the Python dict where we should
711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// look the field up in the containing type.  (e.g., fields_by_name
712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// or extensions_by_name).  We ignore python_dict_name if containing_type
713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// is NULL.
714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::FieldReferencingExpression(
715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor* containing_type,
716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& field,
717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string& python_dict_name) const {
718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We should only ever be looking up fields in the current file.
719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The only things we refer to from other files are message descriptors.
720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. "
721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                << file_->name();
722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (!containing_type) {
723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return field.name();
724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return strings::Substitute(
726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "$0.$1['$2']",
727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ModuleLevelDescriptorName(*containing_type),
728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      python_dict_name, field.name());
729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
731d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Prints containing_type for nested descriptors or enum descriptors.
732d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilletemplate <typename DescriptorT>
733d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid Generator::FixContainingTypeInDescriptor(
734d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const DescriptorT& descriptor,
735d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const Descriptor* containing_descriptor) const {
736d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (containing_descriptor != NULL) {
737d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const string nested_name = ModuleLevelDescriptorName(descriptor);
738d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const string parent_name = ModuleLevelDescriptorName(
739d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        *containing_descriptor);
740d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer_->Print(
741d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "$nested_name$.containing_type = $parent_name$;\n",
742d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "nested_name", nested_name,
743d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        "parent_name", parent_name);
744d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
745d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
746d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints statements setting the message_type and enum_type fields in the
748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Python descriptor objects we've already output in ths file.  We must
749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// do this in a separate step due to circular references (otherwise, we'd
750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// just set everything in the initial assignment statements).
751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInDescriptors() const {
752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
753d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("\n");
756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// We need to not only set any necessary message_type fields, but
759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// also need to call RegisterExtension() on each message we're
760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// extending.
761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInExtensions() const {
762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Top-level extensions.
763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->extension_count(); ++i) {
764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInExtension(*file_->extension(i));
765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Nested extensions.
767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < file_->message_type_count(); ++i) {
768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInNestedExtensions(*file_->message_type(i));
769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInExtension(
773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& extension_field) const {
774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_CHECK(extension_field.is_extension());
775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // extension_scope() will be NULL for top-level extensions, which is
776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // exactly what FixForeignFieldsInField() wants.
777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  FixForeignFieldsInField(extension_field.extension_scope(), extension_field,
778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                          "extensions_by_name");
779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Confusingly, for FieldDescriptors that happen to be extensions,
782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // containing_type() means "extended type."
783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // On the other hand, extension_scope() will give us what we normally
784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // mean by containing_type().
785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["extended_message_class"] = ModuleLevelMessageName(
786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      *extension_field.containing_type());
787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["field"] = FieldReferencingExpression(extension_field.extension_scope(),
788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                          extension_field,
789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                          "extensions_by_name");
790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::FixForeignFieldsInNestedExtensions(
794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& descriptor) const {
795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Recursively fix up extensions in all nested types.
796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Fix up extensions directly contained within this type.
800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < descriptor.extension_count(); ++i) {
801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    FixForeignFieldsInExtension(*descriptor.extension(i));
802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns a Python expression that instantiates a Python EnumValueDescriptor
806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// object for the given C++ descriptor.
807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintEnumValueDescriptor(
808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const EnumValueDescriptor& descriptor) const {
809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // More circular references.  ::sigh::
811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  descriptor.options().SerializeToString(&options_string);
813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = descriptor.name();
815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["index"] = SimpleItoa(descriptor.index());
816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["number"] = SimpleItoa(descriptor.number());
817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["options"] = OptionsValue("EnumValueOptions", options_string);
818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(
819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      m,
820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "descriptor.EnumValueDescriptor(\n"
821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  name='$name$', index=$index$, number=$number$,\n"
822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  options=$options$,\n"
823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      "  type=None)");
824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::OptionsValue(
827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string& class_name, const string& serialized_options) const {
828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return "None";
830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    string full_class_name = "descriptor_pb2." + class_name;
832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return "descriptor._ParseOptions(" + full_class_name + "(), '"
833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        + CEscape(serialized_options)+ "')";
834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints an expression for a Python FieldDescriptor for |field|.
838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintFieldDescriptor(
839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor& field, bool is_extension) const {
840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string options_string;
841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  field.options().SerializeToString(&options_string);
842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<string, string> m;
843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["name"] = field.name();
844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["full_name"] = field.full_name();
845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["index"] = SimpleItoa(field.index());
846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["number"] = SimpleItoa(field.number());
847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["type"] = SimpleItoa(field.type());
848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["cpp_type"] = SimpleItoa(field.cpp_type());
849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["label"] = SimpleItoa(field.label());
850d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  m["has_default_value"] = field.has_default_value() ? "True" : "False";
851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["default_value"] = StringifyDefaultValue(field);
852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["is_extension"] = is_extension ? "True" : "False";
853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  m["options"] = OptionsValue("FieldOptions", options_string);
854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We always set message_type and enum_type to None at this point, and then
855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // these fields in correctly after all referenced descriptors have been
856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // defined and/or imported (see FixForeignFieldsInDescriptors()).
857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const char field_descriptor_decl[] =
858d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "descriptor.FieldDescriptor(\n"
859d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  name='$name$', full_name='$full_name$', index=$index$,\n"
860d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
861d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  has_default_value=$has_default_value$, default_value=$default_value$,\n"
862d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  message_type=None, enum_type=None, containing_type=None,\n"
863d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  is_extension=$is_extension$, extension_scope=None,\n"
864d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "  options=$options$)";
865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print(m, field_descriptor_decl);
866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Helper for Print{Fields,Extensions}InDescriptor().
869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintFieldDescriptorsInDescriptor(
870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& message_descriptor,
871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bool is_extension,
872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const string& list_variable_name,
873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    int (Descriptor::*CountFn)() const,
874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const {
875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("$list$=[\n", "list", list_variable_name);
876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Indent();
877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i),
879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                         is_extension);
880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    printer_->Print(",\n");
881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Outdent();
883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  printer_->Print("],\n");
884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a statement assigning "fields" to a list of Python FieldDescriptors,
887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// one for each field present in message_descriptor.
888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintFieldsInDescriptor(
889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& message_descriptor) const {
890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const bool is_extension = false;
891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldDescriptorsInDescriptor(
892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_descriptor, is_extension, "fields",
893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      &Descriptor::field_count, &Descriptor::field);
894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints a statement assigning "extensions" to a list of Python
897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FieldDescriptors, one for each extension present in message_descriptor.
898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Generator::PrintExtensionsInDescriptor(
899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const Descriptor& message_descriptor) const {
900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  const bool is_extension = true;
901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  PrintFieldDescriptorsInDescriptor(
902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      message_descriptor, is_extension, "extensions",
903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      &Descriptor::extension_count, &Descriptor::extension);
904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool Generator::GeneratingDescriptorProto() const {
907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return file_->name() == "google/protobuf/descriptor.proto";
908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the unique Python module-level identifier given to a descriptor.
911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This name is module-qualified iff the given descriptor describes an
912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// entity that doesn't come from the current file.
913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate <typename DescriptorT>
914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::ModuleLevelDescriptorName(
915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const DescriptorT& descriptor) const {
916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // FIXME(robinson):
917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We currently don't worry about collisions with underscores in the type
918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // names, so these would collide in nasty ways if found in the same file:
919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto.ProtoA.ProtoB
920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto_ProtoA.ProtoB  # Underscore instead of period.
921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // As would these:
922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto.ProtoA_.ProtoB
923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //   OuterProto.ProtoA._ProtoB  # Leading vs. trailing underscore.
924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // (Contrived, but certainly possible).
925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  //
926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // The C++ implementation doesn't guard against this either.  Leaving
927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // it for now...
928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = NamePrefixedWithNestedTypes(descriptor, "_");
929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UpperString(&name);
930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // Module-private for now.  Easy to make public later; almost impossible
931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // to make private later.
932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  name = "_" + name;
933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // We now have the name relative to its own module.  Also qualify with
934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // the module name iff this descriptor is from a different .proto file.
935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor.file() != file_) {
936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name = ModuleName(descriptor.file()->name()) + "." + name;
937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the name of the message class itself, not the descriptor.
942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Like ModuleLevelDescriptorName(), module-qualifies the name iff
943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the given descriptor describes an entity that doesn't come from
944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the current file.
945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::ModuleLevelMessageName(const Descriptor& descriptor) const {
946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = NamePrefixedWithNestedTypes(descriptor, ".");
947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor.file() != file_) {
948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name = ModuleName(descriptor.file()->name()) + "." + name;
949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Returns the unique Python module-level identifier given to a service
954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// descriptor.
955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Generator::ModuleLevelServiceDescriptorName(
956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const ServiceDescriptor& descriptor) const {
957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  string name = descriptor.name();
958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UpperString(&name);
959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  name = "_" + name;
960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (descriptor.file() != file_) {
961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    name = ModuleName(descriptor.file()->name()) + "." + name;
962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return name;
964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
966d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Prints standard constructor arguments serialized_start and serialized_end.
967d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Args:
968d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   descriptor: The cpp descriptor to have a serialized reference.
969d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   proto: A proto
970d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Example printer output:
971d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// serialized_start=41,
972d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// serialized_end=43,
973d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//
974d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilletemplate <typename DescriptorT, typename DescriptorProtoT>
975d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid Generator::PrintSerializedPbInterval(
976d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const DescriptorT& descriptor, DescriptorProtoT& proto) const {
977d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  descriptor.CopyTo(&proto);
978d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  string sp;
979d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  proto.SerializeToString(&sp);
980d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  int offset = file_descriptor_serialized_.find(sp);
981d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  GOOGLE_CHECK_GE(offset, 0);
982d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
983d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  printer_->Print("serialized_start=$serialized_start$,\n"
984d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                  "serialized_end=$serialized_end$,\n",
985d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                  "serialized_start", SimpleItoa(offset),
986d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                  "serialized_end", SimpleItoa(offset + sp.size()));
987d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
988d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace python
990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace compiler
991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
993