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