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