15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: robinson@google.com (Will Robinson) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This module outputs pure-Python protocol message classes that will 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// largely be constructed at runtime via the metaclass in reflection.py. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In other words, our job is basically to output a Python equivalent 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the C++ *Descriptor objects, and fix up all circular references 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// within these objects. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that the runtime performance of protocol message classes created in 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this way is expected to be lousy. The plan is to create an alternate 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generator that outputs a Python/C extension module that lets 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// performance-minded Python code leverage the fast C++ implementation 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// directly. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/python/python_generator.h> 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h> 55ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/stringprintf.h> 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/printer.h> 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.h> 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream.h> 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h> 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/substitute.h> 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace compiler { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace python { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a copy of |filename| with any trailing ".protodevel" or ".proto 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// suffix stripped. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string StripProto(const string& filename) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* suffix = HasSuffixString(filename, ".protodevel") 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? ".protodevel" : ".proto"; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StripSuffixString(filename, suffix); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the Python module name expected for a given .proto filename. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ModuleName(const string& filename) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string basename = StripProto(filename); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StripString(&basename, "-", '_'); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StripString(&basename, "/", '.'); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return basename + "_pb2"; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the name of all containing types for descriptor, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in order from outermost to innermost, followed by descriptor's 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// own name. Each name is separated by |separator|. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename DescriptorT> 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& separator) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name = descriptor.name(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (const Descriptor* current = descriptor.containing_type(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current != NULL; current = current->containing_type()) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = current->name() + separator + name; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Name of the class attribute where we store the Python 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor.Descriptor instance for the generated class. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Must stay consistent with the _DESCRIPTOR_KEY constant 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in proto2/public/reflection.py. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDescriptorKey[] = "DESCRIPTOR"; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Does the file have top-level enums? 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochinline bool HasTopLevelEnums(const FileDescriptor *file) { 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return file->enum_type_count() > 0; 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Should we generate generic services for this file? 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool HasGenericServices(const FileDescriptor *file) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file->service_count() > 0 && 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->options().py_generic_services(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints the common boilerplate needed at the top of every .py 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// file output by this generator. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintTopBoilerplate( 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Printer* printer, const FileDescriptor* file, bool descriptor_proto) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(robinson): Allow parameterization of Python version? 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" 130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "# source: $filename$\n" 131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "\n", 132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "filename", file->name()); 133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (HasTopLevelEnums(file)) { 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer->Print( 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "from google.protobuf.internal import enum_type_wrapper\n"); 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer->Print( 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "from google.protobuf import descriptor as _descriptor\n" 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "from google.protobuf import message as _message\n" 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "from google.protobuf import reflection as _reflection\n" 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasGenericServices(file)) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "from google.protobuf import service as _service\n" 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "from google.protobuf import service_reflection\n"); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Avoid circular imports if this module is descriptor_pb2. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!descriptor_proto) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "from google.protobuf import descriptor_pb2\n"); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print( 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "# @@protoc_insertion_point(imports)\n"); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer->Print("\n\n"); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a Python literal giving the default value for a field. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the field specifies no explicit default value, we'll return 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the default default value for the field type (zero for numbers, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// empty string for strings, empty list for repeated fields, and 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// None for non-repeated, composite fields). 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(robinson): Unify with code from 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// //compiler/cpp/internal/primitive_field.cc 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// //compiler/cpp/internal/enum_field.cc 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// //compiler/cpp/internal/string_field.cc 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string StringifyDefaultValue(const FieldDescriptor& field) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field.is_repeated()) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "[]"; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (field.cpp_type()) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT32: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(field.default_value_int32()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT32: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(field.default_value_uint32()); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT64: 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(field.default_value_int64()); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT64: 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(field.default_value_uint64()); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_DOUBLE: { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double value = field.default_value_double(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == numeric_limits<double>::infinity()) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Python pre-2.6 on Windows does not parse "inf" correctly. However, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a numeric literal that is too big for a double will become infinity. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "1e10000"; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value == -numeric_limits<double>::infinity()) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See above. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "-1e10000"; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value != value) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // infinity * 0 = nan 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "(1e10000 * 0)"; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleDtoa(value); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_FLOAT: { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float value = field.default_value_float(); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == numeric_limits<float>::infinity()) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Python pre-2.6 on Windows does not parse "inf" correctly. However, 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a numeric literal that is too big for a double will become infinity. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "1e10000"; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value == -numeric_limits<float>::infinity()) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See above. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "-1e10000"; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value != value) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // infinity - infinity = nan 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "(1e10000 * 0)"; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleFtoa(value); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_BOOL: 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return field.default_value_bool() ? "True" : "False"; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_ENUM: 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(field.default_value_enum()->number()); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_STRING: 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field.type() == FieldDescriptor::TYPE_STRING) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "unicode(\"" + CEscape(field.default_value_string()) + 222ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "\", \"utf-8\")"; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "\"" + CEscape(field.default_value_string()) + "\""; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 226ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case FieldDescriptor::CPPTYPE_MESSAGE: 227ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return "None"; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (We could add a default case above but then we wouldn't get the nice 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compiler warning when a new type is added.) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Not reached."; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Generator::Generator() : file_(NULL) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Generator::~Generator() { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Generator::Generate(const FileDescriptor* file, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& parameter, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GeneratorContext* context, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* error) const { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Completely serialize all Generate() calls on this instance. The 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread-safety constraints of the CodeGenerator interface aren't clear so 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // just be as conservative as possible. It's easier to relax this later if 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we need to, but I doubt it will be an issue. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): The proper thing to do would be to allocate any state on 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the stack and use that, so that the Generator class itself does not need 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to have any mutable members. Then it is implicitly thread-safe. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MutexLock lock(&mutex_); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_ = file; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string module_name = ModuleName(file->name()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string filename = module_name; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StripString(&filename, ".", '/'); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filename += ".py"; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorProto fdp; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->CopyTo(&fdp); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fdp.SerializeToString(&file_descriptor_serialized_); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(output.get()); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Printer printer(output.get(), '$'); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_ = &printer; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintImports(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFileDescriptor(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintTopLevelEnums(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintTopLevelExtensions(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintAllNestedEnumsInFile(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintMessageDescriptors(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInDescriptors(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintMessages(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have to fix up the extensions after the message classes themselves, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since they need to call static RegisterExtension() methods on these 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // classes. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInExtensions(); 288ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Descriptor options may have custom extensions. These custom options 289ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // can only be successfully parsed after we register corresponding 290ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // extensions. Therefore we parse all options again here to recognize 291ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // custom options that may be unknown when we define the descriptors. 292ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixAllDescriptorOptions(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasGenericServices(file)) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintServices(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer.Print( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "# @@protoc_insertion_point(module_scope)\n"); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !printer.failed(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints Python imports for all modules imported by |file|. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintImports() const { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->dependency_count(); ++i) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string module_name = ModuleName(file_->dependency(i)->name()); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("import $module$\n", "module", 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) module_name); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 311ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 312ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Print public imports. 313ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < file_->public_dependency_count(); ++i) { 314ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string module_name = ModuleName(file_->public_dependency(i)->name()); 315ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("from $module$ import *\n", "module", module_name); 316ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("\n"); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints the single file descriptor for this file. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintFileDescriptor() const { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["descriptor_name"] = kDescriptorKey; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["name"] = file_->name(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["package"] = file_->package(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char file_descriptor_template[] = 327ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "$descriptor_name$ = _descriptor.FileDescriptor(\n" 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " name='$name$',\n" 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " package='$package$',\n"; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, file_descriptor_template); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "serialized_pb='$value$'", 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "value", strings::CHexEscape(file_descriptor_serialized_)); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(falk): Also print options and fix the message_type, enum_type, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // service and extension later in the generation. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(")\n"); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints descriptors and module-level constants for all top-level 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enums defined in |file|. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintTopLevelEnums() const { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<pair<string, int> > top_level_enum_values; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->enum_type_count(); ++i) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor& enum_descriptor = *file_->enum_type(i); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintEnum(enum_descriptor); 351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("$name$ = " 352ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)", 353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "name", enum_descriptor.name(), 354ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "descriptor_name", 355ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ModuleLevelDescriptorName(enum_descriptor)); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < enum_descriptor.value_count(); ++j) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_level_enum_values.push_back( 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_pair(value_descriptor.name(), value_descriptor.number())); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < top_level_enum_values.size(); ++i) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("$name$ = $value$\n", 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name", top_level_enum_values[i].first, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "value", SimpleItoa(top_level_enum_values[i].second)); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints all enums contained in all message types in |file|. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintAllNestedEnumsInFile() const { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); ++i) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintNestedEnums(*file_->message_type(i)); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a Python statement assigning the appropriate module-level 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enum name to a Python EnumDescriptor object equivalent to 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enum_descriptor. 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["descriptor_name"] = ModuleLevelDescriptorName(enum_descriptor); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["name"] = enum_descriptor.name(); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["full_name"] = enum_descriptor.full_name(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["file"] = kDescriptorKey; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char enum_descriptor_template[] = 390ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "$descriptor_name$ = _descriptor.EnumDescriptor(\n" 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " name='$name$',\n" 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " full_name='$full_name$',\n" 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " filename=None,\n" 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " file=$file$,\n" 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " values=[\n"; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string options_string; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_descriptor.options().SerializeToString(&options_string); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, enum_descriptor_template); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < enum_descriptor.value_count(); ++i) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintEnumValueDescriptor(*enum_descriptor.value(i)); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(",\n"); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("],\n"); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("containing_type=None,\n"); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("options=$options_value$,\n", 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options_value", 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptionsValue("EnumOptions", options_string)); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumDescriptorProto edp; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSerializedPbInterval(enum_descriptor, edp); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(")\n"); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Recursively prints enums in nested types within descriptor, then 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prints enums contained at the top level in descriptor. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintNestedEnums(const Descriptor& descriptor) const { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.nested_type_count(); ++i) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintNestedEnums(*descriptor.nested_type(i)); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.enum_type_count(); ++i) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintEnum(*descriptor.enum_type(i)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintTopLevelExtensions() const { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool is_extension = true; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->extension_count(); ++i) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor& extension_field = *file_->extension(i); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string constant_name = extension_field.name() + "_FIELD_NUMBER"; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpperString(&constant_name); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("$constant_name$ = $number$\n", 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "constant_name", constant_name, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "number", SimpleItoa(extension_field.number())); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("$name$ = ", "name", extension_field.name()); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldDescriptor(extension_field, is_extension); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints Python equivalents of all Descriptors in |file|. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintMessageDescriptors() const { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); ++i) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintDescriptor(*file_->message_type(i)); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintServices() const { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->service_count(); ++i) { 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintServiceDescriptor(*file_->service(i)); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintServiceClass(*file_->service(i)); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintServiceStub(*file_->service(i)); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintServiceDescriptor( 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptor& descriptor) const { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string service_name = ModuleLevelServiceDescriptorName(descriptor); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string options_string; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor.options().SerializeToString(&options_string); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 471ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "$service_name$ = _descriptor.ServiceDescriptor(\n", 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "service_name", service_name); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["name"] = descriptor.name(); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["full_name"] = descriptor.full_name(); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["file"] = kDescriptorKey; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["index"] = SimpleItoa(descriptor.index()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["options_value"] = OptionsValue("ServiceOptions", options_string); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char required_function_arguments[] = 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name='$name$',\n" 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "full_name='$full_name$',\n" 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "file=$file$,\n" 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "index=$index$,\n" 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options=$options_value$,\n"; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, required_function_arguments); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceDescriptorProto sdp; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSerializedPbInterval(descriptor, sdp); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("methods=[\n"); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.method_count(); ++i) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MethodDescriptor* method = descriptor.method(i); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->options().SerializeToString(&options_string); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.clear(); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["name"] = method->name(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["full_name"] = method->full_name(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["index"] = SimpleItoa(method->index()); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["serialized_options"] = CEscape(options_string); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["input_type"] = ModuleLevelDescriptorName(*(method->input_type())); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["output_type"] = ModuleLevelDescriptorName(*(method->output_type())); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["options_value"] = OptionsValue("MethodOptions", options_string); 504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("_descriptor.MethodDescriptor(\n"); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m, 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name='$name$',\n" 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "full_name='$full_name$',\n" 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "index=$index$,\n" 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "containing_service=None,\n" 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "input_type=$input_type$,\n" 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "output_type=$output_type$,\n" 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options=$options_value$,\n"); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("),\n"); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("])\n\n"); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print the service. 525ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("class $class_name$(_service.Service):\n", 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "class_name", descriptor.name()); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "__metaclass__ = service_reflection.GeneratedServiceType\n" 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$descriptor_key$ = $descriptor_name$\n", 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "descriptor_key", kDescriptorKey, 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "descriptor_name", ModuleLevelServiceDescriptorName(descriptor)); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print the service stub. 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("class $class_name$_Stub($class_name$):\n", 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "class_name", descriptor.name()); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "__metaclass__ = service_reflection.GeneratedServiceStubType\n" 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$descriptor_key$ = $descriptor_name$\n", 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "descriptor_key", kDescriptorKey, 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "descriptor_name", ModuleLevelServiceDescriptorName(descriptor)); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints statement assigning ModuleLevelDescriptorName(message_descriptor) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a Python Descriptor object for message_descriptor. 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mutually recursive with PrintNestedDescriptors(). 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintNestedDescriptors(message_descriptor); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 557ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "descriptor_name", 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModuleLevelDescriptorName(message_descriptor)); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["name"] = message_descriptor.name(); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["full_name"] = message_descriptor.full_name(); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["file"] = kDescriptorKey; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char required_function_arguments[] = 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name='$name$',\n" 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "full_name='$full_name$',\n" 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "filename=None,\n" 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "file=$file$,\n" 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "containing_type=None,\n"; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, required_function_arguments); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldsInDescriptor(message_descriptor); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintExtensionsInDescriptor(message_descriptor); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nested types 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("nested_types=["); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message_descriptor.nested_type_count(); ++i) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string nested_name = ModuleLevelDescriptorName( 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *message_descriptor.nested_type(i)); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("$name$, ", "name", nested_name); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("],\n"); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enum types 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("enum_types=[\n"); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message_descriptor.enum_type_count(); ++i) { 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string descriptor_name = ModuleLevelDescriptorName( 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *message_descriptor.enum_type(i)); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(descriptor_name.c_str()); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(",\n"); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("],\n"); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string options_string; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_descriptor.options().SerializeToString(&options_string); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options=$options_value$,\n" 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "is_extendable=$extendable$", 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "options_value", OptionsValue("MessageOptions", options_string), 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "extendable", message_descriptor.extension_range_count() > 0 ? 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "True" : "False"); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(",\n"); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extension ranges 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("extension_ranges=["); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message_descriptor.extension_range_count(); ++i) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor::ExtensionRange* range = 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_descriptor.extension_range(i); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("($start$, $end$), ", 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "start", SimpleItoa(range->start), 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "end", SimpleItoa(range->end)); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("],\n"); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Serialization of proto 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorProto edp; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSerializedPbInterval(message_descriptor, edp); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(")\n"); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints Python Descriptor objects for all nested types contained in 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message_descriptor. 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mutually recursive with PrintDescriptor(). 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintNestedDescriptors( 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& containing_descriptor) const { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintDescriptor(*containing_descriptor.nested_type(i)); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints all messages in |file|. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintMessages() const { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); ++i) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintMessage(*file_->message_type(i)); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a Python class for the given message descriptor. We defer to the 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// metaclass to do almost all of the work of actually creating a useful class. 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The purpose of this function and its many helper functions above is merely 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to output a Python version of the descriptors, which the metaclass in 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reflection.py will use to construct the meat of the class itself. 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mutually recursive with PrintNestedMessages(). 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintMessage( 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& message_descriptor) const { 652ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("class $name$(_message.Message):\n", "name", 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_descriptor.name()); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 655ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("__metaclass__ = _reflection.GeneratedProtocolMessageType\n"); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintNestedMessages(message_descriptor); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["descriptor_key"] = kDescriptorKey; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, "$descriptor_key$ = $descriptor_name$\n"); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\n" 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "# @@protoc_insertion_point(class_scope:$full_name$)\n", 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "full_name", message_descriptor.full_name()); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints all nested messages within |containing_descriptor|. 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Mutually recursive with PrintMessage(). 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintNestedMessages( 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& containing_descriptor) const { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintMessage(*containing_descriptor.nested_type(i)); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Recursively fixes foreign fields in all nested types in |descriptor|, then 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sets the message_type and enum_type of all message and enum fields to point 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to their respective descriptors. 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Args: 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor: descriptor to print fields for. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// containing_descriptor: if descriptor is a nested type, this is its 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// containing type, or NULL if this is a root/top-level type. 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::FixForeignFieldsInDescriptor( 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& descriptor, 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* containing_descriptor) const { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.nested_type_count(); ++i) { 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.field_count(); ++i) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor& field_descriptor = *descriptor.field(i); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name"); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixContainingTypeInDescriptor(descriptor, containing_descriptor); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.enum_type_count(); ++i) { 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixContainingTypeInDescriptor(enum_descriptor, &descriptor); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["descriptor_name"] = kDescriptorKey; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["message_name"] = descriptor.name(); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char file_descriptor_template[] = 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$descriptor_name$.message_types_by_name['$message_name$'] = " 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$message_descriptor_name$\n"; 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, file_descriptor_template); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets any necessary message_type and enum_type attributes 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the Python version of |field|. 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// containing_type may be NULL, in which case this is a module-level field. 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// python_dict_name is the name of the Python dict where we should 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// look the field up in the containing type. (e.g., fields_by_name 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or extensions_by_name). We ignore python_dict_name if containing_type 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is NULL. 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::FixForeignFieldsInField(const Descriptor* containing_type, 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor& field, 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& python_dict_name) const { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string field_referencing_expression = FieldReferencingExpression( 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing_type, field, python_dict_name); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["field_ref"] = field_referencing_expression; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* foreign_message_type = field.message_type(); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (foreign_message_type) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n"); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* enum_type = field.enum_type(); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enum_type) { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["enum_type"] = ModuleLevelDescriptorName(*enum_type); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n"); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the module-level expression for the given FieldDescriptor. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only works for fields in the .proto file this Generator is generating for. 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// containing_type may be NULL, in which case this is a module-level field. 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// python_dict_name is the name of the Python dict where we should 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// look the field up in the containing type. (e.g., fields_by_name 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or extensions_by_name). We ignore python_dict_name if containing_type 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is NULL. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Generator::FieldReferencingExpression( 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* containing_type, 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor& field, 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& python_dict_name) const { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should only ever be looking up fields in the current file. 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The only things we refer to from other files are message descriptors. 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_EQ(field.file(), file_) << field.file()->name() << " vs. " 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << file_->name(); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!containing_type) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return field.name(); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return strings::Substitute( 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$0.$1['$2']", 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ModuleLevelDescriptorName(*containing_type), 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) python_dict_name, field.name()); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints containing_type for nested descriptors or enum descriptors. 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename DescriptorT> 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::FixContainingTypeInDescriptor( 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorT& descriptor, 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* containing_descriptor) const { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (containing_descriptor != NULL) { 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string nested_name = ModuleLevelDescriptorName(descriptor); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string parent_name = ModuleLevelDescriptorName( 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *containing_descriptor); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "$nested_name$.containing_type = $parent_name$;\n", 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "nested_name", nested_name, 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "parent_name", parent_name); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints statements setting the message_type and enum_type fields in the 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Python descriptor objects we've already output in ths file. We must 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// do this in a separate step due to circular references (otherwise, we'd 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// just set everything in the initial assignment statements). 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::FixForeignFieldsInDescriptors() const { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); ++i) { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInDescriptor(*file_->message_type(i), NULL); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); ++i) { 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddMessageToFileDescriptor(*file_->message_type(i)); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("\n"); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We need to not only set any necessary message_type fields, but 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// also need to call RegisterExtension() on each message we're 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extending. 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::FixForeignFieldsInExtensions() const { 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Top-level extensions. 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->extension_count(); ++i) { 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInExtension(*file_->extension(i)); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nested extensions. 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file_->message_type_count(); ++i) { 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInNestedExtensions(*file_->message_type(i)); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 813ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_->Print("\n"); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::FixForeignFieldsInExtension( 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor& extension_field) const { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(extension_field.is_extension()); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension_scope() will be NULL for top-level extensions, which is 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exactly what FixForeignFieldsInField() wants. 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInField(extension_field.extension_scope(), extension_field, 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "extensions_by_name"); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Confusingly, for FieldDescriptors that happen to be extensions, 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // containing_type() means "extended type." 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On the other hand, extension_scope() will give us what we normally 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mean by containing_type(). 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["extended_message_class"] = ModuleLevelMessageName( 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *extension_field.containing_type()); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["field"] = FieldReferencingExpression(extension_field.extension_scope(), 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_field, 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "extensions_by_name"); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n"); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::FixForeignFieldsInNestedExtensions( 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& descriptor) const { 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Recursively fix up extensions in all nested types. 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.nested_type_count(); ++i) { 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i)); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fix up extensions directly contained within this type. 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor.extension_count(); ++i) { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FixForeignFieldsInExtension(*descriptor.extension(i)); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a Python expression that instantiates a Python EnumValueDescriptor 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object for the given C++ descriptor. 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintEnumValueDescriptor( 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptor& descriptor) const { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(robinson): Fix up EnumValueDescriptor "type" fields. 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // More circular references. ::sigh:: 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string options_string; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor.options().SerializeToString(&options_string); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["name"] = descriptor.name(); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["index"] = SimpleItoa(descriptor.index()); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["number"] = SimpleItoa(descriptor.number()); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["options"] = OptionsValue("EnumValueOptions", options_string); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print( 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m, 864ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "_descriptor.EnumValueDescriptor(\n" 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " name='$name$', index=$index$, number=$number$,\n" 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " options=$options$,\n" 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " type=None)"); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a Python expression that calls descriptor._ParseOptions using 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the given descriptor class name and serialized options protobuf string. 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Generator::OptionsValue( 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& class_name, const string& serialized_options) const { 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (serialized_options.length() == 0 || GeneratingDescriptorProto()) { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "None"; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string full_class_name = "descriptor_pb2." + class_name; 878ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return "_descriptor._ParseOptions(" + full_class_name + "(), '" 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + CEscape(serialized_options)+ "')"; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints an expression for a Python FieldDescriptor for |field|. 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintFieldDescriptor( 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor& field, bool is_extension) const { 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string options_string; 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field.options().SerializeToString(&options_string); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) map<string, string> m; 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["name"] = field.name(); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["full_name"] = field.full_name(); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["index"] = SimpleItoa(field.index()); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["number"] = SimpleItoa(field.number()); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["type"] = SimpleItoa(field.type()); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["cpp_type"] = SimpleItoa(field.cpp_type()); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["label"] = SimpleItoa(field.label()); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["has_default_value"] = field.has_default_value() ? "True" : "False"; 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["default_value"] = StringifyDefaultValue(field); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["is_extension"] = is_extension ? "True" : "False"; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m["options"] = OptionsValue("FieldOptions", options_string); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We always set message_type and enum_type to None at this point, and then 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // these fields in correctly after all referenced descriptors have been 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // defined and/or imported (see FixForeignFieldsInDescriptors()). 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char field_descriptor_decl[] = 904ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "_descriptor.FieldDescriptor(\n" 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " name='$name$', full_name='$full_name$', index=$index$,\n" 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n" 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " has_default_value=$has_default_value$, default_value=$default_value$,\n" 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " message_type=None, enum_type=None, containing_type=None,\n" 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " is_extension=$is_extension$, extension_scope=None,\n" 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " options=$options$)"; 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(m, field_descriptor_decl); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper for Print{Fields,Extensions}InDescriptor(). 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintFieldDescriptorsInDescriptor( 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& message_descriptor, 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_extension, 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& list_variable_name, 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int (Descriptor::*CountFn)() const, 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const { 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("$list$=[\n", "list", list_variable_name); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Indent(); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) { 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i), 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_extension); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print(",\n"); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Outdent(); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("],\n"); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a statement assigning "fields" to a list of Python FieldDescriptors, 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one for each field present in message_descriptor. 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintFieldsInDescriptor( 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& message_descriptor) const { 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool is_extension = false; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldDescriptorsInDescriptor( 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_descriptor, is_extension, "fields", 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Descriptor::field_count, &Descriptor::field); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints a statement assigning "extensions" to a list of Python 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FieldDescriptors, one for each extension present in message_descriptor. 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintExtensionsInDescriptor( 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor& message_descriptor) const { 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool is_extension = true; 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldDescriptorsInDescriptor( 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_descriptor, is_extension, "extensions", 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Descriptor::extension_count, &Descriptor::extension); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Generator::GeneratingDescriptorProto() const { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file_->name() == "google/protobuf/descriptor.proto"; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the unique Python module-level identifier given to a descriptor. 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This name is module-qualified iff the given descriptor describes an 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// entity that doesn't come from the current file. 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename DescriptorT> 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Generator::ModuleLevelDescriptorName( 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorT& descriptor) const { 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME(robinson): 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We currently don't worry about collisions with underscores in the type 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // names, so these would collide in nasty ways if found in the same file: 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OuterProto.ProtoA.ProtoB 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OuterProto_ProtoA.ProtoB # Underscore instead of period. 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As would these: 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OuterProto.ProtoA_.ProtoB 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OuterProto.ProtoA._ProtoB # Leading vs. trailing underscore. 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (Contrived, but certainly possible). 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The C++ implementation doesn't guard against this either. Leaving 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it for now... 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name = NamePrefixedWithNestedTypes(descriptor, "_"); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpperString(&name); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Module-private for now. Easy to make public later; almost impossible 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to make private later. 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = "_" + name; 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We now have the name relative to its own module. Also qualify with 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the module name iff this descriptor is from a different .proto file. 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor.file() != file_) { 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = ModuleName(descriptor.file()->name()) + "." + name; 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name; 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the name of the message class itself, not the descriptor. 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Like ModuleLevelDescriptorName(), module-qualifies the name iff 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the given descriptor describes an entity that doesn't come from 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the current file. 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Generator::ModuleLevelMessageName(const Descriptor& descriptor) const { 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name = NamePrefixedWithNestedTypes(descriptor, "."); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor.file() != file_) { 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = ModuleName(descriptor.file()->name()) + "." + name; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the unique Python module-level identifier given to a service 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor. 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Generator::ModuleLevelServiceDescriptorName( 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptor& descriptor) const { 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name = descriptor.name(); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpperString(&name); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = "_" + name; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (descriptor.file() != file_) { 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = ModuleName(descriptor.file()->name()) + "." + name; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints standard constructor arguments serialized_start and serialized_end. 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Args: 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor: The cpp descriptor to have a serialized reference. 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proto: A proto 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example printer output: 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// serialized_start=41, 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// serialized_end=43, 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename DescriptorT, typename DescriptorProtoT> 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Generator::PrintSerializedPbInterval( 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorT& descriptor, DescriptorProtoT& proto) const { 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor.CopyTo(&proto); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string sp; 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto.SerializeToString(&sp); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset = file_descriptor_serialized_.find(sp); 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK_GE(offset, 0); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer_->Print("serialized_start=$serialized_start$,\n" 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "serialized_end=$serialized_end$,\n", 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "serialized_start", SimpleItoa(offset), 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "serialized_end", SimpleItoa(offset + sp.size())); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace { 1036ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid PrintDescriptorOptionsFixingCode(const string& descriptor, 1037ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const string& options, 1038ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch io::Printer* printer) { 1039ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase 1040ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // in proto2 python runtime but it couldn't be used here because appengine 1041ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // uses a snapshot version of the library in which the new method is not 1042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // yet present. After appengine has synced their runtime library, the code 1043ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // below should be cleaned up to use _SetOptions(). 1044ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer->Print( 1045ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "$descriptor$.has_options = True\n" 1046ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "$descriptor$._options = $options$\n", 1047ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "descriptor", descriptor, "options", options); 1048ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1049ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} // namespace 1050ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1051ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Prints expressions that set the options field of all descriptors. 1052ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid Generator::FixAllDescriptorOptions() const { 1053ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Prints an expression that sets the file descriptor's options. 1054ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string file_options = OptionsValue( 1055ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "FileOptions", file_->options().SerializeAsString()); 1056ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (file_options != "None") { 1057ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_); 1058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Prints expressions that set the options for all top level enums. 1060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < file_->enum_type_count(); ++i) { 1061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const EnumDescriptor& enum_descriptor = *file_->enum_type(i); 1062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixOptionsForEnum(enum_descriptor); 1063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Prints expressions that set the options for all top level extensions. 1065ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < file_->extension_count(); ++i) { 1066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor& field = *file_->extension(i); 1067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixOptionsForField(field); 1068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Prints expressions that set the options for all messages, nested enums, 1070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // nested extensions and message fields. 1071ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < file_->message_type_count(); ++i) { 1072ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixOptionsForMessage(*file_->message_type(i)); 1073ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1074ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1075ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1076ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Prints expressions that set the options for an enum descriptor and its 1077ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// value descriptors. 1078ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { 1079ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string descriptor_name = ModuleLevelDescriptorName(enum_descriptor); 1080ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string enum_options = OptionsValue( 1081ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "EnumOptions", enum_descriptor.options().SerializeAsString()); 1082ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (enum_options != "None") { 1083ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_); 1084ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1085ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < enum_descriptor.value_count(); ++i) { 1086ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i); 1087ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string value_options = OptionsValue( 1088ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "EnumValueOptions", value_descriptor.options().SerializeAsString()); 1089ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (value_options != "None") { 1090ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PrintDescriptorOptionsFixingCode( 1091ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), 1092ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch value_descriptor.name().c_str()), 1093ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch value_options, printer_); 1094ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1095ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1096ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1097ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1098ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Prints expressions that set the options for field descriptors (including 1099ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// extensions). 1100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid Generator::FixOptionsForField( 1101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor& field) const { 1102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string field_options = OptionsValue( 1103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "FieldOptions", field.options().SerializeAsString()); 1104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field_options != "None") { 1105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string field_name; 1106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field.is_extension()) { 1107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field.extension_scope() == NULL) { 1108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Top level extensions. 1109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch field_name = field.name(); 1110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 1111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch field_name = FieldReferencingExpression( 1112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch field.extension_scope(), field, "extensions_by_name"); 1113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 1115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch field_name = FieldReferencingExpression( 1116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch field.containing_type(), field, "fields_by_name"); 1117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PrintDescriptorOptionsFixingCode(field_name, field_options, printer_); 1119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Prints expressions that set the options for a message and all its inner 1123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// types (nested messages, nested enums, extensions, fields). 1124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid Generator::FixOptionsForMessage(const Descriptor& descriptor) const { 1125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Nested messages. 1126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < descriptor.nested_type_count(); ++i) { 1127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixOptionsForMessage(*descriptor.nested_type(i)); 1128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Enums. 1130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < descriptor.enum_type_count(); ++i) { 1131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixOptionsForEnum(*descriptor.enum_type(i)); 1132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Fields. 1134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < descriptor.field_count(); ++i) { 1135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor& field = *descriptor.field(i); 1136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixOptionsForField(field); 1137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Extensions. 1139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < descriptor.extension_count(); ++i) { 1140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor& field = *descriptor.extension(i); 1141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FixOptionsForField(field); 1142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Message option for this message. 1144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string message_options = OptionsValue( 1145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "MessageOptions", descriptor.options().SerializeAsString()); 1146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (message_options != "None") { 1147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string descriptor_name = ModuleLevelDescriptorName(descriptor); 1148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PrintDescriptorOptionsFixingCode(descriptor_name, 1149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message_options, 1150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer_); 1151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace python 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace compiler 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 1158