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