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