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