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