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 // Author: jonp (at) google.com (Jon Perlow)
     33 //  Based on original Protocol Buffers design by
     34 //  Sanjay Ghemawat, Jeff Dean, and others.
     35 
     36 #include <map>
     37 #include <string>
     38 
     39 #include <google/protobuf/stubs/logging.h>
     40 #include <google/protobuf/stubs/common.h>
     41 #include <google/protobuf/compiler/java/java_context.h>
     42 #include <google/protobuf/compiler/java/java_doc_comment.h>
     43 #include <google/protobuf/compiler/java/java_helpers.h>
     44 #include <google/protobuf/compiler/java/java_name_resolver.h>
     45 #include <google/protobuf/compiler/java/java_string_field.h>
     46 #include <google/protobuf/io/printer.h>
     47 #include <google/protobuf/wire_format.h>
     48 #include <google/protobuf/stubs/strutil.h>
     49 
     50 namespace google {
     51 namespace protobuf {
     52 namespace compiler {
     53 namespace java {
     54 
     55 using internal::WireFormat;
     56 using internal::WireFormatLite;
     57 
     58 namespace {
     59 
     60 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
     61                            int messageBitIndex,
     62                            int builderBitIndex,
     63                            const FieldGeneratorInfo* info,
     64                            ClassNameResolver* name_resolver,
     65                            map<string, string>* variables) {
     66   SetCommonFieldVariables(descriptor, info, variables);
     67 
     68   (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
     69 
     70   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
     71   (*variables)["default_init"] =
     72       "= " + ImmutableDefaultValue(descriptor, name_resolver);
     73   (*variables)["capitalized_type"] = "String";
     74   (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
     75   (*variables)["tag_size"] = SimpleItoa(
     76       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
     77   (*variables)["null_check"] =
     78       "  if (value == null) {\n"
     79       "    throw new NullPointerException();\n"
     80       "  }\n";
     81   (*variables)["writeString"] =
     82       "com.google.protobuf.GeneratedMessage.writeString";
     83   (*variables)["computeStringSize"] =
     84       "com.google.protobuf.GeneratedMessage.computeStringSize";
     85 
     86   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
     87   // by the proto compiler
     88   (*variables)["deprecation"] = descriptor->options().deprecated()
     89       ? "@java.lang.Deprecated " : "";
     90   (*variables)["on_changed"] = "onChanged();";
     91 
     92   if (SupportFieldPresence(descriptor->file())) {
     93     // For singular messages and builders, one bit is used for the hasField bit.
     94     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
     95     (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
     96 
     97     // Note that these have a trailing ";".
     98     (*variables)["set_has_field_bit_message"] =
     99         GenerateSetBit(messageBitIndex) + ";";
    100     (*variables)["set_has_field_bit_builder"] =
    101         GenerateSetBit(builderBitIndex) + ";";
    102     (*variables)["clear_has_field_bit_builder"] =
    103         GenerateClearBit(builderBitIndex) + ";";
    104 
    105     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
    106   } else {
    107     (*variables)["set_has_field_bit_message"] = "";
    108     (*variables)["set_has_field_bit_builder"] = "";
    109     (*variables)["clear_has_field_bit_builder"] = "";
    110 
    111     (*variables)["is_field_present_message"] =
    112         "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
    113   }
    114 
    115   // For repeated builders, one bit is used for whether the array is immutable.
    116   (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
    117   (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
    118   (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
    119 
    120   // For repeated fields, one bit is used for whether the array is immutable
    121   // in the parsing constructor.
    122   (*variables)["get_mutable_bit_parser"] =
    123       GenerateGetBitMutableLocal(builderBitIndex);
    124   (*variables)["set_mutable_bit_parser"] =
    125       GenerateSetBitMutableLocal(builderBitIndex);
    126 
    127   (*variables)["get_has_field_bit_from_local"] =
    128       GenerateGetBitFromLocal(builderBitIndex);
    129   (*variables)["set_has_field_bit_to_local"] =
    130       GenerateSetBitToLocal(messageBitIndex);
    131 }
    132 
    133 }  // namespace
    134 
    135 // ===================================================================
    136 
    137 ImmutableStringFieldGenerator::
    138 ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
    139                               int messageBitIndex,
    140                               int builderBitIndex,
    141                               Context* context)
    142   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
    143     builderBitIndex_(builderBitIndex), context_(context),
    144     name_resolver_(context->GetNameResolver()) {
    145   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
    146                         context->GetFieldGeneratorInfo(descriptor),
    147                         name_resolver_, &variables_);
    148 }
    149 
    150 ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
    151 
    152 int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
    153   return 1;
    154 }
    155 
    156 int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
    157   return 1;
    158 }
    159 
    160 // A note about how strings are handled. This code used to just store a String
    161 // in the Message. This had two issues:
    162 //
    163 //  1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
    164 //     strings, but rather fields that were raw bytes incorrectly marked
    165 //     as strings in the proto file. This is common because in the proto1
    166 //     syntax, string was the way to indicate bytes and C++ engineers can
    167 //     easily make this mistake without affecting the C++ API. By converting to
    168 //     strings immediately, some java code might corrupt these byte arrays as
    169 //     it passes through a java server even if the field was never accessed by
    170 //     application code.
    171 //
    172 //  2. There's a performance hit to converting between bytes and strings and
    173 //     it many cases, the field is never even read by the application code. This
    174 //     avoids unnecessary conversions in the common use cases.
    175 //
    176 // So now, the field for String is maintained as an Object reference which can
    177 // either store a String or a ByteString. The code uses an instanceof check
    178 // to see which one it has and converts to the other one if needed. It remembers
    179 // the last value requested (in a thread safe manner) as this is most likely
    180 // the one needed next. The thread safety is such that if two threads both
    181 // convert the field because the changes made by each thread were not visible to
    182 // the other, they may cause a conversion to happen more times than would
    183 // otherwise be necessary. This was deemed better than adding synchronization
    184 // overhead. It will not cause any corruption issues or affect the behavior of
    185 // the API. The instanceof check is also highly optimized in the JVM and we
    186 // decided it was better to reduce the memory overhead by not having two
    187 // separate fields but rather use dynamic type checking.
    188 //
    189 // For single fields, the logic for this is done inside the generated code. For
    190 // repeated fields, the logic is done in LazyStringArrayList and
    191 // UnmodifiableLazyStringList.
    192 void ImmutableStringFieldGenerator::
    193 GenerateInterfaceMembers(io::Printer* printer) const {
    194   if (SupportFieldPresence(descriptor_->file())) {
    195     WriteFieldDocComment(printer, descriptor_);
    196     printer->Print(variables_,
    197       "$deprecation$boolean has$capitalized_name$();\n");
    198   }
    199   WriteFieldDocComment(printer, descriptor_);
    200   printer->Print(variables_,
    201     "$deprecation$java.lang.String get$capitalized_name$();\n");
    202   WriteFieldDocComment(printer, descriptor_);
    203   printer->Print(variables_,
    204     "$deprecation$com.google.protobuf.ByteString\n"
    205     "    get$capitalized_name$Bytes();\n");
    206 }
    207 
    208 void ImmutableStringFieldGenerator::
    209 GenerateMembers(io::Printer* printer) const {
    210   printer->Print(variables_,
    211     "private volatile java.lang.Object $name$_;\n");
    212   PrintExtraFieldInfo(variables_, printer);
    213 
    214   if (SupportFieldPresence(descriptor_->file())) {
    215     WriteFieldDocComment(printer, descriptor_);
    216     printer->Print(variables_,
    217       "$deprecation$public boolean has$capitalized_name$() {\n"
    218       "  return $get_has_field_bit_message$;\n"
    219       "}\n");
    220   }
    221 
    222   WriteFieldDocComment(printer, descriptor_);
    223   printer->Print(variables_,
    224     "$deprecation$public java.lang.String get$capitalized_name$() {\n"
    225     "  java.lang.Object ref = $name$_;\n"
    226     "  if (ref instanceof java.lang.String) {\n"
    227     "    return (java.lang.String) ref;\n"
    228     "  } else {\n"
    229     "    com.google.protobuf.ByteString bs = \n"
    230     "        (com.google.protobuf.ByteString) ref;\n"
    231       "    java.lang.String s = bs.toStringUtf8();\n");
    232   if (CheckUtf8(descriptor_)) {
    233     printer->Print(variables_,
    234       "    $name$_ = s;\n");
    235   } else {
    236     printer->Print(variables_,
    237       "    if (bs.isValidUtf8()) {\n"
    238       "      $name$_ = s;\n"
    239       "    }\n");
    240   }
    241   printer->Print(variables_,
    242     "    return s;\n"
    243     "  }\n"
    244     "}\n");
    245   WriteFieldDocComment(printer, descriptor_);
    246   printer->Print(variables_,
    247     "$deprecation$public com.google.protobuf.ByteString\n"
    248     "    get$capitalized_name$Bytes() {\n"
    249     "  java.lang.Object ref = $name$_;\n"
    250     "  if (ref instanceof java.lang.String) {\n"
    251     "    com.google.protobuf.ByteString b = \n"
    252     "        com.google.protobuf.ByteString.copyFromUtf8(\n"
    253     "            (java.lang.String) ref);\n"
    254     "    $name$_ = b;\n"
    255     "    return b;\n"
    256     "  } else {\n"
    257     "    return (com.google.protobuf.ByteString) ref;\n"
    258     "  }\n"
    259     "}\n");
    260 }
    261 
    262 void ImmutableStringFieldGenerator::
    263 GenerateBuilderMembers(io::Printer* printer) const {
    264   printer->Print(variables_,
    265     "private java.lang.Object $name$_ $default_init$;\n");
    266   if (SupportFieldPresence(descriptor_->file())) {
    267     WriteFieldDocComment(printer, descriptor_);
    268     printer->Print(variables_,
    269       "$deprecation$public boolean has$capitalized_name$() {\n"
    270       "  return $get_has_field_bit_builder$;\n"
    271       "}\n");
    272   }
    273 
    274   WriteFieldDocComment(printer, descriptor_);
    275   printer->Print(variables_,
    276     "$deprecation$public java.lang.String get$capitalized_name$() {\n"
    277     "  java.lang.Object ref = $name$_;\n"
    278     "  if (!(ref instanceof java.lang.String)) {\n"
    279     "    com.google.protobuf.ByteString bs =\n"
    280     "        (com.google.protobuf.ByteString) ref;\n"
    281     "    java.lang.String s = bs.toStringUtf8();\n");
    282   if (CheckUtf8(descriptor_)) {
    283     printer->Print(variables_,
    284       "    $name$_ = s;\n");
    285   } else {
    286     printer->Print(variables_,
    287       "    if (bs.isValidUtf8()) {\n"
    288       "      $name$_ = s;\n"
    289       "    }\n");
    290   }
    291   printer->Print(variables_,
    292     "    return s;\n"
    293     "  } else {\n"
    294     "    return (java.lang.String) ref;\n"
    295     "  }\n"
    296     "}\n");
    297 
    298   WriteFieldDocComment(printer, descriptor_);
    299   printer->Print(variables_,
    300     "$deprecation$public com.google.protobuf.ByteString\n"
    301     "    get$capitalized_name$Bytes() {\n"
    302     "  java.lang.Object ref = $name$_;\n"
    303     "  if (ref instanceof String) {\n"
    304     "    com.google.protobuf.ByteString b = \n"
    305     "        com.google.protobuf.ByteString.copyFromUtf8(\n"
    306     "            (java.lang.String) ref);\n"
    307     "    $name$_ = b;\n"
    308     "    return b;\n"
    309     "  } else {\n"
    310     "    return (com.google.protobuf.ByteString) ref;\n"
    311     "  }\n"
    312     "}\n");
    313 
    314   WriteFieldDocComment(printer, descriptor_);
    315   printer->Print(variables_,
    316     "$deprecation$public Builder set$capitalized_name$(\n"
    317     "    java.lang.String value) {\n"
    318     "$null_check$"
    319     "  $set_has_field_bit_builder$\n"
    320     "  $name$_ = value;\n"
    321     "  $on_changed$\n"
    322     "  return this;\n"
    323     "}\n");
    324   WriteFieldDocComment(printer, descriptor_);
    325   printer->Print(variables_,
    326     "$deprecation$public Builder clear$capitalized_name$() {\n"
    327     "  $clear_has_field_bit_builder$\n");
    328   // The default value is not a simple literal so we want to avoid executing
    329   // it multiple times.  Instead, get the default out of the default instance.
    330   printer->Print(variables_,
    331     "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
    332   printer->Print(variables_,
    333     "  $on_changed$\n"
    334     "  return this;\n"
    335     "}\n");
    336 
    337   WriteFieldDocComment(printer, descriptor_);
    338   printer->Print(variables_,
    339     "$deprecation$public Builder set$capitalized_name$Bytes(\n"
    340     "    com.google.protobuf.ByteString value) {\n"
    341     "$null_check$");
    342   if (CheckUtf8(descriptor_)) {
    343     printer->Print(variables_,
    344       "  checkByteStringIsUtf8(value);\n");
    345   }
    346   printer->Print(variables_,
    347     "  $set_has_field_bit_builder$\n"
    348     "  $name$_ = value;\n"
    349     "  $on_changed$\n"
    350     "  return this;\n"
    351     "}\n");
    352 }
    353 
    354 void ImmutableStringFieldGenerator::
    355 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
    356   // noop for primitives
    357 }
    358 
    359 void ImmutableStringFieldGenerator::
    360 GenerateInitializationCode(io::Printer* printer) const {
    361   printer->Print(variables_, "$name$_ = $default$;\n");
    362 }
    363 
    364 void ImmutableStringFieldGenerator::
    365 GenerateBuilderClearCode(io::Printer* printer) const {
    366   printer->Print(variables_,
    367     "$name$_ = $default$;\n"
    368     "$clear_has_field_bit_builder$\n");
    369 }
    370 
    371 void ImmutableStringFieldGenerator::
    372 GenerateMergingCode(io::Printer* printer) const {
    373   if (SupportFieldPresence(descriptor_->file())) {
    374     // Allow a slight breach of abstraction here in order to avoid forcing
    375     // all string fields to Strings when copying fields from a Message.
    376     printer->Print(variables_,
    377       "if (other.has$capitalized_name$()) {\n"
    378       "  $set_has_field_bit_builder$\n"
    379       "  $name$_ = other.$name$_;\n"
    380       "  $on_changed$\n"
    381       "}\n");
    382   } else {
    383     printer->Print(variables_,
    384       "if (!other.get$capitalized_name$().isEmpty()) {\n"
    385       "  $name$_ = other.$name$_;\n"
    386       "  $on_changed$\n"
    387       "}\n");
    388   }
    389 }
    390 
    391 void ImmutableStringFieldGenerator::
    392 GenerateBuildingCode(io::Printer* printer) const {
    393   if (SupportFieldPresence(descriptor_->file())) {
    394     printer->Print(variables_,
    395       "if ($get_has_field_bit_from_local$) {\n"
    396       "  $set_has_field_bit_to_local$;\n"
    397       "}\n");
    398   }
    399   printer->Print(variables_,
    400     "result.$name$_ = $name$_;\n");
    401 }
    402 
    403 void ImmutableStringFieldGenerator::
    404 GenerateParsingCode(io::Printer* printer) const {
    405   if (CheckUtf8(descriptor_)) {
    406     printer->Print(variables_,
    407       "java.lang.String s = input.readStringRequireUtf8();\n"
    408       "$set_has_field_bit_message$\n"
    409       "$name$_ = s;\n");
    410   } else {
    411     printer->Print(variables_,
    412       "com.google.protobuf.ByteString bs = input.readBytes();\n"
    413       "$set_has_field_bit_message$\n"
    414       "$name$_ = bs;\n");
    415   }
    416 }
    417 
    418 void ImmutableStringFieldGenerator::
    419 GenerateParsingDoneCode(io::Printer* printer) const {
    420   // noop for strings.
    421 }
    422 
    423 void ImmutableStringFieldGenerator::
    424 GenerateSerializationCode(io::Printer* printer) const {
    425   printer->Print(variables_,
    426     "if ($is_field_present_message$) {\n"
    427     "  $writeString$(output, $number$, $name$_);\n"
    428     "}\n");
    429 }
    430 
    431 void ImmutableStringFieldGenerator::
    432 GenerateSerializedSizeCode(io::Printer* printer) const {
    433   printer->Print(variables_,
    434     "if ($is_field_present_message$) {\n"
    435     "  size += $computeStringSize$($number$, $name$_);\n"
    436     "}\n");
    437 }
    438 
    439 void ImmutableStringFieldGenerator::
    440 GenerateEqualsCode(io::Printer* printer) const {
    441   printer->Print(variables_,
    442     "result = result && get$capitalized_name$()\n"
    443     "    .equals(other.get$capitalized_name$());\n");
    444 }
    445 
    446 void ImmutableStringFieldGenerator::
    447 GenerateHashCode(io::Printer* printer) const {
    448   printer->Print(variables_,
    449     "hash = (37 * hash) + $constant_name$;\n");
    450   printer->Print(variables_,
    451     "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
    452 }
    453 
    454 string ImmutableStringFieldGenerator::GetBoxedType() const {
    455   return "java.lang.String";
    456 }
    457 
    458 // ===================================================================
    459 
    460 ImmutableStringOneofFieldGenerator::
    461 ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
    462                                    int messageBitIndex,
    463                                    int builderBitIndex,
    464                                    Context* context)
    465     : ImmutableStringFieldGenerator(
    466           descriptor, messageBitIndex, builderBitIndex, context) {
    467   const OneofGeneratorInfo* info =
    468       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
    469   SetCommonOneofVariables(descriptor, info, &variables_);
    470 }
    471 
    472 ImmutableStringOneofFieldGenerator::
    473 ~ImmutableStringOneofFieldGenerator() {}
    474 
    475 void ImmutableStringOneofFieldGenerator::
    476 GenerateMembers(io::Printer* printer) const {
    477   PrintExtraFieldInfo(variables_, printer);
    478 
    479   if (SupportFieldPresence(descriptor_->file())) {
    480   WriteFieldDocComment(printer, descriptor_);
    481   printer->Print(variables_,
    482     "$deprecation$public boolean has$capitalized_name$() {\n"
    483     "  return $has_oneof_case_message$;\n"
    484     "}\n");
    485   }
    486 
    487   WriteFieldDocComment(printer, descriptor_);
    488   printer->Print(variables_,
    489     "$deprecation$public java.lang.String get$capitalized_name$() {\n"
    490     "  java.lang.Object ref $default_init$;\n"
    491     "  if ($has_oneof_case_message$) {\n"
    492     "    ref = $oneof_name$_;\n"
    493     "  }\n"
    494     "  if (ref instanceof java.lang.String) {\n"
    495     "    return (java.lang.String) ref;\n"
    496     "  } else {\n"
    497     "    com.google.protobuf.ByteString bs = \n"
    498     "        (com.google.protobuf.ByteString) ref;\n"
    499     "    java.lang.String s = bs.toStringUtf8();\n");
    500   if (CheckUtf8(descriptor_)) {
    501     printer->Print(variables_,
    502     "    if ($has_oneof_case_message$) {\n"
    503     "      $oneof_name$_ = s;\n"
    504     "    }\n");
    505   } else {
    506     printer->Print(variables_,
    507     "    if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
    508     "      $oneof_name$_ = s;\n"
    509     "    }\n");
    510   }
    511   printer->Print(variables_,
    512     "    return s;\n"
    513     "  }\n"
    514     "}\n");
    515   WriteFieldDocComment(printer, descriptor_);
    516 
    517   printer->Print(variables_,
    518     "$deprecation$public com.google.protobuf.ByteString\n"
    519     "    get$capitalized_name$Bytes() {\n"
    520     "  java.lang.Object ref $default_init$;\n"
    521     "  if ($has_oneof_case_message$) {\n"
    522     "    ref = $oneof_name$_;\n"
    523     "  }\n"
    524     "  if (ref instanceof java.lang.String) {\n"
    525     "    com.google.protobuf.ByteString b = \n"
    526     "        com.google.protobuf.ByteString.copyFromUtf8(\n"
    527     "            (java.lang.String) ref);\n"
    528     "    if ($has_oneof_case_message$) {\n"
    529     "      $oneof_name$_ = b;\n"
    530     "    }\n"
    531     "    return b;\n"
    532     "  } else {\n"
    533     "    return (com.google.protobuf.ByteString) ref;\n"
    534     "  }\n"
    535     "}\n");
    536 }
    537 
    538 void ImmutableStringOneofFieldGenerator::
    539 GenerateBuilderMembers(io::Printer* printer) const {
    540   if (SupportFieldPresence(descriptor_->file())) {
    541     WriteFieldDocComment(printer, descriptor_);
    542     printer->Print(variables_,
    543       "$deprecation$public boolean has$capitalized_name$() {\n"
    544       "  return $has_oneof_case_message$;\n"
    545       "}\n");
    546   }
    547 
    548   WriteFieldDocComment(printer, descriptor_);
    549   printer->Print(variables_,
    550     "$deprecation$public java.lang.String get$capitalized_name$() {\n"
    551     "  java.lang.Object ref $default_init$;\n"
    552     "  if ($has_oneof_case_message$) {\n"
    553     "    ref = $oneof_name$_;\n"
    554     "  }\n"
    555     "  if (!(ref instanceof java.lang.String)) {\n"
    556     "    com.google.protobuf.ByteString bs =\n"
    557     "        (com.google.protobuf.ByteString) ref;\n"
    558     "    java.lang.String s = bs.toStringUtf8();\n"
    559     "    if ($has_oneof_case_message$) {\n");
    560   if (CheckUtf8(descriptor_)) {
    561     printer->Print(variables_,
    562       "      $oneof_name$_ = s;\n");
    563   } else {
    564     printer->Print(variables_,
    565       "      if (bs.isValidUtf8()) {\n"
    566       "        $oneof_name$_ = s;\n"
    567       "      }\n");
    568   }
    569   printer->Print(variables_,
    570     "    }\n"
    571     "    return s;\n"
    572     "  } else {\n"
    573     "    return (java.lang.String) ref;\n"
    574     "  }\n"
    575     "}\n");
    576 
    577   WriteFieldDocComment(printer, descriptor_);
    578   printer->Print(variables_,
    579     "$deprecation$public com.google.protobuf.ByteString\n"
    580     "    get$capitalized_name$Bytes() {\n"
    581     "  java.lang.Object ref $default_init$;\n"
    582     "  if ($has_oneof_case_message$) {\n"
    583     "    ref = $oneof_name$_;\n"
    584     "  }\n"
    585     "  if (ref instanceof String) {\n"
    586     "    com.google.protobuf.ByteString b = \n"
    587     "        com.google.protobuf.ByteString.copyFromUtf8(\n"
    588     "            (java.lang.String) ref);\n"
    589     "    if ($has_oneof_case_message$) {\n"
    590     "      $oneof_name$_ = b;\n"
    591     "    }\n"
    592     "    return b;\n"
    593     "  } else {\n"
    594     "    return (com.google.protobuf.ByteString) ref;\n"
    595     "  }\n"
    596     "}\n");
    597 
    598   WriteFieldDocComment(printer, descriptor_);
    599   printer->Print(variables_,
    600     "$deprecation$public Builder set$capitalized_name$(\n"
    601     "    java.lang.String value) {\n"
    602     "$null_check$"
    603     "  $set_oneof_case_message$;\n"
    604     "  $oneof_name$_ = value;\n"
    605     "  $on_changed$\n"
    606     "  return this;\n"
    607     "}\n");
    608   WriteFieldDocComment(printer, descriptor_);
    609   printer->Print(variables_,
    610     "$deprecation$public Builder clear$capitalized_name$() {\n"
    611     "  if ($has_oneof_case_message$) {\n"
    612     "    $clear_oneof_case_message$;\n"
    613     "    $oneof_name$_ = null;\n"
    614     "    $on_changed$\n"
    615     "  }\n"
    616     "  return this;\n"
    617     "}\n");
    618 
    619   WriteFieldDocComment(printer, descriptor_);
    620   printer->Print(variables_,
    621     "$deprecation$public Builder set$capitalized_name$Bytes(\n"
    622     "    com.google.protobuf.ByteString value) {\n"
    623     "$null_check$");
    624   if (CheckUtf8(descriptor_)) {
    625     printer->Print(variables_,
    626       "  checkByteStringIsUtf8(value);\n");
    627   }
    628   printer->Print(variables_,
    629     "  $set_oneof_case_message$;\n"
    630     "  $oneof_name$_ = value;\n"
    631     "  $on_changed$\n"
    632     "  return this;\n"
    633     "}\n");
    634 }
    635 
    636 void ImmutableStringOneofFieldGenerator::
    637 GenerateMergingCode(io::Printer* printer) const {
    638   // Allow a slight breach of abstraction here in order to avoid forcing
    639   // all string fields to Strings when copying fields from a Message.
    640   printer->Print(variables_,
    641     "$set_oneof_case_message$;\n"
    642     "$oneof_name$_ = other.$oneof_name$_;\n"
    643     "$on_changed$\n");
    644 }
    645 
    646 void ImmutableStringOneofFieldGenerator::
    647 GenerateBuildingCode(io::Printer* printer) const {
    648   printer->Print(variables_,
    649     "if ($has_oneof_case_message$) {\n"
    650     "  result.$oneof_name$_ = $oneof_name$_;\n"
    651     "}\n");
    652 }
    653 
    654 void ImmutableStringOneofFieldGenerator::
    655 GenerateParsingCode(io::Printer* printer) const {
    656   if (CheckUtf8(descriptor_)) {
    657     printer->Print(variables_,
    658       "java.lang.String s = input.readStringRequireUtf8();\n"
    659       "$set_oneof_case_message$;\n"
    660       "$oneof_name$_ = s;\n");
    661   } else {
    662     printer->Print(variables_,
    663       "com.google.protobuf.ByteString bs = input.readBytes();\n"
    664       "$set_oneof_case_message$;\n"
    665       "$oneof_name$_ = bs;\n");
    666   }
    667 }
    668 
    669 void ImmutableStringOneofFieldGenerator::
    670 GenerateSerializationCode(io::Printer* printer) const {
    671   printer->Print(variables_,
    672     "if ($has_oneof_case_message$) {\n"
    673     "  $writeString$(output, $number$, $oneof_name$_);\n"
    674     "}\n");
    675 }
    676 
    677 void ImmutableStringOneofFieldGenerator::
    678 GenerateSerializedSizeCode(io::Printer* printer) const {
    679   printer->Print(variables_,
    680     "if ($has_oneof_case_message$) {\n"
    681     "  size += $computeStringSize$($number$, $oneof_name$_);\n"
    682     "}\n");
    683 }
    684 
    685 // ===================================================================
    686 
    687 RepeatedImmutableStringFieldGenerator::
    688 RepeatedImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
    689                                       int messageBitIndex,
    690                                       int builderBitIndex,
    691                                       Context* context)
    692   : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
    693     builderBitIndex_(builderBitIndex), context_(context),
    694     name_resolver_(context->GetNameResolver()) {
    695   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
    696                         context->GetFieldGeneratorInfo(descriptor),
    697                         name_resolver_, &variables_);
    698 }
    699 
    700 RepeatedImmutableStringFieldGenerator::
    701 ~RepeatedImmutableStringFieldGenerator() {}
    702 
    703 int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const {
    704   return 0;
    705 }
    706 
    707 int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
    708   return 1;
    709 }
    710 
    711 void RepeatedImmutableStringFieldGenerator::
    712 GenerateInterfaceMembers(io::Printer* printer) const {
    713   WriteFieldDocComment(printer, descriptor_);
    714   printer->Print(variables_,
    715     "$deprecation$com.google.protobuf.ProtocolStringList\n"
    716     "    get$capitalized_name$List();\n");
    717   WriteFieldDocComment(printer, descriptor_);
    718   printer->Print(variables_,
    719     "$deprecation$int get$capitalized_name$Count();\n");
    720   WriteFieldDocComment(printer, descriptor_);
    721   printer->Print(variables_,
    722     "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
    723   WriteFieldDocComment(printer, descriptor_);
    724   printer->Print(variables_,
    725     "$deprecation$com.google.protobuf.ByteString\n"
    726     "    get$capitalized_name$Bytes(int index);\n");
    727 }
    728 
    729 
    730 void RepeatedImmutableStringFieldGenerator::
    731 GenerateMembers(io::Printer* printer) const {
    732   printer->Print(variables_,
    733     "private com.google.protobuf.LazyStringList $name$_;\n");
    734   PrintExtraFieldInfo(variables_, printer);
    735   WriteFieldDocComment(printer, descriptor_);
    736   printer->Print(variables_,
    737     "$deprecation$public com.google.protobuf.ProtocolStringList\n"
    738     "    get$capitalized_name$List() {\n"
    739     "  return $name$_;\n"   // note:  unmodifiable list
    740     "}\n");
    741   WriteFieldDocComment(printer, descriptor_);
    742   printer->Print(variables_,
    743     "$deprecation$public int get$capitalized_name$Count() {\n"
    744     "  return $name$_.size();\n"
    745     "}\n");
    746   WriteFieldDocComment(printer, descriptor_);
    747   printer->Print(variables_,
    748     "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
    749     "  return $name$_.get(index);\n"
    750     "}\n");
    751   WriteFieldDocComment(printer, descriptor_);
    752   printer->Print(variables_,
    753     "$deprecation$public com.google.protobuf.ByteString\n"
    754     "    get$capitalized_name$Bytes(int index) {\n"
    755     "  return $name$_.getByteString(index);\n"
    756     "}\n");
    757 }
    758 
    759 void RepeatedImmutableStringFieldGenerator::
    760 GenerateBuilderMembers(io::Printer* printer) const {
    761   // One field is the list and the bit field keeps track of whether the
    762   // list is immutable. If it's immutable, the invariant is that it must
    763   // either an instance of Collections.emptyList() or it's an ArrayList
    764   // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
    765   // a refererence to the underlying ArrayList. This invariant allows us to
    766   // share instances of lists between protocol buffers avoiding expensive
    767   // memory allocations. Note, immutable is a strong guarantee here -- not
    768   // just that the list cannot be modified via the reference but that the
    769   // list can never be modified.
    770   printer->Print(variables_,
    771     "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
    772 
    773   printer->Print(variables_,
    774     "private void ensure$capitalized_name$IsMutable() {\n"
    775     "  if (!$get_mutable_bit_builder$) {\n"
    776     "    $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
    777     "    $set_mutable_bit_builder$;\n"
    778     "   }\n"
    779     "}\n");
    780 
    781     // Note:  We return an unmodifiable list because otherwise the caller
    782     //   could hold on to the returned list and modify it after the message
    783     //   has been built, thus mutating the message which is supposed to be
    784     //   immutable.
    785   WriteFieldDocComment(printer, descriptor_);
    786   printer->Print(variables_,
    787     "$deprecation$public com.google.protobuf.ProtocolStringList\n"
    788     "    get$capitalized_name$List() {\n"
    789     "  return $name$_.getUnmodifiableView();\n"
    790     "}\n");
    791   WriteFieldDocComment(printer, descriptor_);
    792   printer->Print(variables_,
    793     "$deprecation$public int get$capitalized_name$Count() {\n"
    794     "  return $name$_.size();\n"
    795     "}\n");
    796   WriteFieldDocComment(printer, descriptor_);
    797   printer->Print(variables_,
    798     "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
    799     "  return $name$_.get(index);\n"
    800     "}\n");
    801   WriteFieldDocComment(printer, descriptor_);
    802   printer->Print(variables_,
    803     "$deprecation$public com.google.protobuf.ByteString\n"
    804     "    get$capitalized_name$Bytes(int index) {\n"
    805     "  return $name$_.getByteString(index);\n"
    806     "}\n");
    807   WriteFieldDocComment(printer, descriptor_);
    808   printer->Print(variables_,
    809     "$deprecation$public Builder set$capitalized_name$(\n"
    810     "    int index, java.lang.String value) {\n"
    811     "$null_check$"
    812     "  ensure$capitalized_name$IsMutable();\n"
    813     "  $name$_.set(index, value);\n"
    814     "  $on_changed$\n"
    815     "  return this;\n"
    816     "}\n");
    817   WriteFieldDocComment(printer, descriptor_);
    818   printer->Print(variables_,
    819     "$deprecation$public Builder add$capitalized_name$(\n"
    820     "    java.lang.String value) {\n"
    821     "$null_check$"
    822     "  ensure$capitalized_name$IsMutable();\n"
    823     "  $name$_.add(value);\n"
    824     "  $on_changed$\n"
    825     "  return this;\n"
    826     "}\n");
    827   WriteFieldDocComment(printer, descriptor_);
    828   printer->Print(variables_,
    829     "$deprecation$public Builder addAll$capitalized_name$(\n"
    830     "    java.lang.Iterable<java.lang.String> values) {\n"
    831     "  ensure$capitalized_name$IsMutable();\n"
    832     "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
    833     "      values, $name$_);\n"
    834     "  $on_changed$\n"
    835     "  return this;\n"
    836     "}\n");
    837   WriteFieldDocComment(printer, descriptor_);
    838   printer->Print(variables_,
    839     "$deprecation$public Builder clear$capitalized_name$() {\n"
    840     "  $name$_ = $empty_list$;\n"
    841     "  $clear_mutable_bit_builder$;\n"
    842     "  $on_changed$\n"
    843     "  return this;\n"
    844     "}\n");
    845 
    846   WriteFieldDocComment(printer, descriptor_);
    847   printer->Print(variables_,
    848     "$deprecation$public Builder add$capitalized_name$Bytes(\n"
    849     "    com.google.protobuf.ByteString value) {\n"
    850     "$null_check$");
    851   if (CheckUtf8(descriptor_)) {
    852     printer->Print(variables_,
    853       "  checkByteStringIsUtf8(value);\n");
    854   }
    855   printer->Print(variables_,
    856     "  ensure$capitalized_name$IsMutable();\n"
    857     "  $name$_.add(value);\n"
    858     "  $on_changed$\n"
    859     "  return this;\n"
    860     "}\n");
    861 }
    862 
    863 void RepeatedImmutableStringFieldGenerator::
    864 GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
    865   // noop for primitives
    866 }
    867 
    868 void RepeatedImmutableStringFieldGenerator::
    869 GenerateInitializationCode(io::Printer* printer) const {
    870   printer->Print(variables_, "$name$_ = $empty_list$;\n");
    871 }
    872 
    873 void RepeatedImmutableStringFieldGenerator::
    874 GenerateBuilderClearCode(io::Printer* printer) const {
    875   printer->Print(variables_,
    876     "$name$_ = $empty_list$;\n"
    877     "$clear_mutable_bit_builder$;\n");
    878 }
    879 
    880 void RepeatedImmutableStringFieldGenerator::
    881 GenerateMergingCode(io::Printer* printer) const {
    882   // The code below does two optimizations:
    883   //   1. If the other list is empty, there's nothing to do. This ensures we
    884   //      don't allocate a new array if we already have an immutable one.
    885   //   2. If the other list is non-empty and our current list is empty, we can
    886   //      reuse the other list which is guaranteed to be immutable.
    887   printer->Print(variables_,
    888     "if (!other.$name$_.isEmpty()) {\n"
    889     "  if ($name$_.isEmpty()) {\n"
    890     "    $name$_ = other.$name$_;\n"
    891     "    $clear_mutable_bit_builder$;\n"
    892     "  } else {\n"
    893     "    ensure$capitalized_name$IsMutable();\n"
    894     "    $name$_.addAll(other.$name$_);\n"
    895     "  }\n"
    896     "  $on_changed$\n"
    897     "}\n");
    898 }
    899 
    900 void RepeatedImmutableStringFieldGenerator::
    901 GenerateBuildingCode(io::Printer* printer) const {
    902   // The code below ensures that the result has an immutable list. If our
    903   // list is immutable, we can just reuse it. If not, we make it immutable.
    904 
    905   printer->Print(variables_,
    906     "if ($get_mutable_bit_builder$) {\n"
    907     "  $name$_ = $name$_.getUnmodifiableView();\n"
    908     "  $clear_mutable_bit_builder$;\n"
    909     "}\n"
    910     "result.$name$_ = $name$_;\n");
    911 }
    912 
    913 void RepeatedImmutableStringFieldGenerator::
    914 GenerateParsingCode(io::Printer* printer) const {
    915   if (CheckUtf8(descriptor_)) {
    916     printer->Print(variables_,
    917     "java.lang.String s = input.readStringRequireUtf8();\n");
    918   } else {
    919     printer->Print(variables_,
    920     "com.google.protobuf.ByteString bs = input.readBytes();\n");
    921   }
    922   printer->Print(variables_,
    923     "if (!$get_mutable_bit_parser$) {\n"
    924     "  $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
    925     "  $set_mutable_bit_parser$;\n"
    926     "}\n");
    927   if (CheckUtf8(descriptor_)) {
    928     printer->Print(variables_,
    929       "$name$_.add(s);\n");
    930   } else {
    931     printer->Print(variables_,
    932       "$name$_.add(bs);\n");
    933   }
    934 }
    935 
    936 void RepeatedImmutableStringFieldGenerator::
    937 GenerateParsingDoneCode(io::Printer* printer) const {
    938   printer->Print(variables_,
    939     "if ($get_mutable_bit_parser$) {\n"
    940     "  $name$_ = $name$_.getUnmodifiableView();\n"
    941     "}\n");
    942 }
    943 
    944 void RepeatedImmutableStringFieldGenerator::
    945 GenerateSerializationCode(io::Printer* printer) const {
    946   printer->Print(variables_,
    947     "for (int i = 0; i < $name$_.size(); i++) {\n"
    948     "  $writeString$(output, $number$, $name$_.getRaw(i));\n"
    949     "}\n");
    950 }
    951 
    952 void RepeatedImmutableStringFieldGenerator::
    953 GenerateSerializedSizeCode(io::Printer* printer) const {
    954   printer->Print(variables_,
    955     "{\n"
    956     "  int dataSize = 0;\n");
    957   printer->Indent();
    958 
    959   printer->Print(variables_,
    960     "for (int i = 0; i < $name$_.size(); i++) {\n"
    961     "  dataSize += computeStringSizeNoTag($name$_.getRaw(i));\n"
    962     "}\n");
    963 
    964   printer->Print(
    965       "size += dataSize;\n");
    966 
    967   printer->Print(variables_,
    968     "size += $tag_size$ * get$capitalized_name$List().size();\n");
    969 
    970   printer->Outdent();
    971   printer->Print("}\n");
    972 }
    973 
    974 void RepeatedImmutableStringFieldGenerator::
    975 GenerateEqualsCode(io::Printer* printer) const {
    976   printer->Print(variables_,
    977     "result = result && get$capitalized_name$List()\n"
    978     "    .equals(other.get$capitalized_name$List());\n");
    979 }
    980 
    981 void RepeatedImmutableStringFieldGenerator::
    982 GenerateHashCode(io::Printer* printer) const {
    983   printer->Print(variables_,
    984     "if (get$capitalized_name$Count() > 0) {\n"
    985     "  hash = (37 * hash) + $constant_name$;\n"
    986     "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
    987     "}\n");
    988 }
    989 
    990 string RepeatedImmutableStringFieldGenerator::GetBoxedType() const {
    991   return "String";
    992 }
    993 
    994 }  // namespace java
    995 }  // namespace compiler
    996 }  // namespace protobuf
    997 }  // namespace google
    998