Home | History | Annotate | Download | only in java
      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 (at) 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 <string>
     37 
     38 #include <google/protobuf/stubs/logging.h>
     39 #include <google/protobuf/stubs/common.h>
     40 #include <google/protobuf/compiler/java/java_context.h>
     41 #include <google/protobuf/compiler/java/java_doc_comment.h>
     42 #include <google/protobuf/compiler/java/java_enum_field_lite.h>
     43 #include <google/protobuf/compiler/java/java_helpers.h>
     44 #include <google/protobuf/compiler/java/java_name_resolver.h>
     45 #include <google/protobuf/io/printer.h>
     46 #include <google/protobuf/wire_format.h>
     47 #include <google/protobuf/stubs/strutil.h>
     48 
     49 namespace google {
     50 namespace protobuf {
     51 namespace compiler {
     52 namespace java {
     53 
     54 namespace {
     55 
     56 void SetEnumVariables(const FieldDescriptor* descriptor,
     57                       int messageBitIndex,
     58                       int builderBitIndex,
     59                       const FieldGeneratorInfo* info,
     60                       ClassNameResolver* name_resolver,
     61                       map<string, string>* variables) {
     62   SetCommonFieldVariables(descriptor, info, variables);
     63 
     64   (*variables)["type"] =
     65       name_resolver->GetImmutableClassName(descriptor->enum_type());
     66   (*variables)["mutable_type"] =
     67       name_resolver->GetMutableClassName(descriptor->enum_type());
     68   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
     69   (*variables)["default_number"] = SimpleItoa(
     70       descriptor->default_value_enum()->number());
     71   (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
     72   (*variables)["tag_size"] = SimpleItoa(
     73       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
     74   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
     75   // by the proto compiler
     76   (*variables)["deprecation"] = descriptor->options().deprecated()
     77       ? "@java.lang.Deprecated " : "";
     78 
     79   if (SupportFieldPresence(descriptor->file())) {
     80     // For singular messages and builders, one bit is used for the hasField bit.
     81     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
     82 
     83     // Note that these have a trailing ";".
     84     (*variables)["set_has_field_bit_message"] =
     85         GenerateSetBit(messageBitIndex) + ";";
     86     (*variables)["clear_has_field_bit_message"] =
     87         GenerateClearBit(messageBitIndex) + ";";
     88 
     89     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
     90   } else {
     91     (*variables)["set_has_field_bit_message"] = "";
     92     (*variables)["clear_has_field_bit_message"] = "";
     93 
     94     (*variables)["is_field_present_message"] =
     95         (*variables)["name"] + "_ != " +
     96         (*variables)["default"] + ".getNumber()";
     97   }
     98 
     99   // For repeated builders, the underlying list tracks mutability state.
    100   (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
    101 
    102   (*variables)["get_has_field_bit_from_local"] =
    103       GenerateGetBitFromLocal(builderBitIndex);
    104   (*variables)["set_has_field_bit_to_local"] =
    105       GenerateSetBitToLocal(messageBitIndex);
    106 
    107   if (SupportUnknownEnumValue(descriptor->file())) {
    108     (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
    109   } else {
    110     (*variables)["unknown"] = (*variables)["default"];
    111   }
    112 }
    113 
    114 }  // namespace
    115 
    116 // ===================================================================
    117 
    118 ImmutableEnumFieldLiteGenerator::
    119 ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
    120                             int messageBitIndex,
    121                             int builderBitIndex,
    122                             Context* context)
    123   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
    124     builderBitIndex_(builderBitIndex),
    125     name_resolver_(context->GetNameResolver()) {
    126   SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
    127                    context->GetFieldGeneratorInfo(descriptor),
    128                    name_resolver_, &variables_);
    129 }
    130 
    131 ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
    132 
    133 int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
    134   return 1;
    135 }
    136 
    137 int ImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
    138   return 0;
    139 }
    140 
    141 void ImmutableEnumFieldLiteGenerator::
    142 GenerateInterfaceMembers(io::Printer* printer) const {
    143   if (SupportFieldPresence(descriptor_->file())) {
    144     WriteFieldDocComment(printer, descriptor_);
    145     printer->Print(variables_,
    146       "$deprecation$boolean has$capitalized_name$();\n");
    147   }
    148   if (SupportUnknownEnumValue(descriptor_->file())) {
    149     WriteFieldDocComment(printer, descriptor_);
    150     printer->Print(variables_,
    151       "$deprecation$int get$capitalized_name$Value();\n");
    152   }
    153   WriteFieldDocComment(printer, descriptor_);
    154   printer->Print(variables_,
    155     "$deprecation$$type$ get$capitalized_name$();\n");
    156 }
    157 
    158 void ImmutableEnumFieldLiteGenerator::
    159 GenerateMembers(io::Printer* printer) const {
    160   printer->Print(variables_,
    161     "private int $name$_;\n");
    162   PrintExtraFieldInfo(variables_, printer);
    163   if (SupportFieldPresence(descriptor_->file())) {
    164     WriteFieldDocComment(printer, descriptor_);
    165     printer->Print(variables_,
    166       "$deprecation$public boolean has$capitalized_name$() {\n"
    167       "  return $get_has_field_bit_message$;\n"
    168       "}\n");
    169   }
    170   if (SupportUnknownEnumValue(descriptor_->file())) {
    171     WriteFieldDocComment(printer, descriptor_);
    172     printer->Print(variables_,
    173       "$deprecation$public int get$capitalized_name$Value() {\n"
    174       "  return $name$_;\n"
    175       "}\n");
    176   }
    177   WriteFieldDocComment(printer, descriptor_);
    178   printer->Print(variables_,
    179     "$deprecation$public $type$ get$capitalized_name$() {\n"
    180     "  $type$ result = $type$.forNumber($name$_);\n"
    181     "  return result == null ? $unknown$ : result;\n"
    182     "}\n");
    183 
    184   // Generate private setters for the builder to proxy into.
    185   if (SupportUnknownEnumValue(descriptor_->file())) {
    186     WriteFieldDocComment(printer, descriptor_);
    187     printer->Print(variables_,
    188       "private void set$capitalized_name$Value(int value) {\n"
    189       "  $set_has_field_bit_message$"
    190       "  $name$_ = value;\n"
    191       "}\n");
    192   }
    193   WriteFieldDocComment(printer, descriptor_);
    194   printer->Print(variables_,
    195     "private void set$capitalized_name$($type$ value) {\n"
    196     "  if (value == null) {\n"
    197     "    throw new NullPointerException();\n"
    198     "  }\n"
    199     "  $set_has_field_bit_message$\n"
    200     "  $name$_ = value.getNumber();\n"
    201     "}\n");
    202   WriteFieldDocComment(printer, descriptor_);
    203   printer->Print(variables_,
    204     "private void clear$capitalized_name$() {\n"
    205     "  $clear_has_field_bit_message$\n"
    206     "  $name$_ = $default_number$;\n"
    207     "}\n");
    208 }
    209 
    210 void ImmutableEnumFieldLiteGenerator::
    211 GenerateBuilderMembers(io::Printer* printer) const {
    212   if (SupportFieldPresence(descriptor_->file())) {
    213     WriteFieldDocComment(printer, descriptor_);
    214     printer->Print(variables_,
    215       "$deprecation$public boolean has$capitalized_name$() {\n"
    216       "  return instance.has$capitalized_name$();\n"
    217       "}\n");
    218   }
    219   if (SupportUnknownEnumValue(descriptor_->file())) {
    220     WriteFieldDocComment(printer, descriptor_);
    221     printer->Print(variables_,
    222       "$deprecation$public int get$capitalized_name$Value() {\n"
    223       "  return instance.get$capitalized_name$Value();\n"
    224       "}\n");
    225     WriteFieldDocComment(printer, descriptor_);
    226     printer->Print(variables_,
    227       "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
    228       "  copyOnWrite();\n"
    229       "  instance.set$capitalized_name$Value(value);\n"
    230       "  return this;\n"
    231       "}\n");
    232   }
    233   WriteFieldDocComment(printer, descriptor_);
    234   printer->Print(variables_,
    235     "$deprecation$public $type$ get$capitalized_name$() {\n"
    236     "  return instance.get$capitalized_name$();\n"
    237     "}\n");
    238   WriteFieldDocComment(printer, descriptor_);
    239   printer->Print(variables_,
    240     "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
    241     "  copyOnWrite();\n"
    242     "  instance.set$capitalized_name$(value);\n"
    243     "  return this;\n"
    244     "}\n");
    245   WriteFieldDocComment(printer, descriptor_);
    246   printer->Print(variables_,
    247     "$deprecation$public Builder clear$capitalized_name$() {\n"
    248     "  copyOnWrite();\n"
    249     "  instance.clear$capitalized_name$();\n"
    250     "  return this;\n"
    251     "}\n");
    252 }
    253 
    254 void ImmutableEnumFieldLiteGenerator::
    255 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
    256   // noop for enums
    257 }
    258 
    259 void ImmutableEnumFieldLiteGenerator::
    260 GenerateInitializationCode(io::Printer* printer) const {
    261   printer->Print(variables_, "$name$_ = $default_number$;\n");
    262 }
    263 
    264 void ImmutableEnumFieldLiteGenerator::
    265 GenerateVisitCode(io::Printer* printer) const {
    266   if (SupportFieldPresence(descriptor_->file())) {
    267     printer->Print(variables_,
    268       "$name$_ = visitor.visitInt(has$capitalized_name$(), $name$_,\n"
    269       "    other.has$capitalized_name$(), other.$name$_);\n");
    270   } else if (SupportUnknownEnumValue(descriptor_->file())) {
    271     printer->Print(variables_,
    272       "$name$_ = visitor.visitInt($name$_ != $default_number$, $name$_,"
    273       "    other.$name$_ != $default_number$, other.$name$_);\n");
    274   } else {
    275     GOOGLE_LOG(FATAL) << "Can't reach here.";
    276   }
    277 }
    278 
    279 void ImmutableEnumFieldLiteGenerator::
    280 GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
    281   // noop for scalars
    282 }
    283 
    284 void ImmutableEnumFieldLiteGenerator::
    285 GenerateParsingCode(io::Printer* printer) const {
    286   if (SupportUnknownEnumValue(descriptor_->file())) {
    287     printer->Print(variables_,
    288       "int rawValue = input.readEnum();\n"
    289       "$set_has_field_bit_message$\n"
    290       "$name$_ = rawValue;\n");
    291   } else {
    292     printer->Print(variables_,
    293       "int rawValue = input.readEnum();\n"
    294       "$type$ value = $type$.forNumber(rawValue);\n"
    295       "if (value == null) {\n");
    296     if (PreserveUnknownFields(descriptor_->containing_type())) {
    297       printer->Print(variables_,
    298         "  super.mergeVarintField($number$, rawValue);\n");
    299     }
    300     printer->Print(variables_,
    301       "} else {\n"
    302       "  $set_has_field_bit_message$\n"
    303       "  $name$_ = rawValue;\n"
    304       "}\n");
    305   }
    306 }
    307 
    308 void ImmutableEnumFieldLiteGenerator::
    309 GenerateParsingDoneCode(io::Printer* printer) const {
    310   // noop for enums
    311 }
    312 
    313 void ImmutableEnumFieldLiteGenerator::
    314 GenerateSerializationCode(io::Printer* printer) const {
    315   printer->Print(variables_,
    316     "if ($is_field_present_message$) {\n"
    317     "  output.writeEnum($number$, $name$_);\n"
    318     "}\n");
    319 }
    320 
    321 void ImmutableEnumFieldLiteGenerator::
    322 GenerateSerializedSizeCode(io::Printer* printer) const {
    323   printer->Print(variables_,
    324     "if ($is_field_present_message$) {\n"
    325     "  size += com.google.protobuf.CodedOutputStream\n"
    326     "    .computeEnumSize($number$, $name$_);\n"
    327     "}\n");
    328 }
    329 
    330 void ImmutableEnumFieldLiteGenerator::
    331 GenerateEqualsCode(io::Printer* printer) const {
    332   printer->Print(variables_,
    333     "result = result && $name$_ == other.$name$_;\n");
    334 }
    335 
    336 void ImmutableEnumFieldLiteGenerator::
    337 GenerateHashCode(io::Printer* printer) const {
    338   printer->Print(variables_,
    339     "hash = (37 * hash) + $constant_name$;\n"
    340     "hash = (53 * hash) + $name$_;\n");
    341 }
    342 
    343 string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
    344   return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
    345 }
    346 
    347 // ===================================================================
    348 
    349 ImmutableEnumOneofFieldLiteGenerator::
    350 ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
    351                                  int messageBitIndex,
    352                                  int builderBitIndex,
    353                                  Context* context)
    354     : ImmutableEnumFieldLiteGenerator(
    355           descriptor, messageBitIndex, builderBitIndex, context) {
    356   const OneofGeneratorInfo* info =
    357       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
    358   SetCommonOneofVariables(descriptor, info, &variables_);
    359 }
    360 
    361 ImmutableEnumOneofFieldLiteGenerator::
    362 ~ImmutableEnumOneofFieldLiteGenerator() {}
    363 
    364 void ImmutableEnumOneofFieldLiteGenerator::
    365 GenerateMembers(io::Printer* printer) const {
    366   PrintExtraFieldInfo(variables_, printer);
    367   if (SupportFieldPresence(descriptor_->file())) {
    368     WriteFieldDocComment(printer, descriptor_);
    369     printer->Print(variables_,
    370       "$deprecation$public boolean has$capitalized_name$() {\n"
    371       "  return $has_oneof_case_message$;\n"
    372       "}\n");
    373   }
    374   if (SupportUnknownEnumValue(descriptor_->file())) {
    375     WriteFieldDocComment(printer, descriptor_);
    376     printer->Print(variables_,
    377       "$deprecation$public int get$capitalized_name$Value() {\n"
    378       "  if ($has_oneof_case_message$) {\n"
    379       "    return (java.lang.Integer) $oneof_name$_;\n"
    380       "  }\n"
    381       "  return $default_number$;\n"
    382       "}\n");
    383   }
    384   WriteFieldDocComment(printer, descriptor_);
    385   printer->Print(variables_,
    386     "$deprecation$public $type$ get$capitalized_name$() {\n"
    387     "  if ($has_oneof_case_message$) {\n"
    388     "    $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n"
    389     "    return result == null ? $unknown$ : result;\n"
    390     "  }\n"
    391     "  return $default$;\n"
    392     "}\n");
    393 
    394   // Generate private setters for the builder to proxy into.
    395   if (SupportUnknownEnumValue(descriptor_->file())) {
    396     WriteFieldDocComment(printer, descriptor_);
    397     printer->Print(variables_,
    398       "private void set$capitalized_name$Value(int value) {\n"
    399       "  $set_oneof_case_message$;\n"
    400       "  $oneof_name$_ = value;\n"
    401       "}\n");
    402   }
    403   WriteFieldDocComment(printer, descriptor_);
    404   printer->Print(variables_,
    405     "private void set$capitalized_name$($type$ value) {\n"
    406     "  if (value == null) {\n"
    407     "    throw new NullPointerException();\n"
    408     "  }\n"
    409     "  $set_oneof_case_message$;\n"
    410     "  $oneof_name$_ = value.getNumber();\n"
    411     "}\n");
    412   WriteFieldDocComment(printer, descriptor_);
    413   printer->Print(variables_,
    414     "private void clear$capitalized_name$() {\n"
    415     "  if ($has_oneof_case_message$) {\n"
    416     "    $clear_oneof_case_message$;\n"
    417     "    $oneof_name$_ = null;\n"
    418     "  }\n"
    419     "}\n");
    420 }
    421 
    422 void ImmutableEnumOneofFieldLiteGenerator::
    423 GenerateBuilderMembers(io::Printer* printer) const {
    424   if (SupportFieldPresence(descriptor_->file())) {
    425     WriteFieldDocComment(printer, descriptor_);
    426     printer->Print(variables_,
    427       "$deprecation$public boolean has$capitalized_name$() {\n"
    428       "  return instance.has$capitalized_name$();\n"
    429       "}\n");
    430   }
    431   if (SupportUnknownEnumValue(descriptor_->file())) {
    432     WriteFieldDocComment(printer, descriptor_);
    433     printer->Print(variables_,
    434       "$deprecation$public int get$capitalized_name$Value() {\n"
    435       "  return instance.get$capitalized_name$Value();\n"
    436       "}\n");
    437     WriteFieldDocComment(printer, descriptor_);
    438     printer->Print(variables_,
    439       "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
    440       "  copyOnWrite();\n"
    441       "  instance.set$capitalized_name$Value(value);\n"
    442       "  return this;\n"
    443       "}\n");
    444   }
    445   WriteFieldDocComment(printer, descriptor_);
    446   printer->Print(variables_,
    447     "$deprecation$public $type$ get$capitalized_name$() {\n"
    448     "  return instance.get$capitalized_name$();\n"
    449     "}\n");
    450   WriteFieldDocComment(printer, descriptor_);
    451   printer->Print(variables_,
    452     "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
    453     "  copyOnWrite();\n"
    454     "  instance.set$capitalized_name$(value);\n"
    455     "  return this;\n"
    456     "}\n");
    457   WriteFieldDocComment(printer, descriptor_);
    458   printer->Print(variables_,
    459     "$deprecation$public Builder clear$capitalized_name$() {\n"
    460     "  copyOnWrite();\n"
    461     "  instance.clear$capitalized_name$();\n"
    462     "  return this;\n"
    463     "}\n");
    464 }
    465 
    466 void ImmutableEnumOneofFieldLiteGenerator::
    467 GenerateVisitCode(io::Printer* printer) const {
    468   printer->Print(variables_,
    469     "$oneof_name$_ = visitor.visitOneofInt(\n"
    470     "   $has_oneof_case_message$, $oneof_name$_, other.$oneof_name$_);\n");
    471 }
    472 
    473 void ImmutableEnumOneofFieldLiteGenerator::
    474 GenerateParsingCode(io::Printer* printer) const {
    475   if (SupportUnknownEnumValue(descriptor_->file())) {
    476     printer->Print(variables_,
    477       "int rawValue = input.readEnum();\n"
    478       "$set_oneof_case_message$;\n"
    479       "$oneof_name$_ = rawValue;\n");
    480   } else {
    481     printer->Print(variables_,
    482       "int rawValue = input.readEnum();\n"
    483       "$type$ value = $type$.forNumber(rawValue);\n"
    484       "if (value == null) {\n");
    485     if (PreserveUnknownFields(descriptor_->containing_type())) {
    486       printer->Print(variables_,
    487         "  super.mergeVarintField($number$, rawValue);\n");
    488     }
    489     printer->Print(variables_,
    490       "} else {\n"
    491       "  $set_oneof_case_message$;\n"
    492       "  $oneof_name$_ = rawValue;\n"
    493       "}\n");
    494   }
    495 }
    496 
    497 void ImmutableEnumOneofFieldLiteGenerator::
    498 GenerateSerializationCode(io::Printer* printer) const {
    499   printer->Print(variables_,
    500     "if ($has_oneof_case_message$) {\n"
    501     "  output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
    502     "}\n");
    503 }
    504 
    505 void ImmutableEnumOneofFieldLiteGenerator::
    506 GenerateSerializedSizeCode(io::Printer* printer) const {
    507   printer->Print(variables_,
    508     "if ($has_oneof_case_message$) {\n"
    509     "  size += com.google.protobuf.CodedOutputStream\n"
    510     "    .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
    511     "}\n");
    512 }
    513 
    514 void ImmutableEnumOneofFieldLiteGenerator::
    515 GenerateEqualsCode(io::Printer* printer) const {
    516   if (SupportUnknownEnumValue(descriptor_->file())) {
    517     printer->Print(variables_,
    518       "result = result && get$capitalized_name$Value()\n"
    519       "    == other.get$capitalized_name$Value();\n");
    520   } else {
    521     printer->Print(variables_,
    522       "result = result && get$capitalized_name$()\n"
    523       "    .equals(other.get$capitalized_name$());\n");
    524   }
    525 }
    526 
    527 void ImmutableEnumOneofFieldLiteGenerator::
    528 GenerateHashCode(io::Printer* printer) const {
    529   if (SupportUnknownEnumValue(descriptor_->file())) {
    530     printer->Print(variables_,
    531       "hash = (37 * hash) + $constant_name$;\n"
    532       "hash = (53 * hash) + get$capitalized_name$Value();\n");
    533   } else {
    534     printer->Print(variables_,
    535       "hash = (37 * hash) + $constant_name$;\n"
    536       "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
    537   }
    538 }
    539 
    540 // ===================================================================
    541 
    542 RepeatedImmutableEnumFieldLiteGenerator::
    543 RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
    544                                     int messageBitIndex,
    545                                     int builderBitIndex,
    546                                     Context* context)
    547   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
    548     builderBitIndex_(builderBitIndex), context_(context),
    549     name_resolver_(context->GetNameResolver()) {
    550   SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
    551                    context->GetFieldGeneratorInfo(descriptor),
    552                    name_resolver_, &variables_);
    553 }
    554 
    555 RepeatedImmutableEnumFieldLiteGenerator::
    556 ~RepeatedImmutableEnumFieldLiteGenerator() {}
    557 
    558 int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
    559   return 0;
    560 }
    561 
    562 int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
    563   return 0;
    564 }
    565 
    566 void RepeatedImmutableEnumFieldLiteGenerator::
    567 GenerateInterfaceMembers(io::Printer* printer) const {
    568   WriteFieldDocComment(printer, descriptor_);
    569   printer->Print(variables_,
    570     "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
    571   WriteFieldDocComment(printer, descriptor_);
    572   printer->Print(variables_,
    573     "$deprecation$int get$capitalized_name$Count();\n");
    574   WriteFieldDocComment(printer, descriptor_);
    575   printer->Print(variables_,
    576     "$deprecation$$type$ get$capitalized_name$(int index);\n");
    577   if (SupportUnknownEnumValue(descriptor_->file())) {
    578     WriteFieldDocComment(printer, descriptor_);
    579     printer->Print(variables_,
    580       "$deprecation$java.util.List<java.lang.Integer>\n"
    581       "get$capitalized_name$ValueList();\n");
    582     WriteFieldDocComment(printer, descriptor_);
    583     printer->Print(variables_,
    584       "$deprecation$int get$capitalized_name$Value(int index);\n");
    585   }
    586 }
    587 
    588 void RepeatedImmutableEnumFieldLiteGenerator::
    589 GenerateMembers(io::Printer* printer) const {
    590   printer->Print(variables_,
    591     "private com.google.protobuf.Internal.IntList $name$_;\n"
    592     "private static final com.google.protobuf.Internal.ListAdapter.Converter<\n"
    593     "    java.lang.Integer, $type$> $name$_converter_ =\n"
    594     "        new com.google.protobuf.Internal.ListAdapter.Converter<\n"
    595     "            java.lang.Integer, $type$>() {\n"
    596     "          public $type$ convert(java.lang.Integer from) {\n"
    597     "            $type$ result = $type$.forNumber(from);\n"
    598     "            return result == null ? $unknown$ : result;\n"
    599     "          }\n"
    600     "        };\n");
    601   PrintExtraFieldInfo(variables_, printer);
    602   WriteFieldDocComment(printer, descriptor_);
    603   printer->Print(variables_,
    604     "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
    605     "  return new com.google.protobuf.Internal.ListAdapter<\n"
    606     "      java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
    607     "}\n");
    608   WriteFieldDocComment(printer, descriptor_);
    609   printer->Print(variables_,
    610     "$deprecation$public int get$capitalized_name$Count() {\n"
    611     "  return $name$_.size();\n"
    612     "}\n");
    613   WriteFieldDocComment(printer, descriptor_);
    614   printer->Print(variables_,
    615     "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
    616     "  return $name$_converter_.convert($name$_.getInt(index));\n"
    617     "}\n");
    618   if (SupportUnknownEnumValue(descriptor_->file())) {
    619     WriteFieldDocComment(printer, descriptor_);
    620     printer->Print(variables_,
    621       "$deprecation$public java.util.List<java.lang.Integer>\n"
    622       "get$capitalized_name$ValueList() {\n"
    623       "  return $name$_;\n"
    624       "}\n");
    625     WriteFieldDocComment(printer, descriptor_);
    626     printer->Print(variables_,
    627       "$deprecation$public int get$capitalized_name$Value(int index) {\n"
    628       "  return $name$_.getInt(index);\n"
    629       "}\n");
    630   }
    631 
    632   if (descriptor_->options().packed() &&
    633       context_->HasGeneratedMethods(descriptor_->containing_type())) {
    634     printer->Print(variables_,
    635       "private int $name$MemoizedSerializedSize;\n");
    636   }
    637 
    638   // Generate private setters for the builder to proxy into.
    639   printer->Print(variables_,
    640     "private void ensure$capitalized_name$IsMutable() {\n"
    641     "  if (!$is_mutable$) {\n"
    642     "    $name$_ =\n"
    643     "        com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
    644     "  }\n"
    645     "}\n");
    646   WriteFieldDocComment(printer, descriptor_);
    647   printer->Print(variables_,
    648     "private void set$capitalized_name$(\n"
    649     "    int index, $type$ value) {\n"
    650     "  if (value == null) {\n"
    651     "    throw new NullPointerException();\n"
    652     "  }\n"
    653     "  ensure$capitalized_name$IsMutable();\n"
    654     "  $name$_.setInt(index, value.getNumber());\n"
    655     "}\n");
    656   WriteFieldDocComment(printer, descriptor_);
    657   printer->Print(variables_,
    658     "private void add$capitalized_name$($type$ value) {\n"
    659     "  if (value == null) {\n"
    660     "    throw new NullPointerException();\n"
    661     "  }\n"
    662     "  ensure$capitalized_name$IsMutable();\n"
    663     "  $name$_.addInt(value.getNumber());\n"
    664     "}\n");
    665   WriteFieldDocComment(printer, descriptor_);
    666   printer->Print(variables_,
    667     "private void addAll$capitalized_name$(\n"
    668     "    java.lang.Iterable<? extends $type$> values) {\n"
    669     "  ensure$capitalized_name$IsMutable();\n"
    670     "  for ($type$ value : values) {\n"
    671     "    $name$_.addInt(value.getNumber());\n"
    672     "  }\n"
    673     "}\n");
    674   WriteFieldDocComment(printer, descriptor_);
    675   printer->Print(variables_,
    676     "private void clear$capitalized_name$() {\n"
    677     "  $name$_ = emptyIntList();\n"
    678     "}\n");
    679 
    680   if (SupportUnknownEnumValue(descriptor_->file())) {
    681     WriteFieldDocComment(printer, descriptor_);
    682     printer->Print(variables_,
    683       "private void set$capitalized_name$Value(\n"
    684       "    int index, int value) {\n"
    685       "  ensure$capitalized_name$IsMutable();\n"
    686       "  $name$_.setInt(index, value);\n"
    687       "}\n");
    688     WriteFieldDocComment(printer, descriptor_);
    689     printer->Print(variables_,
    690       "private void add$capitalized_name$Value(int value) {\n"
    691       "  ensure$capitalized_name$IsMutable();\n"
    692       "  $name$_.addInt(value);\n"
    693       "}\n");
    694     WriteFieldDocComment(printer, descriptor_);
    695     printer->Print(variables_,
    696       "private void addAll$capitalized_name$Value(\n"
    697       "    java.lang.Iterable<java.lang.Integer> values) {\n"
    698       "  ensure$capitalized_name$IsMutable();\n"
    699       "  for (int value : values) {\n"
    700       "    $name$_.addInt(value);\n"
    701       "  }\n"
    702       "}\n");
    703   }
    704 }
    705 
    706 void RepeatedImmutableEnumFieldLiteGenerator::
    707 GenerateBuilderMembers(io::Printer* printer) const {
    708   WriteFieldDocComment(printer, descriptor_);
    709   printer->Print(variables_,
    710     "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
    711     "  return instance.get$capitalized_name$List();\n"
    712     "}\n");
    713   WriteFieldDocComment(printer, descriptor_);
    714   printer->Print(variables_,
    715     "$deprecation$public int get$capitalized_name$Count() {\n"
    716     "  return instance.get$capitalized_name$Count();\n"
    717     "}\n");
    718   WriteFieldDocComment(printer, descriptor_);
    719   printer->Print(variables_,
    720     "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
    721     "  return instance.get$capitalized_name$(index);\n"
    722     "}\n");
    723   WriteFieldDocComment(printer, descriptor_);
    724   printer->Print(variables_,
    725     "$deprecation$public Builder set$capitalized_name$(\n"
    726     "    int index, $type$ value) {\n"
    727     "  copyOnWrite();\n"
    728     "  instance.set$capitalized_name$(index, value);\n"
    729     "  return this;\n"
    730     "}\n");
    731   WriteFieldDocComment(printer, descriptor_);
    732   printer->Print(variables_,
    733     "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
    734     "  copyOnWrite();\n"
    735     "  instance.add$capitalized_name$(value);\n"
    736     "  return this;\n"
    737     "}\n");
    738   WriteFieldDocComment(printer, descriptor_);
    739   printer->Print(variables_,
    740     "$deprecation$public Builder addAll$capitalized_name$(\n"
    741     "    java.lang.Iterable<? extends $type$> values) {\n"
    742     "  copyOnWrite();\n"
    743     "  instance.addAll$capitalized_name$(values);"
    744     "  return this;\n"
    745     "}\n");
    746   WriteFieldDocComment(printer, descriptor_);
    747   printer->Print(variables_,
    748     "$deprecation$public Builder clear$capitalized_name$() {\n"
    749     "  copyOnWrite();\n"
    750     "  instance.clear$capitalized_name$();\n"
    751     "  return this;\n"
    752     "}\n");
    753 
    754   if (SupportUnknownEnumValue(descriptor_->file())) {
    755     WriteFieldDocComment(printer, descriptor_);
    756     printer->Print(variables_,
    757       "$deprecation$public java.util.List<java.lang.Integer>\n"
    758       "get$capitalized_name$ValueList() {\n"
    759       "  return java.util.Collections.unmodifiableList(\n"
    760       "      instance.get$capitalized_name$ValueList());\n"
    761       "}\n");
    762     WriteFieldDocComment(printer, descriptor_);
    763     printer->Print(variables_,
    764       "$deprecation$public int get$capitalized_name$Value(int index) {\n"
    765       "  return instance.get$capitalized_name$Value(index);\n"
    766       "}\n");
    767     WriteFieldDocComment(printer, descriptor_);
    768     printer->Print(variables_,
    769       "$deprecation$public Builder set$capitalized_name$Value(\n"
    770       "    int index, int value) {\n"
    771       "  copyOnWrite();\n"
    772       "  instance.set$capitalized_name$Value(index, value);\n"
    773       "  return this;\n"
    774       "}\n");
    775     WriteFieldDocComment(printer, descriptor_);
    776     printer->Print(variables_,
    777       "$deprecation$public Builder add$capitalized_name$Value(int value) {\n"
    778       "  instance.add$capitalized_name$Value(value);\n"
    779       "  return this;\n"
    780       "}\n");
    781     WriteFieldDocComment(printer, descriptor_);
    782     printer->Print(variables_,
    783       "$deprecation$public Builder addAll$capitalized_name$Value(\n"
    784       "    java.lang.Iterable<java.lang.Integer> values) {\n"
    785       "  copyOnWrite();\n"
    786       "  instance.addAll$capitalized_name$Value(values);\n"
    787       "  return this;\n"
    788       "}\n");
    789   }
    790 }
    791 
    792 void RepeatedImmutableEnumFieldLiteGenerator::
    793 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
    794   // noop for enums
    795 }
    796 
    797 void RepeatedImmutableEnumFieldLiteGenerator::
    798 GenerateInitializationCode(io::Printer* printer) const {
    799   printer->Print(variables_, "$name$_ = emptyIntList();\n");
    800 }
    801 
    802 void RepeatedImmutableEnumFieldLiteGenerator::
    803 GenerateVisitCode(io::Printer* printer) const {
    804   printer->Print(variables_,
    805     "$name$_= visitor.visitIntList($name$_, other.$name$_);\n");
    806 }
    807 
    808 void RepeatedImmutableEnumFieldLiteGenerator::
    809 GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
    810   printer->Print(variables_,
    811     "$name$_.makeImmutable();\n");
    812 }
    813 
    814 void RepeatedImmutableEnumFieldLiteGenerator::
    815 GenerateParsingCode(io::Printer* printer) const {
    816   // Read and store the enum
    817   printer->Print(variables_,
    818     "if (!$is_mutable$) {\n"
    819     "  $name$_ =\n"
    820     "      com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
    821     "}\n");
    822 
    823   if (SupportUnknownEnumValue(descriptor_->file())) {
    824     printer->Print(variables_,
    825       "$name$_.addInt(input.readEnum());\n");
    826   } else {
    827     printer->Print(variables_,
    828       "int rawValue = input.readEnum();\n"
    829       "$type$ value = $type$.forNumber(rawValue);\n"
    830       "if (value == null) {\n"
    831       // We store the unknown value in unknown fields.
    832       "  super.mergeVarintField($number$, rawValue);\n"
    833       "} else {\n"
    834       "  $name$_.addInt(rawValue);\n"
    835       "}\n");
    836   }
    837 }
    838 
    839 void RepeatedImmutableEnumFieldLiteGenerator::
    840 GenerateParsingCodeFromPacked(io::Printer* printer) const {
    841   printer->Print(variables_,
    842     "if (!$is_mutable$) {\n"
    843     "  $name$_ =\n"
    844     "      com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
    845     "}\n");
    846 
    847   printer->Print(variables_,
    848     "int length = input.readRawVarint32();\n"
    849     "int oldLimit = input.pushLimit(length);\n"
    850     "while(input.getBytesUntilLimit() > 0) {\n");
    851   printer->Indent();
    852 
    853   // Read and store the enum
    854   if (SupportUnknownEnumValue(descriptor_->file())) {
    855     printer->Print(variables_,
    856       "$name$_.addInt(input.readEnum());\n");
    857   } else {
    858     printer->Print(variables_,
    859       "int rawValue = input.readEnum();\n"
    860       "$type$ value = $type$.forNumber(rawValue);\n"
    861       "if (value == null) {\n"
    862       // We store the unknown value in unknown fields.
    863       "  super.mergeVarintField($number$, rawValue);\n"
    864       "} else {\n"
    865       "  $name$_.addInt(rawValue);\n"
    866       "}\n");
    867   }
    868 
    869   printer->Outdent();
    870   printer->Print(variables_,
    871     "}\n"
    872     "input.popLimit(oldLimit);\n");
    873 }
    874 
    875 void RepeatedImmutableEnumFieldLiteGenerator::
    876 GenerateParsingDoneCode(io::Printer* printer) const {
    877   printer->Print(variables_,
    878     "if ($is_mutable$) {\n"
    879     "  $name$_.makeImmutable();\n"
    880     "}\n");
    881 }
    882 
    883 void RepeatedImmutableEnumFieldLiteGenerator::
    884 GenerateSerializationCode(io::Printer* printer) const {
    885   if (descriptor_->options().packed()) {
    886     printer->Print(variables_,
    887       "if (get$capitalized_name$List().size() > 0) {\n"
    888       "  output.writeRawVarint32($tag$);\n"
    889       "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
    890       "}\n"
    891       "for (int i = 0; i < $name$_.size(); i++) {\n"
    892       "  output.writeEnumNoTag($name$_.getInt(i));\n"
    893       "}\n");
    894   } else {
    895     printer->Print(variables_,
    896       "for (int i = 0; i < $name$_.size(); i++) {\n"
    897       "  output.writeEnum($number$, $name$_.getInt(i));\n"
    898       "}\n");
    899   }
    900 }
    901 
    902 void RepeatedImmutableEnumFieldLiteGenerator::
    903 GenerateSerializedSizeCode(io::Printer* printer) const {
    904   printer->Print(variables_,
    905     "{\n"
    906     "  int dataSize = 0;\n");
    907   printer->Indent();
    908 
    909   printer->Print(variables_,
    910     "for (int i = 0; i < $name$_.size(); i++) {\n"
    911     "  dataSize += com.google.protobuf.CodedOutputStream\n"
    912     "    .computeEnumSizeNoTag($name$_.getInt(i));\n"
    913     "}\n");
    914   printer->Print(
    915     "size += dataSize;\n");
    916   if (descriptor_->options().packed()) {
    917     printer->Print(variables_,
    918       "if (!get$capitalized_name$List().isEmpty()) {"
    919       "  size += $tag_size$;\n"
    920       "  size += com.google.protobuf.CodedOutputStream\n"
    921       "    .computeRawVarint32Size(dataSize);\n"
    922       "}");
    923   } else {
    924     printer->Print(variables_,
    925       "size += $tag_size$ * $name$_.size();\n");
    926   }
    927 
    928   // cache the data size for packed fields.
    929   if (descriptor_->options().packed()) {
    930     printer->Print(variables_,
    931       "$name$MemoizedSerializedSize = dataSize;\n");
    932   }
    933 
    934   printer->Outdent();
    935   printer->Print("}\n");
    936 }
    937 
    938 void RepeatedImmutableEnumFieldLiteGenerator::
    939 GenerateEqualsCode(io::Printer* printer) const {
    940   printer->Print(variables_,
    941     "result = result && $name$_.equals(other.$name$_);\n");
    942 }
    943 
    944 void RepeatedImmutableEnumFieldLiteGenerator::
    945 GenerateHashCode(io::Printer* printer) const {
    946   printer->Print(variables_,
    947     "if (get$capitalized_name$Count() > 0) {\n"
    948     "  hash = (37 * hash) + $constant_name$;\n"
    949     "  hash = (53 * hash) + $name$_.hashCode();\n"
    950     "}\n");
    951 }
    952 
    953 string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
    954   return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
    955 }
    956 
    957 }  // namespace java
    958 }  // namespace compiler
    959 }  // namespace protobuf
    960 }  // namespace google
    961