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