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 package com.google.protobuf; 32 33 import com.google.protobuf.Descriptors.Descriptor; 34 import com.google.protobuf.Descriptors.EnumDescriptor; 35 import com.google.protobuf.Descriptors.EnumValueDescriptor; 36 import com.google.protobuf.Descriptors.FieldDescriptor; 37 import com.google.protobuf.Descriptors.FileDescriptor; 38 import com.google.protobuf.Descriptors.OneofDescriptor; 39 import com.google.protobuf.GeneratedMessage.GeneratedExtension; 40 41 import java.io.IOException; 42 import java.io.InputStream; 43 import java.io.ObjectStreamException; 44 import java.io.Serializable; 45 import java.lang.reflect.InvocationTargetException; 46 import java.lang.reflect.Method; 47 import java.util.ArrayList; 48 import java.util.Collections; 49 import java.util.Iterator; 50 import java.util.List; 51 import java.util.Map; 52 import java.util.TreeMap; 53 54 /** 55 * All generated protocol message classes extend this class. This class 56 * implements most of the Message and Builder interfaces using Java reflection. 57 * Users can ignore this class and pretend that generated messages implement 58 * the Message interface directly. 59 * 60 * @author kenton@google.com Kenton Varda 61 */ 62 public abstract class GeneratedMessageV3 extends AbstractMessage 63 implements Serializable { 64 private static final long serialVersionUID = 1L; 65 66 /** 67 * For testing. Allows a test to disable the optimization that avoids using 68 * field builders for nested messages until they are requested. By disabling 69 * this optimization, existing tests can be reused to test the field builders. 70 */ 71 protected static boolean alwaysUseFieldBuilders = false; 72 73 /** For use by generated code only. */ 74 protected UnknownFieldSet unknownFields; 75 GeneratedMessageV3()76 protected GeneratedMessageV3() { 77 unknownFields = UnknownFieldSet.getDefaultInstance(); 78 } 79 GeneratedMessageV3(Builder<?> builder)80 protected GeneratedMessageV3(Builder<?> builder) { 81 unknownFields = builder.getUnknownFields(); 82 } 83 84 @Override getParserForType()85 public Parser<? extends GeneratedMessageV3> getParserForType() { 86 throw new UnsupportedOperationException( 87 "This is supposed to be overridden by subclasses."); 88 } 89 90 /** 91 * For testing. Allows a test to disable the optimization that avoids using 92 * field builders for nested messages until they are requested. By disabling 93 * this optimization, existing tests can be reused to test the field builders. 94 * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}. 95 */ enableAlwaysUseFieldBuildersForTesting()96 static void enableAlwaysUseFieldBuildersForTesting() { 97 alwaysUseFieldBuilders = true; 98 } 99 100 /** 101 * Get the FieldAccessorTable for this type. We can't have the message 102 * class pass this in to the constructor because of bootstrapping trouble 103 * with DescriptorProtos. 104 */ internalGetFieldAccessorTable()105 protected abstract FieldAccessorTable internalGetFieldAccessorTable(); 106 107 @Override getDescriptorForType()108 public Descriptor getDescriptorForType() { 109 return internalGetFieldAccessorTable().descriptor; 110 } 111 112 /** 113 * Internal helper to return a modifiable map containing all the fields. 114 * The returned Map is modifialbe so that the caller can add additional 115 * extension fields to implement {@link #getAllFields()}. 116 * 117 * @param getBytesForString whether to generate ByteString for string fields 118 */ getAllFieldsMutable( boolean getBytesForString)119 private Map<FieldDescriptor, Object> getAllFieldsMutable( 120 boolean getBytesForString) { 121 final TreeMap<FieldDescriptor, Object> result = 122 new TreeMap<FieldDescriptor, Object>(); 123 final Descriptor descriptor = internalGetFieldAccessorTable().descriptor; 124 final List<FieldDescriptor> fields = descriptor.getFields(); 125 126 for (int i = 0; i < fields.size(); i++) { 127 FieldDescriptor field = fields.get(i); 128 final OneofDescriptor oneofDescriptor = field.getContainingOneof(); 129 130 /* 131 * If the field is part of a Oneof, then at maximum one field in the Oneof is set 132 * and it is not repeated. There is no need to iterate through the others. 133 */ 134 if (oneofDescriptor != null) { 135 // Skip other fields in the Oneof we know are not set 136 i += oneofDescriptor.getFieldCount() - 1; 137 if (!hasOneof(oneofDescriptor)) { 138 // If no field is set in the Oneof, skip all the fields in the Oneof 139 continue; 140 } 141 // Get the pointer to the only field which is set in the Oneof 142 field = getOneofFieldDescriptor(oneofDescriptor); 143 } else { 144 // If we are not in a Oneof, we need to check if the field is set and if it is repeated 145 if (field.isRepeated()) { 146 final List<?> value = (List<?>) getField(field); 147 if (!value.isEmpty()) { 148 result.put(field, value); 149 } 150 continue; 151 } 152 if (!hasField(field)) { 153 continue; 154 } 155 } 156 // Add the field to the map 157 if (getBytesForString && field.getJavaType() == FieldDescriptor.JavaType.STRING) { 158 result.put(field, getFieldRaw(field)); 159 } else { 160 result.put(field, getField(field)); 161 } 162 } 163 return result; 164 } 165 166 @Override isInitialized()167 public boolean isInitialized() { 168 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 169 // Check that all required fields are present. 170 if (field.isRequired()) { 171 if (!hasField(field)) { 172 return false; 173 } 174 } 175 // Check that embedded messages are initialized. 176 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 177 if (field.isRepeated()) { 178 @SuppressWarnings("unchecked") final 179 List<Message> messageList = (List<Message>) getField(field); 180 for (final Message element : messageList) { 181 if (!element.isInitialized()) { 182 return false; 183 } 184 } 185 } else { 186 if (hasField(field) && !((Message) getField(field)).isInitialized()) { 187 return false; 188 } 189 } 190 } 191 } 192 193 return true; 194 } 195 196 @Override getAllFields()197 public Map<FieldDescriptor, Object> getAllFields() { 198 return Collections.unmodifiableMap( 199 getAllFieldsMutable(/* getBytesForString = */ false)); 200 } 201 202 /** 203 * Returns a collection of all the fields in this message which are set 204 * and their corresponding values. A singular ("required" or "optional") 205 * field is set iff hasField() returns true for that field. A "repeated" 206 * field is set iff getRepeatedFieldCount() is greater than zero. The 207 * values are exactly what would be returned by calling 208 * {@link #getFieldRaw(Descriptors.FieldDescriptor)} for each field. The map 209 * is guaranteed to be a sorted map, so iterating over it will return fields 210 * in order by field number. 211 */ getAllFieldsRaw()212 Map<FieldDescriptor, Object> getAllFieldsRaw() { 213 return Collections.unmodifiableMap( 214 getAllFieldsMutable(/* getBytesForString = */ true)); 215 } 216 217 @Override hasOneof(final OneofDescriptor oneof)218 public boolean hasOneof(final OneofDescriptor oneof) { 219 return internalGetFieldAccessorTable().getOneof(oneof).has(this); 220 } 221 222 @Override getOneofFieldDescriptor(final OneofDescriptor oneof)223 public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) { 224 return internalGetFieldAccessorTable().getOneof(oneof).get(this); 225 } 226 227 @Override hasField(final FieldDescriptor field)228 public boolean hasField(final FieldDescriptor field) { 229 return internalGetFieldAccessorTable().getField(field).has(this); 230 } 231 232 @Override getField(final FieldDescriptor field)233 public Object getField(final FieldDescriptor field) { 234 return internalGetFieldAccessorTable().getField(field).get(this); 235 } 236 237 /** 238 * Obtains the value of the given field, or the default value if it is 239 * not set. For primitive fields, the boxed primitive value is returned. 240 * For enum fields, the EnumValueDescriptor for the value is returned. For 241 * embedded message fields, the sub-message is returned. For repeated 242 * fields, a java.util.List is returned. For present string fields, a 243 * ByteString is returned representing the bytes that the field contains. 244 */ getFieldRaw(final FieldDescriptor field)245 Object getFieldRaw(final FieldDescriptor field) { 246 return internalGetFieldAccessorTable().getField(field).getRaw(this); 247 } 248 249 @Override getRepeatedFieldCount(final FieldDescriptor field)250 public int getRepeatedFieldCount(final FieldDescriptor field) { 251 return internalGetFieldAccessorTable().getField(field) 252 .getRepeatedCount(this); 253 } 254 255 @Override getRepeatedField(final FieldDescriptor field, final int index)256 public Object getRepeatedField(final FieldDescriptor field, final int index) { 257 return internalGetFieldAccessorTable().getField(field) 258 .getRepeated(this, index); 259 } 260 261 @Override getUnknownFields()262 public UnknownFieldSet getUnknownFields() { 263 throw new UnsupportedOperationException( 264 "This is supposed to be overridden by subclasses."); 265 } 266 267 /** 268 * Called by subclasses to parse an unknown field. 269 * @return {@code true} unless the tag is an end-group tag. 270 */ parseUnknownField( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, int tag)271 protected boolean parseUnknownField( 272 CodedInputStream input, 273 UnknownFieldSet.Builder unknownFields, 274 ExtensionRegistryLite extensionRegistry, 275 int tag) throws IOException { 276 return unknownFields.mergeFieldFrom(tag, input); 277 } 278 parseWithIOException(Parser<M> parser, InputStream input)279 protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input) 280 throws IOException { 281 try { 282 return parser.parseFrom(input); 283 } catch (InvalidProtocolBufferException e) { 284 throw e.unwrapIOException(); 285 } 286 } 287 parseWithIOException(Parser<M> parser, InputStream input, ExtensionRegistryLite extensions)288 protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input, 289 ExtensionRegistryLite extensions) throws IOException { 290 try { 291 return parser.parseFrom(input, extensions); 292 } catch (InvalidProtocolBufferException e) { 293 throw e.unwrapIOException(); 294 } 295 } 296 parseWithIOException(Parser<M> parser, CodedInputStream input)297 protected static <M extends Message> M parseWithIOException(Parser<M> parser, 298 CodedInputStream input) throws IOException { 299 try { 300 return parser.parseFrom(input); 301 } catch (InvalidProtocolBufferException e) { 302 throw e.unwrapIOException(); 303 } 304 } 305 parseWithIOException(Parser<M> parser, CodedInputStream input, ExtensionRegistryLite extensions)306 protected static <M extends Message> M parseWithIOException(Parser<M> parser, 307 CodedInputStream input, ExtensionRegistryLite extensions) throws IOException { 308 try { 309 return parser.parseFrom(input, extensions); 310 } catch (InvalidProtocolBufferException e) { 311 throw e.unwrapIOException(); 312 } 313 } 314 parseDelimitedWithIOException(Parser<M> parser, InputStream input)315 protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser, 316 InputStream input) throws IOException { 317 try { 318 return parser.parseDelimitedFrom(input); 319 } catch (InvalidProtocolBufferException e) { 320 throw e.unwrapIOException(); 321 } 322 } 323 parseDelimitedWithIOException(Parser<M> parser, InputStream input, ExtensionRegistryLite extensions)324 protected static <M extends Message> M parseDelimitedWithIOException(Parser<M> parser, 325 InputStream input, ExtensionRegistryLite extensions) throws IOException { 326 try { 327 return parser.parseDelimitedFrom(input, extensions); 328 } catch (InvalidProtocolBufferException e) { 329 throw e.unwrapIOException(); 330 } 331 } 332 333 @Override writeTo(final CodedOutputStream output)334 public void writeTo(final CodedOutputStream output) throws IOException { 335 MessageReflection.writeMessageTo(this, getAllFieldsRaw(), output, false); 336 } 337 338 @Override getSerializedSize()339 public int getSerializedSize() { 340 int size = memoizedSize; 341 if (size != -1) { 342 return size; 343 } 344 345 memoizedSize = MessageReflection.getSerializedSize( 346 this, getAllFieldsRaw()); 347 return memoizedSize; 348 } 349 350 351 352 /** 353 * Used by parsing constructors in generated classes. 354 */ makeExtensionsImmutable()355 protected void makeExtensionsImmutable() { 356 // Noop for messages without extensions. 357 } 358 359 /** 360 * TODO(xiaofeng): remove this after b/29368482 is fixed. We need to move this 361 * interface to AbstractMessage in order to versioning GeneratedMessageV3 but 362 * this move breaks binary compatibility for AppEngine. After AppEngine is 363 * fixed we can exlude this from google3. 364 */ 365 protected interface BuilderParent extends AbstractMessage.BuilderParent {} 366 367 /** 368 * TODO(xiaofeng): remove this together with GeneratedMessageV3.BuilderParent. 369 */ newBuilderForType(BuilderParent parent)370 protected abstract Message.Builder newBuilderForType(BuilderParent parent); 371 372 @Override newBuilderForType(final AbstractMessage.BuilderParent parent)373 protected Message.Builder newBuilderForType(final AbstractMessage.BuilderParent parent) { 374 return newBuilderForType(new BuilderParent() { 375 @Override 376 public void markDirty() { 377 parent.markDirty(); 378 } 379 }); 380 } 381 382 383 @SuppressWarnings("unchecked") 384 public abstract static class Builder <BuilderType extends Builder<BuilderType>> 385 extends AbstractMessage.Builder<BuilderType> { 386 387 private BuilderParent builderParent; 388 389 private BuilderParentImpl meAsParent; 390 391 // Indicates that we've built a message and so we are now obligated 392 // to dispatch dirty invalidations. See GeneratedMessageV3.BuilderListener. 393 private boolean isClean; 394 395 private UnknownFieldSet unknownFields = 396 UnknownFieldSet.getDefaultInstance(); 397 398 protected Builder() { 399 this(null); 400 } 401 402 protected Builder(BuilderParent builderParent) { 403 this.builderParent = builderParent; 404 } 405 406 @Override 407 void dispose() { 408 builderParent = null; 409 } 410 411 /** 412 * Called by the subclass when a message is built. 413 */ 414 protected void onBuilt() { 415 if (builderParent != null) { 416 markClean(); 417 } 418 } 419 420 /** 421 * Called by the subclass or a builder to notify us that a message was 422 * built and may be cached and therefore invalidations are needed. 423 */ 424 @Override 425 protected void markClean() { 426 this.isClean = true; 427 } 428 429 /** 430 * Gets whether invalidations are needed 431 * 432 * @return whether invalidations are needed 433 */ 434 protected boolean isClean() { 435 return isClean; 436 } 437 438 @Override 439 public BuilderType clone() { 440 BuilderType builder = 441 (BuilderType) getDefaultInstanceForType().newBuilderForType(); 442 builder.mergeFrom(buildPartial()); 443 return builder; 444 } 445 446 /** 447 * Called by the initialization and clear code paths to allow subclasses to 448 * reset any of their builtin fields back to the initial values. 449 */ 450 @Override 451 public BuilderType clear() { 452 unknownFields = UnknownFieldSet.getDefaultInstance(); 453 onChanged(); 454 return (BuilderType) this; 455 } 456 457 /** 458 * Get the FieldAccessorTable for this type. We can't have the message 459 * class pass this in to the constructor because of bootstrapping trouble 460 * with DescriptorProtos. 461 */ 462 protected abstract FieldAccessorTable internalGetFieldAccessorTable(); 463 464 @Override 465 public Descriptor getDescriptorForType() { 466 return internalGetFieldAccessorTable().descriptor; 467 } 468 469 @Override 470 public Map<FieldDescriptor, Object> getAllFields() { 471 return Collections.unmodifiableMap(getAllFieldsMutable()); 472 } 473 474 /** Internal helper which returns a mutable map. */ 475 private Map<FieldDescriptor, Object> getAllFieldsMutable() { 476 final TreeMap<FieldDescriptor, Object> result = 477 new TreeMap<FieldDescriptor, Object>(); 478 final Descriptor descriptor = internalGetFieldAccessorTable().descriptor; 479 final List<FieldDescriptor> fields = descriptor.getFields(); 480 481 for (int i = 0; i < fields.size(); i++) { 482 FieldDescriptor field = fields.get(i); 483 final OneofDescriptor oneofDescriptor = field.getContainingOneof(); 484 485 /* 486 * If the field is part of a Oneof, then at maximum one field in the Oneof is set 487 * and it is not repeated. There is no need to iterate through the others. 488 */ 489 if (oneofDescriptor != null) { 490 // Skip other fields in the Oneof we know are not set 491 i += oneofDescriptor.getFieldCount() - 1; 492 if (!hasOneof(oneofDescriptor)) { 493 // If no field is set in the Oneof, skip all the fields in the Oneof 494 continue; 495 } 496 // Get the pointer to the only field which is set in the Oneof 497 field = getOneofFieldDescriptor(oneofDescriptor); 498 } else { 499 // If we are not in a Oneof, we need to check if the field is set and if it is repeated 500 if (field.isRepeated()) { 501 final List<?> value = (List<?>) getField(field); 502 if (!value.isEmpty()) { 503 result.put(field, value); 504 } 505 continue; 506 } 507 if (!hasField(field)) { 508 continue; 509 } 510 } 511 // Add the field to the map 512 result.put(field, getField(field)); 513 } 514 return result; 515 } 516 517 @Override 518 public Message.Builder newBuilderForField(final FieldDescriptor field) { 519 return internalGetFieldAccessorTable().getField(field).newBuilder(); 520 } 521 522 @Override 523 public Message.Builder getFieldBuilder(final FieldDescriptor field) { 524 return internalGetFieldAccessorTable().getField(field).getBuilder(this); 525 } 526 527 @Override 528 public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) { 529 return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder( 530 this, index); 531 } 532 533 @Override 534 public boolean hasOneof(final OneofDescriptor oneof) { 535 return internalGetFieldAccessorTable().getOneof(oneof).has(this); 536 } 537 538 @Override 539 public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) { 540 return internalGetFieldAccessorTable().getOneof(oneof).get(this); 541 } 542 543 @Override 544 public boolean hasField(final FieldDescriptor field) { 545 return internalGetFieldAccessorTable().getField(field).has(this); 546 } 547 548 @Override 549 public Object getField(final FieldDescriptor field) { 550 Object object = internalGetFieldAccessorTable().getField(field).get(this); 551 if (field.isRepeated()) { 552 // The underlying list object is still modifiable at this point. 553 // Make sure not to expose the modifiable list to the caller. 554 return Collections.unmodifiableList((List) object); 555 } else { 556 return object; 557 } 558 } 559 560 @Override 561 public BuilderType setField(final FieldDescriptor field, final Object value) { 562 internalGetFieldAccessorTable().getField(field).set(this, value); 563 return (BuilderType) this; 564 } 565 566 @Override 567 public BuilderType clearField(final FieldDescriptor field) { 568 internalGetFieldAccessorTable().getField(field).clear(this); 569 return (BuilderType) this; 570 } 571 572 @Override 573 public BuilderType clearOneof(final OneofDescriptor oneof) { 574 internalGetFieldAccessorTable().getOneof(oneof).clear(this); 575 return (BuilderType) this; 576 } 577 578 @Override 579 public int getRepeatedFieldCount(final FieldDescriptor field) { 580 return internalGetFieldAccessorTable().getField(field) 581 .getRepeatedCount(this); 582 } 583 584 @Override 585 public Object getRepeatedField(final FieldDescriptor field, final int index) { 586 return internalGetFieldAccessorTable().getField(field) 587 .getRepeated(this, index); 588 } 589 590 @Override 591 public BuilderType setRepeatedField( 592 final FieldDescriptor field, final int index, final Object value) { 593 internalGetFieldAccessorTable().getField(field) 594 .setRepeated(this, index, value); 595 return (BuilderType) this; 596 } 597 598 @Override 599 public BuilderType addRepeatedField(final FieldDescriptor field, final Object value) { 600 internalGetFieldAccessorTable().getField(field).addRepeated(this, value); 601 return (BuilderType) this; 602 } 603 604 @Override 605 public BuilderType setUnknownFields(final UnknownFieldSet unknownFields) { 606 this.unknownFields = unknownFields; 607 onChanged(); 608 return (BuilderType) this; 609 } 610 611 @Override 612 public BuilderType mergeUnknownFields( 613 final UnknownFieldSet unknownFields) { 614 this.unknownFields = 615 UnknownFieldSet.newBuilder(this.unknownFields) 616 .mergeFrom(unknownFields) 617 .build(); 618 onChanged(); 619 return (BuilderType) this; 620 } 621 622 @Override 623 public boolean isInitialized() { 624 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 625 // Check that all required fields are present. 626 if (field.isRequired()) { 627 if (!hasField(field)) { 628 return false; 629 } 630 } 631 // Check that embedded messages are initialized. 632 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 633 if (field.isRepeated()) { 634 @SuppressWarnings("unchecked") final 635 List<Message> messageList = (List<Message>) getField(field); 636 for (final Message element : messageList) { 637 if (!element.isInitialized()) { 638 return false; 639 } 640 } 641 } else { 642 if (hasField(field) && 643 !((Message) getField(field)).isInitialized()) { 644 return false; 645 } 646 } 647 } 648 } 649 return true; 650 } 651 652 @Override 653 public final UnknownFieldSet getUnknownFields() { 654 return unknownFields; 655 } 656 657 /** 658 * Called by subclasses to parse an unknown field. 659 * @return {@code true} unless the tag is an end-group tag. 660 */ 661 protected boolean parseUnknownField( 662 final CodedInputStream input, 663 final UnknownFieldSet.Builder unknownFields, 664 final ExtensionRegistryLite extensionRegistry, 665 final int tag) throws IOException { 666 return unknownFields.mergeFieldFrom(tag, input); 667 } 668 669 /** 670 * Implementation of {@link BuilderParent} for giving to our children. This 671 * small inner class makes it so we don't publicly expose the BuilderParent 672 * methods. 673 */ 674 private class BuilderParentImpl implements BuilderParent { 675 676 @Override 677 public void markDirty() { 678 onChanged(); 679 } 680 } 681 682 /** 683 * Gets the {@link BuilderParent} for giving to our children. 684 * @return The builder parent for our children. 685 */ 686 protected BuilderParent getParentForChildren() { 687 if (meAsParent == null) { 688 meAsParent = new BuilderParentImpl(); 689 } 690 return meAsParent; 691 } 692 693 /** 694 * Called when a the builder or one of its nested children has changed 695 * and any parent should be notified of its invalidation. 696 */ 697 protected final void onChanged() { 698 if (isClean && builderParent != null) { 699 builderParent.markDirty(); 700 701 // Don't keep dispatching invalidations until build is called again. 702 isClean = false; 703 } 704 } 705 706 /** 707 * Gets the map field with the given field number. This method should be 708 * overridden in the generated message class if the message contains map 709 * fields. 710 * 711 * Unlike other field types, reflection support for map fields can't be 712 * implemented based on generated public API because we need to access a 713 * map field as a list in reflection API but the generated API only allows 714 * us to access it as a map. This method returns the underlying map field 715 * directly and thus enables us to access the map field as a list. 716 */ 717 @SuppressWarnings({"unused", "rawtypes"}) 718 protected MapField internalGetMapField(int fieldNumber) { 719 // Note that we can't use descriptor names here because this method will 720 // be called when descriptor is being initialized. 721 throw new RuntimeException( 722 "No map fields found in " + getClass().getName()); 723 } 724 725 /** Like {@link #internalGetMapField} but return a mutable version. */ 726 @SuppressWarnings({"unused", "rawtypes"}) 727 protected MapField internalGetMutableMapField(int fieldNumber) { 728 // Note that we can't use descriptor names here because this method will 729 // be called when descriptor is being initialized. 730 throw new RuntimeException( 731 "No map fields found in " + getClass().getName()); 732 } 733 } 734 735 // ================================================================= 736 // Extensions-related stuff 737 738 public interface ExtendableMessageOrBuilder< 739 MessageType extends ExtendableMessage> extends MessageOrBuilder { 740 // Re-define for return type covariance. 741 @Override 742 Message getDefaultInstanceForType(); 743 744 /** Check if a singular extension is present. */ 745 <Type> boolean hasExtension( 746 ExtensionLite<MessageType, Type> extension); 747 748 /** Get the number of elements in a repeated extension. */ 749 <Type> int getExtensionCount( 750 ExtensionLite<MessageType, List<Type>> extension); 751 752 /** Get the value of an extension. */ 753 <Type> Type getExtension( 754 ExtensionLite<MessageType, Type> extension); 755 756 /** Get one element of a repeated extension. */ 757 <Type> Type getExtension( 758 ExtensionLite<MessageType, List<Type>> extension, 759 int index); 760 761 /** Check if a singular extension is present. */ 762 <Type> boolean hasExtension( 763 Extension<MessageType, Type> extension); 764 /** Check if a singular extension is present. */ 765 <Type> boolean hasExtension( 766 GeneratedExtension<MessageType, Type> extension); 767 /** Get the number of elements in a repeated extension. */ 768 <Type> int getExtensionCount( 769 Extension<MessageType, List<Type>> extension); 770 /** Get the number of elements in a repeated extension. */ 771 <Type> int getExtensionCount( 772 GeneratedExtension<MessageType, List<Type>> extension); 773 /** Get the value of an extension. */ 774 <Type> Type getExtension( 775 Extension<MessageType, Type> extension); 776 /** Get the value of an extension. */ 777 <Type> Type getExtension( 778 GeneratedExtension<MessageType, Type> extension); 779 /** Get one element of a repeated extension. */ 780 <Type> Type getExtension( 781 Extension<MessageType, List<Type>> extension, 782 int index); 783 /** Get one element of a repeated extension. */ 784 <Type> Type getExtension( 785 GeneratedExtension<MessageType, List<Type>> extension, 786 int index); 787 } 788 789 /** 790 * Generated message classes for message types that contain extension ranges 791 * subclass this. 792 * 793 * <p>This class implements type-safe accessors for extensions. They 794 * implement all the same operations that you can do with normal fields -- 795 * e.g. "has", "get", and "getCount" -- but for extensions. The extensions 796 * are identified using instances of the class {@link GeneratedExtension}; 797 * the protocol compiler generates a static instance of this class for every 798 * extension in its input. Through the magic of generics, all is made 799 * type-safe. 800 * 801 * <p>For example, imagine you have the {@code .proto} file: 802 * 803 * <pre> 804 * option java_class = "MyProto"; 805 * 806 * message Foo { 807 * extensions 1000 to max; 808 * } 809 * 810 * extend Foo { 811 * optional int32 bar; 812 * } 813 * </pre> 814 * 815 * <p>Then you might write code like: 816 * 817 * <pre> 818 * MyProto.Foo foo = getFoo(); 819 * int i = foo.getExtension(MyProto.bar); 820 * </pre> 821 * 822 * <p>See also {@link ExtendableBuilder}. 823 */ 824 public abstract static class ExtendableMessage< 825 MessageType extends ExtendableMessage> 826 extends GeneratedMessageV3 827 implements ExtendableMessageOrBuilder<MessageType> { 828 829 private static final long serialVersionUID = 1L; 830 831 private final FieldSet<FieldDescriptor> extensions; 832 833 protected ExtendableMessage() { 834 this.extensions = FieldSet.newFieldSet(); 835 } 836 837 protected ExtendableMessage( 838 ExtendableBuilder<MessageType, ?> builder) { 839 super(builder); 840 this.extensions = builder.buildExtensions(); 841 } 842 843 private void verifyExtensionContainingType( 844 final Extension<MessageType, ?> extension) { 845 if (extension.getDescriptor().getContainingType() != 846 getDescriptorForType()) { 847 // This can only happen if someone uses unchecked operations. 848 throw new IllegalArgumentException( 849 "Extension is for type \"" + 850 extension.getDescriptor().getContainingType().getFullName() + 851 "\" which does not match message type \"" + 852 getDescriptorForType().getFullName() + "\"."); 853 } 854 } 855 856 /** Check if a singular extension is present. */ 857 @Override 858 public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) { 859 Extension<MessageType, Type> extension = checkNotLite(extensionLite); 860 861 verifyExtensionContainingType(extension); 862 return extensions.hasField(extension.getDescriptor()); 863 } 864 865 /** Get the number of elements in a repeated extension. */ 866 @Override 867 public final <Type> int getExtensionCount( 868 final ExtensionLite<MessageType, List<Type>> extensionLite) { 869 Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); 870 871 verifyExtensionContainingType(extension); 872 final FieldDescriptor descriptor = extension.getDescriptor(); 873 return extensions.getRepeatedFieldCount(descriptor); 874 } 875 876 /** Get the value of an extension. */ 877 @Override 878 @SuppressWarnings("unchecked") 879 public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) { 880 Extension<MessageType, Type> extension = checkNotLite(extensionLite); 881 882 verifyExtensionContainingType(extension); 883 FieldDescriptor descriptor = extension.getDescriptor(); 884 final Object value = extensions.getField(descriptor); 885 if (value == null) { 886 if (descriptor.isRepeated()) { 887 return (Type) Collections.emptyList(); 888 } else if (descriptor.getJavaType() == 889 FieldDescriptor.JavaType.MESSAGE) { 890 return (Type) extension.getMessageDefaultInstance(); 891 } else { 892 return (Type) extension.fromReflectionType( 893 descriptor.getDefaultValue()); 894 } 895 } else { 896 return (Type) extension.fromReflectionType(value); 897 } 898 } 899 900 /** Get one element of a repeated extension. */ 901 @Override 902 @SuppressWarnings("unchecked") 903 public final <Type> Type getExtension( 904 final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) { 905 Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); 906 907 verifyExtensionContainingType(extension); 908 FieldDescriptor descriptor = extension.getDescriptor(); 909 return (Type) extension.singularFromReflectionType( 910 extensions.getRepeatedField(descriptor, index)); 911 } 912 913 /** Check if a singular extension is present. */ 914 @Override 915 public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) { 916 return hasExtension((ExtensionLite<MessageType, Type>) extension); 917 } 918 /** Check if a singular extension is present. */ 919 @Override 920 public final <Type> boolean hasExtension( 921 final GeneratedExtension<MessageType, Type> extension) { 922 return hasExtension((ExtensionLite<MessageType, Type>) extension); 923 } 924 /** Get the number of elements in a repeated extension. */ 925 @Override 926 public final <Type> int getExtensionCount( 927 final Extension<MessageType, List<Type>> extension) { 928 return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); 929 } 930 /** Get the number of elements in a repeated extension. */ 931 @Override 932 public final <Type> int getExtensionCount( 933 final GeneratedExtension<MessageType, List<Type>> extension) { 934 return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); 935 } 936 /** Get the value of an extension. */ 937 @Override 938 public final <Type> Type getExtension(final Extension<MessageType, Type> extension) { 939 return getExtension((ExtensionLite<MessageType, Type>) extension); 940 } 941 /** Get the value of an extension. */ 942 @Override 943 public final <Type> Type getExtension( 944 final GeneratedExtension<MessageType, Type> extension) { 945 return getExtension((ExtensionLite<MessageType, Type>) extension); 946 } 947 /** Get one element of a repeated extension. */ 948 @Override 949 public final <Type> Type getExtension( 950 final Extension<MessageType, List<Type>> extension, final int index) { 951 return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); 952 } 953 /** Get one element of a repeated extension. */ 954 @Override 955 public final <Type> Type getExtension( 956 final GeneratedExtension<MessageType, List<Type>> extension, final int index) { 957 return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); 958 } 959 960 /** Called by subclasses to check if all extensions are initialized. */ 961 protected boolean extensionsAreInitialized() { 962 return extensions.isInitialized(); 963 } 964 965 @Override 966 public boolean isInitialized() { 967 return super.isInitialized() && extensionsAreInitialized(); 968 } 969 970 @Override 971 protected boolean parseUnknownField( 972 CodedInputStream input, 973 UnknownFieldSet.Builder unknownFields, 974 ExtensionRegistryLite extensionRegistry, 975 int tag) throws IOException { 976 return MessageReflection.mergeFieldFrom( 977 input, unknownFields, extensionRegistry, getDescriptorForType(), 978 new MessageReflection.ExtensionAdapter(extensions), tag); 979 } 980 981 982 /** 983 * Used by parsing constructors in generated classes. 984 */ 985 @Override 986 protected void makeExtensionsImmutable() { 987 extensions.makeImmutable(); 988 } 989 990 /** 991 * Used by subclasses to serialize extensions. Extension ranges may be 992 * interleaved with field numbers, but we must write them in canonical 993 * (sorted by field number) order. ExtensionWriter helps us write 994 * individual ranges of extensions at once. 995 */ 996 protected class ExtensionWriter { 997 // Imagine how much simpler this code would be if Java iterators had 998 // a way to get the next element without advancing the iterator. 999 1000 private final Iterator<Map.Entry<FieldDescriptor, Object>> iter = 1001 extensions.iterator(); 1002 private Map.Entry<FieldDescriptor, Object> next; 1003 private final boolean messageSetWireFormat; 1004 1005 private ExtensionWriter(final boolean messageSetWireFormat) { 1006 if (iter.hasNext()) { 1007 next = iter.next(); 1008 } 1009 this.messageSetWireFormat = messageSetWireFormat; 1010 } 1011 1012 public void writeUntil(final int end, final CodedOutputStream output) 1013 throws IOException { 1014 while (next != null && next.getKey().getNumber() < end) { 1015 FieldDescriptor descriptor = next.getKey(); 1016 if (messageSetWireFormat && descriptor.getLiteJavaType() == 1017 WireFormat.JavaType.MESSAGE && 1018 !descriptor.isRepeated()) { 1019 if (next instanceof LazyField.LazyEntry<?>) { 1020 output.writeRawMessageSetExtension(descriptor.getNumber(), 1021 ((LazyField.LazyEntry<?>) next).getField().toByteString()); 1022 } else { 1023 output.writeMessageSetExtension(descriptor.getNumber(), 1024 (Message) next.getValue()); 1025 } 1026 } else { 1027 // TODO(xiangl): Taken care of following code, it may cause 1028 // problem when we use LazyField for normal fields/extensions. 1029 // Due to the optional field can be duplicated at the end of 1030 // serialized bytes, which will make the serialized size change 1031 // after lazy field parsed. So when we use LazyField globally, 1032 // we need to change the following write method to write cached 1033 // bytes directly rather than write the parsed message. 1034 FieldSet.writeField(descriptor, next.getValue(), output); 1035 } 1036 if (iter.hasNext()) { 1037 next = iter.next(); 1038 } else { 1039 next = null; 1040 } 1041 } 1042 } 1043 } 1044 1045 protected ExtensionWriter newExtensionWriter() { 1046 return new ExtensionWriter(false); 1047 } 1048 protected ExtensionWriter newMessageSetExtensionWriter() { 1049 return new ExtensionWriter(true); 1050 } 1051 1052 /** Called by subclasses to compute the size of extensions. */ 1053 protected int extensionsSerializedSize() { 1054 return extensions.getSerializedSize(); 1055 } 1056 protected int extensionsSerializedSizeAsMessageSet() { 1057 return extensions.getMessageSetSerializedSize(); 1058 } 1059 1060 // --------------------------------------------------------------- 1061 // Reflection 1062 1063 protected Map<FieldDescriptor, Object> getExtensionFields() { 1064 return extensions.getAllFields(); 1065 } 1066 1067 @Override 1068 public Map<FieldDescriptor, Object> getAllFields() { 1069 final Map<FieldDescriptor, Object> result = 1070 super.getAllFieldsMutable(/* getBytesForString = */ false); 1071 result.putAll(getExtensionFields()); 1072 return Collections.unmodifiableMap(result); 1073 } 1074 1075 @Override 1076 public Map<FieldDescriptor, Object> getAllFieldsRaw() { 1077 final Map<FieldDescriptor, Object> result = 1078 super.getAllFieldsMutable(/* getBytesForString = */ false); 1079 result.putAll(getExtensionFields()); 1080 return Collections.unmodifiableMap(result); 1081 } 1082 1083 @Override 1084 public boolean hasField(final FieldDescriptor field) { 1085 if (field.isExtension()) { 1086 verifyContainingType(field); 1087 return extensions.hasField(field); 1088 } else { 1089 return super.hasField(field); 1090 } 1091 } 1092 1093 @Override 1094 public Object getField(final FieldDescriptor field) { 1095 if (field.isExtension()) { 1096 verifyContainingType(field); 1097 final Object value = extensions.getField(field); 1098 if (value == null) { 1099 if (field.isRepeated()) { 1100 return Collections.emptyList(); 1101 } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1102 // Lacking an ExtensionRegistry, we have no way to determine the 1103 // extension's real type, so we return a DynamicMessage. 1104 return DynamicMessage.getDefaultInstance(field.getMessageType()); 1105 } else { 1106 return field.getDefaultValue(); 1107 } 1108 } else { 1109 return value; 1110 } 1111 } else { 1112 return super.getField(field); 1113 } 1114 } 1115 1116 @Override 1117 public int getRepeatedFieldCount(final FieldDescriptor field) { 1118 if (field.isExtension()) { 1119 verifyContainingType(field); 1120 return extensions.getRepeatedFieldCount(field); 1121 } else { 1122 return super.getRepeatedFieldCount(field); 1123 } 1124 } 1125 1126 @Override 1127 public Object getRepeatedField(final FieldDescriptor field, 1128 final int index) { 1129 if (field.isExtension()) { 1130 verifyContainingType(field); 1131 return extensions.getRepeatedField(field, index); 1132 } else { 1133 return super.getRepeatedField(field, index); 1134 } 1135 } 1136 1137 private void verifyContainingType(final FieldDescriptor field) { 1138 if (field.getContainingType() != getDescriptorForType()) { 1139 throw new IllegalArgumentException( 1140 "FieldDescriptor does not match message type."); 1141 } 1142 } 1143 } 1144 1145 /** 1146 * Generated message builders for message types that contain extension ranges 1147 * subclass this. 1148 * 1149 * <p>This class implements type-safe accessors for extensions. They 1150 * implement all the same operations that you can do with normal fields -- 1151 * e.g. "get", "set", and "add" -- but for extensions. The extensions are 1152 * identified using instances of the class {@link GeneratedExtension}; the 1153 * protocol compiler generates a static instance of this class for every 1154 * extension in its input. Through the magic of generics, all is made 1155 * type-safe. 1156 * 1157 * <p>For example, imagine you have the {@code .proto} file: 1158 * 1159 * <pre> 1160 * option java_class = "MyProto"; 1161 * 1162 * message Foo { 1163 * extensions 1000 to max; 1164 * } 1165 * 1166 * extend Foo { 1167 * optional int32 bar; 1168 * } 1169 * </pre> 1170 * 1171 * <p>Then you might write code like: 1172 * 1173 * <pre> 1174 * MyProto.Foo foo = 1175 * MyProto.Foo.newBuilder() 1176 * .setExtension(MyProto.bar, 123) 1177 * .build(); 1178 * </pre> 1179 * 1180 * <p>See also {@link ExtendableMessage}. 1181 */ 1182 @SuppressWarnings("unchecked") 1183 public abstract static class ExtendableBuilder< 1184 MessageType extends ExtendableMessage, 1185 BuilderType extends ExtendableBuilder<MessageType, BuilderType>> 1186 extends Builder<BuilderType> 1187 implements ExtendableMessageOrBuilder<MessageType> { 1188 1189 private FieldSet<FieldDescriptor> extensions = FieldSet.emptySet(); 1190 1191 protected ExtendableBuilder() {} 1192 1193 protected ExtendableBuilder( 1194 BuilderParent parent) { 1195 super(parent); 1196 } 1197 1198 // For immutable message conversion. 1199 void internalSetExtensionSet(FieldSet<FieldDescriptor> extensions) { 1200 this.extensions = extensions; 1201 } 1202 1203 @Override 1204 public BuilderType clear() { 1205 extensions = FieldSet.emptySet(); 1206 return super.clear(); 1207 } 1208 1209 // This is implemented here only to work around an apparent bug in the 1210 // Java compiler and/or build system. See bug #1898463. The mere presence 1211 // of this clone() implementation makes it go away. 1212 @Override 1213 public BuilderType clone() { 1214 return super.clone(); 1215 } 1216 1217 private void ensureExtensionsIsMutable() { 1218 if (extensions.isImmutable()) { 1219 extensions = extensions.clone(); 1220 } 1221 } 1222 1223 private void verifyExtensionContainingType( 1224 final Extension<MessageType, ?> extension) { 1225 if (extension.getDescriptor().getContainingType() != 1226 getDescriptorForType()) { 1227 // This can only happen if someone uses unchecked operations. 1228 throw new IllegalArgumentException( 1229 "Extension is for type \"" + 1230 extension.getDescriptor().getContainingType().getFullName() + 1231 "\" which does not match message type \"" + 1232 getDescriptorForType().getFullName() + "\"."); 1233 } 1234 } 1235 1236 /** Check if a singular extension is present. */ 1237 @Override 1238 public final <Type> boolean hasExtension(final ExtensionLite<MessageType, Type> extensionLite) { 1239 Extension<MessageType, Type> extension = checkNotLite(extensionLite); 1240 1241 verifyExtensionContainingType(extension); 1242 return extensions.hasField(extension.getDescriptor()); 1243 } 1244 1245 /** Get the number of elements in a repeated extension. */ 1246 @Override 1247 public final <Type> int getExtensionCount( 1248 final ExtensionLite<MessageType, List<Type>> extensionLite) { 1249 Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); 1250 1251 verifyExtensionContainingType(extension); 1252 final FieldDescriptor descriptor = extension.getDescriptor(); 1253 return extensions.getRepeatedFieldCount(descriptor); 1254 } 1255 1256 /** Get the value of an extension. */ 1257 @Override 1258 public final <Type> Type getExtension(final ExtensionLite<MessageType, Type> extensionLite) { 1259 Extension<MessageType, Type> extension = checkNotLite(extensionLite); 1260 1261 verifyExtensionContainingType(extension); 1262 FieldDescriptor descriptor = extension.getDescriptor(); 1263 final Object value = extensions.getField(descriptor); 1264 if (value == null) { 1265 if (descriptor.isRepeated()) { 1266 return (Type) Collections.emptyList(); 1267 } else if (descriptor.getJavaType() == 1268 FieldDescriptor.JavaType.MESSAGE) { 1269 return (Type) extension.getMessageDefaultInstance(); 1270 } else { 1271 return (Type) extension.fromReflectionType( 1272 descriptor.getDefaultValue()); 1273 } 1274 } else { 1275 return (Type) extension.fromReflectionType(value); 1276 } 1277 } 1278 1279 /** Get one element of a repeated extension. */ 1280 @Override 1281 public final <Type> Type getExtension( 1282 final ExtensionLite<MessageType, List<Type>> extensionLite, final int index) { 1283 Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); 1284 1285 verifyExtensionContainingType(extension); 1286 FieldDescriptor descriptor = extension.getDescriptor(); 1287 return (Type) extension.singularFromReflectionType( 1288 extensions.getRepeatedField(descriptor, index)); 1289 } 1290 1291 /** Set the value of an extension. */ 1292 public final <Type> BuilderType setExtension( 1293 final ExtensionLite<MessageType, Type> extensionLite, 1294 final Type value) { 1295 Extension<MessageType, Type> extension = checkNotLite(extensionLite); 1296 1297 verifyExtensionContainingType(extension); 1298 ensureExtensionsIsMutable(); 1299 final FieldDescriptor descriptor = extension.getDescriptor(); 1300 extensions.setField(descriptor, extension.toReflectionType(value)); 1301 onChanged(); 1302 return (BuilderType) this; 1303 } 1304 1305 /** Set the value of one element of a repeated extension. */ 1306 public final <Type> BuilderType setExtension( 1307 final ExtensionLite<MessageType, List<Type>> extensionLite, 1308 final int index, final Type value) { 1309 Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); 1310 1311 verifyExtensionContainingType(extension); 1312 ensureExtensionsIsMutable(); 1313 final FieldDescriptor descriptor = extension.getDescriptor(); 1314 extensions.setRepeatedField( 1315 descriptor, index, 1316 extension.singularToReflectionType(value)); 1317 onChanged(); 1318 return (BuilderType) this; 1319 } 1320 1321 /** Append a value to a repeated extension. */ 1322 public final <Type> BuilderType addExtension( 1323 final ExtensionLite<MessageType, List<Type>> extensionLite, 1324 final Type value) { 1325 Extension<MessageType, List<Type>> extension = checkNotLite(extensionLite); 1326 1327 verifyExtensionContainingType(extension); 1328 ensureExtensionsIsMutable(); 1329 final FieldDescriptor descriptor = extension.getDescriptor(); 1330 extensions.addRepeatedField( 1331 descriptor, extension.singularToReflectionType(value)); 1332 onChanged(); 1333 return (BuilderType) this; 1334 } 1335 1336 /** Clear an extension. */ 1337 public final <Type> BuilderType clearExtension( 1338 final ExtensionLite<MessageType, ?> extensionLite) { 1339 Extension<MessageType, ?> extension = checkNotLite(extensionLite); 1340 1341 verifyExtensionContainingType(extension); 1342 ensureExtensionsIsMutable(); 1343 extensions.clearField(extension.getDescriptor()); 1344 onChanged(); 1345 return (BuilderType) this; 1346 } 1347 1348 /** Check if a singular extension is present. */ 1349 @Override 1350 public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) { 1351 return hasExtension((ExtensionLite<MessageType, Type>) extension); 1352 } 1353 /** Check if a singular extension is present. */ 1354 @Override 1355 public final <Type> boolean hasExtension( 1356 final GeneratedExtension<MessageType, Type> extension) { 1357 return hasExtension((ExtensionLite<MessageType, Type>) extension); 1358 } 1359 /** Get the number of elements in a repeated extension. */ 1360 @Override 1361 public final <Type> int getExtensionCount( 1362 final Extension<MessageType, List<Type>> extension) { 1363 return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); 1364 } 1365 /** Get the number of elements in a repeated extension. */ 1366 @Override 1367 public final <Type> int getExtensionCount( 1368 final GeneratedExtension<MessageType, List<Type>> extension) { 1369 return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); 1370 } 1371 /** Get the value of an extension. */ 1372 @Override 1373 public final <Type> Type getExtension(final Extension<MessageType, Type> extension) { 1374 return getExtension((ExtensionLite<MessageType, Type>) extension); 1375 } 1376 /** Get the value of an extension. */ 1377 @Override 1378 public final <Type> Type getExtension( 1379 final GeneratedExtension<MessageType, Type> extension) { 1380 return getExtension((ExtensionLite<MessageType, Type>) extension); 1381 } 1382 /** Get the value of an extension. */ 1383 @Override 1384 public final <Type> Type getExtension( 1385 final Extension<MessageType, List<Type>> extension, final int index) { 1386 return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); 1387 } 1388 /** Get the value of an extension. */ 1389 @Override 1390 public final <Type> Type getExtension( 1391 final GeneratedExtension<MessageType, List<Type>> extension, final int index) { 1392 return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); 1393 } 1394 /** Set the value of an extension. */ 1395 public final <Type> BuilderType setExtension( 1396 final Extension<MessageType, Type> extension, final Type value) { 1397 return setExtension((ExtensionLite<MessageType, Type>) extension, value); 1398 } 1399 /** Set the value of an extension. */ 1400 public <Type> BuilderType setExtension( 1401 final GeneratedExtension<MessageType, Type> extension, final Type value) { 1402 return setExtension((ExtensionLite<MessageType, Type>) extension, value); 1403 } 1404 /** Set the value of one element of a repeated extension. */ 1405 public final <Type> BuilderType setExtension( 1406 final Extension<MessageType, List<Type>> extension, 1407 final int index, final Type value) { 1408 return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value); 1409 } 1410 /** Set the value of one element of a repeated extension. */ 1411 public <Type> BuilderType setExtension( 1412 final GeneratedExtension<MessageType, List<Type>> extension, 1413 final int index, final Type value) { 1414 return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value); 1415 } 1416 /** Append a value to a repeated extension. */ 1417 public final <Type> BuilderType addExtension( 1418 final Extension<MessageType, List<Type>> extension, final Type value) { 1419 return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value); 1420 } 1421 /** Append a value to a repeated extension. */ 1422 public <Type> BuilderType addExtension( 1423 final GeneratedExtension<MessageType, List<Type>> extension, final Type value) { 1424 return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value); 1425 } 1426 /** Clear an extension. */ 1427 public final <Type> BuilderType clearExtension( 1428 final Extension<MessageType, ?> extension) { 1429 return clearExtension((ExtensionLite<MessageType, ?>) extension); 1430 } 1431 /** Clear an extension. */ 1432 public <Type> BuilderType clearExtension( 1433 final GeneratedExtension<MessageType, ?> extension) { 1434 return clearExtension((ExtensionLite<MessageType, ?>) extension); 1435 } 1436 1437 /** Called by subclasses to check if all extensions are initialized. */ 1438 protected boolean extensionsAreInitialized() { 1439 return extensions.isInitialized(); 1440 } 1441 1442 /** 1443 * Called by the build code path to create a copy of the extensions for 1444 * building the message. 1445 */ 1446 private FieldSet<FieldDescriptor> buildExtensions() { 1447 extensions.makeImmutable(); 1448 return extensions; 1449 } 1450 1451 @Override 1452 public boolean isInitialized() { 1453 return super.isInitialized() && extensionsAreInitialized(); 1454 } 1455 1456 /** 1457 * Called by subclasses to parse an unknown field or an extension. 1458 * @return {@code true} unless the tag is an end-group tag. 1459 */ 1460 @Override 1461 protected boolean parseUnknownField( 1462 final CodedInputStream input, 1463 final UnknownFieldSet.Builder unknownFields, 1464 final ExtensionRegistryLite extensionRegistry, 1465 final int tag) throws IOException { 1466 return MessageReflection.mergeFieldFrom( 1467 input, unknownFields, extensionRegistry, getDescriptorForType(), 1468 new MessageReflection.BuilderAdapter(this), tag); 1469 } 1470 1471 // --------------------------------------------------------------- 1472 // Reflection 1473 1474 @Override 1475 public Map<FieldDescriptor, Object> getAllFields() { 1476 final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable(); 1477 result.putAll(extensions.getAllFields()); 1478 return Collections.unmodifiableMap(result); 1479 } 1480 1481 @Override 1482 public Object getField(final FieldDescriptor field) { 1483 if (field.isExtension()) { 1484 verifyContainingType(field); 1485 final Object value = extensions.getField(field); 1486 if (value == null) { 1487 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1488 // Lacking an ExtensionRegistry, we have no way to determine the 1489 // extension's real type, so we return a DynamicMessage. 1490 return DynamicMessage.getDefaultInstance(field.getMessageType()); 1491 } else { 1492 return field.getDefaultValue(); 1493 } 1494 } else { 1495 return value; 1496 } 1497 } else { 1498 return super.getField(field); 1499 } 1500 } 1501 1502 @Override 1503 public int getRepeatedFieldCount(final FieldDescriptor field) { 1504 if (field.isExtension()) { 1505 verifyContainingType(field); 1506 return extensions.getRepeatedFieldCount(field); 1507 } else { 1508 return super.getRepeatedFieldCount(field); 1509 } 1510 } 1511 1512 @Override 1513 public Object getRepeatedField(final FieldDescriptor field, 1514 final int index) { 1515 if (field.isExtension()) { 1516 verifyContainingType(field); 1517 return extensions.getRepeatedField(field, index); 1518 } else { 1519 return super.getRepeatedField(field, index); 1520 } 1521 } 1522 1523 @Override 1524 public boolean hasField(final FieldDescriptor field) { 1525 if (field.isExtension()) { 1526 verifyContainingType(field); 1527 return extensions.hasField(field); 1528 } else { 1529 return super.hasField(field); 1530 } 1531 } 1532 1533 @Override 1534 public BuilderType setField(final FieldDescriptor field, 1535 final Object value) { 1536 if (field.isExtension()) { 1537 verifyContainingType(field); 1538 ensureExtensionsIsMutable(); 1539 extensions.setField(field, value); 1540 onChanged(); 1541 return (BuilderType) this; 1542 } else { 1543 return super.setField(field, value); 1544 } 1545 } 1546 1547 @Override 1548 public BuilderType clearField(final FieldDescriptor field) { 1549 if (field.isExtension()) { 1550 verifyContainingType(field); 1551 ensureExtensionsIsMutable(); 1552 extensions.clearField(field); 1553 onChanged(); 1554 return (BuilderType) this; 1555 } else { 1556 return super.clearField(field); 1557 } 1558 } 1559 1560 @Override 1561 public BuilderType setRepeatedField(final FieldDescriptor field, 1562 final int index, final Object value) { 1563 if (field.isExtension()) { 1564 verifyContainingType(field); 1565 ensureExtensionsIsMutable(); 1566 extensions.setRepeatedField(field, index, value); 1567 onChanged(); 1568 return (BuilderType) this; 1569 } else { 1570 return super.setRepeatedField(field, index, value); 1571 } 1572 } 1573 1574 @Override 1575 public BuilderType addRepeatedField(final FieldDescriptor field, 1576 final Object value) { 1577 if (field.isExtension()) { 1578 verifyContainingType(field); 1579 ensureExtensionsIsMutable(); 1580 extensions.addRepeatedField(field, value); 1581 onChanged(); 1582 return (BuilderType) this; 1583 } else { 1584 return super.addRepeatedField(field, value); 1585 } 1586 } 1587 1588 protected final void mergeExtensionFields(final ExtendableMessage other) { 1589 ensureExtensionsIsMutable(); 1590 extensions.mergeFrom(other.extensions); 1591 onChanged(); 1592 } 1593 1594 private void verifyContainingType(final FieldDescriptor field) { 1595 if (field.getContainingType() != getDescriptorForType()) { 1596 throw new IllegalArgumentException( 1597 "FieldDescriptor does not match message type."); 1598 } 1599 } 1600 } 1601 1602 // ----------------------------------------------------------------- 1603 1604 /** 1605 * Gets the descriptor for an extension. The implementation depends on whether 1606 * the extension is scoped in the top level of a file or scoped in a Message. 1607 */ 1608 static interface ExtensionDescriptorRetriever { 1609 FieldDescriptor getDescriptor(); 1610 } 1611 1612 private abstract static class CachedDescriptorRetriever 1613 implements ExtensionDescriptorRetriever { 1614 private volatile FieldDescriptor descriptor; 1615 protected abstract FieldDescriptor loadDescriptor(); 1616 1617 @Override 1618 public FieldDescriptor getDescriptor() { 1619 if (descriptor == null) { 1620 synchronized (this) { 1621 if (descriptor == null) { 1622 descriptor = loadDescriptor(); 1623 } 1624 } 1625 } 1626 return descriptor; 1627 } 1628 } 1629 1630 // ================================================================= 1631 1632 /** Calls Class.getMethod and throws a RuntimeException if it fails. */ 1633 @SuppressWarnings("unchecked") 1634 private static Method getMethodOrDie( 1635 final Class clazz, final String name, final Class... params) { 1636 try { 1637 return clazz.getMethod(name, params); 1638 } catch (NoSuchMethodException e) { 1639 throw new RuntimeException( 1640 "Generated message class \"" + clazz.getName() + 1641 "\" missing method \"" + name + "\".", e); 1642 } 1643 } 1644 1645 /** Calls invoke and throws a RuntimeException if it fails. */ 1646 private static Object invokeOrDie( 1647 final Method method, final Object object, final Object... params) { 1648 try { 1649 return method.invoke(object, params); 1650 } catch (IllegalAccessException e) { 1651 throw new RuntimeException( 1652 "Couldn't use Java reflection to implement protocol message " + 1653 "reflection.", e); 1654 } catch (InvocationTargetException e) { 1655 final Throwable cause = e.getCause(); 1656 if (cause instanceof RuntimeException) { 1657 throw (RuntimeException) cause; 1658 } else if (cause instanceof Error) { 1659 throw (Error) cause; 1660 } else { 1661 throw new RuntimeException( 1662 "Unexpected exception thrown by generated accessor method.", cause); 1663 } 1664 } 1665 } 1666 1667 /** 1668 * Gets the map field with the given field number. This method should be 1669 * overridden in the generated message class if the message contains map 1670 * fields. 1671 * 1672 * Unlike other field types, reflection support for map fields can't be 1673 * implemented based on generated public API because we need to access a 1674 * map field as a list in reflection API but the generated API only allows 1675 * us to access it as a map. This method returns the underlying map field 1676 * directly and thus enables us to access the map field as a list. 1677 */ 1678 @SuppressWarnings({"rawtypes", "unused"}) 1679 protected MapField internalGetMapField(int fieldNumber) { 1680 // Note that we can't use descriptor names here because this method will 1681 // be called when descriptor is being initialized. 1682 throw new RuntimeException( 1683 "No map fields found in " + getClass().getName()); 1684 } 1685 1686 /** 1687 * Users should ignore this class. This class provides the implementation 1688 * with access to the fields of a message object using Java reflection. 1689 */ 1690 public static final class FieldAccessorTable { 1691 1692 /** 1693 * Construct a FieldAccessorTable for a particular message class. Only 1694 * one FieldAccessorTable should ever be constructed per class. 1695 * 1696 * @param descriptor The type's descriptor. 1697 * @param camelCaseNames The camelcase names of all fields in the message. 1698 * These are used to derive the accessor method names. 1699 * @param messageClass The message type. 1700 * @param builderClass The builder type. 1701 */ 1702 public FieldAccessorTable( 1703 final Descriptor descriptor, 1704 final String[] camelCaseNames, 1705 final Class<? extends GeneratedMessageV3> messageClass, 1706 final Class<? extends Builder> builderClass) { 1707 this(descriptor, camelCaseNames); 1708 ensureFieldAccessorsInitialized(messageClass, builderClass); 1709 } 1710 1711 /** 1712 * Construct a FieldAccessorTable for a particular message class without 1713 * initializing FieldAccessors. 1714 */ 1715 public FieldAccessorTable( 1716 final Descriptor descriptor, 1717 final String[] camelCaseNames) { 1718 this.descriptor = descriptor; 1719 this.camelCaseNames = camelCaseNames; 1720 fields = new FieldAccessor[descriptor.getFields().size()]; 1721 oneofs = new OneofAccessor[descriptor.getOneofs().size()]; 1722 initialized = false; 1723 } 1724 1725 private boolean isMapFieldEnabled(FieldDescriptor field) { 1726 boolean result = true; 1727 return result; 1728 } 1729 1730 /** 1731 * Ensures the field accessors are initialized. This method is thread-safe. 1732 * 1733 * @param messageClass The message type. 1734 * @param builderClass The builder type. 1735 * @return this 1736 */ 1737 public FieldAccessorTable ensureFieldAccessorsInitialized( 1738 Class<? extends GeneratedMessageV3> messageClass, 1739 Class<? extends Builder> builderClass) { 1740 if (initialized) { return this; } 1741 synchronized (this) { 1742 if (initialized) { return this; } 1743 int fieldsSize = fields.length; 1744 for (int i = 0; i < fieldsSize; i++) { 1745 FieldDescriptor field = descriptor.getFields().get(i); 1746 String containingOneofCamelCaseName = null; 1747 if (field.getContainingOneof() != null) { 1748 containingOneofCamelCaseName = 1749 camelCaseNames[fieldsSize + field.getContainingOneof().getIndex()]; 1750 } 1751 if (field.isRepeated()) { 1752 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1753 if (field.isMapField() && isMapFieldEnabled(field)) { 1754 fields[i] = new MapFieldAccessor( 1755 field, camelCaseNames[i], messageClass, builderClass); 1756 } else { 1757 fields[i] = new RepeatedMessageFieldAccessor( 1758 field, camelCaseNames[i], messageClass, builderClass); 1759 } 1760 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1761 fields[i] = new RepeatedEnumFieldAccessor( 1762 field, camelCaseNames[i], messageClass, builderClass); 1763 } else { 1764 fields[i] = new RepeatedFieldAccessor( 1765 field, camelCaseNames[i], messageClass, builderClass); 1766 } 1767 } else { 1768 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1769 fields[i] = new SingularMessageFieldAccessor( 1770 field, camelCaseNames[i], messageClass, builderClass, 1771 containingOneofCamelCaseName); 1772 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1773 fields[i] = new SingularEnumFieldAccessor( 1774 field, camelCaseNames[i], messageClass, builderClass, 1775 containingOneofCamelCaseName); 1776 } else if (field.getJavaType() == FieldDescriptor.JavaType.STRING) { 1777 fields[i] = new SingularStringFieldAccessor( 1778 field, camelCaseNames[i], messageClass, builderClass, 1779 containingOneofCamelCaseName); 1780 } else { 1781 fields[i] = new SingularFieldAccessor( 1782 field, camelCaseNames[i], messageClass, builderClass, 1783 containingOneofCamelCaseName); 1784 } 1785 } 1786 } 1787 1788 int oneofsSize = oneofs.length; 1789 for (int i = 0; i < oneofsSize; i++) { 1790 oneofs[i] = new OneofAccessor( 1791 descriptor, camelCaseNames[i + fieldsSize], 1792 messageClass, builderClass); 1793 } 1794 initialized = true; 1795 camelCaseNames = null; 1796 return this; 1797 } 1798 } 1799 1800 private final Descriptor descriptor; 1801 private final FieldAccessor[] fields; 1802 private String[] camelCaseNames; 1803 private final OneofAccessor[] oneofs; 1804 private volatile boolean initialized; 1805 1806 /** Get the FieldAccessor for a particular field. */ 1807 private FieldAccessor getField(final FieldDescriptor field) { 1808 if (field.getContainingType() != descriptor) { 1809 throw new IllegalArgumentException( 1810 "FieldDescriptor does not match message type."); 1811 } else if (field.isExtension()) { 1812 // If this type had extensions, it would subclass ExtendableMessage, 1813 // which overrides the reflection interface to handle extensions. 1814 throw new IllegalArgumentException( 1815 "This type does not have extensions."); 1816 } 1817 return fields[field.getIndex()]; 1818 } 1819 1820 /** Get the OneofAccessor for a particular oneof. */ 1821 private OneofAccessor getOneof(final OneofDescriptor oneof) { 1822 if (oneof.getContainingType() != descriptor) { 1823 throw new IllegalArgumentException( 1824 "OneofDescriptor does not match message type."); 1825 } 1826 return oneofs[oneof.getIndex()]; 1827 } 1828 1829 /** 1830 * Abstract interface that provides access to a single field. This is 1831 * implemented differently depending on the field type and cardinality. 1832 */ 1833 private interface FieldAccessor { 1834 Object get(GeneratedMessageV3 message); 1835 Object get(GeneratedMessageV3.Builder builder); 1836 Object getRaw(GeneratedMessageV3 message); 1837 Object getRaw(GeneratedMessageV3.Builder builder); 1838 void set(Builder builder, Object value); 1839 Object getRepeated(GeneratedMessageV3 message, int index); 1840 Object getRepeated(GeneratedMessageV3.Builder builder, int index); 1841 Object getRepeatedRaw(GeneratedMessageV3 message, int index); 1842 Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index); 1843 void setRepeated(Builder builder, 1844 int index, Object value); 1845 void addRepeated(Builder builder, Object value); 1846 boolean has(GeneratedMessageV3 message); 1847 boolean has(GeneratedMessageV3.Builder builder); 1848 int getRepeatedCount(GeneratedMessageV3 message); 1849 int getRepeatedCount(GeneratedMessageV3.Builder builder); 1850 void clear(Builder builder); 1851 Message.Builder newBuilder(); 1852 Message.Builder getBuilder(GeneratedMessageV3.Builder builder); 1853 Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, 1854 int index); 1855 } 1856 1857 /** OneofAccessor provides access to a single oneof. */ 1858 private static class OneofAccessor { 1859 OneofAccessor( 1860 final Descriptor descriptor, final String camelCaseName, 1861 final Class<? extends GeneratedMessageV3> messageClass, 1862 final Class<? extends Builder> builderClass) { 1863 this.descriptor = descriptor; 1864 caseMethod = 1865 getMethodOrDie(messageClass, "get" + camelCaseName + "Case"); 1866 caseMethodBuilder = 1867 getMethodOrDie(builderClass, "get" + camelCaseName + "Case"); 1868 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 1869 } 1870 1871 private final Descriptor descriptor; 1872 private final Method caseMethod; 1873 private final Method caseMethodBuilder; 1874 private final Method clearMethod; 1875 1876 public boolean has(final GeneratedMessageV3 message) { 1877 if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) { 1878 return false; 1879 } 1880 return true; 1881 } 1882 1883 public boolean has(GeneratedMessageV3.Builder builder) { 1884 if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) { 1885 return false; 1886 } 1887 return true; 1888 } 1889 1890 public FieldDescriptor get(final GeneratedMessageV3 message) { 1891 int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); 1892 if (fieldNumber > 0) { 1893 return descriptor.findFieldByNumber(fieldNumber); 1894 } 1895 return null; 1896 } 1897 1898 public FieldDescriptor get(GeneratedMessageV3.Builder builder) { 1899 int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); 1900 if (fieldNumber > 0) { 1901 return descriptor.findFieldByNumber(fieldNumber); 1902 } 1903 return null; 1904 } 1905 1906 public void clear(final Builder builder) { 1907 invokeOrDie(clearMethod, builder); 1908 } 1909 } 1910 1911 private static boolean supportFieldPresence(FileDescriptor file) { 1912 return file.getSyntax() == FileDescriptor.Syntax.PROTO2; 1913 } 1914 1915 // --------------------------------------------------------------- 1916 1917 private static class SingularFieldAccessor implements FieldAccessor { 1918 SingularFieldAccessor( 1919 final FieldDescriptor descriptor, final String camelCaseName, 1920 final Class<? extends GeneratedMessageV3> messageClass, 1921 final Class<? extends Builder> builderClass, 1922 final String containingOneofCamelCaseName) { 1923 field = descriptor; 1924 isOneofField = descriptor.getContainingOneof() != null; 1925 hasHasMethod = supportFieldPresence(descriptor.getFile()) 1926 || (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE); 1927 getMethod = getMethodOrDie(messageClass, "get" + camelCaseName); 1928 getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName); 1929 type = getMethod.getReturnType(); 1930 setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type); 1931 hasMethod = 1932 hasHasMethod ? getMethodOrDie(messageClass, "has" + camelCaseName) : null; 1933 hasMethodBuilder = 1934 hasHasMethod ? getMethodOrDie(builderClass, "has" + camelCaseName) : null; 1935 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 1936 caseMethod = isOneofField ? getMethodOrDie( 1937 messageClass, "get" + containingOneofCamelCaseName + "Case") : null; 1938 caseMethodBuilder = isOneofField ? getMethodOrDie( 1939 builderClass, "get" + containingOneofCamelCaseName + "Case") : null; 1940 } 1941 1942 // Note: We use Java reflection to call public methods rather than 1943 // access private fields directly as this avoids runtime security 1944 // checks. 1945 protected final Class<?> type; 1946 protected final Method getMethod; 1947 protected final Method getMethodBuilder; 1948 protected final Method setMethod; 1949 protected final Method hasMethod; 1950 protected final Method hasMethodBuilder; 1951 protected final Method clearMethod; 1952 protected final Method caseMethod; 1953 protected final Method caseMethodBuilder; 1954 protected final FieldDescriptor field; 1955 protected final boolean isOneofField; 1956 protected final boolean hasHasMethod; 1957 1958 private int getOneofFieldNumber(final GeneratedMessageV3 message) { 1959 return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); 1960 } 1961 1962 private int getOneofFieldNumber(final GeneratedMessageV3.Builder builder) { 1963 return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); 1964 } 1965 1966 @Override 1967 public Object get(final GeneratedMessageV3 message) { 1968 return invokeOrDie(getMethod, message); 1969 } 1970 @Override 1971 public Object get(GeneratedMessageV3.Builder builder) { 1972 return invokeOrDie(getMethodBuilder, builder); 1973 } 1974 @Override 1975 public Object getRaw(final GeneratedMessageV3 message) { 1976 return get(message); 1977 } 1978 @Override 1979 public Object getRaw(GeneratedMessageV3.Builder builder) { 1980 return get(builder); 1981 } 1982 @Override 1983 public void set(final Builder builder, final Object value) { 1984 invokeOrDie(setMethod, builder, value); 1985 } 1986 @Override 1987 public Object getRepeated(final GeneratedMessageV3 message, final int index) { 1988 throw new UnsupportedOperationException( 1989 "getRepeatedField() called on a singular field."); 1990 } 1991 @Override 1992 public Object getRepeatedRaw(final GeneratedMessageV3 message, final int index) { 1993 throw new UnsupportedOperationException( 1994 "getRepeatedFieldRaw() called on a singular field."); 1995 } 1996 @Override 1997 public Object getRepeated(GeneratedMessageV3.Builder builder, int index) { 1998 throw new UnsupportedOperationException( 1999 "getRepeatedField() called on a singular field."); 2000 } 2001 @Override 2002 public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) { 2003 throw new UnsupportedOperationException( 2004 "getRepeatedFieldRaw() called on a singular field."); 2005 } 2006 @Override 2007 public void setRepeated(final Builder builder, final int index, final Object value) { 2008 throw new UnsupportedOperationException( 2009 "setRepeatedField() called on a singular field."); 2010 } 2011 @Override 2012 public void addRepeated(final Builder builder, final Object value) { 2013 throw new UnsupportedOperationException( 2014 "addRepeatedField() called on a singular field."); 2015 } 2016 @Override 2017 public boolean has(final GeneratedMessageV3 message) { 2018 if (!hasHasMethod) { 2019 if (isOneofField) { 2020 return getOneofFieldNumber(message) == field.getNumber(); 2021 } 2022 return !get(message).equals(field.getDefaultValue()); 2023 } 2024 return (Boolean) invokeOrDie(hasMethod, message); 2025 } 2026 @Override 2027 public boolean has(GeneratedMessageV3.Builder builder) { 2028 if (!hasHasMethod) { 2029 if (isOneofField) { 2030 return getOneofFieldNumber(builder) == field.getNumber(); 2031 } 2032 return !get(builder).equals(field.getDefaultValue()); 2033 } 2034 return (Boolean) invokeOrDie(hasMethodBuilder, builder); 2035 } 2036 @Override 2037 public int getRepeatedCount(final GeneratedMessageV3 message) { 2038 throw new UnsupportedOperationException( 2039 "getRepeatedFieldSize() called on a singular field."); 2040 } 2041 @Override 2042 public int getRepeatedCount(GeneratedMessageV3.Builder builder) { 2043 throw new UnsupportedOperationException( 2044 "getRepeatedFieldSize() called on a singular field."); 2045 } 2046 @Override 2047 public void clear(final Builder builder) { 2048 invokeOrDie(clearMethod, builder); 2049 } 2050 @Override 2051 public Message.Builder newBuilder() { 2052 throw new UnsupportedOperationException( 2053 "newBuilderForField() called on a non-Message type."); 2054 } 2055 @Override 2056 public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) { 2057 throw new UnsupportedOperationException( 2058 "getFieldBuilder() called on a non-Message type."); 2059 } 2060 @Override 2061 public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) { 2062 throw new UnsupportedOperationException( 2063 "getRepeatedFieldBuilder() called on a non-Message type."); 2064 } 2065 } 2066 2067 private static class RepeatedFieldAccessor implements FieldAccessor { 2068 protected final Class type; 2069 protected final Method getMethod; 2070 protected final Method getMethodBuilder; 2071 protected final Method getRepeatedMethod; 2072 protected final Method getRepeatedMethodBuilder; 2073 protected final Method setRepeatedMethod; 2074 protected final Method addRepeatedMethod; 2075 protected final Method getCountMethod; 2076 protected final Method getCountMethodBuilder; 2077 protected final Method clearMethod; 2078 2079 RepeatedFieldAccessor( 2080 final FieldDescriptor descriptor, final String camelCaseName, 2081 final Class<? extends GeneratedMessageV3> messageClass, 2082 final Class<? extends Builder> builderClass) { 2083 getMethod = getMethodOrDie(messageClass, 2084 "get" + camelCaseName + "List"); 2085 getMethodBuilder = getMethodOrDie(builderClass, 2086 "get" + camelCaseName + "List"); 2087 getRepeatedMethod = 2088 getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE); 2089 getRepeatedMethodBuilder = 2090 getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE); 2091 type = getRepeatedMethod.getReturnType(); 2092 setRepeatedMethod = 2093 getMethodOrDie(builderClass, "set" + camelCaseName, 2094 Integer.TYPE, type); 2095 addRepeatedMethod = 2096 getMethodOrDie(builderClass, "add" + camelCaseName, type); 2097 getCountMethod = 2098 getMethodOrDie(messageClass, "get" + camelCaseName + "Count"); 2099 getCountMethodBuilder = 2100 getMethodOrDie(builderClass, "get" + camelCaseName + "Count"); 2101 2102 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 2103 } 2104 2105 @Override 2106 public Object get(final GeneratedMessageV3 message) { 2107 return invokeOrDie(getMethod, message); 2108 } 2109 @Override 2110 public Object get(GeneratedMessageV3.Builder builder) { 2111 return invokeOrDie(getMethodBuilder, builder); 2112 } 2113 @Override 2114 public Object getRaw(final GeneratedMessageV3 message) { 2115 return get(message); 2116 } 2117 @Override 2118 public Object getRaw(GeneratedMessageV3.Builder builder) { 2119 return get(builder); 2120 } 2121 @Override 2122 public void set(final Builder builder, final Object value) { 2123 // Add all the elements individually. This serves two purposes: 2124 // 1) Verifies that each element has the correct type. 2125 // 2) Insures that the caller cannot modify the list later on and 2126 // have the modifications be reflected in the message. 2127 clear(builder); 2128 for (final Object element : (List<?>) value) { 2129 addRepeated(builder, element); 2130 } 2131 } 2132 @Override 2133 public Object getRepeated(final GeneratedMessageV3 message, final int index) { 2134 return invokeOrDie(getRepeatedMethod, message, index); 2135 } 2136 @Override 2137 public Object getRepeated(GeneratedMessageV3.Builder builder, int index) { 2138 return invokeOrDie(getRepeatedMethodBuilder, builder, index); 2139 } 2140 @Override 2141 public Object getRepeatedRaw(GeneratedMessageV3 message, int index) { 2142 return getRepeated(message, index); 2143 } 2144 @Override 2145 public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) { 2146 return getRepeated(builder, index); 2147 } 2148 @Override 2149 public void setRepeated(final Builder builder, final int index, final Object value) { 2150 invokeOrDie(setRepeatedMethod, builder, index, value); 2151 } 2152 @Override 2153 public void addRepeated(final Builder builder, final Object value) { 2154 invokeOrDie(addRepeatedMethod, builder, value); 2155 } 2156 @Override 2157 public boolean has(final GeneratedMessageV3 message) { 2158 throw new UnsupportedOperationException( 2159 "hasField() called on a repeated field."); 2160 } 2161 @Override 2162 public boolean has(GeneratedMessageV3.Builder builder) { 2163 throw new UnsupportedOperationException( 2164 "hasField() called on a repeated field."); 2165 } 2166 @Override 2167 public int getRepeatedCount(final GeneratedMessageV3 message) { 2168 return (Integer) invokeOrDie(getCountMethod, message); 2169 } 2170 @Override 2171 public int getRepeatedCount(GeneratedMessageV3.Builder builder) { 2172 return (Integer) invokeOrDie(getCountMethodBuilder, builder); 2173 } 2174 @Override 2175 public void clear(final Builder builder) { 2176 invokeOrDie(clearMethod, builder); 2177 } 2178 @Override 2179 public Message.Builder newBuilder() { 2180 throw new UnsupportedOperationException( 2181 "newBuilderForField() called on a non-Message type."); 2182 } 2183 @Override 2184 public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) { 2185 throw new UnsupportedOperationException( 2186 "getFieldBuilder() called on a non-Message type."); 2187 } 2188 @Override 2189 public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) { 2190 throw new UnsupportedOperationException( 2191 "getRepeatedFieldBuilder() called on a non-Message type."); 2192 } 2193 } 2194 2195 private static class MapFieldAccessor implements FieldAccessor { 2196 MapFieldAccessor( 2197 final FieldDescriptor descriptor, final String camelCaseName, 2198 final Class<? extends GeneratedMessageV3> messageClass, 2199 final Class<? extends Builder> builderClass) { 2200 field = descriptor; 2201 Method getDefaultInstanceMethod = 2202 getMethodOrDie(messageClass, "getDefaultInstance"); 2203 MapField defaultMapField = getMapField( 2204 (GeneratedMessageV3) invokeOrDie(getDefaultInstanceMethod, null)); 2205 mapEntryMessageDefaultInstance = 2206 defaultMapField.getMapEntryMessageDefaultInstance(); 2207 } 2208 2209 private final FieldDescriptor field; 2210 private final Message mapEntryMessageDefaultInstance; 2211 2212 private MapField<?, ?> getMapField(GeneratedMessageV3 message) { 2213 return (MapField<?, ?>) message.internalGetMapField(field.getNumber()); 2214 } 2215 2216 private MapField<?, ?> getMapField(GeneratedMessageV3.Builder builder) { 2217 return (MapField<?, ?>) builder.internalGetMapField(field.getNumber()); 2218 } 2219 2220 private MapField<?, ?> getMutableMapField( 2221 GeneratedMessageV3.Builder builder) { 2222 return (MapField<?, ?>) builder.internalGetMutableMapField( 2223 field.getNumber()); 2224 } 2225 2226 @Override 2227 public Object get(GeneratedMessageV3 message) { 2228 List result = new ArrayList(); 2229 for (int i = 0; i < getRepeatedCount(message); i++) { 2230 result.add(getRepeated(message, i)); 2231 } 2232 return Collections.unmodifiableList(result); 2233 } 2234 2235 @Override 2236 public Object get(Builder builder) { 2237 List result = new ArrayList(); 2238 for (int i = 0; i < getRepeatedCount(builder); i++) { 2239 result.add(getRepeated(builder, i)); 2240 } 2241 return Collections.unmodifiableList(result); 2242 } 2243 2244 @Override 2245 public Object getRaw(GeneratedMessageV3 message) { 2246 return get(message); 2247 } 2248 2249 @Override 2250 public Object getRaw(GeneratedMessageV3.Builder builder) { 2251 return get(builder); 2252 } 2253 2254 @Override 2255 public void set(Builder builder, Object value) { 2256 clear(builder); 2257 for (Object entry : (List) value) { 2258 addRepeated(builder, entry); 2259 } 2260 } 2261 2262 @Override 2263 public Object getRepeated(GeneratedMessageV3 message, int index) { 2264 return getMapField(message).getList().get(index); 2265 } 2266 2267 @Override 2268 public Object getRepeated(Builder builder, int index) { 2269 return getMapField(builder).getList().get(index); 2270 } 2271 2272 @Override 2273 public Object getRepeatedRaw(GeneratedMessageV3 message, int index) { 2274 return getRepeated(message, index); 2275 } 2276 2277 @Override 2278 public Object getRepeatedRaw(Builder builder, int index) { 2279 return getRepeated(builder, index); 2280 } 2281 2282 @Override 2283 public void setRepeated(Builder builder, int index, Object value) { 2284 getMutableMapField(builder).getMutableList().set(index, (Message) value); 2285 } 2286 2287 @Override 2288 public void addRepeated(Builder builder, Object value) { 2289 getMutableMapField(builder).getMutableList().add((Message) value); 2290 } 2291 2292 @Override 2293 public boolean has(GeneratedMessageV3 message) { 2294 throw new UnsupportedOperationException( 2295 "hasField() is not supported for repeated fields."); 2296 } 2297 2298 @Override 2299 public boolean has(Builder builder) { 2300 throw new UnsupportedOperationException( 2301 "hasField() is not supported for repeated fields."); 2302 } 2303 2304 @Override 2305 public int getRepeatedCount(GeneratedMessageV3 message) { 2306 return getMapField(message).getList().size(); 2307 } 2308 2309 @Override 2310 public int getRepeatedCount(Builder builder) { 2311 return getMapField(builder).getList().size(); 2312 } 2313 2314 @Override 2315 public void clear(Builder builder) { 2316 getMutableMapField(builder).getMutableList().clear(); 2317 } 2318 2319 @Override 2320 public com.google.protobuf.Message.Builder newBuilder() { 2321 return mapEntryMessageDefaultInstance.newBuilderForType(); 2322 } 2323 2324 @Override 2325 public com.google.protobuf.Message.Builder getBuilder(Builder builder) { 2326 throw new UnsupportedOperationException( 2327 "Nested builder not supported for map fields."); 2328 } 2329 2330 @Override 2331 public com.google.protobuf.Message.Builder getRepeatedBuilder(Builder builder, int index) { 2332 throw new UnsupportedOperationException( 2333 "Nested builder not supported for map fields."); 2334 } 2335 } 2336 2337 // --------------------------------------------------------------- 2338 2339 private static final class SingularEnumFieldAccessor 2340 extends SingularFieldAccessor { 2341 SingularEnumFieldAccessor( 2342 final FieldDescriptor descriptor, final String camelCaseName, 2343 final Class<? extends GeneratedMessageV3> messageClass, 2344 final Class<? extends Builder> builderClass, 2345 final String containingOneofCamelCaseName) { 2346 super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName); 2347 2348 enumDescriptor = descriptor.getEnumType(); 2349 2350 valueOfMethod = getMethodOrDie(type, "valueOf", 2351 EnumValueDescriptor.class); 2352 getValueDescriptorMethod = 2353 getMethodOrDie(type, "getValueDescriptor"); 2354 2355 supportUnknownEnumValue = descriptor.getFile().supportsUnknownEnumValue(); 2356 if (supportUnknownEnumValue) { 2357 getValueMethod = 2358 getMethodOrDie(messageClass, "get" + camelCaseName + "Value"); 2359 getValueMethodBuilder = 2360 getMethodOrDie(builderClass, "get" + camelCaseName + "Value"); 2361 setValueMethod = 2362 getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class); 2363 } 2364 } 2365 2366 private EnumDescriptor enumDescriptor; 2367 2368 private Method valueOfMethod; 2369 private Method getValueDescriptorMethod; 2370 2371 private boolean supportUnknownEnumValue; 2372 private Method getValueMethod; 2373 private Method getValueMethodBuilder; 2374 private Method setValueMethod; 2375 2376 @Override 2377 public Object get(final GeneratedMessageV3 message) { 2378 if (supportUnknownEnumValue) { 2379 int value = (Integer) invokeOrDie(getValueMethod, message); 2380 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2381 } 2382 return invokeOrDie(getValueDescriptorMethod, super.get(message)); 2383 } 2384 2385 @Override 2386 public Object get(final GeneratedMessageV3.Builder builder) { 2387 if (supportUnknownEnumValue) { 2388 int value = (Integer) invokeOrDie(getValueMethodBuilder, builder); 2389 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2390 } 2391 return invokeOrDie(getValueDescriptorMethod, super.get(builder)); 2392 } 2393 2394 @Override 2395 public void set(final Builder builder, final Object value) { 2396 if (supportUnknownEnumValue) { 2397 invokeOrDie(setValueMethod, builder, 2398 ((EnumValueDescriptor) value).getNumber()); 2399 return; 2400 } 2401 super.set(builder, invokeOrDie(valueOfMethod, null, value)); 2402 } 2403 } 2404 2405 private static final class RepeatedEnumFieldAccessor 2406 extends RepeatedFieldAccessor { 2407 RepeatedEnumFieldAccessor( 2408 final FieldDescriptor descriptor, final String camelCaseName, 2409 final Class<? extends GeneratedMessageV3> messageClass, 2410 final Class<? extends Builder> builderClass) { 2411 super(descriptor, camelCaseName, messageClass, builderClass); 2412 2413 enumDescriptor = descriptor.getEnumType(); 2414 2415 valueOfMethod = getMethodOrDie(type, "valueOf", 2416 EnumValueDescriptor.class); 2417 getValueDescriptorMethod = 2418 getMethodOrDie(type, "getValueDescriptor"); 2419 2420 supportUnknownEnumValue = descriptor.getFile().supportsUnknownEnumValue(); 2421 if (supportUnknownEnumValue) { 2422 getRepeatedValueMethod = 2423 getMethodOrDie(messageClass, "get" + camelCaseName + "Value", int.class); 2424 getRepeatedValueMethodBuilder = 2425 getMethodOrDie(builderClass, "get" + camelCaseName + "Value", int.class); 2426 setRepeatedValueMethod = 2427 getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class, int.class); 2428 addRepeatedValueMethod = 2429 getMethodOrDie(builderClass, "add" + camelCaseName + "Value", int.class); 2430 } 2431 } 2432 private EnumDescriptor enumDescriptor; 2433 2434 private final Method valueOfMethod; 2435 private final Method getValueDescriptorMethod; 2436 2437 private boolean supportUnknownEnumValue; 2438 private Method getRepeatedValueMethod; 2439 private Method getRepeatedValueMethodBuilder; 2440 private Method setRepeatedValueMethod; 2441 private Method addRepeatedValueMethod; 2442 2443 @Override 2444 @SuppressWarnings("unchecked") 2445 public Object get(final GeneratedMessageV3 message) { 2446 final List newList = new ArrayList(); 2447 final int size = getRepeatedCount(message); 2448 for (int i = 0; i < size; i++) { 2449 newList.add(getRepeated(message, i)); 2450 } 2451 return Collections.unmodifiableList(newList); 2452 } 2453 2454 @Override 2455 @SuppressWarnings("unchecked") 2456 public Object get(final GeneratedMessageV3.Builder builder) { 2457 final List newList = new ArrayList(); 2458 final int size = getRepeatedCount(builder); 2459 for (int i = 0; i < size; i++) { 2460 newList.add(getRepeated(builder, i)); 2461 } 2462 return Collections.unmodifiableList(newList); 2463 } 2464 2465 @Override 2466 public Object getRepeated(final GeneratedMessageV3 message, 2467 final int index) { 2468 if (supportUnknownEnumValue) { 2469 int value = (Integer) invokeOrDie(getRepeatedValueMethod, message, index); 2470 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2471 } 2472 return invokeOrDie(getValueDescriptorMethod, 2473 super.getRepeated(message, index)); 2474 } 2475 @Override 2476 public Object getRepeated(final GeneratedMessageV3.Builder builder, 2477 final int index) { 2478 if (supportUnknownEnumValue) { 2479 int value = (Integer) invokeOrDie(getRepeatedValueMethodBuilder, builder, index); 2480 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2481 } 2482 return invokeOrDie(getValueDescriptorMethod, 2483 super.getRepeated(builder, index)); 2484 } 2485 @Override 2486 public void setRepeated(final Builder builder, 2487 final int index, final Object value) { 2488 if (supportUnknownEnumValue) { 2489 invokeOrDie(setRepeatedValueMethod, builder, index, 2490 ((EnumValueDescriptor) value).getNumber()); 2491 return; 2492 } 2493 super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null, 2494 value)); 2495 } 2496 @Override 2497 public void addRepeated(final Builder builder, final Object value) { 2498 if (supportUnknownEnumValue) { 2499 invokeOrDie(addRepeatedValueMethod, builder, 2500 ((EnumValueDescriptor) value).getNumber()); 2501 return; 2502 } 2503 super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value)); 2504 } 2505 } 2506 2507 // --------------------------------------------------------------- 2508 2509 /** 2510 * Field accessor for string fields. 2511 * 2512 * <p>This class makes getFooBytes() and setFooBytes() available for 2513 * reflection API so that reflection based serialize/parse functions can 2514 * access the raw bytes of the field to preserve non-UTF8 bytes in the 2515 * string. 2516 * 2517 * <p>This ensures the serialize/parse round-trip safety, which is important 2518 * for servers which forward messages. 2519 */ 2520 private static final class SingularStringFieldAccessor 2521 extends SingularFieldAccessor { 2522 SingularStringFieldAccessor( 2523 final FieldDescriptor descriptor, final String camelCaseName, 2524 final Class<? extends GeneratedMessageV3> messageClass, 2525 final Class<? extends Builder> builderClass, 2526 final String containingOneofCamelCaseName) { 2527 super(descriptor, camelCaseName, messageClass, builderClass, 2528 containingOneofCamelCaseName); 2529 getBytesMethod = getMethodOrDie(messageClass, 2530 "get" + camelCaseName + "Bytes"); 2531 getBytesMethodBuilder = getMethodOrDie(builderClass, 2532 "get" + camelCaseName + "Bytes"); 2533 setBytesMethodBuilder = getMethodOrDie(builderClass, 2534 "set" + camelCaseName + "Bytes", ByteString.class); 2535 } 2536 2537 private final Method getBytesMethod; 2538 private final Method getBytesMethodBuilder; 2539 private final Method setBytesMethodBuilder; 2540 2541 @Override 2542 public Object getRaw(final GeneratedMessageV3 message) { 2543 return invokeOrDie(getBytesMethod, message); 2544 } 2545 2546 @Override 2547 public Object getRaw(GeneratedMessageV3.Builder builder) { 2548 return invokeOrDie(getBytesMethodBuilder, builder); 2549 } 2550 2551 @Override 2552 public void set(GeneratedMessageV3.Builder builder, Object value) { 2553 if (value instanceof ByteString) { 2554 invokeOrDie(setBytesMethodBuilder, builder, value); 2555 } else { 2556 super.set(builder, value); 2557 } 2558 } 2559 } 2560 2561 // --------------------------------------------------------------- 2562 2563 private static final class SingularMessageFieldAccessor 2564 extends SingularFieldAccessor { 2565 SingularMessageFieldAccessor( 2566 final FieldDescriptor descriptor, final String camelCaseName, 2567 final Class<? extends GeneratedMessageV3> messageClass, 2568 final Class<? extends Builder> builderClass, 2569 final String containingOneofCamelCaseName) { 2570 super(descriptor, camelCaseName, messageClass, builderClass, 2571 containingOneofCamelCaseName); 2572 2573 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 2574 getBuilderMethodBuilder = 2575 getMethodOrDie(builderClass, "get" + camelCaseName + "Builder"); 2576 } 2577 2578 private final Method newBuilderMethod; 2579 private final Method getBuilderMethodBuilder; 2580 2581 private Object coerceType(final Object value) { 2582 if (type.isInstance(value)) { 2583 return value; 2584 } else { 2585 // The value is not the exact right message type. However, if it 2586 // is an alternative implementation of the same type -- e.g. a 2587 // DynamicMessage -- we should accept it. In this case we can make 2588 // a copy of the message. 2589 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 2590 .mergeFrom((Message) value).buildPartial(); 2591 } 2592 } 2593 2594 @Override 2595 public void set(final Builder builder, final Object value) { 2596 super.set(builder, coerceType(value)); 2597 } 2598 @Override 2599 public Message.Builder newBuilder() { 2600 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 2601 } 2602 @Override 2603 public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) { 2604 return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder); 2605 } 2606 } 2607 2608 private static final class RepeatedMessageFieldAccessor 2609 extends RepeatedFieldAccessor { 2610 RepeatedMessageFieldAccessor( 2611 final FieldDescriptor descriptor, final String camelCaseName, 2612 final Class<? extends GeneratedMessageV3> messageClass, 2613 final Class<? extends Builder> builderClass) { 2614 super(descriptor, camelCaseName, messageClass, builderClass); 2615 2616 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 2617 getBuilderMethodBuilder = getMethodOrDie(builderClass, 2618 "get" + camelCaseName + "Builder", Integer.TYPE); 2619 } 2620 2621 private final Method newBuilderMethod; 2622 private final Method getBuilderMethodBuilder; 2623 2624 private Object coerceType(final Object value) { 2625 if (type.isInstance(value)) { 2626 return value; 2627 } else { 2628 // The value is not the exact right message type. However, if it 2629 // is an alternative implementation of the same type -- e.g. a 2630 // DynamicMessage -- we should accept it. In this case we can make 2631 // a copy of the message. 2632 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 2633 .mergeFrom((Message) value).build(); 2634 } 2635 } 2636 2637 @Override 2638 public void setRepeated(final Builder builder, 2639 final int index, final Object value) { 2640 super.setRepeated(builder, index, coerceType(value)); 2641 } 2642 @Override 2643 public void addRepeated(final Builder builder, final Object value) { 2644 super.addRepeated(builder, coerceType(value)); 2645 } 2646 @Override 2647 public Message.Builder newBuilder() { 2648 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 2649 } 2650 @Override 2651 public Message.Builder getRepeatedBuilder( 2652 final GeneratedMessageV3.Builder builder, final int index) { 2653 return (Message.Builder) invokeOrDie( 2654 getBuilderMethodBuilder, builder, index); 2655 } 2656 } 2657 } 2658 2659 /** 2660 * Replaces this object in the output stream with a serialized form. 2661 * Part of Java's serialization magic. Generated sub-classes must override 2662 * this method by calling {@code return super.writeReplace();} 2663 * @return a SerializedForm of this message 2664 */ 2665 protected Object writeReplace() throws ObjectStreamException { 2666 return new GeneratedMessageLite.SerializedForm(this); 2667 } 2668 2669 /** 2670 * Checks that the {@link Extension} is non-Lite and returns it as a 2671 * {@link GeneratedExtension}. 2672 */ 2673 private static <MessageType extends ExtendableMessage<MessageType>, T> 2674 Extension<MessageType, T> checkNotLite( 2675 ExtensionLite<MessageType, T> extension) { 2676 if (extension.isLite()) { 2677 throw new IllegalArgumentException("Expected non-lite extension."); 2678 } 2679 2680 return (Extension<MessageType, T>) extension; 2681 } 2682 2683 protected static int computeStringSize(final int fieldNumber, final Object value) { 2684 if (value instanceof String) { 2685 return CodedOutputStream.computeStringSize(fieldNumber, (String) value); 2686 } else { 2687 return CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) value); 2688 } 2689 } 2690 2691 protected static int computeStringSizeNoTag(final Object value) { 2692 if (value instanceof String) { 2693 return CodedOutputStream.computeStringSizeNoTag((String) value); 2694 } else { 2695 return CodedOutputStream.computeBytesSizeNoTag((ByteString) value); 2696 } 2697 } 2698 2699 protected static void writeString( 2700 CodedOutputStream output, final int fieldNumber, final Object value) throws IOException { 2701 if (value instanceof String) { 2702 output.writeString(fieldNumber, (String) value); 2703 } else { 2704 output.writeBytes(fieldNumber, (ByteString) value); 2705 } 2706 } 2707 2708 protected static void writeStringNoTag( 2709 CodedOutputStream output, final Object value) throws IOException { 2710 if (value instanceof String) { 2711 output.writeStringNoTag((String) value); 2712 } else { 2713 output.writeBytesNoTag((ByteString) value); 2714 } 2715 } 2716 } 2717