• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // 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 <map>
37 #include <memory>
38 #ifndef _SHARED_PTR_H
39 #include <google/protobuf/stubs/shared_ptr.h>
40 #endif
41 #include <set>
42 
43 #include <google/protobuf/compiler/cpp/cpp_enum.h>
44 #include <google/protobuf/compiler/cpp/cpp_service.h>
45 #include <google/protobuf/compiler/cpp/cpp_extension.h>
46 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
47 #include <google/protobuf/compiler/cpp/cpp_message.h>
48 #include <google/protobuf/compiler/cpp/cpp_field.h>
49 #include <google/protobuf/io/printer.h>
50 #include <google/protobuf/descriptor.pb.h>
51 #include <google/protobuf/stubs/strutil.h>
52 
53 namespace google {
54 namespace protobuf {
55 namespace compiler {
56 namespace cpp {
57 
58 // ===================================================================
59 
FileGenerator(const FileDescriptor * file,const Options & options)60 FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
61     : file_(file),
62       options_(options),
63       message_generators_(
64           new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
65       enum_generators_(
66           new google::protobuf::scoped_ptr<EnumGenerator>[file->enum_type_count()]),
67       service_generators_(
68           new google::protobuf::scoped_ptr<ServiceGenerator>[file->service_count()]),
69       extension_generators_(
70           new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]) {
71 
72   for (int i = 0; i < file->message_type_count(); i++) {
73     message_generators_[i].reset(
74       new MessageGenerator(file->message_type(i), options));
75   }
76 
77   for (int i = 0; i < file->enum_type_count(); i++) {
78     enum_generators_[i].reset(
79       new EnumGenerator(file->enum_type(i), options));
80   }
81 
82   for (int i = 0; i < file->service_count(); i++) {
83     service_generators_[i].reset(
84       new ServiceGenerator(file->service(i), options));
85   }
86 
87   for (int i = 0; i < file->extension_count(); i++) {
88     extension_generators_[i].reset(
89       new ExtensionGenerator(file->extension(i), options));
90   }
91 
92   SplitStringUsing(file_->package(), ".", &package_parts_);
93 }
94 
~FileGenerator()95 FileGenerator::~FileGenerator() {}
96 
GenerateProtoHeader(io::Printer * printer,const string & info_path)97 void FileGenerator::GenerateProtoHeader(io::Printer* printer,
98                                         const string& info_path) {
99   if (!options_.proto_h) {
100     return;
101   }
102 
103   string filename_identifier = FilenameIdentifier(file_->name());
104   GenerateTopHeaderGuard(printer, filename_identifier);
105 
106 
107   GenerateLibraryIncludes(printer);
108 
109   for (int i = 0; i < file_->public_dependency_count(); i++) {
110     const FileDescriptor* dep = file_->public_dependency(i);
111     const char* extension = ".proto.h";
112     string dependency = StripProto(dep->name()) + extension;
113     printer->Print(
114       "#include \"$dependency$\"  // IWYU pragma: export\n",
115       "dependency", dependency);
116   }
117 
118   GenerateMetadataPragma(printer, info_path);
119 
120   printer->Print(
121     "// @@protoc_insertion_point(includes)\n");
122 
123 
124   GenerateForwardDeclarations(printer);
125 
126   // Open namespace.
127   GenerateNamespaceOpeners(printer);
128 
129   GenerateGlobalStateFunctionDeclarations(printer);
130 
131   printer->Print("\n");
132 
133   GenerateEnumDefinitions(printer);
134 
135   printer->Print(kThickSeparator);
136   printer->Print("\n");
137 
138   GenerateMessageDefinitions(printer);
139 
140   printer->Print("\n");
141   printer->Print(kThickSeparator);
142   printer->Print("\n");
143 
144   GenerateServiceDefinitions(printer);
145 
146   GenerateExtensionIdentifiers(printer);
147 
148   printer->Print("\n");
149   printer->Print(kThickSeparator);
150   printer->Print("\n");
151 
152   GenerateInlineFunctionDefinitions(printer);
153 
154   printer->Print(
155     "\n"
156     "// @@protoc_insertion_point(namespace_scope)\n"
157     "\n");
158 
159   // Close up namespace.
160   GenerateNamespaceClosers(printer);
161 
162   // We need to specialize some templates in the ::google::protobuf namespace:
163   GenerateProto2NamespaceEnumSpecializations(printer);
164 
165   printer->Print(
166     "\n"
167     "// @@protoc_insertion_point(global_scope)\n"
168     "\n");
169 
170   GenerateBottomHeaderGuard(printer, filename_identifier);
171 }
172 
GeneratePBHeader(io::Printer * printer,const string & info_path)173 void FileGenerator::GeneratePBHeader(io::Printer* printer,
174                                      const string& info_path) {
175   string filename_identifier =
176       FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : ""));
177   GenerateTopHeaderGuard(printer, filename_identifier);
178 
179   if (options_.proto_h) {
180     printer->Print("#include \"$basename$.proto.h\"  // IWYU pragma: export\n",
181                    "basename", StripProto(file_->name()));
182   } else {
183     GenerateLibraryIncludes(printer);
184   }
185   GenerateDependencyIncludes(printer);
186   GenerateMetadataPragma(printer, info_path);
187 
188   printer->Print(
189     "// @@protoc_insertion_point(includes)\n");
190 
191 
192 
193   // Open namespace.
194   GenerateNamespaceOpeners(printer);
195 
196   if (!options_.proto_h) {
197     GenerateGlobalStateFunctionDeclarations(printer);
198     GenerateMessageForwardDeclarations(printer);
199 
200     printer->Print("\n");
201 
202     GenerateEnumDefinitions(printer);
203 
204     printer->Print(kThickSeparator);
205     printer->Print("\n");
206 
207     GenerateMessageDefinitions(printer);
208 
209     printer->Print("\n");
210     printer->Print(kThickSeparator);
211     printer->Print("\n");
212 
213     GenerateServiceDefinitions(printer);
214 
215     GenerateExtensionIdentifiers(printer);
216 
217     printer->Print("\n");
218     printer->Print(kThickSeparator);
219     printer->Print("\n");
220 
221     GenerateInlineFunctionDefinitions(printer);
222   }
223 
224   printer->Print(
225     "\n"
226     "// @@protoc_insertion_point(namespace_scope)\n");
227 
228   // Close up namespace.
229   GenerateNamespaceClosers(printer);
230 
231   if (!options_.proto_h) {
232     // We need to specialize some templates in the ::google::protobuf namespace:
233     GenerateProto2NamespaceEnumSpecializations(printer);
234   }
235 
236   printer->Print(
237     "\n"
238     "// @@protoc_insertion_point(global_scope)\n"
239     "\n");
240 
241   GenerateBottomHeaderGuard(printer, filename_identifier);
242 }
243 
GenerateSource(io::Printer * printer)244 void FileGenerator::GenerateSource(io::Printer* printer) {
245   const bool use_system_include = IsWellKnownMessage(file_);
246   string header =
247       StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h");
248   printer->Print(
249     "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
250     "// source: $filename$\n"
251     "\n"
252     // The generated code calls accessors that might be deprecated. We don't
253     // want the compiler to warn in generated code.
254     "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
255     "#include $left$$header$$right$\n"
256     "\n"
257     "#include <algorithm>\n"    // for swap()
258     "\n"
259     "#include <google/protobuf/stubs/common.h>\n"
260     "#include <google/protobuf/stubs/port.h>\n"
261     "#include <google/protobuf/stubs/once.h>\n"
262     "#include <google/protobuf/io/coded_stream.h>\n"
263     "#include <google/protobuf/wire_format_lite_inl.h>\n",
264     "filename", file_->name(),
265     "header", header,
266     "left", use_system_include ? "<" : "\"",
267     "right", use_system_include ? ">" : "\"");
268 
269   // Unknown fields implementation in lite mode uses StringOutputStream
270   if (!UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) {
271     printer->Print(
272       "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
273   }
274 
275   if (HasDescriptorMethods(file_, options_)) {
276     printer->Print(
277       "#include <google/protobuf/descriptor.h>\n"
278       "#include <google/protobuf/generated_message_reflection.h>\n"
279       "#include <google/protobuf/reflection_ops.h>\n"
280       "#include <google/protobuf/wire_format.h>\n");
281   }
282 
283   if (options_.proto_h) {
284     // Use the smaller .proto.h files.
285     for (int i = 0; i < file_->dependency_count(); i++) {
286       const FileDescriptor* dep = file_->dependency(i);
287       const char* extension = ".proto.h";
288       string dependency = StripProto(dep->name()) + extension;
289       printer->Print(
290           "#include \"$dependency$\"\n",
291           "dependency", dependency);
292     }
293   }
294 
295   printer->Print(
296     "// @@protoc_insertion_point(includes)\n");
297 
298   GenerateNamespaceOpeners(printer);
299 
300   if (HasDescriptorMethods(file_, options_)) {
301     printer->Print(
302       "\n"
303       "namespace {\n"
304       "\n");
305     for (int i = 0; i < file_->message_type_count(); i++) {
306       message_generators_[i]->GenerateDescriptorDeclarations(printer);
307     }
308     for (int i = 0; i < file_->enum_type_count(); i++) {
309       printer->Print(
310         "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
311         "name", ClassName(file_->enum_type(i), false));
312     }
313 
314     if (HasGenericServices(file_, options_)) {
315       for (int i = 0; i < file_->service_count(); i++) {
316         printer->Print(
317           "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
318           "name", file_->service(i)->name());
319       }
320     }
321 
322     printer->Print(
323       "\n"
324       "}  // namespace\n"
325       "\n");
326   }
327 
328   // Define our externally-visible BuildDescriptors() function.  (For the lite
329   // library, all this does is initialize default instances.)
330   GenerateBuildDescriptors(printer);
331 
332   // Generate enums.
333   for (int i = 0; i < file_->enum_type_count(); i++) {
334     enum_generators_[i]->GenerateMethods(printer);
335   }
336 
337   // Generate classes.
338   for (int i = 0; i < file_->message_type_count(); i++) {
339     if (i == 0 && HasGeneratedMethods(file_, options_)) {
340       printer->Print(
341           "\n"
342           "namespace {\n"
343           "\n"
344           "static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;\n"
345           "static void MergeFromFail(int line) {\n"
346           "  GOOGLE_CHECK(false) << __FILE__ << \":\" << line;\n"
347           "}\n"
348           "\n"
349           "}  // namespace\n"
350           "\n");
351     }
352     printer->Print("\n");
353     printer->Print(kThickSeparator);
354     printer->Print("\n");
355     message_generators_[i]->GenerateClassMethods(printer);
356 
357     printer->Print("#if PROTOBUF_INLINE_NOT_IN_HEADERS\n");
358     // Generate class inline methods.
359     message_generators_[i]->GenerateInlineMethods(printer,
360                                                   /* is_inline = */ false);
361     printer->Print("#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS\n");
362   }
363 
364   if (HasGenericServices(file_, options_)) {
365     // Generate services.
366     for (int i = 0; i < file_->service_count(); i++) {
367       if (i == 0) printer->Print("\n");
368       printer->Print(kThickSeparator);
369       printer->Print("\n");
370       service_generators_[i]->GenerateImplementation(printer);
371     }
372   }
373 
374   // Define extensions.
375   for (int i = 0; i < file_->extension_count(); i++) {
376     extension_generators_[i]->GenerateDefinition(printer);
377   }
378 
379   printer->Print(
380     "\n"
381     "// @@protoc_insertion_point(namespace_scope)\n");
382 
383   GenerateNamespaceClosers(printer);
384 
385   printer->Print(
386     "\n"
387     "// @@protoc_insertion_point(global_scope)\n");
388 }
389 
390 class FileGenerator::ForwardDeclarations {
391  public:
~ForwardDeclarations()392   ~ForwardDeclarations() {
393     for (map<string, ForwardDeclarations *>::iterator it = namespaces_.begin(),
394                                                       end = namespaces_.end();
395          it != end; ++it) {
396       delete it->second;
397     }
398     namespaces_.clear();
399   }
400 
AddOrGetNamespace(const string & ns_name)401   ForwardDeclarations* AddOrGetNamespace(const string& ns_name) {
402     ForwardDeclarations*& ns = namespaces_[ns_name];
403     if (ns == NULL) {
404       ns = new ForwardDeclarations;
405     }
406     return ns;
407   }
408 
classes()409   map<string, const Descriptor*>& classes() { return classes_; }
enums()410   map<string, const EnumDescriptor*>& enums() { return enums_; }
411 
Print(io::Printer * printer) const412   void Print(io::Printer* printer) const {
413     for (map<string, const EnumDescriptor *>::const_iterator
414              it = enums_.begin(),
415              end = enums_.end();
416          it != end; ++it) {
417       printer->Print("enum $enumname$ : int;\n", "enumname", it->first);
418       printer->Annotate("enumname", it->second);
419       printer->Print("bool $enumname$_IsValid(int value);\n", "enumname",
420                      it->first);
421     }
422     for (map<string, const Descriptor *>::const_iterator it = classes_.begin(),
423                                                          end = classes_.end();
424          it != end; ++it) {
425       printer->Print("class $classname$;\n", "classname", it->first);
426       printer->Annotate("classname", it->second);
427     }
428     for (map<string, ForwardDeclarations *>::const_iterator
429              it = namespaces_.begin(),
430              end = namespaces_.end();
431          it != end; ++it) {
432       printer->Print("namespace $nsname$ {\n",
433                      "nsname", it->first);
434       it->second->Print(printer);
435       printer->Print("}  // namespace $nsname$\n",
436                      "nsname", it->first);
437     }
438   }
439 
440 
441  private:
442   map<string, ForwardDeclarations*> namespaces_;
443   map<string, const Descriptor*> classes_;
444   map<string, const EnumDescriptor*> enums_;
445 };
446 
GenerateBuildDescriptors(io::Printer * printer)447 void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
448   // AddDescriptors() is a file-level procedure which adds the encoded
449   // FileDescriptorProto for this .proto file to the global DescriptorPool for
450   // generated files (DescriptorPool::generated_pool()). It either runs at
451   // static initialization time (by default) or when default_instance() is
452   // called for the first time (in LITE_RUNTIME mode with
453   // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
454   // constructs default instances and registers extensions.
455   //
456   // Its sibling, AssignDescriptors(), actually pulls the compiled
457   // FileDescriptor from the DescriptorPool and uses it to populate all of
458   // the global variables which store pointers to the descriptor objects.
459   // It also constructs the reflection objects.  It is called the first time
460   // anyone calls descriptor() or GetReflection() on one of the types defined
461   // in the file.
462 
463   // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
464   // and we only use AddDescriptors() to allocate default instances.
465   if (HasDescriptorMethods(file_, options_)) {
466     printer->Print(
467       "\n"
468       "void $assigndescriptorsname$() {\n",
469       "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
470     printer->Indent();
471 
472     // Make sure the file has found its way into the pool.  If a descriptor
473     // is requested *during* static init then AddDescriptors() may not have
474     // been called yet, so we call it manually.  Note that it's fine if
475     // AddDescriptors() is called multiple times.
476     printer->Print(
477       "$adddescriptorsname$();\n",
478       "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
479 
480     // Get the file's descriptor from the pool.
481     printer->Print(
482       "const ::google::protobuf::FileDescriptor* file =\n"
483       "  ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
484       "    \"$filename$\");\n"
485       // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
486       // being unused when compiling an empty .proto file.
487       "GOOGLE_CHECK(file != NULL);\n",
488       "filename", file_->name());
489 
490     // Go through all the stuff defined in this file and generated code to
491     // assign the global descriptor pointers based on the file descriptor.
492     for (int i = 0; i < file_->message_type_count(); i++) {
493       message_generators_[i]->GenerateDescriptorInitializer(printer, i);
494     }
495     for (int i = 0; i < file_->enum_type_count(); i++) {
496       enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
497     }
498     if (HasGenericServices(file_, options_)) {
499       for (int i = 0; i < file_->service_count(); i++) {
500         service_generators_[i]->GenerateDescriptorInitializer(printer, i);
501       }
502     }
503 
504     printer->Outdent();
505     printer->Print(
506       "}\n"
507       "\n");
508 
509     // ---------------------------------------------------------------
510 
511     // protobuf_AssignDescriptorsOnce():  The first time it is called, calls
512     // AssignDescriptors().  All later times, waits for the first call to
513     // complete and then returns.
514     printer->Print(
515       "namespace {\n"
516       "\n"
517       "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
518       "inline void protobuf_AssignDescriptorsOnce() {\n"
519       "  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
520       "                 &$assigndescriptorsname$);\n"
521       "}\n"
522       "\n",
523       "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
524 
525     // protobuf_RegisterTypes():  Calls
526     // MessageFactory::InternalRegisterGeneratedType() for each message type.
527     printer->Print(
528       "void protobuf_RegisterTypes(const ::std::string&) {\n"
529       "  protobuf_AssignDescriptorsOnce();\n");
530     printer->Indent();
531 
532     for (int i = 0; i < file_->message_type_count(); i++) {
533       message_generators_[i]->GenerateTypeRegistrations(printer);
534     }
535 
536     printer->Outdent();
537     printer->Print(
538       "}\n"
539       "\n"
540       "}  // namespace\n");
541   }
542 
543   // -----------------------------------------------------------------
544 
545   // ShutdownFile():  Deletes descriptors, default instances, etc. on shutdown.
546   printer->Print(
547     "\n"
548     "void $shutdownfilename$() {\n",
549     "shutdownfilename", GlobalShutdownFileName(file_->name()));
550   printer->Indent();
551 
552   for (int i = 0; i < file_->message_type_count(); i++) {
553     message_generators_[i]->GenerateShutdownCode(printer);
554   }
555 
556   printer->Outdent();
557   printer->Print(
558     "}\n\n");
559 
560   // -----------------------------------------------------------------
561 
562   // Now generate the AddDescriptors() function.
563   PrintHandlingOptionalStaticInitializers(
564       file_, options_, printer,
565       // With static initializers.
566       // Note that we don't need any special synchronization in the following
567       // code
568       // because it is called at static init time before any threads exist.
569       "void $adddescriptorsname$() {\n"
570       "  static bool already_here = false;\n"
571       "  if (already_here) return;\n"
572       "  already_here = true;\n"
573       "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
574       "\n",
575       // Without.
576       "void $adddescriptorsname$_impl() {\n"
577       "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
578       "\n",
579       // Vars.
580       "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
581 
582   printer->Indent();
583 
584   // Call the AddDescriptors() methods for all of our dependencies, to make
585   // sure they get added first.
586   for (int i = 0; i < file_->dependency_count(); i++) {
587     const FileDescriptor* dependency = file_->dependency(i);
588     // Print the namespace prefix for the dependency.
589     string add_desc_name = QualifiedFileLevelSymbol(
590         dependency->package(), GlobalAddDescriptorsName(dependency->name()));
591     // Call its AddDescriptors function.
592     printer->Print(
593       "$name$();\n",
594       "name", add_desc_name);
595   }
596 
597   if (HasDescriptorMethods(file_, options_)) {
598     // Embed the descriptor.  We simply serialize the entire FileDescriptorProto
599     // and embed it as a string literal, which is parsed and built into real
600     // descriptors at initialization time.
601     FileDescriptorProto file_proto;
602     file_->CopyTo(&file_proto);
603     string file_data;
604     file_proto.SerializeToString(&file_data);
605 
606 #ifdef _MSC_VER
607     bool breakdown_large_file = true;
608 #else
609     bool breakdown_large_file = false;
610 #endif
611     // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
612     // bytes in length". Declare a static array of characters rather than use a
613     // string literal.
614     if (breakdown_large_file && file_data.size() > 65535) {
615       // This has to be explicitly marked as a signed char because the generated
616       // code puts negative values in the array, and sometimes plain char is
617       // unsigned. That implicit narrowing conversion is not allowed in C++11.
618       // <http://stackoverflow.com/questions/4434140/narrowing-conversions-in-c0x-is-it-just-me-or-does-this-sound-like-a-breakin>
619       // has details on why.
620       printer->Print(
621           "static const signed char descriptor[] = {\n");
622       printer->Indent();
623 
624       // Only write 25 bytes per line.
625       static const int kBytesPerLine = 25;
626       for (int i = 0; i < file_data.size();) {
627           for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
628             printer->Print(
629                 "$char$, ",
630                 "char", SimpleItoa(file_data[i]));
631           }
632           printer->Print(
633               "\n");
634       }
635 
636       printer->Outdent();
637       printer->Print(
638           "};\n");
639 
640       printer->Print(
641           "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n",
642           "size", SimpleItoa(file_data.size()));
643 
644     } else {
645       printer->Print(
646         "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
647 
648       // Only write 40 bytes per line.
649       static const int kBytesPerLine = 40;
650       for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
651         printer->Print("\n  \"$data$\"",
652                        "data",
653                        EscapeTrigraphs(
654                            CEscape(file_data.substr(i, kBytesPerLine))));
655     }
656     printer->Print(
657         ", $size$);\n",
658         "size", SimpleItoa(file_data.size()));
659     }
660 
661     // Call MessageFactory::InternalRegisterGeneratedFile().
662     printer->Print(
663       "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
664       "  \"$filename$\", &protobuf_RegisterTypes);\n",
665       "filename", file_->name());
666   }
667 
668   // Allocate and initialize default instances.  This can't be done lazily
669   // since default instances are returned by simple accessors and are used with
670   // extensions.  Speaking of which, we also register extensions at this time.
671   for (int i = 0; i < file_->message_type_count(); i++) {
672     message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
673   }
674   for (int i = 0; i < file_->extension_count(); i++) {
675     extension_generators_[i]->GenerateRegistration(printer);
676   }
677   for (int i = 0; i < file_->message_type_count(); i++) {
678     message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
679   }
680 
681   printer->Print(
682     "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
683     "shutdownfilename", GlobalShutdownFileName(file_->name()));
684 
685   printer->Outdent();
686   printer->Print(
687     "}\n"
688     "\n");
689 
690   PrintHandlingOptionalStaticInitializers(
691       file_, options_, printer,
692       // With static initializers.
693       "// Force AddDescriptors() to be called at static initialization time.\n"
694       "struct StaticDescriptorInitializer_$filename$ {\n"
695       "  StaticDescriptorInitializer_$filename$() {\n"
696       "    $adddescriptorsname$();\n"
697       "  }\n"
698       "} static_descriptor_initializer_$filename$_;\n",
699       // Without.
700       "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
701       "void $adddescriptorsname$() {\n"
702       "  ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
703       "                 &$adddescriptorsname$_impl);\n"
704       "}\n",
705       // Vars.
706       "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), "filename",
707       FilenameIdentifier(file_->name()));
708 }
709 
GenerateNamespaceOpeners(io::Printer * printer)710 void FileGenerator::GenerateNamespaceOpeners(io::Printer* printer) {
711   if (package_parts_.size() > 0) printer->Print("\n");
712 
713   for (int i = 0; i < package_parts_.size(); i++) {
714     printer->Print("namespace $part$ {\n",
715                    "part", package_parts_[i]);
716   }
717 }
718 
GenerateNamespaceClosers(io::Printer * printer)719 void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
720   if (package_parts_.size() > 0) printer->Print("\n");
721 
722   for (int i = package_parts_.size() - 1; i >= 0; i--) {
723     printer->Print("}  // namespace $part$\n",
724                    "part", package_parts_[i]);
725   }
726 }
727 
GenerateForwardDeclarations(io::Printer * printer)728 void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
729   ForwardDeclarations decls;
730   for (int i = 0; i < file_->dependency_count(); i++) {
731     FileGenerator dependency(file_->dependency(i), options_);
732     dependency.FillForwardDeclarations(&decls);
733   }
734   FillForwardDeclarations(&decls);
735   decls.Print(printer);
736 }
737 
FillForwardDeclarations(ForwardDeclarations * decls)738 void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) {
739   for (int i = 0; i < file_->public_dependency_count(); i++) {
740     FileGenerator dependency(file_->public_dependency(i), options_);
741     dependency.FillForwardDeclarations(decls);
742   }
743   for (int i = 0; i < package_parts_.size(); i++) {
744     decls = decls->AddOrGetNamespace(package_parts_[i]);
745   }
746   // Generate enum definitions.
747   for (int i = 0; i < file_->message_type_count(); i++) {
748     message_generators_[i]->FillEnumForwardDeclarations(&decls->enums());
749   }
750   for (int i = 0; i < file_->enum_type_count(); i++) {
751     enum_generators_[i]->FillForwardDeclaration(&decls->enums());
752   }
753   // Generate forward declarations of classes.
754   for (int i = 0; i < file_->message_type_count(); i++) {
755     message_generators_[i]->FillMessageForwardDeclarations(
756         &decls->classes());
757   }
758 }
759 
GenerateTopHeaderGuard(io::Printer * printer,const string & filename_identifier)760 void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
761                                            const string& filename_identifier) {
762   // Generate top of header.
763   printer->Print(
764       "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
765       "// source: $filename$\n"
766       "\n"
767       "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
768       "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
769       "\n"
770       "#include <string>\n",
771       "filename", file_->name(), "filename_identifier", filename_identifier);
772   printer->Print("\n");
773 }
774 
GenerateBottomHeaderGuard(io::Printer * printer,const string & filename_identifier)775 void FileGenerator::GenerateBottomHeaderGuard(
776     io::Printer* printer, const string& filename_identifier) {
777   printer->Print(
778     "#endif  // PROTOBUF_$filename_identifier$__INCLUDED\n",
779     "filename_identifier", filename_identifier);
780 }
781 
GenerateLibraryIncludes(io::Printer * printer)782 void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) {
783 
784   printer->Print(
785     "#include <google/protobuf/stubs/common.h>\n"
786     "\n");
787 
788   // Verify the protobuf library header version is compatible with the protoc
789   // version before going any further.
790   printer->Print(
791     "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\n"
792     "#error This file was generated by a newer version of protoc which is\n"
793     "#error incompatible with your Protocol Buffer headers.  Please update\n"
794     "#error your headers.\n"
795     "#endif\n"
796     "#if $protoc_version$ < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n"
797     "#error This file was generated by an older version of protoc which is\n"
798     "#error incompatible with your Protocol Buffer headers.  Please\n"
799     "#error regenerate this file with a newer version of protoc.\n"
800     "#endif\n"
801     "\n",
802     "min_header_version",
803       SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc),
804     "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION));
805 
806   // OK, it's now safe to #include other files.
807   printer->Print(
808     "#include <google/protobuf/arena.h>\n"
809     "#include <google/protobuf/arenastring.h>\n"
810     "#include <google/protobuf/generated_message_util.h>\n");
811   if (UseUnknownFieldSet(file_, options_)) {
812     printer->Print(
813       "#include <google/protobuf/metadata.h>\n");
814   }
815   if (file_->message_type_count() > 0) {
816     if (HasDescriptorMethods(file_, options_)) {
817       printer->Print(
818         "#include <google/protobuf/message.h>\n");
819     } else {
820       printer->Print(
821         "#include <google/protobuf/message_lite.h>\n");
822     }
823   }
824   printer->Print(
825     "#include <google/protobuf/repeated_field.h>\n"
826     "#include <google/protobuf/extension_set.h>\n");
827   if (HasMapFields(file_)) {
828     printer->Print(
829         "#include <google/protobuf/map.h>\n");
830     if (HasDescriptorMethods(file_, options_)) {
831       printer->Print(
832           "#include <google/protobuf/map_field_inl.h>\n");
833     } else {
834       printer->Print(
835           "#include <google/protobuf/map_field_lite.h>\n");
836     }
837   }
838 
839   if (HasEnumDefinitions(file_)) {
840     if (HasDescriptorMethods(file_, options_)) {
841       printer->Print(
842           "#include <google/protobuf/generated_enum_reflection.h>\n");
843     } else {
844       printer->Print(
845           "#include <google/protobuf/generated_enum_util.h>\n");
846     }
847   }
848 
849   if (HasGenericServices(file_, options_)) {
850     printer->Print(
851       "#include <google/protobuf/service.h>\n");
852   }
853 
854   if (UseUnknownFieldSet(file_, options_) && file_->message_type_count() > 0) {
855     printer->Print(
856       "#include <google/protobuf/unknown_field_set.h>\n");
857   }
858 
859 
860   if (IsAnyMessage(file_)) {
861     printer->Print(
862       "#include <google/protobuf/any.h>\n");
863   }
864 }
865 
GenerateMetadataPragma(io::Printer * printer,const string & info_path)866 void FileGenerator::GenerateMetadataPragma(io::Printer* printer,
867                                            const string& info_path) {
868   if (!info_path.empty() && !options_.annotation_pragma_name.empty() &&
869       !options_.annotation_guard_name.empty()) {
870     printer->Print(
871         "#ifdef $guard$\n"
872         "#pragma $pragma$ \"$info_path$\"\n"
873         "#endif  // $guard$\n",
874         "guard", options_.annotation_guard_name, "pragma",
875         options_.annotation_pragma_name, "info_path", info_path);
876   }
877 }
878 
GenerateDependencyIncludes(io::Printer * printer)879 void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) {
880   set<string> public_import_names;
881   for (int i = 0; i < file_->public_dependency_count(); i++) {
882     public_import_names.insert(file_->public_dependency(i)->name());
883   }
884 
885   for (int i = 0; i < file_->dependency_count(); i++) {
886     const bool use_system_include = IsWellKnownMessage(file_->dependency(i));
887     const string& name = file_->dependency(i)->name();
888     bool public_import = (public_import_names.count(name) != 0);
889 
890 
891     printer->Print(
892       "#include $left$$dependency$.pb.h$right$$iwyu$\n",
893       "dependency", StripProto(name),
894       "iwyu", (public_import) ? "  // IWYU pragma: export" : "",
895       "left", use_system_include ? "<" : "\"",
896       "right", use_system_include ? ">" : "\"");
897   }
898 }
899 
GenerateGlobalStateFunctionDeclarations(io::Printer * printer)900 void FileGenerator::GenerateGlobalStateFunctionDeclarations(
901     io::Printer* printer) {
902   // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile
903   // functions, so that we can declare them to be friends of each class.
904   printer->Print(
905     "\n"
906     "// Internal implementation detail -- do not call these.\n"
907     "void $dllexport_decl$$adddescriptorsname$();\n",
908     "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
909     "dllexport_decl",
910     options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " ");
911 
912   printer->Print(
913     // Note that we don't put dllexport_decl on these because they are only
914     // called by the .pb.cc file in which they are defined.
915     "void $assigndescriptorsname$();\n"
916     "void $shutdownfilename$();\n"
917     "\n",
918     "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
919     "shutdownfilename", GlobalShutdownFileName(file_->name()));
920 }
921 
GenerateMessageForwardDeclarations(io::Printer * printer)922 void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) {
923   map<string, const Descriptor*> classes;
924   for (int i = 0; i < file_->message_type_count(); i++) {
925     message_generators_[i]->FillMessageForwardDeclarations(&classes);
926   }
927   for (map<string, const Descriptor *>::const_iterator it = classes.begin(),
928                                                        end = classes.end();
929        it != end; ++it) {
930     printer->Print("class $classname$;\n", "classname", it->first);
931     printer->Annotate("classname", it->second);
932   }
933 }
934 
GenerateMessageDefinitions(io::Printer * printer)935 void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) {
936   // Generate class definitions.
937   for (int i = 0; i < file_->message_type_count(); i++) {
938     if (i > 0) {
939       printer->Print("\n");
940       printer->Print(kThinSeparator);
941       printer->Print("\n");
942     }
943     message_generators_[i]->GenerateClassDefinition(printer);
944   }
945 }
946 
GenerateEnumDefinitions(io::Printer * printer)947 void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) {
948   // Generate enum definitions.
949   for (int i = 0; i < file_->message_type_count(); i++) {
950     message_generators_[i]->GenerateEnumDefinitions(printer);
951   }
952   for (int i = 0; i < file_->enum_type_count(); i++) {
953     enum_generators_[i]->GenerateDefinition(printer);
954   }
955 }
956 
GenerateServiceDefinitions(io::Printer * printer)957 void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) {
958   if (HasGenericServices(file_, options_)) {
959     // Generate service definitions.
960     for (int i = 0; i < file_->service_count(); i++) {
961       if (i > 0) {
962         printer->Print("\n");
963         printer->Print(kThinSeparator);
964         printer->Print("\n");
965       }
966       service_generators_[i]->GenerateDeclarations(printer);
967     }
968 
969     printer->Print("\n");
970     printer->Print(kThickSeparator);
971     printer->Print("\n");
972   }
973 }
974 
GenerateExtensionIdentifiers(io::Printer * printer)975 void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) {
976   // Declare extension identifiers.
977   for (int i = 0; i < file_->extension_count(); i++) {
978     extension_generators_[i]->GenerateDeclaration(printer);
979   }
980 }
981 
GenerateInlineFunctionDefinitions(io::Printer * printer)982 void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
983   // An aside about inline functions in .proto.h mode:
984   //
985   // The PROTOBUF_INLINE_NOT_IN_HEADERS symbol controls conditionally
986   // moving much of the inline functions to the .pb.cc file, which can be a
987   // significant performance benefit for compilation time, at the expense
988   // of non-inline function calls.
989   //
990   // However, in .proto.h mode, the definition of the internal dependent
991   // base class must remain in the header, and can never be out-lined. The
992   // dependent base class also needs access to has-bit manipuation
993   // functions, so the has-bit functions must be unconditionally inlined in
994   // proto_h mode.
995   //
996   // This gives us three flavors of functions:
997   //
998   //  1. Functions on the message not used by the internal dependent base
999   //     class: in .proto.h mode, only some functions are defined on the
1000   //     message class; others are defined on the dependent base class.
1001   //     These are guarded and can be out-lined. These are generated by
1002   //     GenerateInlineMethods, and include has_* bit functions in
1003   //     non-proto_h mode.
1004   //
1005   //  2. Functions on the internal dependent base class: these functions
1006   //     are dependent on a template parameter, so they always need to
1007   //     remain in the header.
1008   //
1009   //  3. Functions on the message that are used by the dependent base: the
1010   //     dependent base class down casts itself to the message
1011   //     implementation class to access these functions (the has_* bit
1012   //     manipulation functions). Unlike #1, these functions must
1013   //     unconditionally remain in the header. These are emitted by
1014   //     GenerateDependentInlineMethods, even though they are not actually
1015   //     dependent.
1016 
1017   printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n");
1018   // Generate class inline methods.
1019   for (int i = 0; i < file_->message_type_count(); i++) {
1020     if (i > 0) {
1021       printer->Print(kThinSeparator);
1022       printer->Print("\n");
1023     }
1024     message_generators_[i]->GenerateInlineMethods(printer,
1025                                                   /* is_inline = */ true);
1026   }
1027   printer->Print("#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS\n");
1028 
1029   for (int i = 0; i < file_->message_type_count(); i++) {
1030     if (i > 0) {
1031       printer->Print(kThinSeparator);
1032       printer->Print("\n");
1033     }
1034     // Methods of the dependent base class must always be inline in the header.
1035     message_generators_[i]->GenerateDependentInlineMethods(printer);
1036   }
1037 }
1038 
GenerateProto2NamespaceEnumSpecializations(io::Printer * printer)1039 void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
1040     io::Printer* printer) {
1041   // Emit GetEnumDescriptor specializations into google::protobuf namespace:
1042   if (HasEnumDefinitions(file_)) {
1043     // The SWIG conditional is to avoid a null-pointer dereference
1044     // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
1045     //   namespace X { void Y<Z::W>(); }
1046     // which appears in GetEnumDescriptor() specializations.
1047     printer->Print(
1048         "\n"
1049         "#ifndef SWIG\n"
1050         "namespace google {\nnamespace protobuf {\n"
1051         "\n");
1052     for (int i = 0; i < file_->message_type_count(); i++) {
1053       message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
1054     }
1055     for (int i = 0; i < file_->enum_type_count(); i++) {
1056       enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
1057     }
1058     printer->Print(
1059         "\n"
1060         "}  // namespace protobuf\n}  // namespace google\n"
1061         "#endif  // SWIG\n");
1062   }
1063 }
1064 
1065 }  // namespace cpp
1066 }  // namespace compiler
1067 }  // namespace protobuf
1068 }  // namespace google
1069