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