1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 //#PY25 compatible generated code for GAE.
32 // Copyright 2007 Google Inc. All Rights Reserved.
33 // Author: robinson@google.com (Will Robinson)
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.
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
55 #include <google/protobuf/compiler/python/python_generator.h>
56 #include <google/protobuf/descriptor.pb.h>
58 #include <google/protobuf/stubs/logging.h>
59 #include <google/protobuf/stubs/common.h>
60 #include <google/protobuf/stubs/stringprintf.h>
61 #include <google/protobuf/io/printer.h>
62 #include <google/protobuf/io/zero_copy_stream.h>
63 #include <google/protobuf/descriptor.h>
64 #include <google/protobuf/stubs/strutil.h>
65 #include <google/protobuf/stubs/substitute.h>
76 bool StrEndsWith(StringPiece sp, StringPiece x) {
77 return sp.size() >= x.size() && sp.substr(sp.size() - x.size()) == x;
80 // Returns a copy of |filename| with any trailing ".protodevel" or ".proto
82 // TODO(robinson): Unify with copy in compiler/cpp/internal/helpers.cc.
83 std::string StripProto(const std::string& filename) {
85 StrEndsWith(filename, ".protodevel") ? ".protodevel" : ".proto";
86 return StripSuffixString(filename, suffix);
89 // Returns the Python module name expected for a given .proto filename.
90 std::string ModuleName(const std::string& filename) {
91 std::string basename = StripProto(filename);
92 ReplaceCharacters(&basename, "-", '_');
93 ReplaceCharacters(&basename, "/", '.');
94 return basename + "_pb2";
97 // Returns the alias we assign to the module of the given .proto filename
98 // when importing. See testPackageInitializationImport in
99 // net/proto2/python/internal/reflection_test.py
100 // to see why we need the alias.
101 std::string ModuleAlias(const std::string& filename) {
102 std::string module_name = ModuleName(filename);
103 // We can't have dots in the module name, so we replace each with _dot_.
104 // But that could lead to a collision between a.b and a_dot_b, so we also
105 // duplicate each underscore.
106 GlobalReplaceSubstring("_", "__", &module_name);
107 GlobalReplaceSubstring(".", "_dot_", &module_name);
111 // Keywords reserved by the Python language.
112 const char* const kKeywords[] = {
113 "False", "None", "True", "and", "as", "assert", "break",
114 "class", "continue", "def", "del", "elif", "else", "except",
115 "finally", "for", "from", "global", "if", "import", "in",
116 "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
117 "return", "try", "while", "with", "yield", "print",
119 const char* const* kKeywordsEnd =
120 kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0]));
122 bool ContainsPythonKeyword(const std::string& module_name) {
123 std::vector<std::string> tokens = Split(module_name, ".");
124 for (int i = 0; i < tokens.size(); ++i) {
125 if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) {
132 inline bool IsPythonKeyword(const string& name) {
133 return (std::find(kKeywords, kKeywordsEnd, name) != kKeywordsEnd);
136 std::string ResolveKeyword(const std::string& name) {
137 if (IsPythonKeyword(name)) {
138 return "globals()['" + name + "']";
143 // Returns the name of all containing types for descriptor,
144 // in order from outermost to innermost, followed by descriptor's
145 // own name. Each name is separated by |separator|.
146 template <typename DescriptorT>
147 std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor,
148 const std::string& separator) {
149 std::string name = descriptor.name();
150 const Descriptor* parent = descriptor.containing_type();
151 if (parent != nullptr) {
152 std::string prefix = NamePrefixedWithNestedTypes(*parent, separator);
153 if (separator == "." && IsPythonKeyword(name)) {
154 return "getattr(" + prefix + ", '" + name + "')";
156 return prefix + separator + name;
159 if (separator == ".") {
160 name = ResolveKeyword(name);
165 // Name of the class attribute where we store the Python
166 // descriptor.Descriptor instance for the generated class.
167 // Must stay consistent with the _DESCRIPTOR_KEY constant
168 // in proto2/public/reflection.py.
169 const char kDescriptorKey[] = "DESCRIPTOR";
171 // Does the file have top-level enums?
172 inline bool HasTopLevelEnums(const FileDescriptor* file) {
173 return file->enum_type_count() > 0;
176 // Should we generate generic services for this file?
177 inline bool HasGenericServices(const FileDescriptor* file) {
178 return file->service_count() > 0 && file->options().py_generic_services();
181 // Prints the common boilerplate needed at the top of every .py
182 // file output by this generator.
183 void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file,
184 bool descriptor_proto) {
185 // TODO(robinson): Allow parameterization of Python version?
187 "# -*- coding: utf-8 -*-\n"
188 "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
189 "# source: $filename$\n"
190 "\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda "
191 "x:x.encode('latin1'))" //##PY25
193 "filename", file->name());
194 if (HasTopLevelEnums(file)) {
196 "from google.protobuf.internal import enum_type_wrapper\n");
199 "from google.protobuf import descriptor as _descriptor\n"
200 "from google.protobuf import message as _message\n"
201 "from google.protobuf import reflection as _reflection\n"
202 "from google.protobuf import symbol_database as "
203 "_symbol_database\n");
204 if (HasGenericServices(file)) {
206 "from google.protobuf import service as _service\n"
207 "from google.protobuf import service_reflection\n");
211 "# @@protoc_insertion_point(imports)\n\n"
212 "_sym_db = _symbol_database.Default()\n");
213 printer->Print("\n\n");
216 // Returns a Python literal giving the default value for a field.
217 // If the field specifies no explicit default value, we'll return
218 // the default default value for the field type (zero for numbers,
219 // empty string for strings, empty list for repeated fields, and
220 // None for non-repeated, composite fields).
222 // TODO(robinson): Unify with code from
223 // //compiler/cpp/internal/primitive_field.cc
224 // //compiler/cpp/internal/enum_field.cc
225 // //compiler/cpp/internal/string_field.cc
226 std::string StringifyDefaultValue(const FieldDescriptor& field) {
227 if (field.is_repeated()) {
231 switch (field.cpp_type()) {
232 case FieldDescriptor::CPPTYPE_INT32:
233 return StrCat(field.default_value_int32());
234 case FieldDescriptor::CPPTYPE_UINT32:
235 return StrCat(field.default_value_uint32());
236 case FieldDescriptor::CPPTYPE_INT64:
237 return StrCat(field.default_value_int64());
238 case FieldDescriptor::CPPTYPE_UINT64:
239 return StrCat(field.default_value_uint64());
240 case FieldDescriptor::CPPTYPE_DOUBLE: {
241 double value = field.default_value_double();
242 if (value == std::numeric_limits<double>::infinity()) {
243 // Python pre-2.6 on Windows does not parse "inf" correctly. However,
244 // a numeric literal that is too big for a double will become infinity.
246 } else if (value == -std::numeric_limits<double>::infinity()) {
249 } else if (value != value) {
250 // infinity * 0 = nan
251 return "(1e10000 * 0)";
253 return "float(" + SimpleDtoa(value) + ")";
256 case FieldDescriptor::CPPTYPE_FLOAT: {
257 float value = field.default_value_float();
258 if (value == std::numeric_limits<float>::infinity()) {
259 // Python pre-2.6 on Windows does not parse "inf" correctly. However,
260 // a numeric literal that is too big for a double will become infinity.
262 } else if (value == -std::numeric_limits<float>::infinity()) {
265 } else if (value != value) {
266 // infinity - infinity = nan
267 return "(1e10000 * 0)";
269 return "float(" + SimpleFtoa(value) + ")";
272 case FieldDescriptor::CPPTYPE_BOOL:
273 return field.default_value_bool() ? "True" : "False";
274 case FieldDescriptor::CPPTYPE_ENUM:
275 return StrCat(field.default_value_enum()->number());
276 case FieldDescriptor::CPPTYPE_STRING:
277 //##!PY25 return "b\"" + CEscape(field.default_value_string())
279 //##!PY25 (field.type() != FieldDescriptor::TYPE_STRING ? "\""
281 //##!PY25 "\".decode('utf-8')");
282 return "_b(\"" + CEscape(field.default_value_string()) + //##PY25
283 (field.type() != FieldDescriptor::TYPE_STRING ? "\")" : //##PY25
284 "\").decode('utf-8')"); //##PY25
285 case FieldDescriptor::CPPTYPE_MESSAGE:
288 // (We could add a default case above but then we wouldn't get the nice
289 // compiler warning when a new type is added.)
290 GOOGLE_LOG(FATAL) << "Not reached.";
294 std::string StringifySyntax(FileDescriptor::Syntax syntax) {
296 case FileDescriptor::SYNTAX_PROTO2:
298 case FileDescriptor::SYNTAX_PROTO3:
300 case FileDescriptor::SYNTAX_UNKNOWN:
302 GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports proto2 "
303 "and proto3 syntax.";
310 Generator::Generator() : file_(NULL) {}
312 Generator::~Generator() {}
314 bool Generator::Generate(const FileDescriptor* file,
315 const std::string& parameter,
316 GeneratorContext* context, std::string* error) const {
318 // Completely serialize all Generate() calls on this instance. The
319 // thread-safety constraints of the CodeGenerator interface aren't clear so
320 // just be as conservative as possible. It's easier to relax this later if
321 // we need to, but I doubt it will be an issue.
322 // TODO(kenton): The proper thing to do would be to allocate any state on
323 // the stack and use that, so that the Generator class itself does not need
324 // to have any mutable members. Then it is implicitly thread-safe.
325 MutexLock lock(&mutex_);
327 std::string module_name = ModuleName(file->name());
328 std::string filename = module_name;
329 ReplaceCharacters(&filename, ".", '/');
332 FileDescriptorProto fdp;
334 fdp.SerializeToString(&file_descriptor_serialized_);
337 std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
338 GOOGLE_CHECK(output.get());
339 io::Printer printer(output.get(), '$');
342 PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
344 PrintFileDescriptor();
345 PrintTopLevelEnums();
346 PrintTopLevelExtensions();
347 PrintAllNestedEnumsInFile();
348 PrintMessageDescriptors();
349 FixForeignFieldsInDescriptors();
351 // We have to fix up the extensions after the message classes themselves,
352 // since they need to call static RegisterExtension() methods on these
354 FixForeignFieldsInExtensions();
355 // Descriptor options may have custom extensions. These custom options
356 // can only be successfully parsed after we register corresponding
357 // extensions. Therefore we parse all options again here to recognize
358 // custom options that may be unknown when we define the descriptors.
359 // This does not apply to services because they are not used by extensions.
360 FixAllDescriptorOptions();
361 PrintServiceDescriptors();
362 if (HasGenericServices(file)) {
366 printer.Print("# @@protoc_insertion_point(module_scope)\n");
368 return !printer.failed();
370 // BEGIN GOOGLE-INTERNAL
371 // Strip the google3.third_party.py. prefix off of a module name as we
372 // NEVER want that invalid module import path to be generated in google3.
373 // Our sys.path has google3/third_party/py/ in it. All modules from
374 // that tree need to be imported using just their own name.
375 // See http://go/ThirdPartyPython
376 void StripThirdPartyPy(std::string* module_name) {
377 const std::string third_party_py_prefix = "google3.third_party.py.";
378 int len = third_party_py_prefix.length();
379 if (module_name->compare(0, len, third_party_py_prefix, 0, len) == 0) {
380 *module_name = module_name->erase(0, len);
383 // END GOOGLE-INTERNAL
385 // Prints Python imports for all modules imported by |file|.
386 void Generator::PrintImports() const {
387 for (int i = 0; i < file_->dependency_count(); ++i) {
388 const std::string& filename = file_->dependency(i)->name();
390 std::string module_name = ModuleName(filename);
391 std::string module_alias = ModuleAlias(filename);
392 // BEGIN GOOGLE-INTERNAL
393 StripThirdPartyPy(&module_name);
394 // END GOOGLE-INTERNAL
395 if (ContainsPythonKeyword(module_name)) {
396 // If the module path contains a Python keyword, we have to quote the
397 // module name and import it using importlib. Otherwise the usual kind of
398 // import statement would result in a syntax error from the presence of
400 printer_->Print("import importlib\n");
401 printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
402 module_alias, "name", module_name);
404 int last_dot_pos = module_name.rfind('.');
405 std::string import_statement;
406 if (last_dot_pos == std::string::npos) {
407 // NOTE(petya): this is not tested as it would require a protocol buffer
408 // outside of any package, and I don't think that is easily achievable.
409 import_statement = "import " + module_name;
411 import_statement = "from " + module_name.substr(0, last_dot_pos) +
412 " import " + module_name.substr(last_dot_pos + 1);
414 printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
415 "alias", module_alias);
418 CopyPublicDependenciesAliases(module_alias, file_->dependency(i));
420 printer_->Print("\n");
422 // Print public imports.
423 for (int i = 0; i < file_->public_dependency_count(); ++i) {
424 std::string module_name = ModuleName(file_->public_dependency(i)->name());
425 // BEGIN GOOGLE-INTERNAL
426 StripThirdPartyPy(&module_name);
427 // END GOOGLE-INTERNAL
428 printer_->Print("from $module$ import *\n", "module", module_name);
430 printer_->Print("\n");
433 // Prints the single file descriptor for this file.
434 void Generator::PrintFileDescriptor() const {
435 std::map<std::string, std::string> m;
436 m["descriptor_name"] = kDescriptorKey;
437 m["name"] = file_->name();
438 m["package"] = file_->package();
439 m["syntax"] = StringifySyntax(file_->syntax());
440 m["options"] = OptionsValue(file_->options().SerializeAsString());
441 const char file_descriptor_template[] =
442 "$descriptor_name$ = _descriptor.FileDescriptor(\n"
444 " package='$package$',\n"
445 " syntax='$syntax$',\n"
446 " serialized_options=$options$,\n";
447 printer_->Print(m, file_descriptor_template);
450 //##!PY25 "serialized_pb=b'$value$'\n",
451 "serialized_pb=_b('$value$')\n", //##PY25
452 "value", strings::CHexEscape(file_descriptor_serialized_));
453 if (file_->dependency_count() != 0) {
454 printer_->Print(",\ndependencies=[");
455 for (int i = 0; i < file_->dependency_count(); ++i) {
456 std::string module_alias = ModuleAlias(file_->dependency(i)->name());
457 printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
460 printer_->Print("]");
462 if (file_->public_dependency_count() > 0) {
463 printer_->Print(",\npublic_dependencies=[");
464 for (int i = 0; i < file_->public_dependency_count(); ++i) {
465 std::string module_alias =
466 ModuleAlias(file_->public_dependency(i)->name());
467 printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
470 printer_->Print("]");
473 // TODO(falk): Also print options and fix the message_type, enum_type,
474 // service and extension later in the generation.
477 printer_->Print(")\n");
478 printer_->Print("\n");
481 // Prints descriptors and module-level constants for all top-level
482 // enums defined in |file|.
483 void Generator::PrintTopLevelEnums() const {
484 std::vector<std::pair<std::string, int> > top_level_enum_values;
485 for (int i = 0; i < file_->enum_type_count(); ++i) {
486 const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
487 PrintEnum(enum_descriptor);
490 "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)",
491 "name", ResolveKeyword(enum_descriptor.name()), "descriptor_name",
492 ModuleLevelDescriptorName(enum_descriptor));
493 printer_->Print("\n");
495 for (int j = 0; j < enum_descriptor.value_count(); ++j) {
496 const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(j);
497 top_level_enum_values.push_back(
498 std::make_pair(value_descriptor.name(), value_descriptor.number()));
502 for (int i = 0; i < top_level_enum_values.size(); ++i) {
503 printer_->Print("$name$ = $value$\n", "name",
504 ResolveKeyword(top_level_enum_values[i].first), "value",
505 StrCat(top_level_enum_values[i].second));
507 printer_->Print("\n");
510 // Prints all enums contained in all message types in |file|.
511 void Generator::PrintAllNestedEnumsInFile() const {
512 for (int i = 0; i < file_->message_type_count(); ++i) {
513 PrintNestedEnums(*file_->message_type(i));
517 // Prints a Python statement assigning the appropriate module-level
518 // enum name to a Python EnumDescriptor object equivalent to
520 void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
521 std::map<std::string, std::string> m;
522 std::string module_level_descriptor_name =
523 ModuleLevelDescriptorName(enum_descriptor);
524 m["descriptor_name"] = module_level_descriptor_name;
525 m["name"] = enum_descriptor.name();
526 m["full_name"] = enum_descriptor.full_name();
527 m["file"] = kDescriptorKey;
528 const char enum_descriptor_template[] =
529 "$descriptor_name$ = _descriptor.EnumDescriptor(\n"
531 " full_name='$full_name$',\n"
535 std::string options_string;
536 enum_descriptor.options().SerializeToString(&options_string);
537 printer_->Print(m, enum_descriptor_template);
540 for (int i = 0; i < enum_descriptor.value_count(); ++i) {
541 PrintEnumValueDescriptor(*enum_descriptor.value(i));
542 printer_->Print(",\n");
545 printer_->Print("],\n");
546 printer_->Print("containing_type=None,\n");
547 printer_->Print("serialized_options=$options_value$,\n", "options_value",
548 OptionsValue(options_string));
549 EnumDescriptorProto edp;
550 PrintSerializedPbInterval(enum_descriptor, edp);
552 printer_->Print(")\n");
553 printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
554 module_level_descriptor_name);
555 printer_->Print("\n");
558 // Recursively prints enums in nested types within descriptor, then
559 // prints enums contained at the top level in descriptor.
560 void Generator::PrintNestedEnums(const Descriptor& descriptor) const {
561 for (int i = 0; i < descriptor.nested_type_count(); ++i) {
562 PrintNestedEnums(*descriptor.nested_type(i));
565 for (int i = 0; i < descriptor.enum_type_count(); ++i) {
566 PrintEnum(*descriptor.enum_type(i));
570 void Generator::PrintTopLevelExtensions() const {
571 const bool is_extension = true;
572 for (int i = 0; i < file_->extension_count(); ++i) {
573 const FieldDescriptor& extension_field = *file_->extension(i);
574 std::string constant_name = extension_field.name() + "_FIELD_NUMBER";
575 UpperString(&constant_name);
576 printer_->Print("$constant_name$ = $number$\n", "constant_name",
577 constant_name, "number",
578 StrCat(extension_field.number()));
579 printer_->Print("$name$ = ", "name",
580 ResolveKeyword(extension_field.name()));
581 PrintFieldDescriptor(extension_field, is_extension);
582 printer_->Print("\n");
584 printer_->Print("\n");
587 // Prints Python equivalents of all Descriptors in |file|.
588 void Generator::PrintMessageDescriptors() const {
589 for (int i = 0; i < file_->message_type_count(); ++i) {
590 PrintDescriptor(*file_->message_type(i));
591 printer_->Print("\n");
595 void Generator::PrintServiceDescriptors() const {
596 for (int i = 0; i < file_->service_count(); ++i) {
597 PrintServiceDescriptor(*file_->service(i));
598 AddServiceToFileDescriptor(*file_->service(i));
599 printer_->Print("\n");
603 void Generator::PrintServices() const {
604 for (int i = 0; i < file_->service_count(); ++i) {
605 PrintServiceClass(*file_->service(i));
606 PrintServiceStub(*file_->service(i));
607 printer_->Print("\n");
611 void Generator::PrintServiceDescriptor(
612 const ServiceDescriptor& descriptor) const {
613 printer_->Print("\n");
614 std::string service_name = ModuleLevelServiceDescriptorName(descriptor);
615 std::string options_string;
616 descriptor.options().SerializeToString(&options_string);
618 printer_->Print("$service_name$ = _descriptor.ServiceDescriptor(\n",
619 "service_name", service_name);
621 std::map<std::string, std::string> m;
622 m["name"] = descriptor.name();
623 m["full_name"] = descriptor.full_name();
624 m["file"] = kDescriptorKey;
625 m["index"] = StrCat(descriptor.index());
626 m["options_value"] = OptionsValue(options_string);
627 const char required_function_arguments[] =
629 "full_name='$full_name$',\n"
632 "serialized_options=$options_value$,\n";
633 printer_->Print(m, required_function_arguments);
635 ServiceDescriptorProto sdp;
636 PrintSerializedPbInterval(descriptor, sdp);
638 printer_->Print("methods=[\n");
639 for (int i = 0; i < descriptor.method_count(); ++i) {
640 const MethodDescriptor* method = descriptor.method(i);
641 method->options().SerializeToString(&options_string);
644 m["name"] = method->name();
645 m["full_name"] = method->full_name();
646 m["index"] = StrCat(method->index());
647 m["serialized_options"] = CEscape(options_string);
648 m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
649 m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
650 m["options_value"] = OptionsValue(options_string);
651 printer_->Print("_descriptor.MethodDescriptor(\n");
655 "full_name='$full_name$',\n"
657 "containing_service=None,\n"
658 "input_type=$input_type$,\n"
659 "output_type=$output_type$,\n"
660 "serialized_options=$options_value$,\n");
662 printer_->Print("),\n");
666 printer_->Print("])\n");
667 printer_->Print("_sym_db.RegisterServiceDescriptor($name$)\n", "name",
669 printer_->Print("\n");
672 void Generator::PrintDescriptorKeyAndModuleName(
673 const ServiceDescriptor& descriptor) const {
674 printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key",
675 kDescriptorKey, "descriptor_name",
676 ModuleLevelServiceDescriptorName(descriptor));
677 printer_->Print("__module__ = '$module_name$'\n", "module_name",
678 ModuleName(file_->name()));
681 void Generator::PrintServiceClass(const ServiceDescriptor& descriptor) const {
682 // Print the service.
684 "$class_name$ = service_reflection.GeneratedServiceType("
685 "'$class_name$', (_service.Service,), dict(\n",
686 "class_name", descriptor.name());
688 Generator::PrintDescriptorKeyAndModuleName(descriptor);
689 printer_->Print("))\n\n");
693 void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
694 // Print the service stub.
696 "$class_name$_Stub = "
697 "service_reflection.GeneratedServiceStubType("
698 "'$class_name$_Stub', ($class_name$,), dict(\n",
699 "class_name", descriptor.name());
701 Generator::PrintDescriptorKeyAndModuleName(descriptor);
702 printer_->Print("))\n\n");
706 // Prints statement assigning ModuleLevelDescriptorName(message_descriptor)
707 // to a Python Descriptor object for message_descriptor.
709 // Mutually recursive with PrintNestedDescriptors().
710 void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
711 PrintNestedDescriptors(message_descriptor);
713 printer_->Print("\n");
714 printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n",
716 ModuleLevelDescriptorName(message_descriptor));
718 std::map<std::string, std::string> m;
719 m["name"] = message_descriptor.name();
720 m["full_name"] = message_descriptor.full_name();
721 m["file"] = kDescriptorKey;
722 const char required_function_arguments[] =
724 "full_name='$full_name$',\n"
727 "containing_type=None,\n";
728 printer_->Print(m, required_function_arguments);
729 PrintFieldsInDescriptor(message_descriptor);
730 PrintExtensionsInDescriptor(message_descriptor);
733 printer_->Print("nested_types=[");
734 for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
735 const std::string nested_name =
736 ModuleLevelDescriptorName(*message_descriptor.nested_type(i));
737 printer_->Print("$name$, ", "name", nested_name);
739 printer_->Print("],\n");
742 printer_->Print("enum_types=[\n");
744 for (int i = 0; i < message_descriptor.enum_type_count(); ++i) {
745 const std::string descriptor_name =
746 ModuleLevelDescriptorName(*message_descriptor.enum_type(i));
747 printer_->Print(descriptor_name.c_str());
748 printer_->Print(",\n");
751 printer_->Print("],\n");
752 std::string options_string;
753 message_descriptor.options().SerializeToString(&options_string);
755 "serialized_options=$options_value$,\n"
756 "is_extendable=$extendable$,\n"
758 "options_value", OptionsValue(options_string), "extendable",
759 message_descriptor.extension_range_count() > 0 ? "True" : "False",
760 "syntax", StringifySyntax(message_descriptor.file()->syntax()));
761 printer_->Print(",\n");
764 printer_->Print("extension_ranges=[");
765 for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
766 const Descriptor::ExtensionRange* range =
767 message_descriptor.extension_range(i);
768 printer_->Print("($start$, $end$), ", "start", StrCat(range->start),
769 "end", StrCat(range->end));
771 printer_->Print("],\n");
772 printer_->Print("oneofs=[\n");
774 for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) {
775 const OneofDescriptor* desc = message_descriptor.oneof_decl(i);
776 std::map<std::string, std::string> m;
777 m["name"] = desc->name();
778 m["full_name"] = desc->full_name();
779 m["index"] = StrCat(desc->index());
780 std::string options_string =
781 OptionsValue(desc->options().SerializeAsString());
782 if (options_string == "None") {
783 m["serialized_options"] = "";
785 m["serialized_options"] = ", serialized_options=" + options_string;
788 "_descriptor.OneofDescriptor(\n"
789 " name='$name$', full_name='$full_name$',\n"
790 " index=$index$, containing_type=None, "
791 "fields=[]$serialized_options$),\n");
794 printer_->Print("],\n");
795 // Serialization of proto
797 PrintSerializedPbInterval(message_descriptor, edp);
800 printer_->Print(")\n");
803 // Prints Python Descriptor objects for all nested types contained in
804 // message_descriptor.
806 // Mutually recursive with PrintDescriptor().
807 void Generator::PrintNestedDescriptors(
808 const Descriptor& containing_descriptor) const {
809 for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
810 PrintDescriptor(*containing_descriptor.nested_type(i));
814 // Prints all messages in |file|.
815 void Generator::PrintMessages() const {
816 for (int i = 0; i < file_->message_type_count(); ++i) {
817 std::vector<std::string> to_register;
818 PrintMessage(*file_->message_type(i), "", &to_register, false);
819 for (int j = 0; j < to_register.size(); ++j) {
820 printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
821 ResolveKeyword(to_register[j]));
823 printer_->Print("\n");
827 // Prints a Python class for the given message descriptor. We defer to the
828 // metaclass to do almost all of the work of actually creating a useful class.
829 // The purpose of this function and its many helper functions above is merely
830 // to output a Python version of the descriptors, which the metaclass in
831 // reflection.py will use to construct the meat of the class itself.
833 // Mutually recursive with PrintNestedMessages().
834 // Collect nested message names to_register for the symbol_database.
835 void Generator::PrintMessage(const Descriptor& message_descriptor,
836 const std::string& prefix,
837 std::vector<std::string>* to_register,
838 bool is_nested) const {
839 std::string qualified_name;
841 if (IsPythonKeyword(message_descriptor.name())) {
843 "getattr(" + prefix + ", '" + message_descriptor.name() + "')";
845 qualified_name = prefix + "." + message_descriptor.name();
848 "'$name$' : _reflection.GeneratedProtocolMessageType('$name$', "
849 "(_message.Message,), {\n",
850 "name", message_descriptor.name());
852 qualified_name = ResolveKeyword(message_descriptor.name());
854 "$qualified_name$ = _reflection.GeneratedProtocolMessageType('$name$', "
855 "(_message.Message,), {\n",
856 "qualified_name", qualified_name, "name", message_descriptor.name());
860 to_register->push_back(qualified_name);
862 PrintNestedMessages(message_descriptor, qualified_name, to_register);
863 std::map<std::string, std::string> m;
864 m["descriptor_key"] = kDescriptorKey;
865 m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
866 printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
867 printer_->Print("'__module__' : '$module_name$'\n", "module_name",
868 ModuleName(file_->name()));
869 printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
870 "full_name", message_descriptor.full_name());
871 printer_->Print("})\n");
875 // Prints all nested messages within |containing_descriptor|.
876 // Mutually recursive with PrintMessage().
877 void Generator::PrintNestedMessages(
878 const Descriptor& containing_descriptor, const std::string& prefix,
879 std::vector<std::string>* to_register) const {
880 for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
881 printer_->Print("\n");
882 PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register,
884 printer_->Print(",\n");
888 // Recursively fixes foreign fields in all nested types in |descriptor|, then
889 // sets the message_type and enum_type of all message and enum fields to point
890 // to their respective descriptors.
892 // descriptor: descriptor to print fields for.
893 // containing_descriptor: if descriptor is a nested type, this is its
894 // containing type, or NULL if this is a root/top-level type.
895 void Generator::FixForeignFieldsInDescriptor(
896 const Descriptor& descriptor,
897 const Descriptor* containing_descriptor) const {
898 for (int i = 0; i < descriptor.nested_type_count(); ++i) {
899 FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
902 for (int i = 0; i < descriptor.field_count(); ++i) {
903 const FieldDescriptor& field_descriptor = *descriptor.field(i);
904 FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
907 FixContainingTypeInDescriptor(descriptor, containing_descriptor);
908 for (int i = 0; i < descriptor.enum_type_count(); ++i) {
909 const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
910 FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
912 for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
913 std::map<std::string, std::string> m;
914 const OneofDescriptor* oneof = descriptor.oneof_decl(i);
915 m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
916 m["oneof_name"] = oneof->name();
917 for (int j = 0; j < oneof->field_count(); ++j) {
918 m["field_name"] = oneof->field(j)->name();
921 "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n"
922 " $descriptor_name$.fields_by_name['$field_name$'])\n");
925 "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = "
926 "$descriptor_name$.oneofs_by_name['$oneof_name$']\n");
931 void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
932 std::map<std::string, std::string> m;
933 m["descriptor_name"] = kDescriptorKey;
934 m["message_name"] = descriptor.name();
935 m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
936 const char file_descriptor_template[] =
937 "$descriptor_name$.message_types_by_name['$message_name$'] = "
938 "$message_descriptor_name$\n";
939 printer_->Print(m, file_descriptor_template);
942 void Generator::AddServiceToFileDescriptor(
943 const ServiceDescriptor& descriptor) const {
944 std::map<std::string, std::string> m;
945 m["descriptor_name"] = kDescriptorKey;
946 m["service_name"] = descriptor.name();
947 m["service_descriptor_name"] = ModuleLevelServiceDescriptorName(descriptor);
948 const char file_descriptor_template[] =
949 "$descriptor_name$.services_by_name['$service_name$'] = "
950 "$service_descriptor_name$\n";
951 printer_->Print(m, file_descriptor_template);
954 void Generator::AddEnumToFileDescriptor(
955 const EnumDescriptor& descriptor) const {
956 std::map<std::string, std::string> m;
957 m["descriptor_name"] = kDescriptorKey;
958 m["enum_name"] = descriptor.name();
959 m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
960 const char file_descriptor_template[] =
961 "$descriptor_name$.enum_types_by_name['$enum_name$'] = "
962 "$enum_descriptor_name$\n";
963 printer_->Print(m, file_descriptor_template);
966 void Generator::AddExtensionToFileDescriptor(
967 const FieldDescriptor& descriptor) const {
968 std::map<std::string, std::string> m;
969 m["descriptor_name"] = kDescriptorKey;
970 m["field_name"] = descriptor.name();
971 m["resolved_name"] = ResolveKeyword(descriptor.name());
972 const char file_descriptor_template[] =
973 "$descriptor_name$.extensions_by_name['$field_name$'] = "
975 printer_->Print(m, file_descriptor_template);
978 // Sets any necessary message_type and enum_type attributes
979 // for the Python version of |field|.
981 // containing_type may be NULL, in which case this is a module-level field.
983 // python_dict_name is the name of the Python dict where we should
984 // look the field up in the containing type. (e.g., fields_by_name
985 // or extensions_by_name). We ignore python_dict_name if containing_type
987 void Generator::FixForeignFieldsInField(
988 const Descriptor* containing_type, const FieldDescriptor& field,
989 const std::string& python_dict_name) const {
990 const std::string field_referencing_expression =
991 FieldReferencingExpression(containing_type, field, python_dict_name);
992 std::map<std::string, std::string> m;
993 m["field_ref"] = field_referencing_expression;
994 const Descriptor* foreign_message_type = field.message_type();
995 if (foreign_message_type) {
996 m["foreign_type"] = ModuleLevelDescriptorName(*foreign_message_type);
997 printer_->Print(m, "$field_ref$.message_type = $foreign_type$\n");
999 const EnumDescriptor* enum_type = field.enum_type();
1001 m["enum_type"] = ModuleLevelDescriptorName(*enum_type);
1002 printer_->Print(m, "$field_ref$.enum_type = $enum_type$\n");
1006 // Returns the module-level expression for the given FieldDescriptor.
1007 // Only works for fields in the .proto file this Generator is generating for.
1009 // containing_type may be NULL, in which case this is a module-level field.
1011 // python_dict_name is the name of the Python dict where we should
1012 // look the field up in the containing type. (e.g., fields_by_name
1013 // or extensions_by_name). We ignore python_dict_name if containing_type
1015 std::string Generator::FieldReferencingExpression(
1016 const Descriptor* containing_type, const FieldDescriptor& field,
1017 const std::string& python_dict_name) const {
1018 // We should only ever be looking up fields in the current file.
1019 // The only things we refer to from other files are message descriptors.
1020 GOOGLE_CHECK_EQ(field.file(), file_)
1021 << field.file()->name() << " vs. " << file_->name();
1022 if (!containing_type) {
1023 return ResolveKeyword(field.name());
1025 return strings::Substitute("$0.$1['$2']",
1026 ModuleLevelDescriptorName(*containing_type),
1027 python_dict_name, field.name());
1030 // Prints containing_type for nested descriptors or enum descriptors.
1031 template <typename DescriptorT>
1032 void Generator::FixContainingTypeInDescriptor(
1033 const DescriptorT& descriptor,
1034 const Descriptor* containing_descriptor) const {
1035 if (containing_descriptor != NULL) {
1036 const std::string nested_name = ModuleLevelDescriptorName(descriptor);
1037 const std::string parent_name =
1038 ModuleLevelDescriptorName(*containing_descriptor);
1039 printer_->Print("$nested_name$.containing_type = $parent_name$\n",
1040 "nested_name", nested_name, "parent_name", parent_name);
1044 // Prints statements setting the message_type and enum_type fields in the
1045 // Python descriptor objects we've already output in ths file. We must
1046 // do this in a separate step due to circular references (otherwise, we'd
1047 // just set everything in the initial assignment statements).
1048 void Generator::FixForeignFieldsInDescriptors() const {
1049 for (int i = 0; i < file_->message_type_count(); ++i) {
1050 FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
1052 for (int i = 0; i < file_->message_type_count(); ++i) {
1053 AddMessageToFileDescriptor(*file_->message_type(i));
1055 for (int i = 0; i < file_->enum_type_count(); ++i) {
1056 AddEnumToFileDescriptor(*file_->enum_type(i));
1058 for (int i = 0; i < file_->extension_count(); ++i) {
1059 AddExtensionToFileDescriptor(*file_->extension(i));
1061 // TODO(jieluo): Move this register to PrintFileDescriptor() when
1062 // FieldDescriptor.file is added in generated file.
1063 printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
1065 printer_->Print("\n");
1068 // We need to not only set any necessary message_type fields, but
1069 // also need to call RegisterExtension() on each message we're
1071 void Generator::FixForeignFieldsInExtensions() const {
1072 // Top-level extensions.
1073 for (int i = 0; i < file_->extension_count(); ++i) {
1074 FixForeignFieldsInExtension(*file_->extension(i));
1076 // Nested extensions.
1077 for (int i = 0; i < file_->message_type_count(); ++i) {
1078 FixForeignFieldsInNestedExtensions(*file_->message_type(i));
1080 printer_->Print("\n");
1083 void Generator::FixForeignFieldsInExtension(
1084 const FieldDescriptor& extension_field) const {
1085 GOOGLE_CHECK(extension_field.is_extension());
1086 // extension_scope() will be NULL for top-level extensions, which is
1087 // exactly what FixForeignFieldsInField() wants.
1088 FixForeignFieldsInField(extension_field.extension_scope(), extension_field,
1089 "extensions_by_name");
1091 std::map<std::string, std::string> m;
1092 // Confusingly, for FieldDescriptors that happen to be extensions,
1093 // containing_type() means "extended type."
1094 // On the other hand, extension_scope() will give us what we normally
1095 // mean by containing_type().
1096 m["extended_message_class"] =
1097 ModuleLevelMessageName(*extension_field.containing_type());
1098 m["field"] = FieldReferencingExpression(
1099 extension_field.extension_scope(), extension_field, "extensions_by_name");
1100 printer_->Print(m, "$extended_message_class$.RegisterExtension($field$)\n");
1103 void Generator::FixForeignFieldsInNestedExtensions(
1104 const Descriptor& descriptor) const {
1105 // Recursively fix up extensions in all nested types.
1106 for (int i = 0; i < descriptor.nested_type_count(); ++i) {
1107 FixForeignFieldsInNestedExtensions(*descriptor.nested_type(i));
1109 // Fix up extensions directly contained within this type.
1110 for (int i = 0; i < descriptor.extension_count(); ++i) {
1111 FixForeignFieldsInExtension(*descriptor.extension(i));
1115 // Returns a Python expression that instantiates a Python EnumValueDescriptor
1116 // object for the given C++ descriptor.
1117 void Generator::PrintEnumValueDescriptor(
1118 const EnumValueDescriptor& descriptor) const {
1119 // TODO(robinson): Fix up EnumValueDescriptor "type" fields.
1120 // More circular references. ::sigh::
1121 std::string options_string;
1122 descriptor.options().SerializeToString(&options_string);
1123 std::map<std::string, std::string> m;
1124 m["name"] = descriptor.name();
1125 m["index"] = StrCat(descriptor.index());
1126 m["number"] = StrCat(descriptor.number());
1127 m["options"] = OptionsValue(options_string);
1129 "_descriptor.EnumValueDescriptor(\n"
1130 " name='$name$', index=$index$, number=$number$,\n"
1131 " serialized_options=$options$,\n"
1135 // Returns a CEscaped string of serialized_options.
1136 std::string Generator::OptionsValue(
1137 const std::string& serialized_options) const {
1138 if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
1141 //##!PY25 return "b'('" + CEscape(serialized_options)+ "')";
1142 return "_b('" + CEscape(serialized_options) + "')"; //##PY25
1146 // Prints an expression for a Python FieldDescriptor for |field|.
1147 void Generator::PrintFieldDescriptor(const FieldDescriptor& field,
1148 bool is_extension) const {
1149 std::string options_string;
1150 field.options().SerializeToString(&options_string);
1151 std::map<std::string, std::string> m;
1152 m["name"] = field.name();
1153 m["full_name"] = field.full_name();
1154 m["index"] = StrCat(field.index());
1155 m["number"] = StrCat(field.number());
1156 m["type"] = StrCat(field.type());
1157 m["cpp_type"] = StrCat(field.cpp_type());
1158 m["label"] = StrCat(field.label());
1159 m["has_default_value"] = field.has_default_value() ? "True" : "False";
1160 m["default_value"] = StringifyDefaultValue(field);
1161 m["is_extension"] = is_extension ? "True" : "False";
1162 m["serialized_options"] = OptionsValue(options_string);
1164 field.has_json_name() ? ", json_name='" + field.json_name() + "'" : "";
1165 // We always set message_type and enum_type to None at this point, and then
1166 // these fields in correctly after all referenced descriptors have been
1167 // defined and/or imported (see FixForeignFieldsInDescriptors()).
1168 const char field_descriptor_decl[] =
1169 "_descriptor.FieldDescriptor(\n"
1170 " name='$name$', full_name='$full_name$', index=$index$,\n"
1171 " number=$number$, type=$type$, cpp_type=$cpp_type$, label=$label$,\n"
1172 " has_default_value=$has_default_value$, "
1173 "default_value=$default_value$,\n"
1174 " message_type=None, enum_type=None, containing_type=None,\n"
1175 " is_extension=$is_extension$, extension_scope=None,\n"
1176 " serialized_options=$serialized_options$$json_name$, file=DESCRIPTOR)";
1177 printer_->Print(m, field_descriptor_decl);
1180 // Helper for Print{Fields,Extensions}InDescriptor().
1181 void Generator::PrintFieldDescriptorsInDescriptor(
1182 const Descriptor& message_descriptor, bool is_extension,
1183 const std::string& list_variable_name, int (Descriptor::*CountFn)() const,
1184 const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const {
1185 printer_->Print("$list$=[\n", "list", list_variable_name);
1187 for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) {
1188 PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i), is_extension);
1189 printer_->Print(",\n");
1191 printer_->Outdent();
1192 printer_->Print("],\n");
1195 // Prints a statement assigning "fields" to a list of Python FieldDescriptors,
1196 // one for each field present in message_descriptor.
1197 void Generator::PrintFieldsInDescriptor(
1198 const Descriptor& message_descriptor) const {
1199 const bool is_extension = false;
1200 PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension, "fields",
1201 &Descriptor::field_count,
1202 &Descriptor::field);
1205 // Prints a statement assigning "extensions" to a list of Python
1206 // FieldDescriptors, one for each extension present in message_descriptor.
1207 void Generator::PrintExtensionsInDescriptor(
1208 const Descriptor& message_descriptor) const {
1209 const bool is_extension = true;
1210 PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension,
1211 "extensions", &Descriptor::extension_count,
1212 &Descriptor::extension);
1215 bool Generator::GeneratingDescriptorProto() const {
1216 return file_->name() == "net/proto2/proto/descriptor.proto" ||
1217 file_->name() == "google/protobuf/descriptor.proto";
1220 // Returns the unique Python module-level identifier given to a descriptor.
1221 // This name is module-qualified iff the given descriptor describes an
1222 // entity that doesn't come from the current file.
1223 template <typename DescriptorT>
1224 std::string Generator::ModuleLevelDescriptorName(
1225 const DescriptorT& descriptor) const {
1227 // We currently don't worry about collisions with underscores in the type
1228 // names, so these would collide in nasty ways if found in the same file:
1229 // OuterProto.ProtoA.ProtoB
1230 // OuterProto_ProtoA.ProtoB # Underscore instead of period.
1232 // OuterProto.ProtoA_.ProtoB
1233 // OuterProto.ProtoA._ProtoB # Leading vs. trailing underscore.
1234 // (Contrived, but certainly possible).
1236 // The C++ implementation doesn't guard against this either. Leaving
1238 std::string name = NamePrefixedWithNestedTypes(descriptor, "_");
1240 // Module-private for now. Easy to make public later; almost impossible
1241 // to make private later.
1243 // We now have the name relative to its own module. Also qualify with
1244 // the module name iff this descriptor is from a different .proto file.
1245 if (descriptor.file() != file_) {
1246 name = ModuleAlias(descriptor.file()->name()) + "." + name;
1251 // Returns the name of the message class itself, not the descriptor.
1252 // Like ModuleLevelDescriptorName(), module-qualifies the name iff
1253 // the given descriptor describes an entity that doesn't come from
1254 // the current file.
1255 std::string Generator::ModuleLevelMessageName(
1256 const Descriptor& descriptor) const {
1257 std::string name = NamePrefixedWithNestedTypes(descriptor, ".");
1258 if (descriptor.file() != file_) {
1259 name = ModuleAlias(descriptor.file()->name()) + "." + name;
1264 // Returns the unique Python module-level identifier given to a service
1266 std::string Generator::ModuleLevelServiceDescriptorName(
1267 const ServiceDescriptor& descriptor) const {
1268 std::string name = descriptor.name();
1271 if (descriptor.file() != file_) {
1272 name = ModuleAlias(descriptor.file()->name()) + "." + name;
1277 // Prints standard constructor arguments serialized_start and serialized_end.
1279 // descriptor: The cpp descriptor to have a serialized reference.
1281 // Example printer output:
1282 // serialized_start=41,
1283 // serialized_end=43,
1285 template <typename DescriptorT, typename DescriptorProtoT>
1286 void Generator::PrintSerializedPbInterval(const DescriptorT& descriptor,
1287 DescriptorProtoT& proto) const {
1288 descriptor.CopyTo(&proto);
1290 proto.SerializeToString(&sp);
1291 int offset = file_descriptor_serialized_.find(sp);
1292 GOOGLE_CHECK_GE(offset, 0);
1295 "serialized_start=$serialized_start$,\n"
1296 "serialized_end=$serialized_end$,\n",
1297 "serialized_start", StrCat(offset), "serialized_end",
1298 StrCat(offset + sp.size()));
1302 void PrintDescriptorOptionsFixingCode(const std::string& descriptor,
1303 const std::string& options,
1304 io::Printer* printer) {
1305 // Reset the _options to None thus DescriptorBase.GetOptions() can
1306 // parse _options again after extensions are registered.
1307 printer->Print("$descriptor$._options = None\n", "descriptor", descriptor);
1311 // Prints expressions that set the options field of all descriptors.
1312 void Generator::FixAllDescriptorOptions() const {
1313 // Prints an expression that sets the file descriptor's options.
1314 std::string file_options = OptionsValue(file_->options().SerializeAsString());
1315 if (file_options != "None") {
1316 PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
1318 // Prints expressions that set the options for all top level enums.
1319 for (int i = 0; i < file_->enum_type_count(); ++i) {
1320 const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
1321 FixOptionsForEnum(enum_descriptor);
1323 // Prints expressions that set the options for all top level extensions.
1324 for (int i = 0; i < file_->extension_count(); ++i) {
1325 const FieldDescriptor& field = *file_->extension(i);
1326 FixOptionsForField(field);
1328 // Prints expressions that set the options for all messages, nested enums,
1329 // nested extensions and message fields.
1330 for (int i = 0; i < file_->message_type_count(); ++i) {
1331 FixOptionsForMessage(*file_->message_type(i));
1335 void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const {
1336 std::string oneof_options = OptionsValue(oneof.options().SerializeAsString());
1337 if (oneof_options != "None") {
1338 std::string oneof_name = strings::Substitute(
1339 "$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()),
1340 "oneofs_by_name", oneof.name());
1341 PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_);
1345 // Prints expressions that set the options for an enum descriptor and its
1346 // value descriptors.
1347 void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
1348 std::string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
1349 std::string enum_options =
1350 OptionsValue(enum_descriptor.options().SerializeAsString());
1351 if (enum_options != "None") {
1352 PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
1354 for (int i = 0; i < enum_descriptor.value_count(); ++i) {
1355 const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
1356 std::string value_options =
1357 OptionsValue(value_descriptor.options().SerializeAsString());
1358 if (value_options != "None") {
1359 PrintDescriptorOptionsFixingCode(
1360 StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
1361 value_descriptor.name().c_str()),
1362 value_options, printer_);
1367 // Prints expressions that set the options for field descriptors (including
1369 void Generator::FixOptionsForField(const FieldDescriptor& field) const {
1370 std::string field_options = OptionsValue(field.options().SerializeAsString());
1371 if (field_options != "None") {
1372 std::string field_name;
1373 if (field.is_extension()) {
1374 if (field.extension_scope() == NULL) {
1375 // Top level extensions.
1376 field_name = field.name();
1378 field_name = FieldReferencingExpression(field.extension_scope(), field,
1379 "extensions_by_name");
1382 field_name = FieldReferencingExpression(field.containing_type(), field,
1385 PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
1389 // Prints expressions that set the options for a message and all its inner
1390 // types (nested messages, nested enums, extensions, fields).
1391 void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
1393 for (int i = 0; i < descriptor.nested_type_count(); ++i) {
1394 FixOptionsForMessage(*descriptor.nested_type(i));
1397 for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
1398 FixOptionsForOneof(*descriptor.oneof_decl(i));
1401 for (int i = 0; i < descriptor.enum_type_count(); ++i) {
1402 FixOptionsForEnum(*descriptor.enum_type(i));
1405 for (int i = 0; i < descriptor.field_count(); ++i) {
1406 const FieldDescriptor& field = *descriptor.field(i);
1407 FixOptionsForField(field);
1410 for (int i = 0; i < descriptor.extension_count(); ++i) {
1411 const FieldDescriptor& field = *descriptor.extension(i);
1412 FixOptionsForField(field);
1414 // Message option for this message.
1415 std::string message_options =
1416 OptionsValue(descriptor.options().SerializeAsString());
1417 if (message_options != "None") {
1418 std::string descriptor_name = ModuleLevelDescriptorName(descriptor);
1419 PrintDescriptorOptionsFixingCode(descriptor_name, message_options,
1424 // If a dependency forwards other files through public dependencies, let's
1425 // copy over the corresponding module aliases.
1426 void Generator::CopyPublicDependenciesAliases(
1427 const std::string& copy_from, const FileDescriptor* file) const {
1428 for (int i = 0; i < file->public_dependency_count(); ++i) {
1429 std::string module_name = ModuleName(file->public_dependency(i)->name());
1430 std::string module_alias = ModuleAlias(file->public_dependency(i)->name());
1431 // There's no module alias in the dependent file if it was generated by
1432 // an old protoc (less than 3.0.0-alpha-1). Use module name in this
1436 " $alias$ = $copy_from$.$alias$\n"
1437 "except AttributeError:\n"
1438 " $alias$ = $copy_from$.$module$\n",
1439 "alias", module_alias, "module", module_name, "copy_from", copy_from);
1440 CopyPublicDependenciesAliases(copy_from, file->public_dependency(i));
1444 } // namespace python
1445 } // namespace compiler
1446 } // namespace protobuf
1447 } // namespace google