LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/java - java_file.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 195 0.0 %
Date: 2015-10-10 Functions: 0 15 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             : // 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/java/java_file.h>
      36             : 
      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/java/java_context.h>
      44             : #include <google/protobuf/compiler/java/java_enum.h>
      45             : #include <google/protobuf/compiler/java/java_extension.h>
      46             : #include <google/protobuf/compiler/java/java_generator_factory.h>
      47             : #include <google/protobuf/compiler/java/java_helpers.h>
      48             : #include <google/protobuf/compiler/java/java_message.h>
      49             : #include <google/protobuf/compiler/java/java_name_resolver.h>
      50             : #include <google/protobuf/compiler/java/java_service.h>
      51             : #include <google/protobuf/compiler/java/java_shared_code_generator.h>
      52             : #include <google/protobuf/compiler/code_generator.h>
      53             : #include <google/protobuf/io/printer.h>
      54             : #include <google/protobuf/io/zero_copy_stream.h>
      55             : #include <google/protobuf/descriptor.pb.h>
      56             : #include <google/protobuf/dynamic_message.h>
      57             : #include <google/protobuf/stubs/strutil.h>
      58             : 
      59             : namespace google {
      60             : namespace protobuf {
      61             : namespace compiler {
      62             : namespace java {
      63             : 
      64             : namespace {
      65             : 
      66             : struct FieldDescriptorCompare {
      67           0 :   bool operator ()(const FieldDescriptor* f1, const FieldDescriptor* f2) {
      68           0 :     if(f1 == NULL) {
      69             :       return false;
      70             :     }
      71           0 :     if(f2 == NULL) {
      72             :       return true;
      73             :     }
      74           0 :     return f1->full_name() < f2->full_name();
      75             :   }
      76             : };
      77             : 
      78             : typedef std::set<const FieldDescriptor*, FieldDescriptorCompare> FieldDescriptorSet;
      79             : 
      80             : // Recursively searches the given message to collect extensions.
      81             : // Returns true if all the extensions can be recognized. The extensions will be
      82             : // appended in to the extensions parameter.
      83             : // Returns false when there are unknown fields, in which case the data in the
      84             : // extensions output parameter is not reliable and should be discarded.
      85           0 : bool CollectExtensions(const Message& message,
      86             :                        FieldDescriptorSet* extensions) {
      87           0 :   const Reflection* reflection = message.GetReflection();
      88             : 
      89             :   // There are unknown fields that could be extensions, thus this call fails.
      90           0 :   if (reflection->GetUnknownFields(message).field_count() > 0) return false;
      91             : 
      92             :   vector<const FieldDescriptor*> fields;
      93           0 :   reflection->ListFields(message, &fields);
      94             : 
      95           0 :   for (int i = 0; i < fields.size(); i++) {
      96           0 :     if (fields[i]->is_extension()) extensions->insert(fields[i]);
      97             : 
      98           0 :     if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
      99           0 :       if (fields[i]->is_repeated()) {
     100           0 :         int size = reflection->FieldSize(message, fields[i]);
     101           0 :         for (int j = 0; j < size; j++) {
     102             :           const Message& sub_message =
     103           0 :             reflection->GetRepeatedMessage(message, fields[i], j);
     104           0 :           if (!CollectExtensions(sub_message, extensions)) return false;
     105             :         }
     106             :       } else {
     107           0 :         const Message& sub_message = reflection->GetMessage(message, fields[i]);
     108           0 :         if (!CollectExtensions(sub_message, extensions)) return false;
     109             :       }
     110             :     }
     111             :   }
     112             : 
     113             :   return true;
     114             : }
     115             : 
     116             : // Finds all extensions in the given message and its sub-messages.  If the
     117             : // message contains unknown fields (which could be extensions), then those
     118             : // extensions are defined in alternate_pool.
     119             : // The message will be converted to a DynamicMessage backed by alternate_pool
     120             : // in order to handle this case.
     121           0 : void CollectExtensions(const FileDescriptorProto& file_proto,
     122             :                        const DescriptorPool& alternate_pool,
     123             :                        FieldDescriptorSet* extensions,
     124             :                        const string& file_data) {
     125           0 :   if (!CollectExtensions(file_proto, extensions)) {
     126             :     // There are unknown fields in the file_proto, which are probably
     127             :     // extensions. We need to parse the data into a dynamic message based on the
     128             :     // builder-pool to find out all extensions.
     129             :     const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
     130           0 :         file_proto.GetDescriptor()->full_name());
     131           0 :     GOOGLE_CHECK(file_proto_desc)
     132           0 :         << "Find unknown fields in FileDescriptorProto when building "
     133           0 :         << file_proto.name()
     134             :         << ". It's likely that those fields are custom options, however, "
     135             :            "descriptor.proto is not in the transitive dependencies. "
     136           0 :            "This normally should not happen. Please report a bug.";
     137           0 :     DynamicMessageFactory factory;
     138             :     google::protobuf::scoped_ptr<Message> dynamic_file_proto(
     139           0 :         factory.GetPrototype(file_proto_desc)->New());
     140           0 :     GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
     141           0 :     GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
     142             : 
     143             :     // Collect the extensions again from the dynamic message. There should be no
     144             :     // more unknown fields this time, i.e. all the custom options should be
     145             :     // parsed as extensions now.
     146             :     extensions->clear();
     147           0 :     GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions))
     148           0 :         << "Find unknown fields in FileDescriptorProto when building "
     149           0 :         << file_proto.name()
     150             :         << ". It's likely that those fields are custom options, however, "
     151             :            "those options cannot be recognized in the builder pool. "
     152           0 :            "This normally should not happen. Please report a bug.";
     153             :   }
     154           0 : }
     155             : 
     156             : // Compare two field descriptors, returning true if the first should come
     157             : // before the second.
     158             : bool CompareFieldsByName(const FieldDescriptor *a, const FieldDescriptor *b) {
     159             :   return a->full_name() < b->full_name();
     160             : }
     161             : 
     162             : // Our static initialization methods can become very, very large.
     163             : // So large that if we aren't careful we end up blowing the JVM's
     164             : // 64K bytes of bytecode/method. Fortunately, since these static
     165             : // methods are executed only once near the beginning of a program,
     166             : // there's usually plenty of stack space available and we can
     167             : // extend our methods by simply chaining them to another method
     168             : // with a tail call. This inserts the sequence call-next-method,
     169             : // end this one, begin-next-method as needed.
     170           0 : void MaybeRestartJavaMethod(io::Printer* printer,
     171             :                             int *bytecode_estimate,
     172             :                             int *method_num,
     173             :                             const char *chain_statement,
     174             :                             const char *method_decl) {
     175             :   // The goal here is to stay under 64K bytes of jvm bytecode/method,
     176             :   // since otherwise we hit a hardcoded limit in the jvm and javac will
     177             :   // then fail with the error "code too large". This limit lets our
     178             :   // estimates be off by a factor of two and still we're okay.
     179             :   static const int bytesPerMethod = 1<<15;  // aka 32K
     180             : 
     181           0 :   if ((*bytecode_estimate) > bytesPerMethod) {
     182           0 :     ++(*method_num);
     183           0 :     printer->Print(chain_statement, "method_num", SimpleItoa(*method_num));
     184           0 :     printer->Outdent();
     185           0 :     printer->Print("}\n");
     186           0 :     printer->Print(method_decl, "method_num", SimpleItoa(*method_num));
     187           0 :     printer->Indent();
     188           0 :     *bytecode_estimate = 0;
     189             :   }
     190           0 : }
     191             : 
     192             : 
     193             : }  // namespace
     194             : 
     195           0 : FileGenerator::FileGenerator(const FileDescriptor* file, bool immutable_api)
     196             :     : file_(file),
     197             :       java_package_(FileJavaPackage(file, immutable_api)),
     198             :       message_generators_(
     199           0 :           new google::protobuf::scoped_ptr<MessageGenerator>[file->message_type_count()]),
     200             :       extension_generators_(
     201           0 :           new google::protobuf::scoped_ptr<ExtensionGenerator>[file->extension_count()]),
     202           0 :       context_(new Context(file)),
     203           0 :       name_resolver_(context_->GetNameResolver()),
     204           0 :       immutable_api_(immutable_api) {
     205           0 :   classname_ = name_resolver_->GetFileClassName(file, immutable_api);
     206             :   generator_factory_.reset(
     207           0 :       new ImmutableGeneratorFactory(context_.get()));
     208           0 :   for (int i = 0; i < file_->message_type_count(); ++i) {
     209           0 :     message_generators_[i].reset(
     210           0 :         generator_factory_->NewMessageGenerator(file_->message_type(i)));
     211             :   }
     212           0 :   for (int i = 0; i < file_->extension_count(); ++i) {
     213           0 :     extension_generators_[i].reset(
     214           0 :         generator_factory_->NewExtensionGenerator(file_->extension(i)));
     215             :   }
     216           0 : }
     217             : 
     218           0 : FileGenerator::~FileGenerator() {}
     219             : 
     220           0 : bool FileGenerator::Validate(string* error) {
     221             :   // Check that no class name matches the file's class name.  This is a common
     222             :   // problem that leads to Java compile errors that can be hard to understand.
     223             :   // It's especially bad when using the java_multiple_files, since we would
     224             :   // end up overwriting the outer class with one of the inner ones.
     225           0 :   if (name_resolver_->HasConflictingClassName(file_, classname_)) {
     226           0 :     error->assign(file_->name());
     227             :     error->append(
     228           0 :       ": Cannot generate Java output because the file's outer class name, \"");
     229           0 :     error->append(classname_);
     230             :     error->append(
     231             :       "\", matches the name of one of the types declared inside it.  "
     232             :       "Please either rename the type or use the java_outer_classname "
     233           0 :       "option to specify a different outer class name for the .proto file.");
     234           0 :     return false;
     235             :   }
     236             :   return true;
     237             : }
     238             : 
     239           0 : void FileGenerator::Generate(io::Printer* printer) {
     240             :   // We don't import anything because we refer to all classes by their
     241             :   // fully-qualified names in the generated source.
     242             :   printer->Print(
     243             :     "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
     244             :     "// source: $filename$\n"
     245             :     "\n",
     246           0 :     "filename", file_->name());
     247           0 :   if (!java_package_.empty()) {
     248             :     printer->Print(
     249             :       "package $package$;\n"
     250             :       "\n",
     251           0 :       "package", java_package_);
     252             :   }
     253             :   printer->Print(
     254             :     "public final class $classname$ {\n"
     255             :     "  private $classname$() {}\n",
     256           0 :     "classname", classname_);
     257           0 :   printer->Indent();
     258             : 
     259             :   // -----------------------------------------------------------------
     260             : 
     261             :   printer->Print(
     262             :     "public static void registerAllExtensions(\n"
     263             :     "    com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
     264           0 :     "lite", HasDescriptorMethods(file_) ? "" : "Lite");
     265             : 
     266           0 :   printer->Indent();
     267             : 
     268           0 :   for (int i = 0; i < file_->extension_count(); i++) {
     269           0 :     extension_generators_[i]->GenerateRegistrationCode(printer);
     270             :   }
     271             : 
     272           0 :   for (int i = 0; i < file_->message_type_count(); i++) {
     273           0 :     message_generators_[i]->GenerateExtensionRegistrationCode(printer);
     274             :   }
     275             : 
     276           0 :   printer->Outdent();
     277             :   printer->Print(
     278           0 :     "}\n");
     279             : 
     280             :   // -----------------------------------------------------------------
     281             : 
     282           0 :   if (!MultipleJavaFiles(file_, immutable_api_)) {
     283           0 :     for (int i = 0; i < file_->enum_type_count(); i++) {
     284             :       EnumGenerator(file_->enum_type(i), immutable_api_, context_.get())
     285           0 :           .Generate(printer);
     286             :     }
     287           0 :     for (int i = 0; i < file_->message_type_count(); i++) {
     288           0 :       message_generators_[i]->GenerateInterface(printer);
     289           0 :       message_generators_[i]->Generate(printer);
     290             :     }
     291           0 :     if (HasGenericServices(file_)) {
     292           0 :       for (int i = 0; i < file_->service_count(); i++) {
     293             :         google::protobuf::scoped_ptr<ServiceGenerator> generator(
     294           0 :             generator_factory_->NewServiceGenerator(file_->service(i)));
     295           0 :         generator->Generate(printer);
     296             :       }
     297             :     }
     298             :   }
     299             : 
     300             :   // Extensions must be generated in the outer class since they are values,
     301             :   // not classes.
     302           0 :   for (int i = 0; i < file_->extension_count(); i++) {
     303           0 :     extension_generators_[i]->Generate(printer);
     304             :   }
     305             : 
     306             :   // Static variables.
     307           0 :   for (int i = 0; i < file_->message_type_count(); i++) {
     308           0 :     message_generators_[i]->GenerateStaticVariables(printer);
     309             :   }
     310             : 
     311           0 :   printer->Print("\n");
     312             : 
     313           0 :   if (HasDescriptorMethods(file_)) {
     314           0 :     if (immutable_api_) {
     315           0 :       GenerateDescriptorInitializationCodeForImmutable(printer);
     316             :     } else {
     317           0 :       GenerateDescriptorInitializationCodeForMutable(printer);
     318             :     }
     319             :   } else {
     320             :     printer->Print(
     321           0 :       "static {\n");
     322           0 :     printer->Indent();
     323           0 :     int bytecode_estimate = 0;
     324           0 :     int method_num = 0;
     325             : 
     326           0 :     for (int i = 0; i < file_->message_type_count(); i++) {
     327           0 :       bytecode_estimate += message_generators_[i]->GenerateStaticVariableInitializers(printer);
     328             :       MaybeRestartJavaMethod(
     329             :         printer,
     330             :         &bytecode_estimate, &method_num,
     331             :         "_clinit_autosplit_$method_num$();\n",
     332           0 :         "private static void _clinit_autosplit_$method_num$() {\n");
     333             :     }
     334             : 
     335           0 :     printer->Outdent();
     336             :     printer->Print(
     337           0 :       "}\n");
     338             :   }
     339             : 
     340             :   printer->Print(
     341             :     "\n"
     342           0 :     "// @@protoc_insertion_point(outer_class_scope)\n");
     343             : 
     344           0 :   printer->Outdent();
     345           0 :   printer->Print("}\n");
     346           0 : }
     347             : 
     348           0 : void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
     349             :     io::Printer* printer) {
     350             :   printer->Print(
     351             :     "public static com.google.protobuf.Descriptors.FileDescriptor\n"
     352             :     "    getDescriptor() {\n"
     353             :     "  return descriptor;\n"
     354             :     "}\n"
     355             :     "private static com.google.protobuf.Descriptors.FileDescriptor\n"
     356             :     "    descriptor;\n"
     357           0 :     "static {\n");
     358           0 :   printer->Indent();
     359             : 
     360           0 :   SharedCodeGenerator shared_code_generator(file_);
     361           0 :   shared_code_generator.GenerateDescriptors(printer);
     362             : 
     363           0 :   int bytecode_estimate = 0;
     364           0 :   int method_num = 0;
     365             : 
     366           0 :   for (int i = 0; i < file_->message_type_count(); i++) {
     367           0 :     bytecode_estimate += message_generators_[i]->GenerateStaticVariableInitializers(printer);
     368             :     MaybeRestartJavaMethod(
     369             :       printer,
     370             :       &bytecode_estimate, &method_num,
     371             :       "_clinit_autosplit_dinit_$method_num$();\n",
     372           0 :       "private static void _clinit_autosplit_dinit_$method_num$() {\n");
     373             :   }
     374           0 :   for (int i = 0; i < file_->extension_count(); i++) {
     375           0 :     bytecode_estimate += extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
     376             :     MaybeRestartJavaMethod(
     377             :       printer,
     378             :       &bytecode_estimate, &method_num,
     379             :       "_clinit_autosplit_dinit_$method_num$();\n",
     380           0 :       "private static void _clinit_autosplit_dinit_$method_num$() {\n");
     381             :   }
     382             : 
     383             :   // Proto compiler builds a DescriptorPool, which holds all the descriptors to
     384             :   // generate, when processing the ".proto" files. We call this DescriptorPool
     385             :   // the parsed pool (a.k.a. file_->pool()).
     386             :   //
     387             :   // Note that when users try to extend the (.*)DescriptorProto in their
     388             :   // ".proto" files, it does not affect the pre-built FileDescriptorProto class
     389             :   // in proto compiler. When we put the descriptor data in the file_proto, those
     390             :   // extensions become unknown fields.
     391             :   //
     392             :   // Now we need to find out all the extension value to the (.*)DescriptorProto
     393             :   // in the file_proto message, and prepare an ExtensionRegistry to return.
     394             :   //
     395             :   // To find those extensions, we need to parse the data into a dynamic message
     396             :   // of the FileDescriptor based on the builder-pool, then we can use
     397             :   // reflections to find all extension fields
     398           0 :   FileDescriptorProto file_proto;
     399           0 :   file_->CopyTo(&file_proto);
     400             :   string file_data;
     401           0 :   file_proto.SerializeToString(&file_data);
     402             :   FieldDescriptorSet extensions;
     403           0 :   CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
     404             : 
     405           0 :   if (extensions.size() > 0) {
     406             :     // Must construct an ExtensionRegistry containing all existing extensions
     407             :     // and use it to parse the descriptor data again to recognize extensions.
     408             :     printer->Print(
     409             :       "com.google.protobuf.ExtensionRegistry registry =\n"
     410           0 :       "    com.google.protobuf.ExtensionRegistry.newInstance();\n");
     411             :     FieldDescriptorSet::iterator it;
     412           0 :     for (it = extensions.begin(); it != extensions.end(); it++) {
     413             :       google::protobuf::scoped_ptr<ExtensionGenerator> generator(
     414           0 :           generator_factory_->NewExtensionGenerator(*it));
     415           0 :       bytecode_estimate += generator->GenerateRegistrationCode(printer);
     416             :       MaybeRestartJavaMethod(
     417             :         printer,
     418             :         &bytecode_estimate, &method_num,
     419             :         "_clinit_autosplit_dinit_$method_num$(registry);\n",
     420             :         "private static void _clinit_autosplit_dinit_$method_num$(\n"
     421           0 :         "    com.google.protobuf.ExtensionRegistry registry) {\n");
     422             :     }
     423             :     printer->Print(
     424             :       "com.google.protobuf.Descriptors.FileDescriptor\n"
     425           0 :       "    .internalUpdateFileDescriptor(descriptor, registry);\n");
     426             :   }
     427             : 
     428             :   // Force descriptor initialization of all dependencies.
     429           0 :   for (int i = 0; i < file_->dependency_count(); i++) {
     430           0 :     if (ShouldIncludeDependency(file_->dependency(i), true)) {
     431             :       string dependency =
     432           0 :           name_resolver_->GetImmutableClassName(file_->dependency(i));
     433             :       printer->Print(
     434             :         "$dependency$.getDescriptor();\n",
     435           0 :         "dependency", dependency);
     436             :     }
     437             :   }
     438             : 
     439           0 :   printer->Outdent();
     440             :   printer->Print(
     441           0 :     "}\n");
     442           0 : }
     443             : 
     444           0 : void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* printer) {
     445             :   printer->Print(
     446             :     "public static com.google.protobuf.Descriptors.FileDescriptor\n"
     447             :     "    getDescriptor() {\n"
     448             :     "  return descriptor;\n"
     449             :     "}\n"
     450             :     "private static com.google.protobuf.Descriptors.FileDescriptor\n"
     451             :     "    descriptor;\n"
     452           0 :     "static {\n");
     453           0 :   printer->Indent();
     454             : 
     455             :   printer->Print(
     456             :     "descriptor = $immutable_package$.$descriptor_classname$.descriptor;\n",
     457             :     "immutable_package", FileJavaPackage(file_, true),
     458           0 :     "descriptor_classname", name_resolver_->GetDescriptorClassName(file_));
     459             : 
     460           0 :   for (int i = 0; i < file_->message_type_count(); i++) {
     461           0 :     message_generators_[i]->GenerateStaticVariableInitializers(printer);
     462             :   }
     463           0 :   for (int i = 0; i < file_->extension_count(); i++) {
     464           0 :     extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
     465             :   }
     466             : 
     467             :   // Check if custom options exist. If any, try to load immutable classes since
     468             :   // custom options are only represented with immutable messages.
     469           0 :   FileDescriptorProto file_proto;
     470           0 :   file_->CopyTo(&file_proto);
     471             :   string file_data;
     472           0 :   file_proto.SerializeToString(&file_data);
     473             :   FieldDescriptorSet extensions;
     474           0 :   CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
     475             : 
     476           0 :   if (extensions.size() > 0) {
     477             :     // Try to load immutable messages' outer class. Its initialization code
     478             :     // will take care of interpreting custom options.
     479             :     printer->Print(
     480             :       "try {\n"
     481             :       // Note that we have to load the immutable class dynamically here as
     482             :       // we want the mutable code to be independent from the immutable code
     483             :       // at compile time. It is required to implement dual-compile for
     484             :       // mutable and immutable API in blaze.
     485             :       "  java.lang.Class immutableClass = java.lang.Class.forName(\n"
     486             :       "      \"$immutable_classname$\");\n"
     487             :       "} catch (java.lang.ClassNotFoundException e) {\n"
     488             :       // The immutable class can not be found. Custom options are left
     489             :       // as unknown fields.
     490             :       // TODO(xiaofeng): inform the user with a warning?
     491             :       "}\n",
     492           0 :       "immutable_classname", name_resolver_->GetImmutableClassName(file_));
     493             :   }
     494             : 
     495             :   // Force descriptor initialization of all dependencies.
     496           0 :   for (int i = 0; i < file_->dependency_count(); i++) {
     497           0 :     if (ShouldIncludeDependency(file_->dependency(i), false)) {
     498             :       string dependency = name_resolver_->GetMutableClassName(
     499           0 :           file_->dependency(i));
     500             :       printer->Print(
     501             :         "$dependency$.getDescriptor();\n",
     502           0 :         "dependency", dependency);
     503             :     }
     504             :   }
     505             : 
     506           0 :   printer->Outdent();
     507             :   printer->Print(
     508           0 :     "}\n");
     509           0 : }
     510             : 
     511             : template<typename GeneratorClass, typename DescriptorClass>
     512           0 : static void GenerateSibling(const string& package_dir,
     513             :                             const string& java_package,
     514           0 :                             const DescriptorClass* descriptor,
     515             :                             GeneratorContext* context,
     516             :                             vector<string>* file_list,
     517             :                             const string& name_suffix,
     518             :                             GeneratorClass* generator,
     519             :                             void (GeneratorClass::*pfn)(io::Printer* printer)) {
     520           0 :   string filename = package_dir + descriptor->name() + name_suffix + ".java";
     521           0 :   file_list->push_back(filename);
     522             : 
     523           0 :   google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
     524           0 :   io::Printer printer(output.get(), '$');
     525             : 
     526           0 :   printer.Print(
     527             :     "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
     528             :     "// source: $filename$\n"
     529             :     "\n",
     530             :     "filename", descriptor->file()->name());
     531           0 :   if (!java_package.empty()) {
     532           0 :     printer.Print(
     533             :       "package $package$;\n"
     534             :       "\n",
     535             :       "package", java_package);
     536             :   }
     537             : 
     538           0 :   (generator->*pfn)(&printer);
     539           0 : }
     540             : 
     541           0 : void FileGenerator::GenerateSiblings(const string& package_dir,
     542             :                                      GeneratorContext* context,
     543             :                                      vector<string>* file_list) {
     544           0 :   if (MultipleJavaFiles(file_, immutable_api_)) {
     545           0 :     for (int i = 0; i < file_->enum_type_count(); i++) {
     546             :       EnumGenerator generator(file_->enum_type(i), immutable_api_,
     547           0 :                               context_.get());
     548             :       GenerateSibling<EnumGenerator>(package_dir, java_package_,
     549             :                                      file_->enum_type(i),
     550             :                                      context, file_list, "",
     551             :                                      &generator,
     552           0 :                                      &EnumGenerator::Generate);
     553           0 :     }
     554           0 :     for (int i = 0; i < file_->message_type_count(); i++) {
     555           0 :       if (immutable_api_) {
     556             :         GenerateSibling<MessageGenerator>(package_dir, java_package_,
     557             :                                           file_->message_type(i),
     558             :                                           context, file_list,
     559             :                                           "OrBuilder",
     560           0 :                                           message_generators_[i].get(),
     561           0 :                                           &MessageGenerator::GenerateInterface);
     562             :       }
     563             :       GenerateSibling<MessageGenerator>(package_dir, java_package_,
     564             :                                         file_->message_type(i),
     565             :                                         context, file_list, "",
     566           0 :                                         message_generators_[i].get(),
     567           0 :                                         &MessageGenerator::Generate);
     568             :     }
     569           0 :     if (HasGenericServices(file_)) {
     570           0 :       for (int i = 0; i < file_->service_count(); i++) {
     571             :         google::protobuf::scoped_ptr<ServiceGenerator> generator(
     572           0 :             generator_factory_->NewServiceGenerator(file_->service(i)));
     573             :         GenerateSibling<ServiceGenerator>(package_dir, java_package_,
     574             :                                           file_->service(i),
     575             :                                           context, file_list, "",
     576             :                                           generator.get(),
     577           0 :                                           &ServiceGenerator::Generate);
     578             :       }
     579             :     }
     580             :   }
     581           0 : }
     582             : 
     583           0 : bool FileGenerator::ShouldIncludeDependency(
     584             :     const FileDescriptor* descriptor, bool immutable_api) {
     585           0 :   return true;
     586             : }
     587             : 
     588             : }  // namespace java
     589             : }  // namespace compiler
     590             : }  // namespace protobuf
     591             : }  // namespace google

Generated by: LCOV version 1.10