LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/javanano - javanano_primitive_field.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 354 0.0 %
Date: 2015-10-10 Functions: 0 53 0.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 <map>
      36             : #include <math.h>
      37             : #include <string>
      38             : 
      39             : #include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
      40             : #include <google/protobuf/stubs/common.h>
      41             : #include <google/protobuf/compiler/javanano/javanano_helpers.h>
      42             : #include <google/protobuf/io/printer.h>
      43             : #include <google/protobuf/wire_format.h>
      44             : #include <google/protobuf/stubs/strutil.h>
      45             : #include <google/protobuf/stubs/substitute.h>
      46             : 
      47             : namespace google {
      48             : namespace protobuf {
      49             : namespace compiler {
      50             : namespace javanano {
      51             : 
      52             : using internal::WireFormat;
      53             : using internal::WireFormatLite;
      54             : 
      55             : namespace {
      56             : 
      57           0 : bool IsReferenceType(JavaType type) {
      58           0 :   switch (type) {
      59             :     case JAVATYPE_INT    : return false;
      60             :     case JAVATYPE_LONG   : return false;
      61             :     case JAVATYPE_FLOAT  : return false;
      62             :     case JAVATYPE_DOUBLE : return false;
      63             :     case JAVATYPE_BOOLEAN: return false;
      64           0 :     case JAVATYPE_STRING : return true;
      65           0 :     case JAVATYPE_BYTES  : return true;
      66             :     case JAVATYPE_ENUM   : return false;
      67           0 :     case JAVATYPE_MESSAGE: return true;
      68             : 
      69             :     // No default because we want the compiler to complain if any new
      70             :     // JavaTypes are added.
      71             :   }
      72             : 
      73           0 :   GOOGLE_LOG(FATAL) << "Can't get here.";
      74           0 :   return false;
      75             : }
      76             : 
      77           0 : bool IsArrayType(JavaType type) {
      78           0 :   switch (type) {
      79             :     case JAVATYPE_INT    : return false;
      80             :     case JAVATYPE_LONG   : return false;
      81             :     case JAVATYPE_FLOAT  : return false;
      82             :     case JAVATYPE_DOUBLE : return false;
      83             :     case JAVATYPE_BOOLEAN: return false;
      84             :     case JAVATYPE_STRING : return false;
      85             :     case JAVATYPE_BYTES  : return true;
      86             :     case JAVATYPE_ENUM   : return false;
      87             :     case JAVATYPE_MESSAGE: return false;
      88             : 
      89             :     // No default because we want the compiler to complain if any new
      90             :     // JavaTypes are added.
      91             :   }
      92             : 
      93           0 :   GOOGLE_LOG(FATAL) << "Can't get here.";
      94           0 :   return false;
      95             : }
      96             : 
      97           0 : const char* GetCapitalizedType(const FieldDescriptor* field) {
      98           0 :   switch (field->type()) {
      99             :     case FieldDescriptor::TYPE_INT32   : return "Int32"   ;
     100           0 :     case FieldDescriptor::TYPE_UINT32  : return "UInt32"  ;
     101           0 :     case FieldDescriptor::TYPE_SINT32  : return "SInt32"  ;
     102           0 :     case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
     103           0 :     case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
     104           0 :     case FieldDescriptor::TYPE_INT64   : return "Int64"   ;
     105           0 :     case FieldDescriptor::TYPE_UINT64  : return "UInt64"  ;
     106           0 :     case FieldDescriptor::TYPE_SINT64  : return "SInt64"  ;
     107           0 :     case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
     108           0 :     case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
     109           0 :     case FieldDescriptor::TYPE_FLOAT   : return "Float"   ;
     110           0 :     case FieldDescriptor::TYPE_DOUBLE  : return "Double"  ;
     111           0 :     case FieldDescriptor::TYPE_BOOL    : return "Bool"    ;
     112           0 :     case FieldDescriptor::TYPE_STRING  : return "String"  ;
     113           0 :     case FieldDescriptor::TYPE_BYTES   : return "Bytes"   ;
     114           0 :     case FieldDescriptor::TYPE_ENUM    : return "Enum"    ;
     115           0 :     case FieldDescriptor::TYPE_GROUP   : return "Group"   ;
     116           0 :     case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
     117             : 
     118             :     // No default because we want the compiler to complain if any new
     119             :     // types are added.
     120             :   }
     121             : 
     122           0 :   GOOGLE_LOG(FATAL) << "Can't get here.";
     123           0 :   return NULL;
     124             : }
     125             : 
     126             : // For encodings with fixed sizes, returns that size in bytes.  Otherwise
     127             : // returns -1.
     128           0 : int FixedSize(FieldDescriptor::Type type) {
     129           0 :   switch (type) {
     130             :     case FieldDescriptor::TYPE_INT32   : return -1;
     131             :     case FieldDescriptor::TYPE_INT64   : return -1;
     132             :     case FieldDescriptor::TYPE_UINT32  : return -1;
     133             :     case FieldDescriptor::TYPE_UINT64  : return -1;
     134             :     case FieldDescriptor::TYPE_SINT32  : return -1;
     135             :     case FieldDescriptor::TYPE_SINT64  : return -1;
     136           0 :     case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
     137           0 :     case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
     138           0 :     case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
     139           0 :     case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
     140           0 :     case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
     141           0 :     case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
     142             : 
     143           0 :     case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
     144             :     case FieldDescriptor::TYPE_ENUM    : return -1;
     145             : 
     146             :     case FieldDescriptor::TYPE_STRING  : return -1;
     147             :     case FieldDescriptor::TYPE_BYTES   : return -1;
     148             :     case FieldDescriptor::TYPE_GROUP   : return -1;
     149             :     case FieldDescriptor::TYPE_MESSAGE : return -1;
     150             : 
     151             :     // No default because we want the compiler to complain if any new
     152             :     // types are added.
     153             :   }
     154           0 :   GOOGLE_LOG(FATAL) << "Can't get here.";
     155           0 :   return -1;
     156             : }
     157             : 
     158             : bool AllAscii(const string& text) {
     159           0 :   for (int i = 0; i < text.size(); i++) {
     160           0 :     if ((text[i] & 0x80) != 0) {
     161             :       return false;
     162             :     }
     163             :   }
     164             :   return true;
     165             : }
     166             : 
     167             : 
     168           0 : void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
     169             :                            map<string, string>* variables) {
     170           0 :   (*variables)["name"] =
     171             :     RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
     172           0 :   (*variables)["capitalized_name"] =
     173             :     RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
     174           0 :   (*variables)["number"] = SimpleItoa(descriptor->number());
     175           0 :   if (params.use_reference_types_for_primitives()
     176           0 :       && !descriptor->is_repeated()) {
     177           0 :     (*variables)["type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
     178             :   } else {
     179           0 :     (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
     180             :   }
     181             :   // Deals with defaults. For C++-string types (string and bytes),
     182             :   // we might need to have the generated code do the unicode decoding
     183             :   // (see comments in InternalNano.java for gory details.). We would
     184             :   // like to do this once into a static field and re-use that from
     185             :   // then on.
     186           0 :   if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
     187           0 :       !descriptor->default_value_string().empty() &&
     188           0 :       !params.use_reference_types_for_primitives()) {
     189           0 :     if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
     190           0 :       (*variables)["default"] = DefaultValue(params, descriptor);
     191           0 :       (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
     192           0 :       (*variables)["default_constant_value"] = strings::Substitute(
     193             :           "com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
     194           0 :           CEscape(descriptor->default_value_string()));
     195           0 :       (*variables)["default_copy_if_needed"] =
     196           0 :           (*variables)["default"] + ".clone()";
     197           0 :     } else if (AllAscii(descriptor->default_value_string())) {
     198             :       // All chars are ASCII.  In this case directly referencing a
     199             :       // CEscape()'d string literal works fine.
     200           0 :       (*variables)["default"] =
     201           0 :           "\"" + CEscape(descriptor->default_value_string()) + "\"";
     202           0 :       (*variables)["default_copy_if_needed"] = (*variables)["default"];
     203             :     } else {
     204             :       // Strings where some chars are non-ASCII. We need to save the
     205             :       // default value.
     206           0 :       (*variables)["default"] = DefaultValue(params, descriptor);
     207           0 :       (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
     208           0 :       (*variables)["default_constant_value"] = strings::Substitute(
     209             :           "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
     210           0 :           CEscape(descriptor->default_value_string()));
     211           0 :       (*variables)["default_copy_if_needed"] = (*variables)["default"];
     212             :     }
     213             :   } else {
     214             :     // Non-string, non-bytes field. Defaults are literals.
     215           0 :     (*variables)["default"] = DefaultValue(params, descriptor);
     216           0 :     (*variables)["default_copy_if_needed"] = (*variables)["default"];
     217             :   }
     218           0 :   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
     219           0 :   (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
     220           0 :   (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
     221           0 :   (*variables)["tag_size"] = SimpleItoa(
     222             :       WireFormat::TagSize(descriptor->number(), descriptor->type()));
     223           0 :   (*variables)["non_packed_tag"] = SimpleItoa(
     224             :       internal::WireFormatLite::MakeTag(descriptor->number(),
     225             :           internal::WireFormat::WireTypeForFieldType(descriptor->type())));
     226           0 :   int fixed_size = FixedSize(descriptor->type());
     227           0 :   if (fixed_size != -1) {
     228           0 :     (*variables)["fixed_size"] = SimpleItoa(fixed_size);
     229             :   }
     230           0 :   (*variables)["message_name"] = descriptor->containing_type()->name();
     231           0 :   (*variables)["empty_array_name"] = EmptyArrayName(params, descriptor);
     232           0 : }
     233             : }  // namespace
     234             : 
     235             : // ===================================================================
     236             : 
     237           0 : PrimitiveFieldGenerator::
     238             : PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
     239           0 :   : FieldGenerator(params), descriptor_(descriptor) {
     240           0 :   SetPrimitiveVariables(descriptor, params, &variables_);
     241           0 : }
     242             : 
     243           0 : PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
     244             : 
     245           0 : bool PrimitiveFieldGenerator::SavedDefaultNeeded() const {
     246           0 :   return variables_.find("default_constant") != variables_.end();
     247             : }
     248             : 
     249           0 : void PrimitiveFieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
     250           0 :   if (variables_.find("default_constant") != variables_.end()) {
     251             :     printer->Print(variables_,
     252           0 :       "$default_constant$ = $default_constant_value$;\n");
     253             :   }
     254           0 : }
     255             : 
     256           0 : void PrimitiveFieldGenerator::
     257             : GenerateMembers(io::Printer* printer, bool lazy_init) const {
     258           0 :   if (variables_.find("default_constant") != variables_.end()) {
     259             :     // Those primitive types that need a saved default.
     260           0 :     if (lazy_init) {
     261             :       printer->Print(variables_,
     262           0 :         "private static $type$ $default_constant$;\n");
     263             :     } else {
     264             :       printer->Print(variables_,
     265             :         "private static final $type$ $default_constant$ =\n"
     266           0 :         "    $default_constant_value$;\n");
     267             :     }
     268             :   }
     269             : 
     270             :   printer->Print(variables_,
     271           0 :     "public $type$ $name$;\n");
     272             : 
     273           0 :   if (params_.generate_has()) {
     274             :     printer->Print(variables_,
     275           0 :       "public boolean has$capitalized_name$;\n");
     276             :   }
     277           0 : }
     278             : 
     279           0 : void PrimitiveFieldGenerator::
     280             : GenerateClearCode(io::Printer* printer) const {
     281             :   printer->Print(variables_,
     282           0 :     "$name$ = $default_copy_if_needed$;\n");
     283             : 
     284           0 :   if (params_.generate_has()) {
     285             :     printer->Print(variables_,
     286           0 :       "has$capitalized_name$ = false;\n");
     287             :   }
     288           0 : }
     289             : 
     290           0 : void PrimitiveFieldGenerator::
     291             : GenerateMergingCode(io::Printer* printer) const {
     292             :   printer->Print(variables_,
     293           0 :     "this.$name$ = input.read$capitalized_type$();\n");
     294             : 
     295           0 :   if (params_.generate_has()) {
     296             :     printer->Print(variables_,
     297           0 :       "has$capitalized_name$ = true;\n");
     298             :   }
     299           0 : }
     300             : 
     301           0 : void PrimitiveFieldGenerator::
     302             : GenerateSerializationConditional(io::Printer* printer) const {
     303           0 :   if (params_.use_reference_types_for_primitives()) {
     304             :     // For reference type mode, serialize based on equality
     305             :     // to null.
     306             :     printer->Print(variables_,
     307           0 :       "if (this.$name$ != null) {\n");
     308           0 :     return;
     309             :   }
     310           0 :   if (params_.generate_has()) {
     311             :     printer->Print(variables_,
     312           0 :       "if (has$capitalized_name$ || ");
     313             :   } else {
     314             :     printer->Print(variables_,
     315           0 :       "if (");
     316             :   }
     317           0 :   JavaType java_type = GetJavaType(descriptor_);
     318           0 :   if (IsArrayType(java_type)) {
     319             :     printer->Print(variables_,
     320           0 :       "!java.util.Arrays.equals(this.$name$, $default$)) {\n");
     321           0 :   } else if (IsReferenceType(java_type)) {
     322             :     printer->Print(variables_,
     323           0 :       "!this.$name$.equals($default$)) {\n");
     324           0 :   } else if (java_type == JAVATYPE_FLOAT) {
     325             :     printer->Print(variables_,
     326             :       "java.lang.Float.floatToIntBits(this.$name$)\n"
     327           0 :       "    != java.lang.Float.floatToIntBits($default$)) {\n");
     328           0 :   } else if (java_type == JAVATYPE_DOUBLE) {
     329             :     printer->Print(variables_,
     330             :       "java.lang.Double.doubleToLongBits(this.$name$)\n"
     331           0 :       "    != java.lang.Double.doubleToLongBits($default$)) {\n");
     332             :   } else {
     333             :     printer->Print(variables_,
     334           0 :       "this.$name$ != $default$) {\n");
     335             :   }
     336             : }
     337             : 
     338           0 : void PrimitiveFieldGenerator::
     339             : GenerateSerializationCode(io::Printer* printer) const {
     340           0 :   if (descriptor_->is_required() && !params_.generate_has()) {
     341             :     // Always serialize a required field if we don't have the 'has' signal.
     342             :     printer->Print(variables_,
     343           0 :       "output.write$capitalized_type$($number$, this.$name$);\n");
     344             :   } else {
     345           0 :     GenerateSerializationConditional(printer);
     346             :     printer->Print(variables_,
     347             :       "  output.write$capitalized_type$($number$, this.$name$);\n"
     348           0 :       "}\n");
     349             :   }
     350           0 : }
     351             : 
     352           0 : void PrimitiveFieldGenerator::
     353             : GenerateSerializedSizeCode(io::Printer* printer) const {
     354           0 :   if (descriptor_->is_required() && !params_.generate_has()) {
     355             :     printer->Print(variables_,
     356             :       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
     357           0 :       "    .compute$capitalized_type$Size($number$, this.$name$);\n");
     358             :   } else {
     359           0 :     GenerateSerializationConditional(printer);
     360             :     printer->Print(variables_,
     361             :       "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
     362             :       "      .compute$capitalized_type$Size($number$, this.$name$);\n"
     363           0 :       "}\n");
     364             :   }
     365           0 : }
     366             : 
     367           0 : void RepeatedPrimitiveFieldGenerator::
     368             : GenerateFixClonedCode(io::Printer* printer) const {
     369             :   printer->Print(variables_,
     370             :     "if (this.$name$ != null && this.$name$.length > 0) {\n"
     371             :     "  cloned.$name$ = this.$name$.clone();\n"
     372           0 :     "}\n");
     373           0 : }
     374             : 
     375           0 : void PrimitiveFieldGenerator::
     376             : GenerateEqualsCode(io::Printer* printer) const {
     377             :   // We define equality as serialized form equality. If generate_has(),
     378             :   // then if the field value equals the default value in both messages,
     379             :   // but one's 'has' field is set and the other's is not, the serialized
     380             :   // forms are different and we should return false.
     381           0 :   JavaType java_type = GetJavaType(descriptor_);
     382           0 :   if (java_type == JAVATYPE_BYTES) {
     383             :     printer->Print(variables_,
     384           0 :       "if (!java.util.Arrays.equals(this.$name$, other.$name$)");
     385           0 :     if (params_.generate_has()) {
     386             :       printer->Print(variables_,
     387             :         "\n"
     388             :         "    || (java.util.Arrays.equals(this.$name$, $default$)\n"
     389           0 :         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
     390             :     }
     391             :     printer->Print(") {\n"
     392             :       "  return false;\n"
     393           0 :       "}\n");
     394           0 :   } else if (java_type == JAVATYPE_STRING
     395           0 :       || params_.use_reference_types_for_primitives()) {
     396             :     printer->Print(variables_,
     397             :       "if (this.$name$ == null) {\n"
     398             :       "  if (other.$name$ != null) {\n"
     399             :       "    return false;\n"
     400             :       "  }\n"
     401           0 :       "} else if (!this.$name$.equals(other.$name$)");
     402           0 :     if (params_.generate_has()) {
     403             :       printer->Print(variables_,
     404             :         "\n"
     405             :         "    || (this.$name$.equals($default$)\n"
     406           0 :         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
     407             :     }
     408             :     printer->Print(") {\n"
     409             :       "  return false;\n"
     410           0 :       "}\n");
     411           0 :   } else if (java_type == JAVATYPE_FLOAT) {
     412             :     printer->Print(variables_,
     413             :       "{\n"
     414             :       "  int bits = java.lang.Float.floatToIntBits(this.$name$);\n"
     415           0 :       "  if (bits != java.lang.Float.floatToIntBits(other.$name$)");
     416           0 :     if (params_.generate_has()) {
     417             :       printer->Print(variables_,
     418             :         "\n"
     419             :         "      || (bits == java.lang.Float.floatToIntBits($default$)\n"
     420           0 :         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
     421             :     }
     422             :     printer->Print(") {\n"
     423             :       "    return false;\n"
     424             :       "  }\n"
     425           0 :       "}\n");
     426           0 :   } else if (java_type == JAVATYPE_DOUBLE) {
     427             :     printer->Print(variables_,
     428             :       "{\n"
     429             :       "  long bits = java.lang.Double.doubleToLongBits(this.$name$);\n"
     430           0 :       "  if (bits != java.lang.Double.doubleToLongBits(other.$name$)");
     431           0 :     if (params_.generate_has()) {
     432             :       printer->Print(variables_,
     433             :         "\n"
     434             :         "      || (bits == java.lang.Double.doubleToLongBits($default$)\n"
     435           0 :         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
     436             :     }
     437             :     printer->Print(") {\n"
     438             :       "    return false;\n"
     439             :       "  }\n"
     440           0 :       "}\n");
     441             :   } else {
     442             :     printer->Print(variables_,
     443           0 :       "if (this.$name$ != other.$name$");
     444           0 :     if (params_.generate_has()) {
     445             :       printer->Print(variables_,
     446             :         "\n"
     447             :         "    || (this.$name$ == $default$\n"
     448           0 :         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
     449             :     }
     450             :     printer->Print(") {\n"
     451             :       "  return false;\n"
     452           0 :       "}\n");
     453             :   }
     454           0 : }
     455             : 
     456           0 : void PrimitiveFieldGenerator::
     457             : GenerateHashCodeCode(io::Printer* printer) const {
     458           0 :   JavaType java_type = GetJavaType(descriptor_);
     459           0 :   if (java_type == JAVATYPE_BYTES) {
     460             :     printer->Print(variables_,
     461           0 :       "result = 31 * result + java.util.Arrays.hashCode(this.$name$);\n");
     462           0 :   } else if (java_type == JAVATYPE_STRING
     463           0 :       || params_.use_reference_types_for_primitives()) {
     464             :     printer->Print(variables_,
     465             :       "result = 31 * result\n"
     466           0 :       "    + (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
     467             :   } else {
     468           0 :     switch (java_type) {
     469             :       // For all Java primitive types below, the hash codes match the
     470             :       // results of BoxedType.valueOf(primitiveValue).hashCode().
     471             :       case JAVATYPE_INT:
     472             :         printer->Print(variables_,
     473           0 :           "result = 31 * result + this.$name$;\n");
     474           0 :         break;
     475             :       case JAVATYPE_LONG:
     476             :         printer->Print(variables_,
     477             :           "result = 31 * result\n"
     478           0 :           "    + (int) (this.$name$ ^ (this.$name$ >>> 32));\n");
     479           0 :         break;
     480             :       case JAVATYPE_FLOAT:
     481             :         printer->Print(variables_,
     482             :           "result = 31 * result\n"
     483           0 :           "    + java.lang.Float.floatToIntBits(this.$name$);\n");
     484           0 :         break;
     485             :       case JAVATYPE_DOUBLE:
     486             :         printer->Print(variables_,
     487             :           "{\n"
     488             :           "  long v = java.lang.Double.doubleToLongBits(this.$name$);\n"
     489             :           "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
     490           0 :           "}\n");
     491           0 :         break;
     492             :       case JAVATYPE_BOOLEAN:
     493             :         printer->Print(variables_,
     494           0 :           "result = 31 * result + (this.$name$ ? 1231 : 1237);\n");
     495           0 :         break;
     496             :       default:
     497           0 :         GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
     498           0 :         break;
     499             :     }
     500             :   }
     501           0 : }
     502             : 
     503             : // ===================================================================
     504             : 
     505           0 : AccessorPrimitiveFieldGenerator::
     506             : AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
     507             :      const Params& params, int has_bit_index)
     508           0 :   : FieldGenerator(params), descriptor_(descriptor) {
     509           0 :   SetPrimitiveVariables(descriptor, params, &variables_);
     510           0 :   SetBitOperationVariables("has", has_bit_index, &variables_);
     511           0 : }
     512             : 
     513           0 : AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
     514             : 
     515           0 : bool AccessorPrimitiveFieldGenerator::SavedDefaultNeeded() const {
     516           0 :   return variables_.find("default_constant") != variables_.end();
     517             : }
     518             : 
     519           0 : void AccessorPrimitiveFieldGenerator::
     520             : GenerateInitSavedDefaultCode(io::Printer* printer) const {
     521           0 :   if (variables_.find("default_constant") != variables_.end()) {
     522             :     printer->Print(variables_,
     523           0 :       "$default_constant$ = $default_constant_value$;\n");
     524             :   }
     525           0 : }
     526             : 
     527           0 : void AccessorPrimitiveFieldGenerator::
     528             : GenerateMembers(io::Printer* printer, bool lazy_init) const {
     529           0 :   if (variables_.find("default_constant") != variables_.end()) {
     530             :     // Those primitive types that need a saved default.
     531           0 :     if (lazy_init) {
     532             :       printer->Print(variables_,
     533           0 :         "private static $type$ $default_constant$;\n");
     534             :     } else {
     535             :       printer->Print(variables_,
     536             :         "private static final $type$ $default_constant$ =\n"
     537           0 :         "    $default_constant_value$;\n");
     538             :     }
     539             :   }
     540             :   printer->Print(variables_,
     541             :     "private $type$ $name$_;\n"
     542             :     "public $type$ get$capitalized_name$() {\n"
     543             :     "  return $name$_;\n"
     544             :     "}\n"
     545           0 :     "public $message_name$ set$capitalized_name$($type$ value) {\n");
     546           0 :   if (IsReferenceType(GetJavaType(descriptor_))) {
     547             :     printer->Print(variables_,
     548             :       "  if (value == null) {\n"
     549             :       "    throw new java.lang.NullPointerException();\n"
     550           0 :       "  }\n");
     551             :   }
     552             :   printer->Print(variables_,
     553             :     "  $name$_ = value;\n"
     554             :     "  $set_has$;\n"
     555             :     "  return this;\n"
     556             :     "}\n"
     557             :     "public boolean has$capitalized_name$() {\n"
     558             :     "  return $get_has$;\n"
     559             :     "}\n"
     560             :     "public $message_name$ clear$capitalized_name$() {\n"
     561             :     "  $name$_ = $default_copy_if_needed$;\n"
     562             :     "  $clear_has$;\n"
     563             :     "  return this;\n"
     564           0 :     "}\n");
     565           0 : }
     566             : 
     567           0 : void AccessorPrimitiveFieldGenerator::
     568             : GenerateClearCode(io::Printer* printer) const {
     569             :   printer->Print(variables_,
     570           0 :     "$name$_ = $default_copy_if_needed$;\n");
     571           0 : }
     572             : 
     573           0 : void AccessorPrimitiveFieldGenerator::
     574             : GenerateMergingCode(io::Printer* printer) const {
     575             :   printer->Print(variables_,
     576             :     "$name$_ = input.read$capitalized_type$();\n"
     577           0 :     "$set_has$;\n");
     578           0 : }
     579             : 
     580           0 : void AccessorPrimitiveFieldGenerator::
     581             : GenerateSerializationCode(io::Printer* printer) const {
     582             :   printer->Print(variables_,
     583             :     "if ($get_has$) {\n"
     584             :     "  output.write$capitalized_type$($number$, $name$_);\n"
     585           0 :     "}\n");
     586           0 : }
     587             : 
     588           0 : void AccessorPrimitiveFieldGenerator::
     589             : GenerateSerializedSizeCode(io::Printer* printer) const {
     590             :   printer->Print(variables_,
     591             :     "if ($get_has$) {\n"
     592             :     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
     593             :     "      .compute$capitalized_type$Size($number$, $name$_);\n"
     594           0 :     "}\n");
     595           0 : }
     596             : 
     597           0 : void AccessorPrimitiveFieldGenerator::
     598             : GenerateEqualsCode(io::Printer* printer) const {
     599           0 :   switch (GetJavaType(descriptor_)) {
     600             :     // For all Java primitive types below, the equality checks match the
     601             :     // results of BoxedType.valueOf(primitiveValue).equals(otherValue).
     602             :     case JAVATYPE_FLOAT:
     603             :       printer->Print(variables_,
     604             :         "if ($different_has$\n"
     605             :         "    || java.lang.Float.floatToIntBits($name$_)\n"
     606             :         "        != java.lang.Float.floatToIntBits(other.$name$_)) {\n"
     607             :         "  return false;\n"
     608           0 :         "}\n");
     609           0 :       break;
     610             :     case JAVATYPE_DOUBLE:
     611             :       printer->Print(variables_,
     612             :         "if ($different_has$\n"
     613             :         "    || java.lang.Double.doubleToLongBits($name$_)\n"
     614             :         "        != java.lang.Double.doubleToLongBits(other.$name$_)) {\n"
     615             :         "  return false;\n"
     616           0 :         "}\n");
     617           0 :       break;
     618             :     case JAVATYPE_INT:
     619             :     case JAVATYPE_LONG:
     620             :     case JAVATYPE_BOOLEAN:
     621             :       printer->Print(variables_,
     622             :         "if ($different_has$\n"
     623             :         "    || $name$_ != other.$name$_) {\n"
     624             :         "  return false;\n"
     625           0 :         "}\n");
     626           0 :       break;
     627             :     case JAVATYPE_STRING:
     628             :       // Accessor style would guarantee $name$_ non-null
     629             :       printer->Print(variables_,
     630             :         "if ($different_has$\n"
     631             :         "    || !$name$_.equals(other.$name$_)) {\n"
     632             :         "  return false;\n"
     633           0 :         "}\n");
     634           0 :       break;
     635             :     case JAVATYPE_BYTES:
     636             :       // Accessor style would guarantee $name$_ non-null
     637             :       printer->Print(variables_,
     638             :         "if ($different_has$\n"
     639             :         "    || !java.util.Arrays.equals($name$_, other.$name$_)) {\n"
     640             :         "  return false;\n"
     641           0 :         "}\n");
     642           0 :       break;
     643             :     default:
     644           0 :       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
     645           0 :       break;
     646             :   }
     647           0 : }
     648             : 
     649           0 : void AccessorPrimitiveFieldGenerator::
     650             : GenerateHashCodeCode(io::Printer* printer) const {
     651           0 :   switch (GetJavaType(descriptor_)) {
     652             :     // For all Java primitive types below, the hash codes match the
     653             :     // results of BoxedType.valueOf(primitiveValue).hashCode().
     654             :     case JAVATYPE_INT:
     655             :       printer->Print(variables_,
     656           0 :         "result = 31 * result + $name$_;\n");
     657           0 :       break;
     658             :     case JAVATYPE_LONG:
     659             :       printer->Print(variables_,
     660           0 :         "result = 31 * result + (int) ($name$_ ^ ($name$_ >>> 32));\n");
     661           0 :       break;
     662             :     case JAVATYPE_FLOAT:
     663             :       printer->Print(variables_,
     664             :         "result = 31 * result +\n"
     665           0 :         "    java.lang.Float.floatToIntBits($name$_);\n");
     666           0 :       break;
     667             :     case JAVATYPE_DOUBLE:
     668             :       printer->Print(variables_,
     669             :         "{\n"
     670             :         "  long v = java.lang.Double.doubleToLongBits($name$_);\n"
     671             :         "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
     672           0 :         "}\n");
     673           0 :       break;
     674             :     case JAVATYPE_BOOLEAN:
     675             :       printer->Print(variables_,
     676           0 :         "result = 31 * result + ($name$_ ? 1231 : 1237);\n");
     677           0 :       break;
     678             :     case JAVATYPE_STRING:
     679             :       // Accessor style would guarantee $name$_ non-null
     680             :       printer->Print(variables_,
     681           0 :         "result = 31 * result + $name$_.hashCode();\n");
     682           0 :       break;
     683             :     case JAVATYPE_BYTES:
     684             :       // Accessor style would guarantee $name$_ non-null
     685             :       printer->Print(variables_,
     686           0 :         "result = 31 * result + java.util.Arrays.hashCode($name$_);\n");
     687           0 :       break;
     688             :     default:
     689           0 :       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
     690           0 :       break;
     691             :   }
     692           0 : }
     693             : 
     694             : // ===================================================================
     695             : 
     696           0 : PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
     697             :     const FieldDescriptor* descriptor, const Params& params)
     698           0 :   : FieldGenerator(params), descriptor_(descriptor) {
     699           0 :     SetPrimitiveVariables(descriptor, params, &variables_);
     700           0 :     SetCommonOneofVariables(descriptor, &variables_);
     701           0 : }
     702             : 
     703           0 : PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
     704             : 
     705           0 : void PrimitiveOneofFieldGenerator::GenerateMembers(
     706             :     io::Printer* printer, bool /*unused lazy_init*/) const {
     707             :   printer->Print(variables_,
     708             :     "public boolean has$capitalized_name$() {\n"
     709             :     "  return $has_oneof_case$;\n"
     710             :     "}\n"
     711             :     "public $type$ get$capitalized_name$() {\n"
     712             :     "  if ($has_oneof_case$) {\n"
     713             :     "    return ($type$) ($boxed_type$) this.$oneof_name$_;\n"
     714             :     "  }\n"
     715             :     "  return $default$;\n"
     716             :     "}\n"
     717             :     "public $message_name$ set$capitalized_name$($type$ value) {\n"
     718             :     "  $set_oneof_case$;\n"
     719             :     "  this.$oneof_name$_ = value;\n"
     720             :     "  return this;\n"
     721           0 :     "}\n");
     722           0 : }
     723             : 
     724           0 : void PrimitiveOneofFieldGenerator::GenerateClearCode(
     725             :     io::Printer* printer) const {
     726             :   // No clear method for oneof fields.
     727           0 : }
     728             : 
     729           0 : void PrimitiveOneofFieldGenerator::GenerateMergingCode(
     730             :     io::Printer* printer) const {
     731             :   printer->Print(variables_,
     732             :     "this.$oneof_name$_ = input.read$capitalized_type$();\n"
     733           0 :     "$set_oneof_case$;\n");
     734           0 : }
     735             : 
     736           0 : void PrimitiveOneofFieldGenerator::GenerateSerializationCode(
     737             :     io::Printer* printer) const {
     738             :   printer->Print(variables_,
     739             :     "if ($has_oneof_case$) {\n"
     740             :     "  output.write$capitalized_type$(\n"
     741             :     "      $number$, ($boxed_type$) this.$oneof_name$_);\n"
     742           0 :     "}\n");
     743           0 : }
     744             : 
     745           0 : void PrimitiveOneofFieldGenerator::GenerateSerializedSizeCode(
     746             :     io::Printer* printer) const {
     747             :   printer->Print(variables_,
     748             :     "if ($has_oneof_case$) {\n"
     749             :     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
     750             :     "      .compute$capitalized_type$Size(\n"
     751             :     "          $number$, ($boxed_type$) this.$oneof_name$_);\n"
     752           0 :     "}\n");
     753           0 : }
     754             : 
     755           0 : void PrimitiveOneofFieldGenerator::GenerateEqualsCode(
     756             :     io::Printer* printer) const {
     757           0 :   GenerateOneofFieldEquals(descriptor_, variables_, printer);
     758           0 : }
     759             : 
     760           0 : void PrimitiveOneofFieldGenerator::GenerateHashCodeCode(
     761             :     io::Printer* printer) const {
     762           0 :   GenerateOneofFieldHashCode(descriptor_, variables_, printer);
     763           0 : }
     764             : 
     765             : // ===================================================================
     766             : 
     767           0 : RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
     768             :     const FieldDescriptor* descriptor, const Params& params)
     769           0 :   : FieldGenerator(params), descriptor_(descriptor) {
     770           0 :   SetPrimitiveVariables(descriptor, params, &variables_);
     771           0 : }
     772             : 
     773           0 : RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
     774             : 
     775           0 : void RepeatedPrimitiveFieldGenerator::
     776             : GenerateMembers(io::Printer* printer, bool /*unused init_defaults*/) const {
     777             :   printer->Print(variables_,
     778           0 :     "public $type$[] $name$;\n");
     779           0 : }
     780             : 
     781           0 : void RepeatedPrimitiveFieldGenerator::
     782             : GenerateClearCode(io::Printer* printer) const {
     783             :   printer->Print(variables_,
     784           0 :     "$name$ = $default$;\n");
     785           0 : }
     786             : 
     787           0 : void RepeatedPrimitiveFieldGenerator::
     788             : GenerateMergingCode(io::Printer* printer) const {
     789             :   // First, figure out the length of the array, then parse.
     790             :   printer->Print(variables_,
     791             :     "int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
     792             :     "    .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
     793           0 :     "int i = this.$name$ == null ? 0 : this.$name$.length;\n");
     794             : 
     795           0 :   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
     796             :     printer->Print(variables_,
     797           0 :       "byte[][] newArray = new byte[i + arrayLength][];\n");
     798             :   } else {
     799             :     printer->Print(variables_,
     800           0 :       "$type$[] newArray = new $type$[i + arrayLength];\n");
     801             :   }
     802             :   printer->Print(variables_,
     803             :     "if (i != 0) {\n"
     804             :     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
     805             :     "}\n"
     806             :     "for (; i < newArray.length - 1; i++) {\n"
     807             :     "  newArray[i] = input.read$capitalized_type$();\n"
     808             :     "  input.readTag();\n"
     809             :     "}\n"
     810             :     "// Last one without readTag.\n"
     811             :     "newArray[i] = input.read$capitalized_type$();\n"
     812           0 :     "this.$name$ = newArray;\n");
     813           0 : }
     814             : 
     815           0 : void RepeatedPrimitiveFieldGenerator::
     816             : GenerateMergingCodeFromPacked(io::Printer* printer) const {
     817             :   printer->Print(
     818             :     "int length = input.readRawVarint32();\n"
     819           0 :     "int limit = input.pushLimit(length);\n");
     820             : 
     821             :   // If we know the elements will all be of the same size, the arrayLength
     822             :   // can be calculated much more easily. However, FixedSize() returns 1 for
     823             :   // repeated bool fields, which are guaranteed to have the fixed size of
     824             :   // 1 byte per value only if we control the output. On the wire they can
     825             :   // legally appear as variable-size integers, so we need to use the slow
     826             :   // way for repeated bool fields.
     827           0 :   if (descriptor_->type() == FieldDescriptor::TYPE_BOOL
     828           0 :       || FixedSize(descriptor_->type()) == -1) {
     829             :     printer->Print(variables_,
     830             :       "// First pass to compute array length.\n"
     831             :       "int arrayLength = 0;\n"
     832             :       "int startPos = input.getPosition();\n"
     833             :       "while (input.getBytesUntilLimit() > 0) {\n"
     834             :       "  input.read$capitalized_type$();\n"
     835             :       "  arrayLength++;\n"
     836             :       "}\n"
     837           0 :       "input.rewindToPosition(startPos);\n");
     838             :   } else {
     839             :     printer->Print(variables_,
     840           0 :       "int arrayLength = length / $fixed_size$;\n");
     841             :   }
     842             : 
     843             :   printer->Print(variables_,
     844             :     "int i = this.$name$ == null ? 0 : this.$name$.length;\n"
     845             :     "$type$[] newArray = new $type$[i + arrayLength];\n"
     846             :     "if (i != 0) {\n"
     847             :     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
     848             :     "}\n"
     849             :     "for (; i < newArray.length; i++) {\n"
     850             :     "  newArray[i] = input.read$capitalized_type$();\n"
     851             :     "}\n"
     852             :     "this.$name$ = newArray;\n"
     853           0 :     "input.popLimit(limit);\n");
     854           0 : }
     855             : 
     856           0 : void RepeatedPrimitiveFieldGenerator::
     857             : GenerateRepeatedDataSizeCode(io::Printer* printer) const {
     858             :   // Creates a variable dataSize and puts the serialized size in there.
     859             :   // If the element type is a Java reference type, also generates
     860             :   // dataCount which stores the number of non-null elements in the field.
     861           0 :   if (IsReferenceType(GetJavaType(descriptor_))) {
     862             :     printer->Print(variables_,
     863             :       "int dataCount = 0;\n"
     864             :       "int dataSize = 0;\n"
     865             :       "for (int i = 0; i < this.$name$.length; i++) {\n"
     866             :       "  $type$ element = this.$name$[i];\n"
     867             :       "  if (element != null) {\n"
     868             :       "    dataCount++;\n"
     869             :       "    dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
     870             :       "        .compute$capitalized_type$SizeNoTag(element);\n"
     871             :       "  }\n"
     872           0 :       "}\n");
     873           0 :   } else if (FixedSize(descriptor_->type()) == -1) {
     874             :     printer->Print(variables_,
     875             :       "int dataSize = 0;\n"
     876             :       "for (int i = 0; i < this.$name$.length; i++) {\n"
     877             :       "  $type$ element = this.$name$[i];\n"
     878             :       "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
     879             :       "      .compute$capitalized_type$SizeNoTag(element);\n"
     880           0 :       "}\n");
     881             :   } else {
     882             :     printer->Print(variables_,
     883           0 :       "int dataSize = $fixed_size$ * this.$name$.length;\n");
     884             :   }
     885           0 : }
     886             : 
     887           0 : void RepeatedPrimitiveFieldGenerator::
     888             : GenerateSerializationCode(io::Printer* printer) const {
     889             :   printer->Print(variables_,
     890           0 :     "if (this.$name$ != null && this.$name$.length > 0) {\n");
     891           0 :   printer->Indent();
     892             : 
     893           0 :   if (descriptor_->is_packable() && descriptor_->options().packed()) {
     894           0 :     GenerateRepeatedDataSizeCode(printer);
     895             :     printer->Print(variables_,
     896             :       "output.writeRawVarint32($tag$);\n"
     897             :       "output.writeRawVarint32(dataSize);\n"
     898             :       "for (int i = 0; i < this.$name$.length; i++) {\n"
     899             :       "  output.write$capitalized_type$NoTag(this.$name$[i]);\n"
     900           0 :       "}\n");
     901           0 :   } else if (IsReferenceType(GetJavaType(descriptor_))) {
     902             :     printer->Print(variables_,
     903             :       "for (int i = 0; i < this.$name$.length; i++) {\n"
     904             :       "  $type$ element = this.$name$[i];\n"
     905             :       "  if (element != null) {\n"
     906             :       "    output.write$capitalized_type$($number$, element);\n"
     907             :       "  }\n"
     908           0 :       "}\n");
     909             :   } else {
     910             :     printer->Print(variables_,
     911             :       "for (int i = 0; i < this.$name$.length; i++) {\n"
     912             :       "  output.write$capitalized_type$($number$, this.$name$[i]);\n"
     913           0 :       "}\n");
     914             :   }
     915             : 
     916           0 :   printer->Outdent();
     917           0 :   printer->Print("}\n");
     918           0 : }
     919             : 
     920           0 : void RepeatedPrimitiveFieldGenerator::
     921             : GenerateSerializedSizeCode(io::Printer* printer) const {
     922             :   printer->Print(variables_,
     923           0 :     "if (this.$name$ != null && this.$name$.length > 0) {\n");
     924           0 :   printer->Indent();
     925             : 
     926           0 :   GenerateRepeatedDataSizeCode(printer);
     927             : 
     928             :   printer->Print(
     929           0 :     "size += dataSize;\n");
     930           0 :   if (descriptor_->is_packable() && descriptor_->options().packed()) {
     931             :     printer->Print(variables_,
     932             :       "size += $tag_size$;\n"
     933             :       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
     934           0 :       "    .computeRawVarint32Size(dataSize);\n");
     935           0 :   } else if (IsReferenceType(GetJavaType(descriptor_))) {
     936             :     printer->Print(variables_,
     937           0 :       "size += $tag_size$ * dataCount;\n");
     938             :   } else {
     939             :     printer->Print(variables_,
     940           0 :       "size += $tag_size$ * this.$name$.length;\n");
     941             :   }
     942             : 
     943           0 :   printer->Outdent();
     944             : 
     945             :   printer->Print(
     946           0 :     "}\n");
     947           0 : }
     948             : 
     949           0 : void RepeatedPrimitiveFieldGenerator::
     950             : GenerateEqualsCode(io::Printer* printer) const {
     951             :   printer->Print(variables_,
     952             :     "if (!com.google.protobuf.nano.InternalNano.equals(\n"
     953             :     "    this.$name$, other.$name$)) {\n"
     954             :     "  return false;\n"
     955           0 :     "}\n");
     956           0 : }
     957             : 
     958           0 : void RepeatedPrimitiveFieldGenerator::
     959             : GenerateHashCodeCode(io::Printer* printer) const {
     960             :   printer->Print(variables_,
     961             :     "result = 31 * result\n"
     962           0 :     "    + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
     963           0 : }
     964             : 
     965             : }  // namespace javanano
     966             : }  // namespace compiler
     967             : }  // namespace protobuf
     968             : }  // namespace google

Generated by: LCOV version 1.10