| 1 | // Protocol Buffers - Google's data interchange format | 
| 2 | // Copyright 2008 Google Inc.  All rights reserved. | 
| 3 | // https://developers.google.com/protocol-buffers/ | 
| 4 | // | 
| 5 | // Redistribution and use in source and binary forms, with or without | 
| 6 | // modification, are permitted provided that the following conditions are | 
| 7 | // met: | 
| 8 | // | 
| 9 | //     * Redistributions of source code must retain the above copyright | 
| 10 | // notice, this list of conditions and the following disclaimer. | 
| 11 | //     * Redistributions in binary form must reproduce the above | 
| 12 | // copyright notice, this list of conditions and the following disclaimer | 
| 13 | // in the documentation and/or other materials provided with the | 
| 14 | // distribution. | 
| 15 | //     * Neither the name of Google Inc. nor the names of its | 
| 16 | // contributors may be used to endorse or promote products derived from | 
| 17 | // this software without specific prior written permission. | 
| 18 | // | 
| 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
| 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
| 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
| 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
| 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
| 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
| 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
| 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
| 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
| 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 30 |  | 
| 31 | // Author: kenton@google.com (Kenton Varda) | 
| 32 | //  Based on original Protocol Buffers design by | 
| 33 | //  Sanjay Ghemawat, Jeff Dean, and others. | 
| 34 |  | 
| 35 | #include <google/protobuf/compiler/java/primitive_field.h> | 
| 36 |  | 
| 37 | #include <cstdint> | 
| 38 | #include <map> | 
| 39 | #include <string> | 
| 40 |  | 
| 41 | #include <google/protobuf/stubs/logging.h> | 
| 42 | #include <google/protobuf/stubs/common.h> | 
| 43 | #include <google/protobuf/io/printer.h> | 
| 44 | #include <google/protobuf/wire_format.h> | 
| 45 | #include <google/protobuf/stubs/strutil.h> | 
| 46 | #include <google/protobuf/compiler/java/context.h> | 
| 47 | #include <google/protobuf/compiler/java/doc_comment.h> | 
| 48 | #include <google/protobuf/compiler/java/helpers.h> | 
| 49 | #include <google/protobuf/compiler/java/name_resolver.h> | 
| 50 |  | 
| 51 | namespace google { | 
| 52 | namespace protobuf { | 
| 53 | namespace compiler { | 
| 54 | namespace java { | 
| 55 |  | 
| 56 | using internal::WireFormat; | 
| 57 |  | 
| 58 | namespace { | 
| 59 |  | 
| 60 | void SetPrimitiveVariables(const FieldDescriptor* descriptor, | 
| 61 |                            int messageBitIndex, int builderBitIndex, | 
| 62 |                            const FieldGeneratorInfo* info, | 
| 63 |                            ClassNameResolver* name_resolver, | 
| 64 |                            std::map<std::string, std::string>* variables) { | 
| 65 |   SetCommonFieldVariables(descriptor, info, variables); | 
| 66 |   JavaType javaType = GetJavaType(field: descriptor); | 
| 67 |  | 
| 68 |   (*variables)["type" ] = PrimitiveTypeName(type: javaType); | 
| 69 |   (*variables)["boxed_type" ] = BoxedPrimitiveTypeName(type: javaType); | 
| 70 |   (*variables)["kt_type" ] = KotlinTypeName(type: javaType); | 
| 71 |   (*variables)["field_type" ] = (*variables)["type" ]; | 
| 72 |  | 
| 73 |   if (javaType == JAVATYPE_BOOLEAN || javaType == JAVATYPE_DOUBLE || | 
| 74 |       javaType == JAVATYPE_FLOAT || javaType == JAVATYPE_INT || | 
| 75 |       javaType == JAVATYPE_LONG) { | 
| 76 |     std::string capitalized_type = UnderscoresToCamelCase( | 
| 77 |         name: PrimitiveTypeName(type: javaType), /*cap_first_letter=*/true); | 
| 78 |     (*variables)["field_list_type" ] = | 
| 79 |         "com.google.protobuf.Internal."  + capitalized_type + "List" ; | 
| 80 |     (*variables)["empty_list" ] = "empty"  + capitalized_type + "List()" ; | 
| 81 |     (*variables)["create_list" ] = "new"  + capitalized_type + "List()" ; | 
| 82 |     (*variables)["mutable_copy_list" ] = | 
| 83 |         "mutableCopy("  + (*variables)["name" ] + "_)" ; | 
| 84 |     (*variables)["name_make_immutable" ] = | 
| 85 |         (*variables)["name" ] + "_.makeImmutable()" ; | 
| 86 |     (*variables)["repeated_get" ] = | 
| 87 |         (*variables)["name" ] + "_.get"  + capitalized_type; | 
| 88 |     (*variables)["repeated_add" ] = | 
| 89 |         (*variables)["name" ] + "_.add"  + capitalized_type; | 
| 90 |     (*variables)["repeated_set" ] = | 
| 91 |         (*variables)["name" ] + "_.set"  + capitalized_type; | 
| 92 |   } else { | 
| 93 |     (*variables)["field_list_type" ] = | 
| 94 |         "java.util.List<"  + (*variables)["boxed_type" ] + ">" ; | 
| 95 |     (*variables)["create_list" ] = | 
| 96 |         "new java.util.ArrayList<"  + (*variables)["boxed_type" ] + ">()" ; | 
| 97 |     (*variables)["mutable_copy_list" ] = "new java.util.ArrayList<"  + | 
| 98 |                                         (*variables)["boxed_type" ] + ">("  + | 
| 99 |                                         (*variables)["name" ] + "_)" ; | 
| 100 |     (*variables)["empty_list" ] = "java.util.Collections.emptyList()" ; | 
| 101 |     (*variables)["name_make_immutable" ] = | 
| 102 |         (*variables)["name" ] + "_ = java.util.Collections.unmodifiableList("  + | 
| 103 |         (*variables)["name" ] + "_)" ; | 
| 104 |     (*variables)["repeated_get" ] = (*variables)["name" ] + "_.get" ; | 
| 105 |     (*variables)["repeated_add" ] = (*variables)["name" ] + "_.add" ; | 
| 106 |     (*variables)["repeated_set" ] = (*variables)["name" ] + "_.set" ; | 
| 107 |   } | 
| 108 |  | 
| 109 |   (*variables)["default" ] = ImmutableDefaultValue(field: descriptor, name_resolver); | 
| 110 |   (*variables)["default_init" ] = | 
| 111 |       IsDefaultValueJavaDefault(field: descriptor) | 
| 112 |           ? ""  | 
| 113 |           : ("= "  + ImmutableDefaultValue(field: descriptor, name_resolver)); | 
| 114 |   (*variables)["capitalized_type" ] = | 
| 115 |       GetCapitalizedType(field: descriptor, /* immutable = */ true); | 
| 116 |   (*variables)["tag" ] = | 
| 117 |       StrCat(a: static_cast<int32_t>(WireFormat::MakeTag(field: descriptor))); | 
| 118 |   (*variables)["tag_size" ] = StrCat( | 
| 119 |       a: WireFormat::TagSize(field_number: descriptor->number(), type: GetType(field: descriptor))); | 
| 120 |   if (IsReferenceType(type: GetJavaType(field: descriptor))) { | 
| 121 |     (*variables)["null_check" ] = | 
| 122 |         "  if (value == null) {\n"  | 
| 123 |         "    throw new NullPointerException();\n"  | 
| 124 |         "  }\n" ; | 
| 125 |   } else { | 
| 126 |     (*variables)["null_check" ] = "" ; | 
| 127 |   } | 
| 128 |   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported | 
| 129 |   // by the proto compiler | 
| 130 |   (*variables)["deprecation" ] = | 
| 131 |       descriptor->options().deprecated() ? "@java.lang.Deprecated "  : "" ; | 
| 132 |   (*variables)["kt_deprecation" ] = | 
| 133 |       descriptor->options().deprecated() | 
| 134 |           ? "@kotlin.Deprecated(message = \"Field "  + (*variables)["name" ] + | 
| 135 |                 " is deprecated\") "  | 
| 136 |           : "" ; | 
| 137 |   int fixed_size = FixedSize(type: GetType(field: descriptor)); | 
| 138 |   if (fixed_size != -1) { | 
| 139 |     (*variables)["fixed_size" ] = StrCat(a: fixed_size); | 
| 140 |   } | 
| 141 |   (*variables)["on_changed" ] = "onChanged();" ; | 
| 142 |  | 
| 143 |   if (HasHasbit(descriptor)) { | 
| 144 |     // For singular messages and builders, one bit is used for the hasField bit. | 
| 145 |     (*variables)["get_has_field_bit_message" ] = GenerateGetBit(bitIndex: messageBitIndex); | 
| 146 |     (*variables)["get_has_field_bit_builder" ] = GenerateGetBit(bitIndex: builderBitIndex); | 
| 147 |  | 
| 148 |     // Note that these have a trailing ";". | 
| 149 |     (*variables)["set_has_field_bit_message" ] = | 
| 150 |         GenerateSetBit(bitIndex: messageBitIndex) + ";" ; | 
| 151 |     (*variables)["set_has_field_bit_builder" ] = | 
| 152 |         GenerateSetBit(bitIndex: builderBitIndex) + ";" ; | 
| 153 |     (*variables)["clear_has_field_bit_builder" ] = | 
| 154 |         GenerateClearBit(bitIndex: builderBitIndex) + ";" ; | 
| 155 |  | 
| 156 |     (*variables)["is_field_present_message" ] = GenerateGetBit(bitIndex: messageBitIndex); | 
| 157 |   } else { | 
| 158 |     (*variables)["set_has_field_bit_message" ] = "" ; | 
| 159 |     (*variables)["set_has_field_bit_builder" ] = "" ; | 
| 160 |     (*variables)["clear_has_field_bit_builder" ] = "" ; | 
| 161 |  | 
| 162 |     switch (descriptor->type()) { | 
| 163 |       case FieldDescriptor::TYPE_BYTES: | 
| 164 |         (*variables)["is_field_present_message" ] = | 
| 165 |             "!"  + (*variables)["name" ] + "_.isEmpty()" ; | 
| 166 |         break; | 
| 167 |       case FieldDescriptor::TYPE_FLOAT: | 
| 168 |         (*variables)["is_field_present_message" ] = | 
| 169 |             "java.lang.Float.floatToRawIntBits("  + (*variables)["name" ] + | 
| 170 |             "_) != 0" ; | 
| 171 |         break; | 
| 172 |       case FieldDescriptor::TYPE_DOUBLE: | 
| 173 |         (*variables)["is_field_present_message" ] = | 
| 174 |             "java.lang.Double.doubleToRawLongBits("  + (*variables)["name" ] + | 
| 175 |             "_) != 0" ; | 
| 176 |         break; | 
| 177 |       default: | 
| 178 |         (*variables)["is_field_present_message" ] = | 
| 179 |             (*variables)["name" ] + "_ != "  + (*variables)["default" ]; | 
| 180 |         break; | 
| 181 |     } | 
| 182 |   } | 
| 183 |  | 
| 184 |   // For repeated builders, one bit is used for whether the array is immutable. | 
| 185 |   (*variables)["get_mutable_bit_builder" ] = GenerateGetBit(bitIndex: builderBitIndex); | 
| 186 |   (*variables)["set_mutable_bit_builder" ] = GenerateSetBit(bitIndex: builderBitIndex); | 
| 187 |   (*variables)["clear_mutable_bit_builder" ] = GenerateClearBit(bitIndex: builderBitIndex); | 
| 188 |  | 
| 189 |   // For repeated fields, one bit is used for whether the array is immutable | 
| 190 |   // in the parsing constructor. | 
| 191 |   (*variables)["get_mutable_bit_parser" ] = | 
| 192 |       GenerateGetBitMutableLocal(bitIndex: builderBitIndex); | 
| 193 |   (*variables)["set_mutable_bit_parser" ] = | 
| 194 |       GenerateSetBitMutableLocal(bitIndex: builderBitIndex); | 
| 195 |  | 
| 196 |   (*variables)["get_has_field_bit_from_local" ] = | 
| 197 |       GenerateGetBitFromLocal(bitIndex: builderBitIndex); | 
| 198 |   (*variables)["set_has_field_bit_to_local" ] = | 
| 199 |       GenerateSetBitToLocal(bitIndex: messageBitIndex); | 
| 200 | } | 
| 201 |  | 
| 202 | }  // namespace | 
| 203 |  | 
| 204 | // =================================================================== | 
| 205 |  | 
| 206 | ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator( | 
| 207 |     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, | 
| 208 |     Context* context) | 
| 209 |     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { | 
| 210 |   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, | 
| 211 |                         info: context->GetFieldGeneratorInfo(field: descriptor), | 
| 212 |                         name_resolver: name_resolver_, variables: &variables_); | 
| 213 | } | 
| 214 |  | 
| 215 | ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {} | 
| 216 |  | 
| 217 | int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { | 
| 218 |   return HasHasbit(descriptor: descriptor_) ? 1 : 0; | 
| 219 | } | 
| 220 |  | 
| 221 | int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { | 
| 222 |   return GetNumBitsForMessage(); | 
| 223 | } | 
| 224 |  | 
| 225 | void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( | 
| 226 |     io::Printer* printer) const { | 
| 227 |   if (HasHazzer(descriptor: descriptor_)) { | 
| 228 |     WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); | 
| 229 |     printer->Print(variables: variables_, | 
| 230 |                    text: "$deprecation$boolean has$capitalized_name$();\n" ); | 
| 231 |   } | 
| 232 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER); | 
| 233 |   printer->Print(variables: variables_, text: "$deprecation$$type$ get$capitalized_name$();\n" ); | 
| 234 | } | 
| 235 |  | 
| 236 | void ImmutablePrimitiveFieldGenerator::GenerateMembers( | 
| 237 |     io::Printer* printer) const { | 
| 238 |   printer->Print(variables: variables_, text: "private $field_type$ $name$_;\n" ); | 
| 239 |   PrintExtraFieldInfo(variables: variables_, printer); | 
| 240 |   if (HasHazzer(descriptor: descriptor_)) { | 
| 241 |     WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); | 
| 242 |     printer->Print( | 
| 243 |         variables: variables_, | 
| 244 |         text: "@java.lang.Override\n"  | 
| 245 |         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"  | 
| 246 |         "  return $get_has_field_bit_message$;\n"  | 
| 247 |         "}\n" ); | 
| 248 |     printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 249 |   } | 
| 250 |  | 
| 251 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER); | 
| 252 |   printer->Print(variables: variables_, | 
| 253 |                  text: "@java.lang.Override\n"  | 
| 254 |                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"  | 
| 255 |                  "  return $name$_;\n"  | 
| 256 |                  "}\n" ); | 
| 257 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 258 | } | 
| 259 |  | 
| 260 | void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( | 
| 261 |     io::Printer* printer) const { | 
| 262 |   printer->Print(variables: variables_, text: "private $field_type$ $name$_ $default_init$;\n" ); | 
| 263 |  | 
| 264 |   if (HasHazzer(descriptor: descriptor_)) { | 
| 265 |     WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); | 
| 266 |     printer->Print( | 
| 267 |         variables: variables_, | 
| 268 |         text: "@java.lang.Override\n"  | 
| 269 |         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"  | 
| 270 |         "  return $get_has_field_bit_builder$;\n"  | 
| 271 |         "}\n" ); | 
| 272 |     printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 273 |   } | 
| 274 |  | 
| 275 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER); | 
| 276 |   printer->Print(variables: variables_, | 
| 277 |                  text: "@java.lang.Override\n"  | 
| 278 |                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"  | 
| 279 |                  "  return $name$_;\n"  | 
| 280 |                  "}\n" ); | 
| 281 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 282 |  | 
| 283 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: SETTER, | 
| 284 |                                /* builder */ true); | 
| 285 |   printer->Print(variables: variables_, | 
| 286 |                  text: "$deprecation$public Builder "  | 
| 287 |                  "${$set$capitalized_name$$}$($type$ value) {\n"  | 
| 288 |                  "$null_check$"  | 
| 289 |                  "  $set_has_field_bit_builder$\n"  | 
| 290 |                  "  $name$_ = value;\n"  | 
| 291 |                  "  $on_changed$\n"  | 
| 292 |                  "  return this;\n"  | 
| 293 |                  "}\n" ); | 
| 294 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 295 |  | 
| 296 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER, | 
| 297 |                                /* builder */ true); | 
| 298 |   printer->Print( | 
| 299 |       variables: variables_, | 
| 300 |       text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"  | 
| 301 |       "  $clear_has_field_bit_builder$\n" ); | 
| 302 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 303 |   JavaType type = GetJavaType(field: descriptor_); | 
| 304 |   if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { | 
| 305 |     // The default value is not a simple literal so we want to avoid executing | 
| 306 |     // it multiple times.  Instead, get the default out of the default instance. | 
| 307 |     printer->Print( | 
| 308 |         variables: variables_, | 
| 309 |         text: "  $name$_ = getDefaultInstance().get$capitalized_name$();\n" ); | 
| 310 |   } else { | 
| 311 |     printer->Print(variables: variables_, text: "  $name$_ = $default$;\n" ); | 
| 312 |   } | 
| 313 |   printer->Print(variables: variables_, | 
| 314 |                  text: "  $on_changed$\n"  | 
| 315 |                  "  return this;\n"  | 
| 316 |                  "}\n" ); | 
| 317 | } | 
| 318 |  | 
| 319 | void ImmutablePrimitiveFieldGenerator::GenerateKotlinDslMembers( | 
| 320 |     io::Printer* printer) const { | 
| 321 |   WriteFieldDocComment(printer, field: descriptor_); | 
| 322 |   printer->Print(variables: variables_, | 
| 323 |                  text: "$kt_deprecation$var $kt_name$: $kt_type$\n"  | 
| 324 |                  "  @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"  | 
| 325 |                  "  get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"  | 
| 326 |                  "  @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"  | 
| 327 |                  "  set(value) {\n"  | 
| 328 |                  "    $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"  | 
| 329 |                  "  }\n" ); | 
| 330 |  | 
| 331 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER, | 
| 332 |                                /* builder */ false); | 
| 333 |   printer->Print(variables: variables_, | 
| 334 |                  text: "fun ${$clear$kt_capitalized_name$$}$() {\n"  | 
| 335 |                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"  | 
| 336 |                  "}\n" ); | 
| 337 |  | 
| 338 |   if (HasHazzer(descriptor: descriptor_)) { | 
| 339 |     WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); | 
| 340 |     printer->Print( | 
| 341 |         variables: variables_, | 
| 342 |         text: "fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"  | 
| 343 |         "  return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"  | 
| 344 |         "}\n" ); | 
| 345 |   } | 
| 346 | } | 
| 347 |  | 
| 348 | void ImmutablePrimitiveFieldGenerator::GenerateFieldBuilderInitializationCode( | 
| 349 |     io::Printer* printer) const { | 
| 350 |   // noop for primitives | 
| 351 | } | 
| 352 |  | 
| 353 | void ImmutablePrimitiveFieldGenerator::GenerateInitializationCode( | 
| 354 |     io::Printer* printer) const { | 
| 355 |   if (!IsDefaultValueJavaDefault(field: descriptor_)) { | 
| 356 |     printer->Print(variables: variables_, text: "$name$_ = $default$;\n" ); | 
| 357 |   } | 
| 358 | } | 
| 359 |  | 
| 360 | void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( | 
| 361 |     io::Printer* printer) const { | 
| 362 |   printer->Print(variables: variables_, | 
| 363 |                  text: "$name$_ = $default$;\n"  | 
| 364 |                  "$clear_has_field_bit_builder$\n" ); | 
| 365 | } | 
| 366 |  | 
| 367 | void ImmutablePrimitiveFieldGenerator::GenerateMergingCode( | 
| 368 |     io::Printer* printer) const { | 
| 369 |   if (HasHazzer(descriptor: descriptor_)) { | 
| 370 |     printer->Print(variables: variables_, | 
| 371 |                    text: "if (other.has$capitalized_name$()) {\n"  | 
| 372 |                    "  set$capitalized_name$(other.get$capitalized_name$());\n"  | 
| 373 |                    "}\n" ); | 
| 374 |   } else { | 
| 375 |     printer->Print(variables: variables_, | 
| 376 |                    text: "if (other.get$capitalized_name$() != $default$) {\n"  | 
| 377 |                    "  set$capitalized_name$(other.get$capitalized_name$());\n"  | 
| 378 |                    "}\n" ); | 
| 379 |   } | 
| 380 | } | 
| 381 |  | 
| 382 | void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode( | 
| 383 |     io::Printer* printer) const { | 
| 384 |   if (HasHazzer(descriptor: descriptor_)) { | 
| 385 |     if (IsDefaultValueJavaDefault(field: descriptor_)) { | 
| 386 |       printer->Print(variables: variables_, | 
| 387 |                      text: "if ($get_has_field_bit_from_local$) {\n"  | 
| 388 |                      "  result.$name$_ = $name$_;\n"  | 
| 389 |                      "  $set_has_field_bit_to_local$;\n"  | 
| 390 |                      "}\n" ); | 
| 391 |     } else { | 
| 392 |       printer->Print(variables: variables_, | 
| 393 |                      text: "if ($get_has_field_bit_from_local$) {\n"  | 
| 394 |                      "  $set_has_field_bit_to_local$;\n"  | 
| 395 |                      "}\n"  | 
| 396 |                      "result.$name$_ = $name$_;\n" ); | 
| 397 |     } | 
| 398 |   } else { | 
| 399 |     printer->Print(variables: variables_, text: "result.$name$_ = $name$_;\n" ); | 
| 400 |   } | 
| 401 | } | 
| 402 |  | 
| 403 | void ImmutablePrimitiveFieldGenerator::GenerateParsingCode( | 
| 404 |     io::Printer* printer) const { | 
| 405 |   printer->Print(variables: variables_, | 
| 406 |                  text: "$set_has_field_bit_message$\n"  | 
| 407 |                  "$name$_ = input.read$capitalized_type$();\n" ); | 
| 408 | } | 
| 409 |  | 
| 410 | void ImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode( | 
| 411 |     io::Printer* printer) const { | 
| 412 |   // noop for primitives. | 
| 413 | } | 
| 414 |  | 
| 415 | void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode( | 
| 416 |     io::Printer* printer) const { | 
| 417 |   printer->Print(variables: variables_, | 
| 418 |                  text: "if ($is_field_present_message$) {\n"  | 
| 419 |                  "  output.write$capitalized_type$($number$, $name$_);\n"  | 
| 420 |                  "}\n" ); | 
| 421 | } | 
| 422 |  | 
| 423 | void ImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode( | 
| 424 |     io::Printer* printer) const { | 
| 425 |   printer->Print(variables: variables_, | 
| 426 |                  text: "if ($is_field_present_message$) {\n"  | 
| 427 |                  "  size += com.google.protobuf.CodedOutputStream\n"  | 
| 428 |                  "    .compute$capitalized_type$Size($number$, $name$_);\n"  | 
| 429 |                  "}\n" ); | 
| 430 | } | 
| 431 |  | 
| 432 | void ImmutablePrimitiveFieldGenerator::GenerateEqualsCode( | 
| 433 |     io::Printer* printer) const { | 
| 434 |   switch (GetJavaType(field: descriptor_)) { | 
| 435 |     case JAVATYPE_INT: | 
| 436 |     case JAVATYPE_LONG: | 
| 437 |     case JAVATYPE_BOOLEAN: | 
| 438 |       printer->Print(variables: variables_, | 
| 439 |                      text: "if (get$capitalized_name$()\n"  | 
| 440 |                      "    != other.get$capitalized_name$()) return false;\n" ); | 
| 441 |       break; | 
| 442 |  | 
| 443 |     case JAVATYPE_FLOAT: | 
| 444 |       printer->Print( | 
| 445 |           variables: variables_, | 
| 446 |           text: "if (java.lang.Float.floatToIntBits(get$capitalized_name$())\n"  | 
| 447 |           "    != java.lang.Float.floatToIntBits(\n"  | 
| 448 |           "        other.get$capitalized_name$())) return false;\n" ); | 
| 449 |       break; | 
| 450 |  | 
| 451 |     case JAVATYPE_DOUBLE: | 
| 452 |       printer->Print( | 
| 453 |           variables: variables_, | 
| 454 |           text: "if (java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"  | 
| 455 |           "    != java.lang.Double.doubleToLongBits(\n"  | 
| 456 |           "        other.get$capitalized_name$())) return false;\n" ); | 
| 457 |       break; | 
| 458 |  | 
| 459 |     case JAVATYPE_STRING: | 
| 460 |     case JAVATYPE_BYTES: | 
| 461 |       printer->Print( | 
| 462 |           variables: variables_, | 
| 463 |           text: "if (!get$capitalized_name$()\n"  | 
| 464 |           "    .equals(other.get$capitalized_name$())) return false;\n" ); | 
| 465 |       break; | 
| 466 |  | 
| 467 |     case JAVATYPE_ENUM: | 
| 468 |     case JAVATYPE_MESSAGE: | 
| 469 |     default: | 
| 470 |       GOOGLE_LOG(FATAL) << "Can't get here." ; | 
| 471 |       break; | 
| 472 |   } | 
| 473 | } | 
| 474 |  | 
| 475 | void ImmutablePrimitiveFieldGenerator::GenerateHashCode( | 
| 476 |     io::Printer* printer) const { | 
| 477 |   printer->Print(variables: variables_, text: "hash = (37 * hash) + $constant_name$;\n" ); | 
| 478 |   switch (GetJavaType(field: descriptor_)) { | 
| 479 |     case JAVATYPE_INT: | 
| 480 |       printer->Print(variables: variables_, | 
| 481 |                      text: "hash = (53 * hash) + get$capitalized_name$();\n" ); | 
| 482 |       break; | 
| 483 |  | 
| 484 |     case JAVATYPE_LONG: | 
| 485 |       printer->Print( | 
| 486 |           variables: variables_, | 
| 487 |           text: "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"  | 
| 488 |           "    get$capitalized_name$());\n" ); | 
| 489 |       break; | 
| 490 |  | 
| 491 |     case JAVATYPE_BOOLEAN: | 
| 492 |       printer->Print( | 
| 493 |           variables: variables_, | 
| 494 |           text: "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"  | 
| 495 |           "    get$capitalized_name$());\n" ); | 
| 496 |       break; | 
| 497 |  | 
| 498 |     case JAVATYPE_FLOAT: | 
| 499 |       printer->Print(variables: variables_, | 
| 500 |                      text: "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"  | 
| 501 |                      "    get$capitalized_name$());\n" ); | 
| 502 |       break; | 
| 503 |  | 
| 504 |     case JAVATYPE_DOUBLE: | 
| 505 |       printer->Print( | 
| 506 |           variables: variables_, | 
| 507 |           text: "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"  | 
| 508 |           "    java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n" ); | 
| 509 |       break; | 
| 510 |  | 
| 511 |     case JAVATYPE_STRING: | 
| 512 |     case JAVATYPE_BYTES: | 
| 513 |       printer->Print( | 
| 514 |           variables: variables_, | 
| 515 |           text: "hash = (53 * hash) + get$capitalized_name$().hashCode();\n" ); | 
| 516 |       break; | 
| 517 |  | 
| 518 |     case JAVATYPE_ENUM: | 
| 519 |     case JAVATYPE_MESSAGE: | 
| 520 |     default: | 
| 521 |       GOOGLE_LOG(FATAL) << "Can't get here." ; | 
| 522 |       break; | 
| 523 |   } | 
| 524 | } | 
| 525 |  | 
| 526 | std::string ImmutablePrimitiveFieldGenerator::GetBoxedType() const { | 
| 527 |   return BoxedPrimitiveTypeName(type: GetJavaType(field: descriptor_)); | 
| 528 | } | 
| 529 |  | 
| 530 | // =================================================================== | 
| 531 |  | 
| 532 | ImmutablePrimitiveOneofFieldGenerator::ImmutablePrimitiveOneofFieldGenerator( | 
| 533 |     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, | 
| 534 |     Context* context) | 
| 535 |     : ImmutablePrimitiveFieldGenerator(descriptor, messageBitIndex, | 
| 536 |                                        builderBitIndex, context) { | 
| 537 |   const OneofGeneratorInfo* info = | 
| 538 |       context->GetOneofGeneratorInfo(oneof: descriptor->containing_oneof()); | 
| 539 |   SetCommonOneofVariables(descriptor, info, variables: &variables_); | 
| 540 | } | 
| 541 |  | 
| 542 | ImmutablePrimitiveOneofFieldGenerator:: | 
| 543 |     ~ImmutablePrimitiveOneofFieldGenerator() {} | 
| 544 |  | 
| 545 | void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( | 
| 546 |     io::Printer* printer) const { | 
| 547 |   PrintExtraFieldInfo(variables: variables_, printer); | 
| 548 |   GOOGLE_DCHECK(HasHazzer(descriptor_)); | 
| 549 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); | 
| 550 |   printer->Print(variables: variables_, | 
| 551 |                  text: "@java.lang.Override\n"  | 
| 552 |                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"  | 
| 553 |                  "  return $has_oneof_case_message$;\n"  | 
| 554 |                  "}\n" ); | 
| 555 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 556 |  | 
| 557 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER); | 
| 558 |   printer->Print(variables: variables_, | 
| 559 |                  text: "@java.lang.Override\n"  | 
| 560 |                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"  | 
| 561 |                  "  if ($has_oneof_case_message$) {\n"  | 
| 562 |                  "    return ($boxed_type$) $oneof_name$_;\n"  | 
| 563 |                  "  }\n"  | 
| 564 |                  "  return $default$;\n"  | 
| 565 |                  "}\n" ); | 
| 566 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 567 | } | 
| 568 |  | 
| 569 | void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( | 
| 570 |     io::Printer* printer) const { | 
| 571 |   GOOGLE_DCHECK(HasHazzer(descriptor_)); | 
| 572 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER); | 
| 573 |   printer->Print(variables: variables_, | 
| 574 |                  text: "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"  | 
| 575 |                  "  return $has_oneof_case_message$;\n"  | 
| 576 |                  "}\n" ); | 
| 577 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 578 |  | 
| 579 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER); | 
| 580 |   printer->Print(variables: variables_, | 
| 581 |                  text: "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"  | 
| 582 |                  "  if ($has_oneof_case_message$) {\n"  | 
| 583 |                  "    return ($boxed_type$) $oneof_name$_;\n"  | 
| 584 |                  "  }\n"  | 
| 585 |                  "  return $default$;\n"  | 
| 586 |                  "}\n" ); | 
| 587 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 588 |  | 
| 589 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: SETTER, | 
| 590 |                                /* builder */ true); | 
| 591 |   printer->Print(variables: variables_, | 
| 592 |                  text: "$deprecation$public Builder "  | 
| 593 |                  "${$set$capitalized_name$$}$($type$ value) {\n"  | 
| 594 |                  "$null_check$"  | 
| 595 |                  "  $set_oneof_case_message$;\n"  | 
| 596 |                  "  $oneof_name$_ = value;\n"  | 
| 597 |                  "  $on_changed$\n"  | 
| 598 |                  "  return this;\n"  | 
| 599 |                  "}\n" ); | 
| 600 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 601 |  | 
| 602 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER, | 
| 603 |                                /* builder */ true); | 
| 604 |   printer->Print( | 
| 605 |       variables: variables_, | 
| 606 |       text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"  | 
| 607 |       "  if ($has_oneof_case_message$) {\n"  | 
| 608 |       "    $clear_oneof_case_message$;\n"  | 
| 609 |       "    $oneof_name$_ = null;\n"  | 
| 610 |       "    $on_changed$\n"  | 
| 611 |       "  }\n"  | 
| 612 |       "  return this;\n"  | 
| 613 |       "}\n" ); | 
| 614 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 615 | } | 
| 616 |  | 
| 617 | void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode( | 
| 618 |     io::Printer* printer) const { | 
| 619 |   printer->Print(variables: variables_, | 
| 620 |                  text: "if ($has_oneof_case_message$) {\n"  | 
| 621 |                  "  result.$oneof_name$_ = $oneof_name$_;\n"  | 
| 622 |                  "}\n" ); | 
| 623 | } | 
| 624 |  | 
| 625 | void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode( | 
| 626 |     io::Printer* printer) const { | 
| 627 |   printer->Print(variables: variables_, | 
| 628 |                  text: "set$capitalized_name$(other.get$capitalized_name$());\n" ); | 
| 629 | } | 
| 630 |  | 
| 631 | void ImmutablePrimitiveOneofFieldGenerator::GenerateParsingCode( | 
| 632 |     io::Printer* printer) const { | 
| 633 |   printer->Print(variables: variables_, | 
| 634 |                  text: "$oneof_name$_ = input.read$capitalized_type$();\n"  | 
| 635 |                  "$set_oneof_case_message$;\n" ); | 
| 636 | } | 
| 637 |  | 
| 638 | void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializationCode( | 
| 639 |     io::Printer* printer) const { | 
| 640 |   printer->Print(variables: variables_, | 
| 641 |                  text: "if ($has_oneof_case_message$) {\n"  | 
| 642 |                  "  output.write$capitalized_type$(\n" ); | 
| 643 |   // $type$ and $boxed_type$ is the same for bytes fields so we don't need to | 
| 644 |   // do redundant casts. | 
| 645 |   if (GetJavaType(field: descriptor_) == JAVATYPE_BYTES) { | 
| 646 |     printer->Print(variables: variables_, text: "      $number$, ($type$) $oneof_name$_);\n" ); | 
| 647 |   } else { | 
| 648 |     printer->Print( | 
| 649 |         variables: variables_, | 
| 650 |         text: "      $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" ); | 
| 651 |   } | 
| 652 |   printer->Print(text: "}\n" ); | 
| 653 | } | 
| 654 |  | 
| 655 | void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializedSizeCode( | 
| 656 |     io::Printer* printer) const { | 
| 657 |   printer->Print(variables: variables_, | 
| 658 |                  text: "if ($has_oneof_case_message$) {\n"  | 
| 659 |                  "  size += com.google.protobuf.CodedOutputStream\n"  | 
| 660 |                  "    .compute$capitalized_type$Size(\n" ); | 
| 661 |   // $type$ and $boxed_type$ is the same for bytes fields so we don't need to | 
| 662 |   // do redundant casts. | 
| 663 |   if (GetJavaType(field: descriptor_) == JAVATYPE_BYTES) { | 
| 664 |     printer->Print(variables: variables_, text: "        $number$, ($type$) $oneof_name$_);\n" ); | 
| 665 |   } else { | 
| 666 |     printer->Print( | 
| 667 |         variables: variables_, | 
| 668 |         text: "        $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" ); | 
| 669 |   } | 
| 670 |   printer->Print(text: "}\n" ); | 
| 671 | } | 
| 672 |  | 
| 673 | // =================================================================== | 
| 674 |  | 
| 675 | RepeatedImmutablePrimitiveFieldGenerator:: | 
| 676 |     RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor, | 
| 677 |                                              int messageBitIndex, | 
| 678 |                                              int builderBitIndex, | 
| 679 |                                              Context* context) | 
| 680 |     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { | 
| 681 |   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, | 
| 682 |                         info: context->GetFieldGeneratorInfo(field: descriptor), | 
| 683 |                         name_resolver: name_resolver_, variables: &variables_); | 
| 684 | } | 
| 685 |  | 
| 686 | RepeatedImmutablePrimitiveFieldGenerator:: | 
| 687 |     ~RepeatedImmutablePrimitiveFieldGenerator() {} | 
| 688 |  | 
| 689 | int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { | 
| 690 |   return 0; | 
| 691 | } | 
| 692 |  | 
| 693 | int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { | 
| 694 |   return 1; | 
| 695 | } | 
| 696 |  | 
| 697 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( | 
| 698 |     io::Printer* printer) const { | 
| 699 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_GETTER); | 
| 700 |   printer->Print(variables: variables_, | 
| 701 |                  text: "$deprecation$java.util.List<$boxed_type$> "  | 
| 702 |                  "get$capitalized_name$List();\n" ); | 
| 703 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_COUNT); | 
| 704 |   printer->Print(variables: variables_, | 
| 705 |                  text: "$deprecation$int get$capitalized_name$Count();\n" ); | 
| 706 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_GETTER); | 
| 707 |   printer->Print(variables: variables_, | 
| 708 |                  text: "$deprecation$$type$ get$capitalized_name$(int index);\n" ); | 
| 709 | } | 
| 710 |  | 
| 711 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers( | 
| 712 |     io::Printer* printer) const { | 
| 713 |   printer->Print(variables: variables_, text: "private $field_list_type$ $name$_;\n" ); | 
| 714 |   PrintExtraFieldInfo(variables: variables_, printer); | 
| 715 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_GETTER); | 
| 716 |   printer->Print(variables: variables_, | 
| 717 |                  text: "@java.lang.Override\n"  | 
| 718 |                  "$deprecation$public java.util.List<$boxed_type$>\n"  | 
| 719 |                  "    ${$get$capitalized_name$List$}$() {\n"  | 
| 720 |                  "  return $name$_;\n"   // note:  unmodifiable list | 
| 721 |                  "}\n" ); | 
| 722 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 723 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_COUNT); | 
| 724 |   printer->Print( | 
| 725 |       variables: variables_, | 
| 726 |       text: "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"  | 
| 727 |       "  return $name$_.size();\n"  | 
| 728 |       "}\n" ); | 
| 729 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 730 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_GETTER); | 
| 731 |   printer->Print( | 
| 732 |       variables: variables_, | 
| 733 |       text: "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"  | 
| 734 |       "  return $repeated_get$(index);\n"  | 
| 735 |       "}\n" ); | 
| 736 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 737 |  | 
| 738 |   if (descriptor_->is_packed()) { | 
| 739 |     printer->Print(variables: variables_, | 
| 740 |                    text: "private int $name$MemoizedSerializedSize = -1;\n" ); | 
| 741 |   } | 
| 742 | } | 
| 743 |  | 
| 744 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( | 
| 745 |     io::Printer* printer) const { | 
| 746 |   // One field is the list and the bit field keeps track of whether the | 
| 747 |   // list is immutable. If it's immutable, the invariant is that it must | 
| 748 |   // either an instance of Collections.emptyList() or it's an ArrayList | 
| 749 |   // wrapped in a Collections.unmodifiableList() wrapper and nobody else has | 
| 750 |   // a reference to the underlying ArrayList. This invariant allows us to | 
| 751 |   // share instances of lists between protocol buffers avoiding expensive | 
| 752 |   // memory allocations. Note, immutable is a strong guarantee here -- not | 
| 753 |   // just that the list cannot be modified via the reference but that the | 
| 754 |   // list can never be modified. | 
| 755 |   printer->Print(variables: variables_, | 
| 756 |                  text: "private $field_list_type$ $name$_ = $empty_list$;\n" ); | 
| 757 |  | 
| 758 |   printer->Print(variables: variables_, | 
| 759 |                  text: "private void ensure$capitalized_name$IsMutable() {\n"  | 
| 760 |                  "  if (!$get_mutable_bit_builder$) {\n"  | 
| 761 |                  "    $name$_ = $mutable_copy_list$;\n"  | 
| 762 |                  "    $set_mutable_bit_builder$;\n"  | 
| 763 |                  "   }\n"  | 
| 764 |                  "}\n" ); | 
| 765 |  | 
| 766 |   // Note:  We return an unmodifiable list because otherwise the caller | 
| 767 |   //   could hold on to the returned list and modify it after the message | 
| 768 |   //   has been built, thus mutating the message which is supposed to be | 
| 769 |   //   immutable. | 
| 770 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_GETTER); | 
| 771 |   printer->Print( | 
| 772 |       variables: variables_, | 
| 773 |       text: "$deprecation$public java.util.List<$boxed_type$>\n"  | 
| 774 |       "    ${$get$capitalized_name$List$}$() {\n"  | 
| 775 |       "  return $get_mutable_bit_builder$ ?\n"  | 
| 776 |       "           java.util.Collections.unmodifiableList($name$_) : $name$_;\n"  | 
| 777 |       "}\n" ); | 
| 778 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 779 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_COUNT); | 
| 780 |   printer->Print( | 
| 781 |       variables: variables_, | 
| 782 |       text: "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"  | 
| 783 |       "  return $name$_.size();\n"  | 
| 784 |       "}\n" ); | 
| 785 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 786 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_GETTER); | 
| 787 |   printer->Print( | 
| 788 |       variables: variables_, | 
| 789 |       text: "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"  | 
| 790 |       "  return $repeated_get$(index);\n"  | 
| 791 |       "}\n" ); | 
| 792 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 793 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_SETTER, | 
| 794 |                                /* builder */ true); | 
| 795 |   printer->Print(variables: variables_, | 
| 796 |                  text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"  | 
| 797 |                  "    int index, $type$ value) {\n"  | 
| 798 |                  "$null_check$"  | 
| 799 |                  "  ensure$capitalized_name$IsMutable();\n"  | 
| 800 |                  "  $repeated_set$(index, value);\n"  | 
| 801 |                  "  $on_changed$\n"  | 
| 802 |                  "  return this;\n"  | 
| 803 |                  "}\n" ); | 
| 804 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 805 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER, | 
| 806 |                                /* builder */ true); | 
| 807 |   printer->Print(variables: variables_, | 
| 808 |                  text: "$deprecation$public Builder "  | 
| 809 |                  "${$add$capitalized_name$$}$($type$ value) {\n"  | 
| 810 |                  "$null_check$"  | 
| 811 |                  "  ensure$capitalized_name$IsMutable();\n"  | 
| 812 |                  "  $repeated_add$(value);\n"  | 
| 813 |                  "  $on_changed$\n"  | 
| 814 |                  "  return this;\n"  | 
| 815 |                  "}\n" ); | 
| 816 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 817 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER, | 
| 818 |                                /* builder */ true); | 
| 819 |   printer->Print(variables: variables_, | 
| 820 |                  text: "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"  | 
| 821 |                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"  | 
| 822 |                  "  ensure$capitalized_name$IsMutable();\n"  | 
| 823 |                  "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"  | 
| 824 |                  "      values, $name$_);\n"  | 
| 825 |                  "  $on_changed$\n"  | 
| 826 |                  "  return this;\n"  | 
| 827 |                  "}\n" ); | 
| 828 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 829 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER, | 
| 830 |                                /* builder */ true); | 
| 831 |   printer->Print( | 
| 832 |       variables: variables_, | 
| 833 |       text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"  | 
| 834 |       "  $name$_ = $empty_list$;\n"  | 
| 835 |       "  $clear_mutable_bit_builder$;\n"  | 
| 836 |       "  $on_changed$\n"  | 
| 837 |       "  return this;\n"  | 
| 838 |       "}\n" ); | 
| 839 |   printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); | 
| 840 | } | 
| 841 |  | 
| 842 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateKotlinDslMembers( | 
| 843 |     io::Printer* printer) const { | 
| 844 |   printer->Print( | 
| 845 |       variables: variables_, | 
| 846 |       text: "/**\n"  | 
| 847 |       " * An uninstantiable, behaviorless type to represent the field in\n"  | 
| 848 |       " * generics.\n"  | 
| 849 |       " */\n"  | 
| 850 |       "@kotlin.OptIn"  | 
| 851 |       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"  | 
| 852 |       "class ${$$kt_capitalized_name$Proxy$}$ private constructor()"  | 
| 853 |       " : com.google.protobuf.kotlin.DslProxy()\n" ); | 
| 854 |  | 
| 855 |   WriteFieldDocComment(printer, field: descriptor_); | 
| 856 |   printer->Print(variables: variables_, | 
| 857 |                  text: "$kt_deprecation$ val $kt_name$: "  | 
| 858 |                  "com.google.protobuf.kotlin.DslList"  | 
| 859 |                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"  | 
| 860 |                  "  @kotlin.jvm.JvmSynthetic\n"  | 
| 861 |                  "  get() = com.google.protobuf.kotlin.DslList(\n"  | 
| 862 |                  "    $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"  | 
| 863 |                  "  )\n" ); | 
| 864 |  | 
| 865 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER, | 
| 866 |                                /* builder */ false); | 
| 867 |   printer->Print(variables: variables_, | 
| 868 |                  text: "@kotlin.jvm.JvmSynthetic\n"  | 
| 869 |                  "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"  | 
| 870 |                  "fun com.google.protobuf.kotlin.DslList"  | 
| 871 |                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."  | 
| 872 |                  "add(value: $kt_type$) {\n"  | 
| 873 |                  "  $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"  | 
| 874 |                  "}" ); | 
| 875 |  | 
| 876 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER, | 
| 877 |                                /* builder */ false); | 
| 878 |   printer->Print(variables: variables_, | 
| 879 |                  text: "@kotlin.jvm.JvmSynthetic\n"  | 
| 880 |                  "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"  | 
| 881 |                  "@Suppress(\"NOTHING_TO_INLINE\")\n"  | 
| 882 |                  "inline operator fun com.google.protobuf.kotlin.DslList"  | 
| 883 |                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."  | 
| 884 |                  "plusAssign(value: $kt_type$) {\n"  | 
| 885 |                  "  add(value)\n"  | 
| 886 |                  "}" ); | 
| 887 |  | 
| 888 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER, | 
| 889 |                                /* builder */ false); | 
| 890 |   printer->Print(variables: variables_, | 
| 891 |                  text: "@kotlin.jvm.JvmSynthetic\n"  | 
| 892 |                  "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"  | 
| 893 |                  "fun com.google.protobuf.kotlin.DslList"  | 
| 894 |                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."  | 
| 895 |                  "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"  | 
| 896 |                  "  $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"  | 
| 897 |                  "}" ); | 
| 898 |  | 
| 899 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER, | 
| 900 |                                /* builder */ false); | 
| 901 |   printer->Print( | 
| 902 |       variables: variables_, | 
| 903 |       text: "@kotlin.jvm.JvmSynthetic\n"  | 
| 904 |       "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"  | 
| 905 |       "@Suppress(\"NOTHING_TO_INLINE\")\n"  | 
| 906 |       "inline operator fun com.google.protobuf.kotlin.DslList"  | 
| 907 |       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."  | 
| 908 |       "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"  | 
| 909 |       "  addAll(values)\n"  | 
| 910 |       "}" ); | 
| 911 |  | 
| 912 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_SETTER, | 
| 913 |                                /* builder */ false); | 
| 914 |   printer->Print( | 
| 915 |       variables: variables_, | 
| 916 |       text: "@kotlin.jvm.JvmSynthetic\n"  | 
| 917 |       "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"  | 
| 918 |       "operator fun com.google.protobuf.kotlin.DslList"  | 
| 919 |       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."  | 
| 920 |       "set(index: kotlin.Int, value: $kt_type$) {\n"  | 
| 921 |       "  $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"  | 
| 922 |       "}" ); | 
| 923 |  | 
| 924 |   WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER, | 
| 925 |                                /* builder */ false); | 
| 926 |   printer->Print(variables: variables_, | 
| 927 |                  text: "@kotlin.jvm.JvmSynthetic\n"  | 
| 928 |                  "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"  | 
| 929 |                  "fun com.google.protobuf.kotlin.DslList"  | 
| 930 |                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."  | 
| 931 |                  "clear() {\n"  | 
| 932 |                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"  | 
| 933 |                  "}" ); | 
| 934 | } | 
| 935 |  | 
| 936 | void RepeatedImmutablePrimitiveFieldGenerator:: | 
| 937 |     GenerateFieldBuilderInitializationCode(io::Printer* printer) const { | 
| 938 |   // noop for primitives | 
| 939 | } | 
| 940 |  | 
| 941 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateInitializationCode( | 
| 942 |     io::Printer* printer) const { | 
| 943 |   printer->Print(variables: variables_, text: "$name$_ = $empty_list$;\n" ); | 
| 944 | } | 
| 945 |  | 
| 946 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( | 
| 947 |     io::Printer* printer) const { | 
| 948 |   printer->Print(variables: variables_, | 
| 949 |                  text: "$name$_ = $empty_list$;\n"  | 
| 950 |                  "$clear_mutable_bit_builder$;\n" ); | 
| 951 | } | 
| 952 |  | 
| 953 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode( | 
| 954 |     io::Printer* printer) const { | 
| 955 |   // The code below does two optimizations: | 
| 956 |   //   1. If the other list is empty, there's nothing to do. This ensures we | 
| 957 |   //      don't allocate a new array if we already have an immutable one. | 
| 958 |   //   2. If the other list is non-empty and our current list is empty, we can | 
| 959 |   //      reuse the other list which is guaranteed to be immutable. | 
| 960 |   printer->Print(variables: variables_, | 
| 961 |                  text: "if (!other.$name$_.isEmpty()) {\n"  | 
| 962 |                  "  if ($name$_.isEmpty()) {\n"  | 
| 963 |                  "    $name$_ = other.$name$_;\n"  | 
| 964 |                  "    $clear_mutable_bit_builder$;\n"  | 
| 965 |                  "  } else {\n"  | 
| 966 |                  "    ensure$capitalized_name$IsMutable();\n"  | 
| 967 |                  "    $name$_.addAll(other.$name$_);\n"  | 
| 968 |                  "  }\n"  | 
| 969 |                  "  $on_changed$\n"  | 
| 970 |                  "}\n" ); | 
| 971 | } | 
| 972 |  | 
| 973 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuildingCode( | 
| 974 |     io::Printer* printer) const { | 
| 975 |   // The code below ensures that the result has an immutable list. If our | 
| 976 |   // list is immutable, we can just reuse it. If not, we make it immutable. | 
| 977 |   printer->Print(variables: variables_, | 
| 978 |                  text: "if ($get_mutable_bit_builder$) {\n"  | 
| 979 |                  "  $name_make_immutable$;\n"  | 
| 980 |                  "  $clear_mutable_bit_builder$;\n"  | 
| 981 |                  "}\n"  | 
| 982 |                  "result.$name$_ = $name$_;\n" ); | 
| 983 | } | 
| 984 |  | 
| 985 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCode( | 
| 986 |     io::Printer* printer) const { | 
| 987 |   printer->Print(variables: variables_, | 
| 988 |                  text: "if (!$get_mutable_bit_parser$) {\n"  | 
| 989 |                  "  $name$_ = $create_list$;\n"  | 
| 990 |                  "  $set_mutable_bit_parser$;\n"  | 
| 991 |                  "}\n"  | 
| 992 |                  "$repeated_add$(input.read$capitalized_type$());\n" ); | 
| 993 | } | 
| 994 |  | 
| 995 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCodeFromPacked( | 
| 996 |     io::Printer* printer) const { | 
| 997 |   printer->Print( | 
| 998 |       variables: variables_, | 
| 999 |       text: "int length = input.readRawVarint32();\n"  | 
| 1000 |       "int limit = input.pushLimit(length);\n"  | 
| 1001 |       "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"  | 
| 1002 |       "  $name$_ = $create_list$;\n"  | 
| 1003 |       "  $set_mutable_bit_parser$;\n"  | 
| 1004 |       "}\n"  | 
| 1005 |       "while (input.getBytesUntilLimit() > 0) {\n"  | 
| 1006 |       "  $repeated_add$(input.read$capitalized_type$());\n"  | 
| 1007 |       "}\n"  | 
| 1008 |       "input.popLimit(limit);\n" ); | 
| 1009 | } | 
| 1010 |  | 
| 1011 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode( | 
| 1012 |     io::Printer* printer) const { | 
| 1013 |   printer->Print(variables: variables_, | 
| 1014 |                  text: "if ($get_mutable_bit_parser$) {\n"  | 
| 1015 |                  "  $name_make_immutable$; // C\n"  | 
| 1016 |                  "}\n" ); | 
| 1017 | } | 
| 1018 |  | 
| 1019 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializationCode( | 
| 1020 |     io::Printer* printer) const { | 
| 1021 |   if (descriptor_->is_packed()) { | 
| 1022 |     // We invoke getSerializedSize in writeTo for messages that have packed | 
| 1023 |     // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods. | 
| 1024 |     // That makes it safe to rely on the memoized size here. | 
| 1025 |     printer->Print(variables: variables_, | 
| 1026 |                    text: "if (get$capitalized_name$List().size() > 0) {\n"  | 
| 1027 |                    "  output.writeUInt32NoTag($tag$);\n"  | 
| 1028 |                    "  output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"  | 
| 1029 |                    "}\n"  | 
| 1030 |                    "for (int i = 0; i < $name$_.size(); i++) {\n"  | 
| 1031 |                    "  output.write$capitalized_type$NoTag($repeated_get$(i));\n"  | 
| 1032 |                    "}\n" ); | 
| 1033 |   } else { | 
| 1034 |     printer->Print( | 
| 1035 |         variables: variables_, | 
| 1036 |         text: "for (int i = 0; i < $name$_.size(); i++) {\n"  | 
| 1037 |         "  output.write$capitalized_type$($number$, $repeated_get$(i));\n"  | 
| 1038 |         "}\n" ); | 
| 1039 |   } | 
| 1040 | } | 
| 1041 |  | 
| 1042 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode( | 
| 1043 |     io::Printer* printer) const { | 
| 1044 |   printer->Print(variables: variables_, | 
| 1045 |                  text: "{\n"  | 
| 1046 |                  "  int dataSize = 0;\n" ); | 
| 1047 |   printer->Indent(); | 
| 1048 |  | 
| 1049 |   if (FixedSize(type: GetType(field: descriptor_)) == -1) { | 
| 1050 |     printer->Print( | 
| 1051 |         variables: variables_, | 
| 1052 |         text: "for (int i = 0; i < $name$_.size(); i++) {\n"  | 
| 1053 |         "  dataSize += com.google.protobuf.CodedOutputStream\n"  | 
| 1054 |         "    .compute$capitalized_type$SizeNoTag($repeated_get$(i));\n"  | 
| 1055 |         "}\n" ); | 
| 1056 |   } else { | 
| 1057 |     printer->Print( | 
| 1058 |         variables: variables_, | 
| 1059 |         text: "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n" ); | 
| 1060 |   } | 
| 1061 |  | 
| 1062 |   printer->Print(text: "size += dataSize;\n" ); | 
| 1063 |  | 
| 1064 |   if (descriptor_->is_packed()) { | 
| 1065 |     printer->Print(variables: variables_, | 
| 1066 |                    text: "if (!get$capitalized_name$List().isEmpty()) {\n"  | 
| 1067 |                    "  size += $tag_size$;\n"  | 
| 1068 |                    "  size += com.google.protobuf.CodedOutputStream\n"  | 
| 1069 |                    "      .computeInt32SizeNoTag(dataSize);\n"  | 
| 1070 |                    "}\n" ); | 
| 1071 |   } else { | 
| 1072 |     printer->Print( | 
| 1073 |         variables: variables_, | 
| 1074 |         text: "size += $tag_size$ * get$capitalized_name$List().size();\n" ); | 
| 1075 |   } | 
| 1076 |  | 
| 1077 |   // cache the data size for packed fields. | 
| 1078 |   if (descriptor_->is_packed()) { | 
| 1079 |     printer->Print(variables: variables_, text: "$name$MemoizedSerializedSize = dataSize;\n" ); | 
| 1080 |   } | 
| 1081 |  | 
| 1082 |   printer->Outdent(); | 
| 1083 |   printer->Print(text: "}\n" ); | 
| 1084 | } | 
| 1085 |  | 
| 1086 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateEqualsCode( | 
| 1087 |     io::Printer* printer) const { | 
| 1088 |   printer->Print( | 
| 1089 |       variables: variables_, | 
| 1090 |       text: "if (!get$capitalized_name$List()\n"  | 
| 1091 |       "    .equals(other.get$capitalized_name$List())) return false;\n" ); | 
| 1092 | } | 
| 1093 |  | 
| 1094 | void RepeatedImmutablePrimitiveFieldGenerator::GenerateHashCode( | 
| 1095 |     io::Printer* printer) const { | 
| 1096 |   printer->Print( | 
| 1097 |       variables: variables_, | 
| 1098 |       text: "if (get$capitalized_name$Count() > 0) {\n"  | 
| 1099 |       "  hash = (37 * hash) + $constant_name$;\n"  | 
| 1100 |       "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"  | 
| 1101 |       "}\n" ); | 
| 1102 | } | 
| 1103 |  | 
| 1104 | std::string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const { | 
| 1105 |   return BoxedPrimitiveTypeName(type: GetJavaType(field: descriptor_)); | 
| 1106 | } | 
| 1107 |  | 
| 1108 | }  // namespace java | 
| 1109 | }  // namespace compiler | 
| 1110 | }  // namespace protobuf | 
| 1111 | }  // namespace google | 
| 1112 |  |