LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/javanano - javanano_file.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 1 84 1.2 %
Date: 2015-10-10 Functions: 2 10 20.0 %

          Line data    Source code
       1             : // Protocol Buffers - Google's data interchange format
       2             : // Copyright 2008 Google Inc.  All rights reserved.
       3             : // http://code.google.com/p/protobuf/
       4             : //
       5             : // Redistribution and use in source and binary forms, with or without
       6             : // modification, are permitted provided that the following conditions are
       7             : // met:
       8             : //
       9             : //     * Redistributions of source code must retain the above copyright
      10             : // notice, this list of conditions and the following disclaimer.
      11             : //     * Redistributions in binary form must reproduce the above
      12             : // copyright notice, this list of conditions and the following disclaimer
      13             : // in the documentation and/or other materials provided with the
      14             : // distribution.
      15             : //     * Neither the name of Google Inc. nor the names of its
      16             : // contributors may be used to endorse or promote products derived from
      17             : // this software without specific prior written permission.
      18             : //
      19             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      20             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      21             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      22             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      23             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      24             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      25             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      26             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      27             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      28             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      29             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      30             : 
      31             : // Author: kenton@google.com (Kenton Varda)
      32             : //  Based on original Protocol Buffers design by
      33             : //  Sanjay Ghemawat, Jeff Dean, and others.
      34             : 
      35             : #include <iostream>
      36             : 
      37             : #include <google/protobuf/compiler/javanano/javanano_file.h>
      38             : #include <google/protobuf/compiler/javanano/javanano_enum.h>
      39             : #include <google/protobuf/compiler/javanano/javanano_extension.h>
      40             : #include <google/protobuf/compiler/javanano/javanano_helpers.h>
      41             : #include <google/protobuf/compiler/javanano/javanano_message.h>
      42             : #include <google/protobuf/compiler/code_generator.h>
      43             : #include <google/protobuf/io/printer.h>
      44             : #include <google/protobuf/io/zero_copy_stream.h>
      45             : #include <google/protobuf/descriptor.pb.h>
      46             : #include <google/protobuf/stubs/strutil.h>
      47             : 
      48             : namespace google {
      49             : namespace protobuf {
      50             : namespace compiler {
      51             : namespace javanano {
      52             : 
      53             : namespace {
      54             : 
      55             : // Recursively searches the given message to see if it contains any extensions.
      56           0 : bool UsesExtensions(const Message& message) {
      57           0 :   const Reflection* reflection = message.GetReflection();
      58             : 
      59             :   // We conservatively assume that unknown fields are extensions.
      60           0 :   if (reflection->GetUnknownFields(message).field_count() > 0) return true;
      61             : 
      62             :   vector<const FieldDescriptor*> fields;
      63           0 :   reflection->ListFields(message, &fields);
      64             : 
      65           0 :   for (int i = 0; i < fields.size(); i++) {
      66           0 :     if (fields[i]->is_extension()) return true;
      67             : 
      68           0 :     if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      69           0 :       if (fields[i]->is_repeated()) {
      70           0 :         int size = reflection->FieldSize(message, fields[i]);
      71           0 :         for (int j = 0; j < size; j++) {
      72             :           const Message& sub_message =
      73           0 :             reflection->GetRepeatedMessage(message, fields[i], j);
      74           0 :           if (UsesExtensions(sub_message)) return true;
      75             :         }
      76             :       } else {
      77           0 :         const Message& sub_message = reflection->GetMessage(message, fields[i]);
      78           0 :         if (UsesExtensions(sub_message)) return true;
      79             :       }
      80             :     }
      81             :   }
      82             : 
      83             :   return false;
      84             : }
      85             : 
      86             : }  // namespace
      87             : 
      88           0 : FileGenerator::FileGenerator(const FileDescriptor* file, const Params& params)
      89             :   : file_(file),
      90             :     params_(params),
      91             :     java_package_(FileJavaPackage(params, file)),
      92           0 :     classname_(FileClassName(params, file)) {}
      93             : 
      94           0 : FileGenerator::~FileGenerator() {}
      95             : 
      96           0 : bool FileGenerator::Validate(string* error) {
      97             :   // Check for extensions
      98           0 :   FileDescriptorProto file_proto;
      99           0 :   file_->CopyTo(&file_proto);
     100           0 :   if (UsesExtensions(file_proto) && !params_.store_unknown_fields()) {
     101           0 :     error->assign(file_->name());
     102             :     error->append(
     103             :         ": Java NANO_RUNTIME only supports extensions when the "
     104           0 :         "'store_unknown_fields' generator option is 'true'.");
     105             :     return false;
     106             :   }
     107             : 
     108           0 :   if (file_->service_count() != 0 && !params_.ignore_services()) {
     109           0 :     error->assign(file_->name());
     110             :     error->append(
     111           0 :       ": Java NANO_RUNTIME does not support services\"");
     112             :     return false;
     113             :   }
     114             : 
     115           0 :   if (!IsOuterClassNeeded(params_, file_)) {
     116             :     return true;
     117             :   }
     118             : 
     119             :   // Check whether legacy javanano generator would omit the outer class.
     120           0 :   if (!params_.has_java_outer_classname(file_->name())
     121           0 :       && file_->message_type_count() == 1
     122           0 :       && file_->enum_type_count() == 0 && file_->extension_count() == 0) {
     123           0 :     cout << "INFO: " << file_->name() << ":" << endl;
     124             :     cout << "Javanano generator has changed to align with java generator. "
     125             :         "An outer class will be created for this file and the single message "
     126             :         "in the file will become a nested class. Use java_multiple_files to "
     127             :         "skip generating the outer class, or set an explicit "
     128           0 :         "java_outer_classname to suppress this message." << endl;
     129             :   }
     130             : 
     131             :   // Check that no class name matches the file's class name.  This is a common
     132             :   // problem that leads to Java compile errors that can be hard to understand.
     133             :   // It's especially bad when using the java_multiple_files, since we would
     134             :   // end up overwriting the outer class with one of the inner ones.
     135           0 :   bool found_conflict = false;
     136           0 :   for (int i = 0; !found_conflict && i < file_->message_type_count(); i++) {
     137           0 :     if (file_->message_type(i)->name() == classname_) {
     138           0 :       found_conflict = true;
     139             :     }
     140             :   }
     141           0 :   if (params_.java_enum_style()) {
     142           0 :     for (int i = 0; !found_conflict && i < file_->enum_type_count(); i++) {
     143           0 :       if (file_->enum_type(i)->name() == classname_) {
     144           0 :         found_conflict = true;
     145             :       }
     146             :     }
     147             :   }
     148           0 :   if (found_conflict) {
     149           0 :     error->assign(file_->name());
     150             :     error->append(
     151           0 :       ": Cannot generate Java output because the file's outer class name, \"");
     152           0 :     error->append(classname_);
     153             :     error->append(
     154             :       "\", matches the name of one of the types declared inside it.  "
     155             :       "Please either rename the type or use the java_outer_classname "
     156           0 :       "option to specify a different outer class name for the .proto file.");
     157             :     return false;
     158             :   }
     159           0 :   return true;
     160             : }
     161             : 
     162           0 : void FileGenerator::Generate(io::Printer* printer) {
     163             :   // We don't import anything because we refer to all classes by their
     164             :   // fully-qualified names in the generated source.
     165             :   printer->Print(
     166           0 :     "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
     167           0 :   if (!java_package_.empty()) {
     168             :     printer->Print(
     169             :       "\n"
     170             :       "package $package$;\n",
     171           0 :       "package", java_package_);
     172             :   }
     173             : 
     174             :   // Note: constants (from enums, emitted in the loop below) may have the same names as constants
     175             :   // in the nested classes. This causes Java warnings, but is not fatal, so we suppress those
     176             :   // warnings here in the top-most class declaration.
     177             :   printer->Print(
     178             :     "\n"
     179             :     "@SuppressWarnings(\"hiding\")\n"
     180             :     "public interface $classname$ {\n",
     181           0 :     "classname", classname_);
     182           0 :   printer->Indent();
     183             : 
     184             :   // -----------------------------------------------------------------
     185             : 
     186             :   // Extensions.
     187           0 :   for (int i = 0; i < file_->extension_count(); i++) {
     188           0 :     ExtensionGenerator(file_->extension(i), params_).Generate(printer);
     189             :   }
     190             : 
     191             :   // Enums.
     192           0 :   for (int i = 0; i < file_->enum_type_count(); i++) {
     193           0 :     EnumGenerator(file_->enum_type(i), params_).Generate(printer);
     194             :   }
     195             : 
     196             :   // Messages.
     197           0 :   if (!params_.java_multiple_files(file_->name())) {
     198           0 :     for (int i = 0; i < file_->message_type_count(); i++) {
     199           0 :       MessageGenerator(file_->message_type(i), params_).Generate(printer);
     200             :     }
     201             :   }
     202             : 
     203             :   // Static variables.
     204           0 :   for (int i = 0; i < file_->message_type_count(); i++) {
     205             :     // TODO(kenton):  Reuse MessageGenerator objects?
     206           0 :     MessageGenerator(file_->message_type(i), params_).GenerateStaticVariables(printer);
     207             :   }
     208             : 
     209           0 :   printer->Outdent();
     210             :   printer->Print(
     211           0 :     "}\n");
     212           0 : }
     213             : 
     214             : template<typename GeneratorClass, typename DescriptorClass>
     215           0 : static void GenerateSibling(const string& package_dir,
     216             :                             const string& java_package,
     217           0 :                             const DescriptorClass* descriptor,
     218             :                             GeneratorContext* output_directory,
     219             :                             vector<string>* file_list,
     220             :                             const Params& params) {
     221           0 :   string filename = package_dir + descriptor->name() + ".java";
     222           0 :   file_list->push_back(filename);
     223             : 
     224             :   scoped_ptr<io::ZeroCopyOutputStream> output(
     225           0 :     output_directory->Open(filename));
     226           0 :   io::Printer printer(output.get(), '$');
     227             : 
     228           0 :   printer.Print(
     229             :     "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
     230           0 :   if (!java_package.empty()) {
     231           0 :     printer.Print(
     232             :       "\n"
     233             :       "package $package$;\n",
     234             :       "package", java_package);
     235             :   }
     236             : 
     237           0 :   GeneratorClass(descriptor, params).Generate(&printer);
     238           0 : }
     239             : 
     240           0 : void FileGenerator::GenerateSiblings(const string& package_dir,
     241             :                                      GeneratorContext* output_directory,
     242             :                                      vector<string>* file_list) {
     243           0 :   if (params_.java_multiple_files(file_->name())) {
     244           0 :     for (int i = 0; i < file_->message_type_count(); i++) {
     245             :       GenerateSibling<MessageGenerator>(package_dir, java_package_,
     246             :                                         file_->message_type(i),
     247           0 :                                         output_directory, file_list, params_);
     248             :     }
     249             : 
     250           0 :     if (params_.java_enum_style()) {
     251           0 :       for (int i = 0; i < file_->enum_type_count(); i++) {
     252             :         GenerateSibling<EnumGenerator>(package_dir, java_package_,
     253             :                                        file_->enum_type(i),
     254           0 :                                        output_directory, file_list, params_);
     255             :       }
     256             :     }
     257             :   }
     258           0 : }
     259             : 
     260             : }  // namespace javanano
     261             : }  // namespace compiler
     262             : }  // namespace protobuf
     263          51 : }  // namespace google

Generated by: LCOV version 1.10