- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / protobuf / src / google / protobuf / compiler / cpp / cpp_file.cc
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
46 namespace google {
47 namespace protobuf {
48 namespace compiler {
49 namespace cpp {
50
51 // ===================================================================
52
53 FileGenerator::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
89 FileGenerator::~FileGenerator() {}
90
91 void 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
305 void 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
409 void 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
636 void 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
645 void 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