LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/python - python_generator.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 4 600 0.7 %
Date: 2015-10-10 Functions: 2 62 3.2 %

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

Generated by: LCOV version 1.10