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