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