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