1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34 35#include <google/protobuf/compiler/cpp/cpp_file.h> 36#include <google/protobuf/compiler/cpp/cpp_enum.h> 37#include <google/protobuf/compiler/cpp/cpp_service.h> 38#include <google/protobuf/compiler/cpp/cpp_extension.h> 39#include <google/protobuf/compiler/cpp/cpp_helpers.h> 40#include <google/protobuf/compiler/cpp/cpp_message.h> 41#include <google/protobuf/compiler/cpp/cpp_field.h> 42#include <google/protobuf/io/printer.h> 43#include <google/protobuf/descriptor.pb.h> 44#include <google/protobuf/stubs/strutil.h> 45 46namespace google { 47namespace protobuf { 48namespace compiler { 49namespace cpp { 50 51// =================================================================== 52 53FileGenerator::FileGenerator(const FileDescriptor* file, 54 const Options& options) 55 : file_(file), 56 message_generators_( 57 new scoped_ptr<MessageGenerator>[file->message_type_count()]), 58 enum_generators_( 59 new scoped_ptr<EnumGenerator>[file->enum_type_count()]), 60 service_generators_( 61 new scoped_ptr<ServiceGenerator>[file->service_count()]), 62 extension_generators_( 63 new scoped_ptr<ExtensionGenerator>[file->extension_count()]), 64 options_(options) { 65 66 for (int i = 0; i < file->message_type_count(); i++) { 67 message_generators_[i].reset( 68 new MessageGenerator(file->message_type(i), options)); 69 } 70 71 for (int i = 0; i < file->enum_type_count(); i++) { 72 enum_generators_[i].reset( 73 new EnumGenerator(file->enum_type(i), options)); 74 } 75 76 for (int i = 0; i < file->service_count(); i++) { 77 service_generators_[i].reset( 78 new ServiceGenerator(file->service(i), options)); 79 } 80 81 for (int i = 0; i < file->extension_count(); i++) { 82 extension_generators_[i].reset( 83 new ExtensionGenerator(file->extension(i), options)); 84 } 85 86 SplitStringUsing(file_->package(), ".", &package_parts_); 87} 88 89FileGenerator::~FileGenerator() {} 90 91void FileGenerator::GenerateHeader(io::Printer* printer) { 92 string filename_identifier = FilenameIdentifier(file_->name()); 93 94 // Generate top of header. 95 printer->Print( 96 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" 97 "// source: $filename$\n" 98 "\n" 99 "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n" 100 "#define PROTOBUF_$filename_identifier$__INCLUDED\n" 101 "\n" 102 "#include <string>\n" 103 "\n", 104 "filename", file_->name(), 105 "filename_identifier", filename_identifier); 106 107 108 printer->Print( 109 "#include <google/protobuf/stubs/common.h>\n" 110 "\n"); 111 112 // Verify the protobuf library header version is compatible with the protoc 113 // version before going any further. 114 printer->Print( 115 "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n" 116 "#error This file was generated by a newer version of protoc which is\n" 117 "#error incompatible with your Protocol Buffer headers. Please update\n" 118 "#error your headers.\n" 119 "#endif\n" 120 "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n" 121 "#error This file was generated by an older version of protoc which is\n" 122 "#error incompatible with your Protocol Buffer headers. Please\n" 123 "#error regenerate this file with a newer version of protoc.\n" 124 "#endif\n" 125 "\n", 126 "min_header_version", 127 SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc), 128 "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION)); 129 130 // OK, it's now safe to #include other files. 131 printer->Print( 132 "#include <google/protobuf/generated_message_util.h>\n"); 133 if (file_->message_type_count() > 0) { 134 if (HasDescriptorMethods(file_)) { 135 printer->Print( 136 "#include <google/protobuf/message.h>\n"); 137 } else { 138 printer->Print( 139 "#include <google/protobuf/message_lite.h>\n"); 140 } 141 } 142 printer->Print( 143 "#include <google/protobuf/repeated_field.h>\n" 144 "#include <google/protobuf/extension_set.h>\n"); 145 146 if (HasUnknownFields(file_)) { 147 printer->Print( 148 "#include <google/protobuf/unknown_field_set.h>\n"); 149 } 150 151 if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) { 152 printer->Print( 153 "#include <google/protobuf/generated_enum_reflection.h>\n"); 154 } 155 156 if (HasGenericServices(file_)) { 157 printer->Print( 158 "#include <google/protobuf/service.h>\n"); 159 } 160 161 if (HasUnknownFields(file_) && file_->message_type_count() > 0) { 162 printer->Print( 163 "#include <google/protobuf/unknown_field_set.h>\n"); 164 } 165 166 167 for (int i = 0; i < file_->dependency_count(); i++) { 168 printer->Print( 169 "#include \"$dependency$.pb.h\"\n", 170 "dependency", StripProto(file_->dependency(i)->name())); 171 } 172 173 174 printer->Print( 175 "// @@protoc_insertion_point(includes)\n"); 176 177 178 // Open namespace. 179 GenerateNamespaceOpeners(printer); 180 181 // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile 182 // functions, so that we can declare them to be friends of each class. 183 printer->Print( 184 "\n" 185 "// Internal implementation detail -- do not call these.\n" 186 "void $dllexport_decl$ $adddescriptorsname$();\n", 187 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), 188 "dllexport_decl", options_.dllexport_decl); 189 190 printer->Print( 191 // Note that we don't put dllexport_decl on these because they are only 192 // called by the .pb.cc file in which they are defined. 193 "void $assigndescriptorsname$();\n" 194 "void $shutdownfilename$();\n" 195 "\n", 196 "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()), 197 "shutdownfilename", GlobalShutdownFileName(file_->name())); 198 199 // Generate forward declarations of classes. 200 for (int i = 0; i < file_->message_type_count(); i++) { 201 message_generators_[i]->GenerateForwardDeclaration(printer); 202 } 203 204 printer->Print("\n"); 205 206 // Generate enum definitions. 207 for (int i = 0; i < file_->message_type_count(); i++) { 208 message_generators_[i]->GenerateEnumDefinitions(printer); 209 } 210 for (int i = 0; i < file_->enum_type_count(); i++) { 211 enum_generators_[i]->GenerateDefinition(printer); 212 } 213 214 printer->Print(kThickSeparator); 215 printer->Print("\n"); 216 217 // Generate class definitions. 218 for (int i = 0; i < file_->message_type_count(); i++) { 219 if (i > 0) { 220 printer->Print("\n"); 221 printer->Print(kThinSeparator); 222 printer->Print("\n"); 223 } 224 message_generators_[i]->GenerateClassDefinition(printer); 225 } 226 227 printer->Print("\n"); 228 printer->Print(kThickSeparator); 229 printer->Print("\n"); 230 231 if (HasGenericServices(file_)) { 232 // Generate service definitions. 233 for (int i = 0; i < file_->service_count(); i++) { 234 if (i > 0) { 235 printer->Print("\n"); 236 printer->Print(kThinSeparator); 237 printer->Print("\n"); 238 } 239 service_generators_[i]->GenerateDeclarations(printer); 240 } 241 242 printer->Print("\n"); 243 printer->Print(kThickSeparator); 244 printer->Print("\n"); 245 } 246 247 // Declare extension identifiers. 248 for (int i = 0; i < file_->extension_count(); i++) { 249 extension_generators_[i]->GenerateDeclaration(printer); 250 } 251 252 printer->Print("\n"); 253 printer->Print(kThickSeparator); 254 printer->Print("\n"); 255 256 // Generate class inline methods. 257 for (int i = 0; i < file_->message_type_count(); i++) { 258 if (i > 0) { 259 printer->Print(kThinSeparator); 260 printer->Print("\n"); 261 } 262 message_generators_[i]->GenerateInlineMethods(printer); 263 } 264 265 printer->Print( 266 "\n" 267 "// @@protoc_insertion_point(namespace_scope)\n"); 268 269 // Close up namespace. 270 GenerateNamespaceClosers(printer); 271 272 // Emit GetEnumDescriptor specializations into google::protobuf namespace: 273 if (HasDescriptorMethods(file_)) { 274 // The SWIG conditional is to avoid a null-pointer dereference 275 // (bug 1984964) in swig-1.3.21 resulting from the following syntax: 276 // namespace X { void Y<Z::W>(); } 277 // which appears in GetEnumDescriptor() specializations. 278 printer->Print( 279 "\n" 280 "#ifndef SWIG\n" 281 "namespace google {\nnamespace protobuf {\n" 282 "\n"); 283 for (int i = 0; i < file_->message_type_count(); i++) { 284 message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 285 } 286 for (int i = 0; i < file_->enum_type_count(); i++) { 287 enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); 288 } 289 printer->Print( 290 "\n" 291 "} // namespace google\n} // namespace protobuf\n" 292 "#endif // SWIG\n"); 293 } 294 295 printer->Print( 296 "\n" 297 "// @@protoc_insertion_point(global_scope)\n" 298 "\n"); 299 300 printer->Print( 301 "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", 302 "filename_identifier", filename_identifier); 303} 304 305void FileGenerator::GenerateSource(io::Printer* printer) { 306 printer->Print( 307 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" 308 "// source: $filename$\n" 309 "\n" 310 311 // The generated code calls accessors that might be deprecated. We don't 312 // want the compiler to warn in generated code. 313 "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n" 314 "#include \"$basename$.pb.h\"\n" 315 "\n" 316 "#include <algorithm>\n" // for swap() 317 "\n" 318 "#include <google/protobuf/stubs/common.h>\n" 319 "#include <google/protobuf/stubs/once.h>\n" 320 "#include <google/protobuf/io/coded_stream.h>\n" 321 "#include <google/protobuf/wire_format_lite_inl.h>\n", 322 "filename", file_->name(), 323 "basename", StripProto(file_->name())); 324 325 if (HasDescriptorMethods(file_)) { 326 printer->Print( 327 "#include <google/protobuf/descriptor.h>\n" 328 "#include <google/protobuf/generated_message_reflection.h>\n" 329 "#include <google/protobuf/reflection_ops.h>\n" 330 "#include <google/protobuf/wire_format.h>\n"); 331 } 332 333 printer->Print( 334 "// @@protoc_insertion_point(includes)\n"); 335 336 GenerateNamespaceOpeners(printer); 337 338 if (HasDescriptorMethods(file_)) { 339 printer->Print( 340 "\n" 341 "namespace {\n" 342 "\n"); 343 for (int i = 0; i < file_->message_type_count(); i++) { 344 message_generators_[i]->GenerateDescriptorDeclarations(printer); 345 } 346 for (int i = 0; i < file_->enum_type_count(); i++) { 347 printer->Print( 348 "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n", 349 "name", ClassName(file_->enum_type(i), false)); 350 } 351 352 if (HasGenericServices(file_)) { 353 for (int i = 0; i < file_->service_count(); i++) { 354 printer->Print( 355 "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n", 356 "name", file_->service(i)->name()); 357 } 358 } 359 360 printer->Print( 361 "\n" 362 "} // namespace\n" 363 "\n"); 364 } 365 366 // Define our externally-visible BuildDescriptors() function. (For the lite 367 // library, all this does is initialize default instances.) 368 GenerateBuildDescriptors(printer); 369 370 // Generate enums. 371 for (int i = 0; i < file_->enum_type_count(); i++) { 372 enum_generators_[i]->GenerateMethods(printer); 373 } 374 375 // Generate classes. 376 for (int i = 0; i < file_->message_type_count(); i++) { 377 printer->Print("\n"); 378 printer->Print(kThickSeparator); 379 printer->Print("\n"); 380 message_generators_[i]->GenerateClassMethods(printer); 381 } 382 383 if (HasGenericServices(file_)) { 384 // Generate services. 385 for (int i = 0; i < file_->service_count(); i++) { 386 if (i == 0) printer->Print("\n"); 387 printer->Print(kThickSeparator); 388 printer->Print("\n"); 389 service_generators_[i]->GenerateImplementation(printer); 390 } 391 } 392 393 // Define extensions. 394 for (int i = 0; i < file_->extension_count(); i++) { 395 extension_generators_[i]->GenerateDefinition(printer); 396 } 397 398 printer->Print( 399 "\n" 400 "// @@protoc_insertion_point(namespace_scope)\n"); 401 402 GenerateNamespaceClosers(printer); 403 404 printer->Print( 405 "\n" 406 "// @@protoc_insertion_point(global_scope)\n"); 407} 408 409void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { 410 // AddDescriptors() is a file-level procedure which adds the encoded 411 // FileDescriptorProto for this .proto file to the global DescriptorPool for 412 // generated files (DescriptorPool::generated_pool()). It either runs at 413 // static initialization time (by default) or when default_instance() is 414 // called for the first time (in LITE_RUNTIME mode with 415 // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also 416 // constructs default instances and registers extensions. 417 // 418 // Its sibling, AssignDescriptors(), actually pulls the compiled 419 // FileDescriptor from the DescriptorPool and uses it to populate all of 420 // the global variables which store pointers to the descriptor objects. 421 // It also constructs the reflection objects. It is called the first time 422 // anyone calls descriptor() or GetReflection() on one of the types defined 423 // in the file. 424 425 // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors() 426 // and we only use AddDescriptors() to allocate default instances. 427 if (HasDescriptorMethods(file_)) { 428 printer->Print( 429 "\n" 430 "void $assigndescriptorsname$() {\n", 431 "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); 432 printer->Indent(); 433 434 // Make sure the file has found its way into the pool. If a descriptor 435 // is requested *during* static init then AddDescriptors() may not have 436 // been called yet, so we call it manually. Note that it's fine if 437 // AddDescriptors() is called multiple times. 438 printer->Print( 439 "$adddescriptorsname$();\n", 440 "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); 441 442 // Get the file's descriptor from the pool. 443 printer->Print( 444 "const ::google::protobuf::FileDescriptor* file =\n" 445 " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n" 446 " \"$filename$\");\n" 447 // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file" 448 // being unused when compiling an empty .proto file. 449 "GOOGLE_CHECK(file != NULL);\n", 450 "filename", file_->name()); 451 452 // Go through all the stuff defined in this file and generated code to 453 // assign the global descriptor pointers based on the file descriptor. 454 for (int i = 0; i < file_->message_type_count(); i++) { 455 message_generators_[i]->GenerateDescriptorInitializer(printer, i); 456 } 457 for (int i = 0; i < file_->enum_type_count(); i++) { 458 enum_generators_[i]->GenerateDescriptorInitializer(printer, i); 459 } 460 if (HasGenericServices(file_)) { 461 for (int i = 0; i < file_->service_count(); i++) { 462 service_generators_[i]->GenerateDescriptorInitializer(printer, i); 463 } 464 } 465 466 printer->Outdent(); 467 printer->Print( 468 "}\n" 469 "\n"); 470 471 // --------------------------------------------------------------- 472 473 // protobuf_AssignDescriptorsOnce(): The first time it is called, calls 474 // AssignDescriptors(). All later times, waits for the first call to 475 // complete and then returns. 476 printer->Print( 477 "namespace {\n" 478 "\n" 479 "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n" 480 "inline void protobuf_AssignDescriptorsOnce() {\n" 481 " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n" 482 " &$assigndescriptorsname$);\n" 483 "}\n" 484 "\n", 485 "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name())); 486 487 // protobuf_RegisterTypes(): Calls 488 // MessageFactory::InternalRegisterGeneratedType() for each message type. 489 printer->Print( 490 "void protobuf_RegisterTypes(const ::std::string&) {\n" 491 " protobuf_AssignDescriptorsOnce();\n"); 492 printer->Indent(); 493 494 for (int i = 0; i < file_->message_type_count(); i++) { 495 message_generators_[i]->GenerateTypeRegistrations(printer); 496 } 497 498 printer->Outdent(); 499 printer->Print( 500 "}\n" 501 "\n" 502 "} // namespace\n"); 503 } 504 505 // ----------------------------------------------------------------- 506 507 // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown. 508 printer->Print( 509 "\n" 510 "void $shutdownfilename$() {\n", 511 "shutdownfilename", GlobalShutdownFileName(file_->name())); 512 printer->Indent(); 513 514 for (int i = 0; i < file_->message_type_count(); i++) { 515 message_generators_[i]->GenerateShutdownCode(printer); 516 } 517 518 printer->Outdent(); 519 printer->Print( 520 "}\n\n"); 521 522 // ----------------------------------------------------------------- 523 524 // Now generate the AddDescriptors() function. 525 PrintHandlingOptionalStaticInitializers( 526 file_, printer, 527 // With static initializers. 528 // Note that we don't need any special synchronization in the following code 529 // because it is called at static init time before any threads exist. 530 "void $adddescriptorsname$() {\n" 531 " static bool already_here = false;\n" 532 " if (already_here) return;\n" 533 " already_here = true;\n" 534 " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" 535 "\n", 536 // Without. 537 "void $adddescriptorsname$_impl() {\n" 538 " GOOGLE_PROTOBUF_VERIFY_VERSION;\n" 539 "\n", 540 // Vars. 541 "adddescriptorsname", GlobalAddDescriptorsName(file_->name())); 542 543 printer->Indent(); 544 545 // Call the AddDescriptors() methods for all of our dependencies, to make 546 // sure they get added first. 547 for (int i = 0; i < file_->dependency_count(); i++) { 548 const FileDescriptor* dependency = file_->dependency(i); 549 // Print the namespace prefix for the dependency. 550 vector<string> dependency_package_parts; 551 SplitStringUsing(dependency->package(), ".", &dependency_package_parts); 552 printer->Print("::"); 553 for (int j = 0; j < dependency_package_parts.size(); j++) { 554 printer->Print("$name$::", 555 "name", dependency_package_parts[j]); 556 } 557 // Call its AddDescriptors function. 558 printer->Print( 559 "$name$();\n", 560 "name", GlobalAddDescriptorsName(dependency->name())); 561 } 562 563 if (HasDescriptorMethods(file_)) { 564 // Embed the descriptor. We simply serialize the entire FileDescriptorProto 565 // and embed it as a string literal, which is parsed and built into real 566 // descriptors at initialization time. 567 FileDescriptorProto file_proto; 568 file_->CopyTo(&file_proto); 569 string file_data; 570 file_proto.SerializeToString(&file_data); 571 572 printer->Print( 573 "::google::protobuf::DescriptorPool::InternalAddGeneratedFile("); 574 575 // Only write 40 bytes per line. 576 static const int kBytesPerLine = 40; 577 for (int i = 0; i < file_data.size(); i += kBytesPerLine) { 578 printer->Print("\n \"$data$\"", 579 "data", 580 EscapeTrigraphs( 581 CEscape(file_data.substr(i, kBytesPerLine)))); 582 } 583 printer->Print( 584 ", $size$);\n", 585 "size", SimpleItoa(file_data.size())); 586 587 // Call MessageFactory::InternalRegisterGeneratedFile(). 588 printer->Print( 589 "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n" 590 " \"$filename$\", &protobuf_RegisterTypes);\n", 591 "filename", file_->name()); 592 } 593 594 // Allocate and initialize default instances. This can't be done lazily 595 // since default instances are returned by simple accessors and are used with 596 // extensions. Speaking of which, we also register extensions at this time. 597 for (int i = 0; i < file_->message_type_count(); i++) { 598 message_generators_[i]->GenerateDefaultInstanceAllocator(printer); 599 } 600 for (int i = 0; i < file_->extension_count(); i++) { 601 extension_generators_[i]->GenerateRegistration(printer); 602 } 603 for (int i = 0; i < file_->message_type_count(); i++) { 604 message_generators_[i]->GenerateDefaultInstanceInitializer(printer); 605 } 606 607 printer->Print( 608 "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n", 609 "shutdownfilename", GlobalShutdownFileName(file_->name())); 610 611 printer->Outdent(); 612 printer->Print( 613 "}\n" 614 "\n"); 615 616 PrintHandlingOptionalStaticInitializers( 617 file_, printer, 618 // With static initializers. 619 "// Force AddDescriptors() to be called at static initialization time.\n" 620 "struct StaticDescriptorInitializer_$filename$ {\n" 621 " StaticDescriptorInitializer_$filename$() {\n" 622 " $adddescriptorsname$();\n" 623 " }\n" 624 "} static_descriptor_initializer_$filename$_;\n", 625 // Without. 626 "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n" 627 "void $adddescriptorsname$() {\n" 628 " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n" 629 " &$adddescriptorsname$_impl);\n" 630 "}\n", 631 // Vars. 632 "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), 633 "filename", FilenameIdentifier(file_->name())); 634} 635 636void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) { 637 if (package_parts_.size() > 0) printer->Print("\n"); 638 639 for (int i = 0; i < package_parts_.size(); i++) { 640 printer->Print("namespace $part$ {\n", 641 "part", package_parts_[i]); 642 } 643} 644 645void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) { 646 if (package_parts_.size() > 0) printer->Print("\n"); 647 648 for (int i = package_parts_.size() - 1; i >= 0; i--) { 649 printer->Print("} // namespace $part$\n", 650 "part", package_parts_[i]); 651 } 652} 653 654} // namespace cpp 655} // namespace compiler 656} // namespace protobuf 657} // namespace google 658