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