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