LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/cpp - cpp_extension.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 73 74 98.6 %
Date: 2015-10-10 Functions: 5 5 100.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/cpp/cpp_extension.h>
      36             : #include <map>
      37             : #include <google/protobuf/compiler/cpp/cpp_helpers.h>
      38             : #include <google/protobuf/stubs/strutil.h>
      39             : #include <google/protobuf/io/printer.h>
      40             : #include <google/protobuf/descriptor.pb.h>
      41             : 
      42             : namespace google {
      43             : namespace protobuf {
      44             : namespace compiler {
      45             : namespace cpp {
      46             : 
      47             : namespace {
      48             : 
      49             : // Returns the fully-qualified class name of the message that this field
      50             : // extends. This function is used in the Google-internal code to handle some
      51             : // legacy cases.
      52         765 : string ExtendeeClassName(const FieldDescriptor* descriptor) {
      53         765 :   const Descriptor* extendee = descriptor->containing_type();
      54         765 :   return ClassName(extendee, true);
      55             : }
      56             : 
      57             : }  // anonymous namespace
      58             : 
      59         255 : ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
      60             :                                        const Options& options)
      61             :   : descriptor_(descriptor),
      62         510 :     options_(options) {
      63             :   // Construct type_traits_.
      64        1010 :   if (descriptor_->is_repeated()) {
      65          97 :     type_traits_ = "Repeated";
      66             :   }
      67             : 
      68         765 :   switch (descriptor_->cpp_type()) {
      69             :     case FieldDescriptor::CPPTYPE_ENUM:
      70          23 :       type_traits_.append("EnumTypeTraits< ");
      71          69 :       type_traits_.append(ClassName(descriptor_->enum_type(), true));
      72          23 :       type_traits_.append(", ");
      73          69 :       type_traits_.append(ClassName(descriptor_->enum_type(), true));
      74          23 :       type_traits_.append("_IsValid>");
      75             :       break;
      76             :     case FieldDescriptor::CPPTYPE_STRING:
      77          33 :       type_traits_.append("StringTypeTraits");
      78             :       break;
      79             :     case FieldDescriptor::CPPTYPE_MESSAGE:
      80          52 :       type_traits_.append("MessageTypeTraits< ");
      81         156 :       type_traits_.append(ClassName(descriptor_->message_type(), true));
      82          52 :       type_traits_.append(" >");
      83             :       break;
      84             :     default:
      85         147 :       type_traits_.append("PrimitiveTypeTraits< ");
      86         441 :       type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type()));
      87         147 :       type_traits_.append(" >");
      88             :       break;
      89             :   }
      90         255 : }
      91             : 
      92         765 : ExtensionGenerator::~ExtensionGenerator() {}
      93             : 
      94         255 : void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
      95             :   map<string, string> vars;
      96        2295 :   vars["extendee"     ] = ExtendeeClassName(descriptor_);
      97        1020 :   vars["number"       ] = SimpleItoa(descriptor_->number());
      98         510 :   vars["type_traits"  ] = type_traits_;
      99         765 :   vars["name"         ] = descriptor_->name();
     100        1020 :   vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
     101         765 :   vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
     102         765 :   vars["constant_name"] = FieldConstantName(descriptor_);
     103             : 
     104             :   // If this is a class member, it needs to be declared "static".  Otherwise,
     105             :   // it needs to be "extern".  In the latter case, it also needs the DLL
     106             :   // export/import specifier.
     107         510 :   if (descriptor_->extension_scope() == NULL) {
     108         472 :     vars["qualifier"] = "extern";
     109         472 :     if (!options_.dllexport_decl.empty()) {
     110           0 :       vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"];
     111             :     }
     112             :   } else {
     113          38 :     vars["qualifier"] = "static";
     114             :   }
     115             : 
     116             :   printer->Print(vars,
     117             :     "static const int $constant_name$ = $number$;\n"
     118             :     "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
     119             :     "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
     120             :     "  $name$;\n"
     121         255 :     );
     122             : 
     123         255 : }
     124             : 
     125         255 : void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
     126             :   // If this is a class member, it needs to be declared in its class scope.
     127        1530 :   string scope = (descriptor_->extension_scope() == NULL) ? "" :
     128         274 :     ClassName(descriptor_->extension_scope(), false) + "::";
     129         510 :   string name = scope + descriptor_->name();
     130             : 
     131             :   map<string, string> vars;
     132        1020 :   vars["extendee"     ] = ExtendeeClassName(descriptor_);
     133         510 :   vars["type_traits"  ] = type_traits_;
     134         510 :   vars["name"         ] = name;
     135         765 :   vars["constant_name"] = FieldConstantName(descriptor_);
     136         765 :   vars["default"      ] = DefaultValue(descriptor_);
     137        1020 :   vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
     138         765 :   vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
     139         510 :   vars["scope"        ] = scope;
     140             : 
     141         765 :   if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
     142             :     // We need to declare a global string which will contain the default value.
     143             :     // We cannot declare it at class scope because that would require exposing
     144             :     // it in the header which would be annoying for other reasons.  So we
     145             :     // replace :: with _ in the name and declare it as a global.
     146          99 :     string global_name = StringReplace(name, "::", "_", true);
     147          66 :     vars["global_name"] = global_name;
     148             :     printer->Print(vars,
     149          33 :       "const ::std::string $global_name$_default($default$);\n");
     150             : 
     151             :     // Update the default to refer to the string global.
     152          99 :     vars["default"] = global_name + "_default";
     153             :   }
     154             : 
     155             :   // Likewise, class members need to declare the field constant variable.
     156         510 :   if (descriptor_->extension_scope() != NULL) {
     157             :     printer->Print(vars,
     158             :       "#ifndef _MSC_VER\n"
     159             :       "const int $scope$$constant_name$;\n"
     160          19 :       "#endif\n");
     161             :   }
     162             : 
     163             :   printer->Print(vars,
     164             :     "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
     165             :     "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
     166         255 :     "  $name$($constant_name$, $default$);\n");
     167         255 : }
     168             : 
     169         255 : void ExtensionGenerator::GenerateRegistration(io::Printer* printer) {
     170             :   map<string, string> vars;
     171        1957 :   vars["extendee"   ] = ExtendeeClassName(descriptor_);
     172        1020 :   vars["number"     ] = SimpleItoa(descriptor_->number());
     173        1020 :   vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
     174         765 :   vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false";
     175         862 :   vars["is_packed"  ] = (descriptor_->is_repeated() &&
     176          97 :                          descriptor_->options().packed())
     177             :                         ? "true" : "false";
     178             : 
     179         765 :   switch (descriptor_->cpp_type()) {
     180             :     case FieldDescriptor::CPPTYPE_ENUM:
     181             :       printer->Print(vars,
     182             :         "::google::protobuf::internal::ExtensionSet::RegisterEnumExtension(\n"
     183             :         "  &$extendee$::default_instance(),\n"
     184          23 :         "  $number$, $field_type$, $is_repeated$, $is_packed$,\n");
     185             :       printer->Print(
     186             :         "  &$type$_IsValid);\n",
     187          69 :         "type", ClassName(descriptor_->enum_type(), true));
     188          23 :       break;
     189             :     case FieldDescriptor::CPPTYPE_MESSAGE:
     190             :       printer->Print(vars,
     191             :         "::google::protobuf::internal::ExtensionSet::RegisterMessageExtension(\n"
     192             :         "  &$extendee$::default_instance(),\n"
     193          52 :         "  $number$, $field_type$, $is_repeated$, $is_packed$,\n");
     194             :       printer->Print(
     195             :         "  &$type$::default_instance());\n",
     196         156 :         "type", ClassName(descriptor_->message_type(), true));
     197          52 :       break;
     198             :     default:
     199             :       printer->Print(vars,
     200             :         "::google::protobuf::internal::ExtensionSet::RegisterExtension(\n"
     201             :         "  &$extendee$::default_instance(),\n"
     202         180 :         "  $number$, $field_type$, $is_repeated$, $is_packed$);\n");
     203             :       break;
     204             :   }
     205         255 : }
     206             : 
     207             : }  // namespace cpp
     208             : }  // namespace compiler
     209             : }  // namespace protobuf
     210             : }  // namespace google

Generated by: LCOV version 1.10