LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/objectivec - objectivec_file.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 128 0.0 %
Date: 2015-10-10 Functions: 0 6 0.0 %

          Line data    Source code
       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             : #include <google/protobuf/compiler/objectivec/objectivec_file.h>
      32             : #include <google/protobuf/compiler/objectivec/objectivec_enum.h>
      33             : #include <google/protobuf/compiler/objectivec/objectivec_extension.h>
      34             : #include <google/protobuf/compiler/objectivec/objectivec_message.h>
      35             : #include <google/protobuf/compiler/code_generator.h>
      36             : #include <google/protobuf/io/printer.h>
      37             : #include <google/protobuf/io/zero_copy_stream_impl.h>
      38             : #include <google/protobuf/stubs/stl_util.h>
      39             : #include <google/protobuf/stubs/strutil.h>
      40             : #include <sstream>
      41             : 
      42             : namespace google {
      43             : namespace protobuf {
      44             : 
      45             : // This is also found in GPBBootstrap.h, and needs to be kept in sync.  It
      46             : // is the version check done to ensure generated code works with the current
      47             : // runtime being used.
      48             : const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30000;
      49             : 
      50             : namespace compiler {
      51             : namespace objectivec {
      52             : 
      53           0 : FileGenerator::FileGenerator(const FileDescriptor *file)
      54             :     : file_(file),
      55             :       root_class_name_(FileClassName(file)),
      56           0 :       is_public_dep_(false) {
      57           0 :   for (int i = 0; i < file_->enum_type_count(); i++) {
      58           0 :     EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
      59           0 :     enum_generators_.push_back(generator);
      60             :   }
      61           0 :   for (int i = 0; i < file_->message_type_count(); i++) {
      62             :     MessageGenerator *generator =
      63           0 :         new MessageGenerator(root_class_name_, file_->message_type(i));
      64           0 :     message_generators_.push_back(generator);
      65             :   }
      66           0 :   for (int i = 0; i < file_->extension_count(); i++) {
      67             :     ExtensionGenerator *generator =
      68           0 :         new ExtensionGenerator(root_class_name_, file_->extension(i));
      69           0 :     extension_generators_.push_back(generator);
      70             :   }
      71           0 : }
      72             : 
      73           0 : FileGenerator::~FileGenerator() {
      74             :   STLDeleteContainerPointers(dependency_generators_.begin(),
      75           0 :                              dependency_generators_.end());
      76           0 :   STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end());
      77             :   STLDeleteContainerPointers(message_generators_.begin(),
      78           0 :                              message_generators_.end());
      79             :   STLDeleteContainerPointers(extension_generators_.begin(),
      80           0 :                              extension_generators_.end());
      81           0 : }
      82             : 
      83           0 : void FileGenerator::GenerateHeader(io::Printer *printer) {
      84             :   printer->Print(
      85             :       "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
      86             :       "// source: $filename$\n"
      87             :       "\n",
      88           0 :       "filename", file_->name());
      89             : 
      90             :   printer->Print(
      91             :       "#import \"GPBProtocolBuffers.h\"\n"
      92           0 :       "\n");
      93             : 
      94             :   // Add some verification that the generated code matches the source the
      95             :   // code is being compiled with.
      96             :   printer->Print(
      97             :       "#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != $protoc_gen_objc_version$\n"
      98             :       "#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.\n"
      99             :       "#endif\n"
     100             :       "\n",
     101             :       "protoc_gen_objc_version",
     102           0 :       SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION));
     103             : 
     104           0 :   const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
     105           0 :   for (vector<FileGenerator *>::const_iterator iter =
     106           0 :            dependency_generators.begin();
     107           0 :        iter != dependency_generators.end(); ++iter) {
     108           0 :     if ((*iter)->IsPublicDependency()) {
     109             :       printer->Print("#import \"$header$.pbobjc.h\"\n",
     110           0 :                      "header", (*iter)->Path());
     111             :     }
     112             :   }
     113             : 
     114             :   printer->Print(
     115             :       "// @@protoc_insertion_point(imports)\n"
     116             :       "\n"
     117             :       "CF_EXTERN_C_BEGIN\n"
     118           0 :       "\n");
     119             : 
     120             :   set<string> fwd_decls;
     121           0 :   for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
     122           0 :        iter != message_generators_.end(); ++iter) {
     123           0 :     (*iter)->DetermineForwardDeclarations(&fwd_decls);
     124             :   }
     125           0 :   for (set<string>::const_iterator i(fwd_decls.begin());
     126           0 :        i != fwd_decls.end(); ++i) {
     127           0 :     printer->Print("$value$;\n", "value", *i);
     128             :   }
     129           0 :   if (fwd_decls.begin() != fwd_decls.end()) {
     130           0 :     printer->Print("\n");
     131             :   }
     132             : 
     133             :   printer->Print(
     134             :       "NS_ASSUME_NONNULL_BEGIN\n"
     135           0 :       "\n");
     136             : 
     137             :   // need to write out all enums first
     138           0 :   for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
     139           0 :        iter != enum_generators_.end(); ++iter) {
     140           0 :     (*iter)->GenerateHeader(printer);
     141             :   }
     142             : 
     143           0 :   for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
     144           0 :        iter != message_generators_.end(); ++iter) {
     145           0 :     (*iter)->GenerateEnumHeader(printer);
     146             :   }
     147             : 
     148             :   // For extensions to chain together, the Root gets created even if there
     149             :   // are no extensions.
     150             :   printer->Print(
     151             :       "#pragma mark - $root_class_name$\n"
     152             :       "\n"
     153             :       "@interface $root_class_name$ : GPBRootObject\n"
     154             :       "\n"
     155             :       "// The base class provides:\n"
     156             :       "//   + (GPBExtensionRegistry *)extensionRegistry;\n"
     157             :       "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
     158             :       "// this file and all files that it depends on.\n"
     159             :       "\n"
     160             :       "@end\n"
     161             :       "\n",
     162           0 :       "root_class_name", root_class_name_);
     163             : 
     164           0 :   if (extension_generators_.size() > 0) {
     165             :     // The dynamic methods block is only needed if there are extensions.
     166             :     printer->Print(
     167             :         "@interface $root_class_name$ (DynamicMethods)\n",
     168           0 :         "root_class_name", root_class_name_);
     169             : 
     170           0 :     for (vector<ExtensionGenerator *>::iterator iter =
     171           0 :              extension_generators_.begin();
     172           0 :          iter != extension_generators_.end(); ++iter) {
     173           0 :       (*iter)->GenerateMembersHeader(printer);
     174             :     }
     175             : 
     176           0 :     printer->Print("@end\n\n");
     177             :   }  // extension_generators_.size() > 0
     178             : 
     179           0 :   for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
     180           0 :        iter != message_generators_.end(); ++iter) {
     181           0 :     (*iter)->GenerateMessageHeader(printer);
     182             :   }
     183             : 
     184             :   printer->Print(
     185             :       "NS_ASSUME_NONNULL_END\n"
     186             :       "\n"
     187             :       "CF_EXTERN_C_END\n"
     188             :       "\n"
     189           0 :       "// @@protoc_insertion_point(global_scope)\n");
     190           0 : }
     191             : 
     192           0 : void FileGenerator::GenerateSource(io::Printer *printer) {
     193             :   printer->Print(
     194             :       "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
     195             :       "// source: $filename$\n"
     196             :       "\n",
     197           0 :       "filename", file_->name());
     198             : 
     199           0 :   string header_file = Path() + ".pbobjc.h";
     200             :   printer->Print(
     201             :       "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n"
     202             :       "#import \"$header_file$\"\n",
     203           0 :       "header_file", header_file);
     204           0 :   const vector<FileGenerator *> &dependency_generators =
     205           0 :       DependencyGenerators();
     206           0 :   for (vector<FileGenerator *>::const_iterator iter =
     207           0 :            dependency_generators.begin();
     208           0 :        iter != dependency_generators.end(); ++iter) {
     209           0 :     if (!(*iter)->IsPublicDependency()) {
     210             :       printer->Print("#import \"$header$.pbobjc.h\"\n",
     211           0 :                      "header", (*iter)->Path());
     212             :     }
     213             :   }
     214             :   printer->Print(
     215             :       "// @@protoc_insertion_point(imports)\n"
     216           0 :       "\n");
     217             : 
     218             :   printer->Print(
     219             :       "#pragma mark - $root_class_name$\n"
     220             :       "\n"
     221             :       "@implementation $root_class_name$\n\n",
     222           0 :       "root_class_name", root_class_name_);
     223             : 
     224             :   // Generate the extension initialization structures for the top level and
     225             :   // any nested messages.
     226           0 :   ostringstream extensions_stringstream;
     227           0 :   if (file_->extension_count() + file_->message_type_count() > 0) {
     228           0 :     io::OstreamOutputStream extensions_outputstream(&extensions_stringstream);
     229           0 :     io::Printer extensions_printer(&extensions_outputstream, '$');
     230           0 :     for (vector<ExtensionGenerator *>::iterator iter =
     231           0 :              extension_generators_.begin();
     232           0 :          iter != extension_generators_.end(); ++iter) {
     233           0 :       (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
     234             :     }
     235           0 :     for (vector<MessageGenerator *>::iterator iter =
     236           0 :              message_generators_.begin();
     237           0 :          iter != message_generators_.end(); ++iter) {
     238           0 :       (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
     239             :     }
     240           0 :     extensions_stringstream.flush();
     241             :   }
     242             : 
     243             :   // If there were any extensions or this file has any dependencies, output
     244             :   // a registry to override to create the file specific registry.
     245           0 :   const string& extensions_str = extensions_stringstream.str();
     246           0 :   if (extensions_str.length() > 0 || file_->dependency_count() > 0) {
     247             :     printer->Print(
     248             :         "+ (GPBExtensionRegistry*)extensionRegistry {\n"
     249             :         "  // This is called by +initialize so there is no need to worry\n"
     250             :         "  // about thread safety and initialization of registry.\n"
     251             :         "  static GPBExtensionRegistry* registry = nil;\n"
     252             :         "  if (!registry) {\n"
     253             :         "    GPBDebugCheckRuntimeVersion();\n"
     254           0 :         "    registry = [[GPBExtensionRegistry alloc] init];\n");
     255             : 
     256           0 :     printer->Indent();
     257           0 :     printer->Indent();
     258             : 
     259           0 :     if (extensions_str.length() > 0) {
     260             :       printer->Print(
     261           0 :           "static GPBExtensionDescription descriptions[] = {\n");
     262           0 :       printer->Indent();
     263           0 :       printer->Print(extensions_str.c_str());
     264           0 :       printer->Outdent();
     265             :       printer->Print(
     266             :           "};\n"
     267             :           "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n"
     268             :           "  GPBExtensionDescriptor *extension =\n"
     269             :           "      [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]];\n"
     270             :           "  [registry addExtension:extension];\n"
     271             :           "  [self globallyRegisterExtension:extension];\n"
     272             :           "  [extension release];\n"
     273           0 :           "}\n");
     274             :     }
     275             : 
     276           0 :     const vector<FileGenerator *> &dependency_generators =
     277           0 :         DependencyGenerators();
     278           0 :     for (vector<FileGenerator *>::const_iterator iter =
     279           0 :              dependency_generators.begin();
     280           0 :          iter != dependency_generators.end(); ++iter) {
     281             :       printer->Print(
     282             :           "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
     283           0 :           "dependency", (*iter)->RootClassName());
     284             :     }
     285             : 
     286           0 :     printer->Outdent();
     287           0 :     printer->Outdent();
     288             : 
     289             :     printer->Print(
     290             :         "  }\n"
     291             :         "  return registry;\n"
     292             :         "}\n"
     293           0 :         "\n");
     294             :   }
     295             : 
     296           0 :   printer->Print("@end\n\n");
     297             : 
     298             :   // File descriptor only needed if there are messages to use it.
     299           0 :   if (message_generators_.size() > 0) {
     300             :     string syntax;
     301           0 :     switch (file_->syntax()) {
     302             :       case FileDescriptor::SYNTAX_UNKNOWN:
     303             :         syntax = "GPBFileSyntaxUnknown";
     304             :         break;
     305             :       case FileDescriptor::SYNTAX_PROTO2:
     306             :         syntax = "GPBFileSyntaxProto2";
     307             :         break;
     308             :       case FileDescriptor::SYNTAX_PROTO3:
     309             :         syntax = "GPBFileSyntaxProto3";
     310             :         break;
     311             :     }
     312             :     printer->Print(
     313             :         "#pragma mark - $root_class_name$_FileDescriptor\n"
     314             :         "\n"
     315             :         "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
     316             :         "  // This is called by +initialize so there is no need to worry\n"
     317             :         "  // about thread safety of the singleton.\n"
     318             :         "  static GPBFileDescriptor *descriptor = NULL;\n"
     319             :         "  if (!descriptor) {\n"
     320             :         "    GPBDebugCheckRuntimeVersion();\n"
     321             :         "    descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
     322             :         "                                                     syntax:$syntax$];\n"
     323             :         "  }\n"
     324             :         "  return descriptor;\n"
     325             :         "}\n"
     326             :         "\n",
     327             :         "root_class_name", root_class_name_,
     328           0 :         "package", file_->package(),
     329           0 :         "syntax", syntax);
     330             :   }
     331             : 
     332           0 :   for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
     333           0 :        iter != enum_generators_.end(); ++iter) {
     334           0 :     (*iter)->GenerateSource(printer);
     335             :   }
     336           0 :   for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
     337           0 :        iter != message_generators_.end(); ++iter) {
     338           0 :     (*iter)->GenerateSource(printer);
     339             :   }
     340             : 
     341             :   printer->Print(
     342             :     "\n"
     343           0 :     "// @@protoc_insertion_point(global_scope)\n");
     344           0 : }
     345             : 
     346           0 : const string FileGenerator::Path() const { return FilePath(file_); }
     347             : 
     348           0 : const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
     349           0 :   if (file_->dependency_count() != dependency_generators_.size()) {
     350             :     set<string> public_import_names;
     351           0 :     for (int i = 0; i < file_->public_dependency_count(); i++) {
     352           0 :       public_import_names.insert(file_->public_dependency(i)->name());
     353             :     }
     354           0 :     for (int i = 0; i < file_->dependency_count(); i++) {
     355           0 :       FileGenerator *generator = new FileGenerator(file_->dependency(i));
     356           0 :       const string& name = file_->dependency(i)->name();
     357           0 :       bool public_import = (public_import_names.count(name) != 0);
     358           0 :       generator->SetIsPublicDependency(public_import);
     359           0 :       dependency_generators_.push_back(generator);
     360             :     }
     361             :   }
     362           0 :   return dependency_generators_;
     363             : }
     364             : 
     365             : }  // namespace objectivec
     366             : }  // namespace compiler
     367             : }  // namespace protobuf
     368             : }  // namespace google

Generated by: LCOV version 1.10