1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // http://code.google.com/p/protobuf/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import com.google.protobuf.Descriptors.Descriptor; 34 import com.google.protobuf.Descriptors.EnumValueDescriptor; 35 import com.google.protobuf.Descriptors.FieldDescriptor; 36 37 import java.io.IOException; 38 import java.io.ObjectStreamException; 39 import java.io.Serializable; 40 import java.lang.reflect.InvocationTargetException; 41 import java.lang.reflect.Method; 42 import java.util.ArrayList; 43 import java.util.Collections; 44 import java.util.Iterator; 45 import java.util.List; 46 import java.util.Map; 47 import java.util.TreeMap; 48 49 /** 50 * All generated protocol message classes extend this class. This class 51 * implements most of the Message and Builder interfaces using Java reflection. 52 * Users can ignore this class and pretend that generated messages implement 53 * the Message interface directly. 54 * 55 * @author kenton (at) google.com Kenton Varda 56 */ 57 public abstract class GeneratedMessage extends AbstractMessage 58 implements Serializable { 59 private static final long serialVersionUID = 1L; 60 61 /** 62 * For testing. Allows a test to disable the optimization that avoids using 63 * field builders for nested messages until they are requested. By disabling 64 * this optimization, existing tests can be reused to test the field builders. 65 */ 66 protected static boolean alwaysUseFieldBuilders = false; 67 68 protected GeneratedMessage() { 69 } 70 71 protected GeneratedMessage(Builder<?> builder) { 72 } 73 74 public Parser<? extends Message> getParserForType() { 75 throw new UnsupportedOperationException( 76 "This is supposed to be overridden by subclasses."); 77 } 78 79 /** 80 * For testing. Allows a test to disable the optimization that avoids using 81 * field builders for nested messages until they are requested. By disabling 82 * this optimization, existing tests can be reused to test the field builders. 83 * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}. 84 */ 85 static void enableAlwaysUseFieldBuildersForTesting() { 86 alwaysUseFieldBuilders = true; 87 } 88 89 /** 90 * Get the FieldAccessorTable for this type. We can't have the message 91 * class pass this in to the constructor because of bootstrapping trouble 92 * with DescriptorProtos. 93 */ 94 protected abstract FieldAccessorTable internalGetFieldAccessorTable(); 95 96 //@Override (Java 1.6 override semantics, but we must support 1.5) 97 public Descriptor getDescriptorForType() { 98 return internalGetFieldAccessorTable().descriptor; 99 } 100 101 /** Internal helper which returns a mutable map. */ 102 private Map<FieldDescriptor, Object> getAllFieldsMutable() { 103 final TreeMap<FieldDescriptor, Object> result = 104 new TreeMap<FieldDescriptor, Object>(); 105 final Descriptor descriptor = internalGetFieldAccessorTable().descriptor; 106 for (final FieldDescriptor field : descriptor.getFields()) { 107 if (field.isRepeated()) { 108 final List<?> value = (List<?>) getField(field); 109 if (!value.isEmpty()) { 110 result.put(field, value); 111 } 112 } else { 113 if (hasField(field)) { 114 result.put(field, getField(field)); 115 } 116 } 117 } 118 return result; 119 } 120 121 @Override 122 public boolean isInitialized() { 123 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 124 // Check that all required fields are present. 125 if (field.isRequired()) { 126 if (!hasField(field)) { 127 return false; 128 } 129 } 130 // Check that embedded messages are initialized. 131 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 132 if (field.isRepeated()) { 133 @SuppressWarnings("unchecked") final 134 List<Message> messageList = (List<Message>) getField(field); 135 for (final Message element : messageList) { 136 if (!element.isInitialized()) { 137 return false; 138 } 139 } 140 } else { 141 if (hasField(field) && !((Message) getField(field)).isInitialized()) { 142 return false; 143 } 144 } 145 } 146 } 147 148 return true; 149 } 150 151 //@Override (Java 1.6 override semantics, but we must support 1.5) 152 public Map<FieldDescriptor, Object> getAllFields() { 153 return Collections.unmodifiableMap(getAllFieldsMutable()); 154 } 155 156 //@Override (Java 1.6 override semantics, but we must support 1.5) 157 public boolean hasField(final FieldDescriptor field) { 158 return internalGetFieldAccessorTable().getField(field).has(this); 159 } 160 161 //@Override (Java 1.6 override semantics, but we must support 1.5) 162 public Object getField(final FieldDescriptor field) { 163 return internalGetFieldAccessorTable().getField(field).get(this); 164 } 165 166 //@Override (Java 1.6 override semantics, but we must support 1.5) 167 public int getRepeatedFieldCount(final FieldDescriptor field) { 168 return internalGetFieldAccessorTable().getField(field) 169 .getRepeatedCount(this); 170 } 171 172 //@Override (Java 1.6 override semantics, but we must support 1.5) 173 public Object getRepeatedField(final FieldDescriptor field, final int index) { 174 return internalGetFieldAccessorTable().getField(field) 175 .getRepeated(this, index); 176 } 177 178 //@Override (Java 1.6 override semantics, but we must support 1.5) 179 public UnknownFieldSet getUnknownFields() { 180 throw new UnsupportedOperationException( 181 "This is supposed to be overridden by subclasses."); 182 } 183 184 /** 185 * Called by subclasses to parse an unknown field. 186 * @return {@code true} unless the tag is an end-group tag. 187 */ 188 protected boolean parseUnknownField( 189 CodedInputStream input, 190 UnknownFieldSet.Builder unknownFields, 191 ExtensionRegistryLite extensionRegistry, 192 int tag) throws IOException { 193 return unknownFields.mergeFieldFrom(tag, input); 194 } 195 196 /** 197 * Used by parsing constructors in generated classes. 198 */ 199 protected void makeExtensionsImmutable() { 200 // Noop for messages without extensions. 201 } 202 203 protected abstract Message.Builder newBuilderForType(BuilderParent parent); 204 205 /** 206 * Interface for the parent of a Builder that allows the builder to 207 * communicate invalidations back to the parent for use when using nested 208 * builders. 209 */ 210 protected interface BuilderParent { 211 212 /** 213 * A builder becomes dirty whenever a field is modified -- including fields 214 * in nested builders -- and becomes clean when build() is called. Thus, 215 * when a builder becomes dirty, all its parents become dirty as well, and 216 * when it becomes clean, all its children become clean. The dirtiness 217 * state is used to invalidate certain cached values. 218 * <br> 219 * To this end, a builder calls markAsDirty() on its parent whenever it 220 * transitions from clean to dirty. The parent must propagate this call to 221 * its own parent, unless it was already dirty, in which case the 222 * grandparent must necessarily already be dirty as well. The parent can 223 * only transition back to "clean" after calling build() on all children. 224 */ 225 void markDirty(); 226 } 227 228 @SuppressWarnings("unchecked") 229 public abstract static class Builder <BuilderType extends Builder> 230 extends AbstractMessage.Builder<BuilderType> { 231 232 private BuilderParent builderParent; 233 234 private BuilderParentImpl meAsParent; 235 236 // Indicates that we've built a message and so we are now obligated 237 // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener. 238 private boolean isClean; 239 240 private UnknownFieldSet unknownFields = 241 UnknownFieldSet.getDefaultInstance(); 242 243 protected Builder() { 244 this(null); 245 } 246 247 protected Builder(BuilderParent builderParent) { 248 this.builderParent = builderParent; 249 } 250 251 void dispose() { 252 builderParent = null; 253 } 254 255 /** 256 * Called by the subclass when a message is built. 257 */ 258 protected void onBuilt() { 259 if (builderParent != null) { 260 markClean(); 261 } 262 } 263 264 /** 265 * Called by the subclass or a builder to notify us that a message was 266 * built and may be cached and therefore invalidations are needed. 267 */ 268 protected void markClean() { 269 this.isClean = true; 270 } 271 272 /** 273 * Gets whether invalidations are needed 274 * 275 * @return whether invalidations are needed 276 */ 277 protected boolean isClean() { 278 return isClean; 279 } 280 281 // This is implemented here only to work around an apparent bug in the 282 // Java compiler and/or build system. See bug #1898463. The mere presence 283 // of this dummy clone() implementation makes it go away. 284 @Override 285 public BuilderType clone() { 286 throw new UnsupportedOperationException( 287 "This is supposed to be overridden by subclasses."); 288 } 289 290 /** 291 * Called by the initialization and clear code paths to allow subclasses to 292 * reset any of their builtin fields back to the initial values. 293 */ 294 public BuilderType clear() { 295 unknownFields = UnknownFieldSet.getDefaultInstance(); 296 onChanged(); 297 return (BuilderType) this; 298 } 299 300 /** 301 * Get the FieldAccessorTable for this type. We can't have the message 302 * class pass this in to the constructor because of bootstrapping trouble 303 * with DescriptorProtos. 304 */ 305 protected abstract FieldAccessorTable internalGetFieldAccessorTable(); 306 307 //@Override (Java 1.6 override semantics, but we must support 1.5) 308 public Descriptor getDescriptorForType() { 309 return internalGetFieldAccessorTable().descriptor; 310 } 311 312 //@Override (Java 1.6 override semantics, but we must support 1.5) 313 public Map<FieldDescriptor, Object> getAllFields() { 314 return Collections.unmodifiableMap(getAllFieldsMutable()); 315 } 316 317 /** Internal helper which returns a mutable map. */ 318 private Map<FieldDescriptor, Object> getAllFieldsMutable() { 319 final TreeMap<FieldDescriptor, Object> result = 320 new TreeMap<FieldDescriptor, Object>(); 321 final Descriptor descriptor = internalGetFieldAccessorTable().descriptor; 322 for (final FieldDescriptor field : descriptor.getFields()) { 323 if (field.isRepeated()) { 324 final List value = (List) getField(field); 325 if (!value.isEmpty()) { 326 result.put(field, value); 327 } 328 } else { 329 if (hasField(field)) { 330 result.put(field, getField(field)); 331 } 332 } 333 } 334 return result; 335 } 336 337 public Message.Builder newBuilderForField( 338 final FieldDescriptor field) { 339 return internalGetFieldAccessorTable().getField(field).newBuilder(); 340 } 341 342 //@Override (Java 1.6 override semantics, but we must support 1.5) 343 public Message.Builder getFieldBuilder(final FieldDescriptor field) { 344 return internalGetFieldAccessorTable().getField(field).getBuilder(this); 345 } 346 347 //@Override (Java 1.6 override semantics, but we must support 1.5) 348 public boolean hasField(final FieldDescriptor field) { 349 return internalGetFieldAccessorTable().getField(field).has(this); 350 } 351 352 //@Override (Java 1.6 override semantics, but we must support 1.5) 353 public Object getField(final FieldDescriptor field) { 354 Object object = internalGetFieldAccessorTable().getField(field).get(this); 355 if (field.isRepeated()) { 356 // The underlying list object is still modifiable at this point. 357 // Make sure not to expose the modifiable list to the caller. 358 return Collections.unmodifiableList((List) object); 359 } else { 360 return object; 361 } 362 } 363 364 public BuilderType setField(final FieldDescriptor field, 365 final Object value) { 366 internalGetFieldAccessorTable().getField(field).set(this, value); 367 return (BuilderType) this; 368 } 369 370 //@Override (Java 1.6 override semantics, but we must support 1.5) 371 public BuilderType clearField(final FieldDescriptor field) { 372 internalGetFieldAccessorTable().getField(field).clear(this); 373 return (BuilderType) this; 374 } 375 376 //@Override (Java 1.6 override semantics, but we must support 1.5) 377 public int getRepeatedFieldCount(final FieldDescriptor field) { 378 return internalGetFieldAccessorTable().getField(field) 379 .getRepeatedCount(this); 380 } 381 382 //@Override (Java 1.6 override semantics, but we must support 1.5) 383 public Object getRepeatedField(final FieldDescriptor field, 384 final int index) { 385 return internalGetFieldAccessorTable().getField(field) 386 .getRepeated(this, index); 387 } 388 389 public BuilderType setRepeatedField(final FieldDescriptor field, 390 final int index, final Object value) { 391 internalGetFieldAccessorTable().getField(field) 392 .setRepeated(this, index, value); 393 return (BuilderType) this; 394 } 395 396 public BuilderType addRepeatedField(final FieldDescriptor field, 397 final Object value) { 398 internalGetFieldAccessorTable().getField(field).addRepeated(this, value); 399 return (BuilderType) this; 400 } 401 402 public final BuilderType setUnknownFields( 403 final UnknownFieldSet unknownFields) { 404 this.unknownFields = unknownFields; 405 onChanged(); 406 return (BuilderType) this; 407 } 408 409 @Override 410 public final BuilderType mergeUnknownFields( 411 final UnknownFieldSet unknownFields) { 412 this.unknownFields = 413 UnknownFieldSet.newBuilder(this.unknownFields) 414 .mergeFrom(unknownFields) 415 .build(); 416 onChanged(); 417 return (BuilderType) this; 418 } 419 420 //@Override (Java 1.6 override semantics, but we must support 1.5) 421 public boolean isInitialized() { 422 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 423 // Check that all required fields are present. 424 if (field.isRequired()) { 425 if (!hasField(field)) { 426 return false; 427 } 428 } 429 // Check that embedded messages are initialized. 430 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 431 if (field.isRepeated()) { 432 @SuppressWarnings("unchecked") final 433 List<Message> messageList = (List<Message>) getField(field); 434 for (final Message element : messageList) { 435 if (!element.isInitialized()) { 436 return false; 437 } 438 } 439 } else { 440 if (hasField(field) && 441 !((Message) getField(field)).isInitialized()) { 442 return false; 443 } 444 } 445 } 446 } 447 return true; 448 } 449 450 //@Override (Java 1.6 override semantics, but we must support 1.5) 451 public final UnknownFieldSet getUnknownFields() { 452 return unknownFields; 453 } 454 455 /** 456 * Called by subclasses to parse an unknown field. 457 * @return {@code true} unless the tag is an end-group tag. 458 */ 459 protected boolean parseUnknownField( 460 final CodedInputStream input, 461 final UnknownFieldSet.Builder unknownFields, 462 final ExtensionRegistryLite extensionRegistry, 463 final int tag) throws IOException { 464 return unknownFields.mergeFieldFrom(tag, input); 465 } 466 467 /** 468 * Implementation of {@link BuilderParent} for giving to our children. This 469 * small inner class makes it so we don't publicly expose the BuilderParent 470 * methods. 471 */ 472 private class BuilderParentImpl implements BuilderParent { 473 474 //@Override (Java 1.6 override semantics, but we must support 1.5) 475 public void markDirty() { 476 onChanged(); 477 } 478 } 479 480 /** 481 * Gets the {@link BuilderParent} for giving to our children. 482 * @return The builder parent for our children. 483 */ 484 protected BuilderParent getParentForChildren() { 485 if (meAsParent == null) { 486 meAsParent = new BuilderParentImpl(); 487 } 488 return meAsParent; 489 } 490 491 /** 492 * Called when a the builder or one of its nested children has changed 493 * and any parent should be notified of its invalidation. 494 */ 495 protected final void onChanged() { 496 if (isClean && builderParent != null) { 497 builderParent.markDirty(); 498 499 // Don't keep dispatching invalidations until build is called again. 500 isClean = false; 501 } 502 } 503 } 504 505 // ================================================================= 506 // Extensions-related stuff 507 508 public interface ExtendableMessageOrBuilder< 509 MessageType extends ExtendableMessage> extends MessageOrBuilder { 510 511 /** Check if a singular extension is present. */ 512 <Type> boolean hasExtension( 513 GeneratedExtension<MessageType, Type> extension); 514 515 /** Get the number of elements in a repeated extension. */ 516 <Type> int getExtensionCount( 517 GeneratedExtension<MessageType, List<Type>> extension); 518 519 /** Get the value of an extension. */ 520 <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension); 521 522 /** Get one element of a repeated extension. */ 523 <Type> Type getExtension( 524 GeneratedExtension<MessageType, List<Type>> extension, 525 int index); 526 } 527 528 /** 529 * Generated message classes for message types that contain extension ranges 530 * subclass this. 531 * 532 * <p>This class implements type-safe accessors for extensions. They 533 * implement all the same operations that you can do with normal fields -- 534 * e.g. "has", "get", and "getCount" -- but for extensions. The extensions 535 * are identified using instances of the class {@link GeneratedExtension}; 536 * the protocol compiler generates a static instance of this class for every 537 * extension in its input. Through the magic of generics, all is made 538 * type-safe. 539 * 540 * <p>For example, imagine you have the {@code .proto} file: 541 * 542 * <pre> 543 * option java_class = "MyProto"; 544 * 545 * message Foo { 546 * extensions 1000 to max; 547 * } 548 * 549 * extend Foo { 550 * optional int32 bar; 551 * } 552 * </pre> 553 * 554 * <p>Then you might write code like: 555 * 556 * <pre> 557 * MyProto.Foo foo = getFoo(); 558 * int i = foo.getExtension(MyProto.bar); 559 * </pre> 560 * 561 * <p>See also {@link ExtendableBuilder}. 562 */ 563 public abstract static class ExtendableMessage< 564 MessageType extends ExtendableMessage> 565 extends GeneratedMessage 566 implements ExtendableMessageOrBuilder<MessageType> { 567 568 private final FieldSet<FieldDescriptor> extensions; 569 570 protected ExtendableMessage() { 571 this.extensions = FieldSet.newFieldSet(); 572 } 573 574 protected ExtendableMessage( 575 ExtendableBuilder<MessageType, ?> builder) { 576 super(builder); 577 this.extensions = builder.buildExtensions(); 578 } 579 580 private void verifyExtensionContainingType( 581 final GeneratedExtension<MessageType, ?> extension) { 582 if (extension.getDescriptor().getContainingType() != 583 getDescriptorForType()) { 584 // This can only happen if someone uses unchecked operations. 585 throw new IllegalArgumentException( 586 "Extension is for type \"" + 587 extension.getDescriptor().getContainingType().getFullName() + 588 "\" which does not match message type \"" + 589 getDescriptorForType().getFullName() + "\"."); 590 } 591 } 592 593 /** Check if a singular extension is present. */ 594 //@Override (Java 1.6 override semantics, but we must support 1.5) 595 public final <Type> boolean hasExtension( 596 final GeneratedExtension<MessageType, Type> extension) { 597 verifyExtensionContainingType(extension); 598 return extensions.hasField(extension.getDescriptor()); 599 } 600 601 /** Get the number of elements in a repeated extension. */ 602 //@Override (Java 1.6 override semantics, but we must support 1.5) 603 public final <Type> int getExtensionCount( 604 final GeneratedExtension<MessageType, List<Type>> extension) { 605 verifyExtensionContainingType(extension); 606 final FieldDescriptor descriptor = extension.getDescriptor(); 607 return extensions.getRepeatedFieldCount(descriptor); 608 } 609 610 /** Get the value of an extension. */ 611 //@Override (Java 1.6 override semantics, but we must support 1.5) 612 @SuppressWarnings("unchecked") 613 public final <Type> Type getExtension( 614 final GeneratedExtension<MessageType, Type> extension) { 615 verifyExtensionContainingType(extension); 616 FieldDescriptor descriptor = extension.getDescriptor(); 617 final Object value = extensions.getField(descriptor); 618 if (value == null) { 619 if (descriptor.isRepeated()) { 620 return (Type) Collections.emptyList(); 621 } else if (descriptor.getJavaType() == 622 FieldDescriptor.JavaType.MESSAGE) { 623 return (Type) extension.getMessageDefaultInstance(); 624 } else { 625 return (Type) extension.fromReflectionType( 626 descriptor.getDefaultValue()); 627 } 628 } else { 629 return (Type) extension.fromReflectionType(value); 630 } 631 } 632 633 /** Get one element of a repeated extension. */ 634 //@Override (Java 1.6 override semantics, but we must support 1.5) 635 @SuppressWarnings("unchecked") 636 public final <Type> Type getExtension( 637 final GeneratedExtension<MessageType, List<Type>> extension, 638 final int index) { 639 verifyExtensionContainingType(extension); 640 FieldDescriptor descriptor = extension.getDescriptor(); 641 return (Type) extension.singularFromReflectionType( 642 extensions.getRepeatedField(descriptor, index)); 643 } 644 645 /** Called by subclasses to check if all extensions are initialized. */ 646 protected boolean extensionsAreInitialized() { 647 return extensions.isInitialized(); 648 } 649 650 @Override 651 public boolean isInitialized() { 652 return super.isInitialized() && extensionsAreInitialized(); 653 } 654 655 @Override 656 protected boolean parseUnknownField( 657 CodedInputStream input, 658 UnknownFieldSet.Builder unknownFields, 659 ExtensionRegistryLite extensionRegistry, 660 int tag) throws IOException { 661 return AbstractMessage.Builder.mergeFieldFrom( 662 input, unknownFields, extensionRegistry, getDescriptorForType(), 663 null, extensions, tag); 664 } 665 666 /** 667 * Used by parsing constructors in generated classes. 668 */ 669 @Override 670 protected void makeExtensionsImmutable() { 671 extensions.makeImmutable(); 672 } 673 674 /** 675 * Used by subclasses to serialize extensions. Extension ranges may be 676 * interleaved with field numbers, but we must write them in canonical 677 * (sorted by field number) order. ExtensionWriter helps us write 678 * individual ranges of extensions at once. 679 */ 680 protected class ExtensionWriter { 681 // Imagine how much simpler this code would be if Java iterators had 682 // a way to get the next element without advancing the iterator. 683 684 private final Iterator<Map.Entry<FieldDescriptor, Object>> iter = 685 extensions.iterator(); 686 private Map.Entry<FieldDescriptor, Object> next; 687 private final boolean messageSetWireFormat; 688 689 private ExtensionWriter(final boolean messageSetWireFormat) { 690 if (iter.hasNext()) { 691 next = iter.next(); 692 } 693 this.messageSetWireFormat = messageSetWireFormat; 694 } 695 696 public void writeUntil(final int end, final CodedOutputStream output) 697 throws IOException { 698 while (next != null && next.getKey().getNumber() < end) { 699 FieldDescriptor descriptor = next.getKey(); 700 if (messageSetWireFormat && descriptor.getLiteJavaType() == 701 WireFormat.JavaType.MESSAGE && 702 !descriptor.isRepeated()) { 703 if (next instanceof LazyField.LazyEntry<?>) { 704 output.writeRawMessageSetExtension(descriptor.getNumber(), 705 ((LazyField.LazyEntry<?>) next).getField().toByteString()); 706 } else { 707 output.writeMessageSetExtension(descriptor.getNumber(), 708 (Message) next.getValue()); 709 } 710 } else { 711 // TODO(xiangl): Taken care of following code, it may cause 712 // problem when we use LazyField for normal fields/extensions. 713 // Due to the optional field can be duplicated at the end of 714 // serialized bytes, which will make the serialized size change 715 // after lazy field parsed. So when we use LazyField globally, 716 // we need to change the following write method to write cached 717 // bytes directly rather than write the parsed message. 718 FieldSet.writeField(descriptor, next.getValue(), output); 719 } 720 if (iter.hasNext()) { 721 next = iter.next(); 722 } else { 723 next = null; 724 } 725 } 726 } 727 } 728 729 protected ExtensionWriter newExtensionWriter() { 730 return new ExtensionWriter(false); 731 } 732 protected ExtensionWriter newMessageSetExtensionWriter() { 733 return new ExtensionWriter(true); 734 } 735 736 /** Called by subclasses to compute the size of extensions. */ 737 protected int extensionsSerializedSize() { 738 return extensions.getSerializedSize(); 739 } 740 protected int extensionsSerializedSizeAsMessageSet() { 741 return extensions.getMessageSetSerializedSize(); 742 } 743 744 // --------------------------------------------------------------- 745 // Reflection 746 747 protected Map<FieldDescriptor, Object> getExtensionFields() { 748 return extensions.getAllFields(); 749 } 750 751 @Override 752 public Map<FieldDescriptor, Object> getAllFields() { 753 final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable(); 754 result.putAll(getExtensionFields()); 755 return Collections.unmodifiableMap(result); 756 } 757 758 @Override 759 public boolean hasField(final FieldDescriptor field) { 760 if (field.isExtension()) { 761 verifyContainingType(field); 762 return extensions.hasField(field); 763 } else { 764 return super.hasField(field); 765 } 766 } 767 768 @Override 769 public Object getField(final FieldDescriptor field) { 770 if (field.isExtension()) { 771 verifyContainingType(field); 772 final Object value = extensions.getField(field); 773 if (value == null) { 774 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 775 // Lacking an ExtensionRegistry, we have no way to determine the 776 // extension's real type, so we return a DynamicMessage. 777 return DynamicMessage.getDefaultInstance(field.getMessageType()); 778 } else { 779 return field.getDefaultValue(); 780 } 781 } else { 782 return value; 783 } 784 } else { 785 return super.getField(field); 786 } 787 } 788 789 @Override 790 public int getRepeatedFieldCount(final FieldDescriptor field) { 791 if (field.isExtension()) { 792 verifyContainingType(field); 793 return extensions.getRepeatedFieldCount(field); 794 } else { 795 return super.getRepeatedFieldCount(field); 796 } 797 } 798 799 @Override 800 public Object getRepeatedField(final FieldDescriptor field, 801 final int index) { 802 if (field.isExtension()) { 803 verifyContainingType(field); 804 return extensions.getRepeatedField(field, index); 805 } else { 806 return super.getRepeatedField(field, index); 807 } 808 } 809 810 private void verifyContainingType(final FieldDescriptor field) { 811 if (field.getContainingType() != getDescriptorForType()) { 812 throw new IllegalArgumentException( 813 "FieldDescriptor does not match message type."); 814 } 815 } 816 } 817 818 /** 819 * Generated message builders for message types that contain extension ranges 820 * subclass this. 821 * 822 * <p>This class implements type-safe accessors for extensions. They 823 * implement all the same operations that you can do with normal fields -- 824 * e.g. "get", "set", and "add" -- but for extensions. The extensions are 825 * identified using instances of the class {@link GeneratedExtension}; the 826 * protocol compiler generates a static instance of this class for every 827 * extension in its input. Through the magic of generics, all is made 828 * type-safe. 829 * 830 * <p>For example, imagine you have the {@code .proto} file: 831 * 832 * <pre> 833 * option java_class = "MyProto"; 834 * 835 * message Foo { 836 * extensions 1000 to max; 837 * } 838 * 839 * extend Foo { 840 * optional int32 bar; 841 * } 842 * </pre> 843 * 844 * <p>Then you might write code like: 845 * 846 * <pre> 847 * MyProto.Foo foo = 848 * MyProto.Foo.newBuilder() 849 * .setExtension(MyProto.bar, 123) 850 * .build(); 851 * </pre> 852 * 853 * <p>See also {@link ExtendableMessage}. 854 */ 855 @SuppressWarnings("unchecked") 856 public abstract static class ExtendableBuilder< 857 MessageType extends ExtendableMessage, 858 BuilderType extends ExtendableBuilder> 859 extends Builder<BuilderType> 860 implements ExtendableMessageOrBuilder<MessageType> { 861 862 private FieldSet<FieldDescriptor> extensions = FieldSet.emptySet(); 863 864 protected ExtendableBuilder() {} 865 866 protected ExtendableBuilder( 867 BuilderParent parent) { 868 super(parent); 869 } 870 871 @Override 872 public BuilderType clear() { 873 extensions = FieldSet.emptySet(); 874 return super.clear(); 875 } 876 877 // This is implemented here only to work around an apparent bug in the 878 // Java compiler and/or build system. See bug #1898463. The mere presence 879 // of this dummy clone() implementation makes it go away. 880 @Override 881 public BuilderType clone() { 882 throw new UnsupportedOperationException( 883 "This is supposed to be overridden by subclasses."); 884 } 885 886 private void ensureExtensionsIsMutable() { 887 if (extensions.isImmutable()) { 888 extensions = extensions.clone(); 889 } 890 } 891 892 private void verifyExtensionContainingType( 893 final GeneratedExtension<MessageType, ?> extension) { 894 if (extension.getDescriptor().getContainingType() != 895 getDescriptorForType()) { 896 // This can only happen if someone uses unchecked operations. 897 throw new IllegalArgumentException( 898 "Extension is for type \"" + 899 extension.getDescriptor().getContainingType().getFullName() + 900 "\" which does not match message type \"" + 901 getDescriptorForType().getFullName() + "\"."); 902 } 903 } 904 905 /** Check if a singular extension is present. */ 906 //@Override (Java 1.6 override semantics, but we must support 1.5) 907 public final <Type> boolean hasExtension( 908 final GeneratedExtension<MessageType, Type> extension) { 909 verifyExtensionContainingType(extension); 910 return extensions.hasField(extension.getDescriptor()); 911 } 912 913 /** Get the number of elements in a repeated extension. */ 914 //@Override (Java 1.6 override semantics, but we must support 1.5) 915 public final <Type> int getExtensionCount( 916 final GeneratedExtension<MessageType, List<Type>> extension) { 917 verifyExtensionContainingType(extension); 918 final FieldDescriptor descriptor = extension.getDescriptor(); 919 return extensions.getRepeatedFieldCount(descriptor); 920 } 921 922 /** Get the value of an extension. */ 923 //@Override (Java 1.6 override semantics, but we must support 1.5) 924 public final <Type> Type getExtension( 925 final GeneratedExtension<MessageType, Type> extension) { 926 verifyExtensionContainingType(extension); 927 FieldDescriptor descriptor = extension.getDescriptor(); 928 final Object value = extensions.getField(descriptor); 929 if (value == null) { 930 if (descriptor.isRepeated()) { 931 return (Type) Collections.emptyList(); 932 } else if (descriptor.getJavaType() == 933 FieldDescriptor.JavaType.MESSAGE) { 934 return (Type) extension.getMessageDefaultInstance(); 935 } else { 936 return (Type) extension.fromReflectionType( 937 descriptor.getDefaultValue()); 938 } 939 } else { 940 return (Type) extension.fromReflectionType(value); 941 } 942 } 943 944 /** Get one element of a repeated extension. */ 945 //@Override (Java 1.6 override semantics, but we must support 1.5) 946 public final <Type> Type getExtension( 947 final GeneratedExtension<MessageType, List<Type>> extension, 948 final int index) { 949 verifyExtensionContainingType(extension); 950 FieldDescriptor descriptor = extension.getDescriptor(); 951 return (Type) extension.singularFromReflectionType( 952 extensions.getRepeatedField(descriptor, index)); 953 } 954 955 /** Set the value of an extension. */ 956 public final <Type> BuilderType setExtension( 957 final GeneratedExtension<MessageType, Type> extension, 958 final Type value) { 959 verifyExtensionContainingType(extension); 960 ensureExtensionsIsMutable(); 961 final FieldDescriptor descriptor = extension.getDescriptor(); 962 extensions.setField(descriptor, extension.toReflectionType(value)); 963 onChanged(); 964 return (BuilderType) this; 965 } 966 967 /** Set the value of one element of a repeated extension. */ 968 public final <Type> BuilderType setExtension( 969 final GeneratedExtension<MessageType, List<Type>> extension, 970 final int index, final Type value) { 971 verifyExtensionContainingType(extension); 972 ensureExtensionsIsMutable(); 973 final FieldDescriptor descriptor = extension.getDescriptor(); 974 extensions.setRepeatedField( 975 descriptor, index, 976 extension.singularToReflectionType(value)); 977 onChanged(); 978 return (BuilderType) this; 979 } 980 981 /** Append a value to a repeated extension. */ 982 public final <Type> BuilderType addExtension( 983 final GeneratedExtension<MessageType, List<Type>> extension, 984 final Type value) { 985 verifyExtensionContainingType(extension); 986 ensureExtensionsIsMutable(); 987 final FieldDescriptor descriptor = extension.getDescriptor(); 988 extensions.addRepeatedField( 989 descriptor, extension.singularToReflectionType(value)); 990 onChanged(); 991 return (BuilderType) this; 992 } 993 994 /** Clear an extension. */ 995 public final <Type> BuilderType clearExtension( 996 final GeneratedExtension<MessageType, ?> extension) { 997 verifyExtensionContainingType(extension); 998 ensureExtensionsIsMutable(); 999 extensions.clearField(extension.getDescriptor()); 1000 onChanged(); 1001 return (BuilderType) this; 1002 } 1003 1004 /** Called by subclasses to check if all extensions are initialized. */ 1005 protected boolean extensionsAreInitialized() { 1006 return extensions.isInitialized(); 1007 } 1008 1009 /** 1010 * Called by the build code path to create a copy of the extensions for 1011 * building the message. 1012 */ 1013 private FieldSet<FieldDescriptor> buildExtensions() { 1014 extensions.makeImmutable(); 1015 return extensions; 1016 } 1017 1018 @Override 1019 public boolean isInitialized() { 1020 return super.isInitialized() && extensionsAreInitialized(); 1021 } 1022 1023 /** 1024 * Called by subclasses to parse an unknown field or an extension. 1025 * @return {@code true} unless the tag is an end-group tag. 1026 */ 1027 @Override 1028 protected boolean parseUnknownField( 1029 final CodedInputStream input, 1030 final UnknownFieldSet.Builder unknownFields, 1031 final ExtensionRegistryLite extensionRegistry, 1032 final int tag) throws IOException { 1033 return AbstractMessage.Builder.mergeFieldFrom( 1034 input, unknownFields, extensionRegistry, getDescriptorForType(), 1035 this, null, tag); 1036 } 1037 1038 // --------------------------------------------------------------- 1039 // Reflection 1040 1041 @Override 1042 public Map<FieldDescriptor, Object> getAllFields() { 1043 final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable(); 1044 result.putAll(extensions.getAllFields()); 1045 return Collections.unmodifiableMap(result); 1046 } 1047 1048 @Override 1049 public Object getField(final FieldDescriptor field) { 1050 if (field.isExtension()) { 1051 verifyContainingType(field); 1052 final Object value = extensions.getField(field); 1053 if (value == null) { 1054 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1055 // Lacking an ExtensionRegistry, we have no way to determine the 1056 // extension's real type, so we return a DynamicMessage. 1057 return DynamicMessage.getDefaultInstance(field.getMessageType()); 1058 } else { 1059 return field.getDefaultValue(); 1060 } 1061 } else { 1062 return value; 1063 } 1064 } else { 1065 return super.getField(field); 1066 } 1067 } 1068 1069 @Override 1070 public int getRepeatedFieldCount(final FieldDescriptor field) { 1071 if (field.isExtension()) { 1072 verifyContainingType(field); 1073 return extensions.getRepeatedFieldCount(field); 1074 } else { 1075 return super.getRepeatedFieldCount(field); 1076 } 1077 } 1078 1079 @Override 1080 public Object getRepeatedField(final FieldDescriptor field, 1081 final int index) { 1082 if (field.isExtension()) { 1083 verifyContainingType(field); 1084 return extensions.getRepeatedField(field, index); 1085 } else { 1086 return super.getRepeatedField(field, index); 1087 } 1088 } 1089 1090 @Override 1091 public boolean hasField(final FieldDescriptor field) { 1092 if (field.isExtension()) { 1093 verifyContainingType(field); 1094 return extensions.hasField(field); 1095 } else { 1096 return super.hasField(field); 1097 } 1098 } 1099 1100 @Override 1101 public BuilderType setField(final FieldDescriptor field, 1102 final Object value) { 1103 if (field.isExtension()) { 1104 verifyContainingType(field); 1105 ensureExtensionsIsMutable(); 1106 extensions.setField(field, value); 1107 onChanged(); 1108 return (BuilderType) this; 1109 } else { 1110 return super.setField(field, value); 1111 } 1112 } 1113 1114 @Override 1115 public BuilderType clearField(final FieldDescriptor field) { 1116 if (field.isExtension()) { 1117 verifyContainingType(field); 1118 ensureExtensionsIsMutable(); 1119 extensions.clearField(field); 1120 onChanged(); 1121 return (BuilderType) this; 1122 } else { 1123 return super.clearField(field); 1124 } 1125 } 1126 1127 @Override 1128 public BuilderType setRepeatedField(final FieldDescriptor field, 1129 final int index, final Object value) { 1130 if (field.isExtension()) { 1131 verifyContainingType(field); 1132 ensureExtensionsIsMutable(); 1133 extensions.setRepeatedField(field, index, value); 1134 onChanged(); 1135 return (BuilderType) this; 1136 } else { 1137 return super.setRepeatedField(field, index, value); 1138 } 1139 } 1140 1141 @Override 1142 public BuilderType addRepeatedField(final FieldDescriptor field, 1143 final Object value) { 1144 if (field.isExtension()) { 1145 verifyContainingType(field); 1146 ensureExtensionsIsMutable(); 1147 extensions.addRepeatedField(field, value); 1148 onChanged(); 1149 return (BuilderType) this; 1150 } else { 1151 return super.addRepeatedField(field, value); 1152 } 1153 } 1154 1155 protected final void mergeExtensionFields(final ExtendableMessage other) { 1156 ensureExtensionsIsMutable(); 1157 extensions.mergeFrom(other.extensions); 1158 onChanged(); 1159 } 1160 1161 private void verifyContainingType(final FieldDescriptor field) { 1162 if (field.getContainingType() != getDescriptorForType()) { 1163 throw new IllegalArgumentException( 1164 "FieldDescriptor does not match message type."); 1165 } 1166 } 1167 } 1168 1169 // ----------------------------------------------------------------- 1170 1171 /** 1172 * Gets the descriptor for an extension. The implementation depends on whether 1173 * the extension is scoped in the top level of a file or scoped in a Message. 1174 */ 1175 private static interface ExtensionDescriptorRetriever { 1176 FieldDescriptor getDescriptor(); 1177 } 1178 1179 /** For use by generated code only. */ 1180 public static <ContainingType extends Message, Type> 1181 GeneratedExtension<ContainingType, Type> 1182 newMessageScopedGeneratedExtension(final Message scope, 1183 final int descriptorIndex, 1184 final Class singularType, 1185 final Message defaultInstance) { 1186 // For extensions scoped within a Message, we use the Message to resolve 1187 // the outer class's descriptor, from which the extension descriptor is 1188 // obtained. 1189 return new GeneratedExtension<ContainingType, Type>( 1190 new ExtensionDescriptorRetriever() { 1191 //@Override (Java 1.6 override semantics, but we must support 1.5) 1192 public FieldDescriptor getDescriptor() { 1193 return scope.getDescriptorForType().getExtensions() 1194 .get(descriptorIndex); 1195 } 1196 }, 1197 singularType, 1198 defaultInstance); 1199 } 1200 1201 /** For use by generated code only. */ 1202 public static <ContainingType extends Message, Type> 1203 GeneratedExtension<ContainingType, Type> 1204 newFileScopedGeneratedExtension(final Class singularType, 1205 final Message defaultInstance) { 1206 // For extensions scoped within a file, we rely on the outer class's 1207 // static initializer to call internalInit() on the extension when the 1208 // descriptor is available. 1209 return new GeneratedExtension<ContainingType, Type>( 1210 null, // ExtensionDescriptorRetriever is initialized in internalInit(); 1211 singularType, 1212 defaultInstance); 1213 } 1214 1215 /** 1216 * Type used to represent generated extensions. The protocol compiler 1217 * generates a static singleton instance of this class for each extension. 1218 * 1219 * <p>For example, imagine you have the {@code .proto} file: 1220 * 1221 * <pre> 1222 * option java_class = "MyProto"; 1223 * 1224 * message Foo { 1225 * extensions 1000 to max; 1226 * } 1227 * 1228 * extend Foo { 1229 * optional int32 bar; 1230 * } 1231 * </pre> 1232 * 1233 * <p>Then, {@code MyProto.Foo.bar} has type 1234 * {@code GeneratedExtension<MyProto.Foo, Integer>}. 1235 * 1236 * <p>In general, users should ignore the details of this type, and simply use 1237 * these static singletons as parameters to the extension accessors defined 1238 * in {@link ExtendableMessage} and {@link ExtendableBuilder}. 1239 */ 1240 public static final class GeneratedExtension< 1241 ContainingType extends Message, Type> { 1242 // TODO(kenton): Find ways to avoid using Java reflection within this 1243 // class. Also try to avoid suppressing unchecked warnings. 1244 1245 // We can't always initialize the descriptor of a GeneratedExtension when 1246 // we first construct it due to initialization order difficulties (namely, 1247 // the descriptor may not have been constructed yet, since it is often 1248 // constructed by the initializer of a separate module). 1249 // 1250 // In the case of nested extensions, we initialize the 1251 // ExtensionDescriptorRetriever with an instance that uses the scoping 1252 // Message's default instance to retrieve the extension's descriptor. 1253 // 1254 // In the case of non-nested extensions, we initialize the 1255 // ExtensionDescriptorRetriever to null and rely on the outer class's static 1256 // initializer to call internalInit() after the descriptor has been parsed. 1257 private GeneratedExtension(ExtensionDescriptorRetriever descriptorRetriever, 1258 Class singularType, 1259 Message messageDefaultInstance) { 1260 if (Message.class.isAssignableFrom(singularType) && 1261 !singularType.isInstance(messageDefaultInstance)) { 1262 throw new IllegalArgumentException( 1263 "Bad messageDefaultInstance for " + singularType.getName()); 1264 } 1265 this.descriptorRetriever = descriptorRetriever; 1266 this.singularType = singularType; 1267 this.messageDefaultInstance = messageDefaultInstance; 1268 1269 if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) { 1270 this.enumValueOf = getMethodOrDie(singularType, "valueOf", 1271 EnumValueDescriptor.class); 1272 this.enumGetValueDescriptor = 1273 getMethodOrDie(singularType, "getValueDescriptor"); 1274 } else { 1275 this.enumValueOf = null; 1276 this.enumGetValueDescriptor = null; 1277 } 1278 } 1279 1280 /** For use by generated code only. */ 1281 public void internalInit(final FieldDescriptor descriptor) { 1282 if (descriptorRetriever != null) { 1283 throw new IllegalStateException("Already initialized."); 1284 } 1285 descriptorRetriever = new ExtensionDescriptorRetriever() { 1286 //@Override (Java 1.6 override semantics, but we must support 1.5) 1287 public FieldDescriptor getDescriptor() { 1288 return descriptor; 1289 } 1290 }; 1291 } 1292 1293 private ExtensionDescriptorRetriever descriptorRetriever; 1294 private final Class singularType; 1295 private final Message messageDefaultInstance; 1296 private final Method enumValueOf; 1297 private final Method enumGetValueDescriptor; 1298 1299 public FieldDescriptor getDescriptor() { 1300 if (descriptorRetriever == null) { 1301 throw new IllegalStateException( 1302 "getDescriptor() called before internalInit()"); 1303 } 1304 return descriptorRetriever.getDescriptor(); 1305 } 1306 1307 /** 1308 * If the extension is an embedded message or group, returns the default 1309 * instance of the message. 1310 */ 1311 public Message getMessageDefaultInstance() { 1312 return messageDefaultInstance; 1313 } 1314 1315 /** 1316 * Convert from the type used by the reflection accessors to the type used 1317 * by native accessors. E.g., for enums, the reflection accessors use 1318 * EnumValueDescriptors but the native accessors use the generated enum 1319 * type. 1320 */ 1321 @SuppressWarnings("unchecked") 1322 private Object fromReflectionType(final Object value) { 1323 FieldDescriptor descriptor = getDescriptor(); 1324 if (descriptor.isRepeated()) { 1325 if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE || 1326 descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1327 // Must convert the whole list. 1328 final List result = new ArrayList(); 1329 for (final Object element : (List) value) { 1330 result.add(singularFromReflectionType(element)); 1331 } 1332 return result; 1333 } else { 1334 return value; 1335 } 1336 } else { 1337 return singularFromReflectionType(value); 1338 } 1339 } 1340 1341 /** 1342 * Like {@link #fromReflectionType(Object)}, but if the type is a repeated 1343 * type, this converts a single element. 1344 */ 1345 private Object singularFromReflectionType(final Object value) { 1346 FieldDescriptor descriptor = getDescriptor(); 1347 switch (descriptor.getJavaType()) { 1348 case MESSAGE: 1349 if (singularType.isInstance(value)) { 1350 return value; 1351 } else { 1352 // It seems the copy of the embedded message stored inside the 1353 // extended message is not of the exact type the user was 1354 // expecting. This can happen if a user defines a 1355 // GeneratedExtension manually and gives it a different type. 1356 // This should not happen in normal use. But, to be nice, we'll 1357 // copy the message to whatever type the caller was expecting. 1358 return messageDefaultInstance.newBuilderForType() 1359 .mergeFrom((Message) value).build(); 1360 } 1361 case ENUM: 1362 return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value); 1363 default: 1364 return value; 1365 } 1366 } 1367 1368 /** 1369 * Convert from the type used by the native accessors to the type used 1370 * by reflection accessors. E.g., for enums, the reflection accessors use 1371 * EnumValueDescriptors but the native accessors use the generated enum 1372 * type. 1373 */ 1374 @SuppressWarnings("unchecked") 1375 private Object toReflectionType(final Object value) { 1376 FieldDescriptor descriptor = getDescriptor(); 1377 if (descriptor.isRepeated()) { 1378 if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1379 // Must convert the whole list. 1380 final List result = new ArrayList(); 1381 for (final Object element : (List) value) { 1382 result.add(singularToReflectionType(element)); 1383 } 1384 return result; 1385 } else { 1386 return value; 1387 } 1388 } else { 1389 return singularToReflectionType(value); 1390 } 1391 } 1392 1393 /** 1394 * Like {@link #toReflectionType(Object)}, but if the type is a repeated 1395 * type, this converts a single element. 1396 */ 1397 private Object singularToReflectionType(final Object value) { 1398 FieldDescriptor descriptor = getDescriptor(); 1399 switch (descriptor.getJavaType()) { 1400 case ENUM: 1401 return invokeOrDie(enumGetValueDescriptor, value); 1402 default: 1403 return value; 1404 } 1405 } 1406 } 1407 1408 // ================================================================= 1409 1410 /** Calls Class.getMethod and throws a RuntimeException if it fails. */ 1411 @SuppressWarnings("unchecked") 1412 private static Method getMethodOrDie( 1413 final Class clazz, final String name, final Class... params) { 1414 try { 1415 return clazz.getMethod(name, params); 1416 } catch (NoSuchMethodException e) { 1417 throw new RuntimeException( 1418 "Generated message class \"" + clazz.getName() + 1419 "\" missing method \"" + name + "\".", e); 1420 } 1421 } 1422 1423 /** Calls invoke and throws a RuntimeException if it fails. */ 1424 private static Object invokeOrDie( 1425 final Method method, final Object object, final Object... params) { 1426 try { 1427 return method.invoke(object, params); 1428 } catch (IllegalAccessException e) { 1429 throw new RuntimeException( 1430 "Couldn't use Java reflection to implement protocol message " + 1431 "reflection.", e); 1432 } catch (InvocationTargetException e) { 1433 final Throwable cause = e.getCause(); 1434 if (cause instanceof RuntimeException) { 1435 throw (RuntimeException) cause; 1436 } else if (cause instanceof Error) { 1437 throw (Error) cause; 1438 } else { 1439 throw new RuntimeException( 1440 "Unexpected exception thrown by generated accessor method.", cause); 1441 } 1442 } 1443 } 1444 1445 /** 1446 * Users should ignore this class. This class provides the implementation 1447 * with access to the fields of a message object using Java reflection. 1448 */ 1449 public static final class FieldAccessorTable { 1450 1451 /** 1452 * Construct a FieldAccessorTable for a particular message class. Only 1453 * one FieldAccessorTable should ever be constructed per class. 1454 * 1455 * @param descriptor The type's descriptor. 1456 * @param camelCaseNames The camelcase names of all fields in the message. 1457 * These are used to derive the accessor method names. 1458 * @param messageClass The message type. 1459 * @param builderClass The builder type. 1460 */ 1461 public FieldAccessorTable( 1462 final Descriptor descriptor, 1463 final String[] camelCaseNames, 1464 final Class<? extends GeneratedMessage> messageClass, 1465 final Class<? extends Builder> builderClass) { 1466 this(descriptor, camelCaseNames); 1467 ensureFieldAccessorsInitialized(messageClass, builderClass); 1468 } 1469 1470 /** 1471 * Construct a FieldAccessorTable for a particular message class without 1472 * initializing FieldAccessors. 1473 */ 1474 public FieldAccessorTable( 1475 final Descriptor descriptor, 1476 final String[] camelCaseNames) { 1477 this.descriptor = descriptor; 1478 this.camelCaseNames = camelCaseNames; 1479 fields = new FieldAccessor[descriptor.getFields().size()]; 1480 initialized = false; 1481 } 1482 1483 /** 1484 * Ensures the field accessors are initialized. This method is thread-safe. 1485 * 1486 * @param messageClass The message type. 1487 * @param builderClass The builder type. 1488 * @return this 1489 */ 1490 public FieldAccessorTable ensureFieldAccessorsInitialized( 1491 Class<? extends GeneratedMessage> messageClass, 1492 Class<? extends Builder> builderClass) { 1493 if (initialized) { return this; } 1494 synchronized (this) { 1495 if (initialized) { return this; } 1496 for (int i = 0; i < fields.length; i++) { 1497 FieldDescriptor field = descriptor.getFields().get(i); 1498 if (field.isRepeated()) { 1499 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1500 fields[i] = new RepeatedMessageFieldAccessor( 1501 field, camelCaseNames[i], messageClass, builderClass); 1502 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1503 fields[i] = new RepeatedEnumFieldAccessor( 1504 field, camelCaseNames[i], messageClass, builderClass); 1505 } else { 1506 fields[i] = new RepeatedFieldAccessor( 1507 field, camelCaseNames[i], messageClass, builderClass); 1508 } 1509 } else { 1510 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1511 fields[i] = new SingularMessageFieldAccessor( 1512 field, camelCaseNames[i], messageClass, builderClass); 1513 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1514 fields[i] = new SingularEnumFieldAccessor( 1515 field, camelCaseNames[i], messageClass, builderClass); 1516 } else { 1517 fields[i] = new SingularFieldAccessor( 1518 field, camelCaseNames[i], messageClass, builderClass); 1519 } 1520 } 1521 } 1522 initialized = true; 1523 camelCaseNames = null; 1524 return this; 1525 } 1526 } 1527 1528 private final Descriptor descriptor; 1529 private final FieldAccessor[] fields; 1530 private String[] camelCaseNames; 1531 private volatile boolean initialized; 1532 1533 /** Get the FieldAccessor for a particular field. */ 1534 private FieldAccessor getField(final FieldDescriptor field) { 1535 if (field.getContainingType() != descriptor) { 1536 throw new IllegalArgumentException( 1537 "FieldDescriptor does not match message type."); 1538 } else if (field.isExtension()) { 1539 // If this type had extensions, it would subclass ExtendableMessage, 1540 // which overrides the reflection interface to handle extensions. 1541 throw new IllegalArgumentException( 1542 "This type does not have extensions."); 1543 } 1544 return fields[field.getIndex()]; 1545 } 1546 1547 /** 1548 * Abstract interface that provides access to a single field. This is 1549 * implemented differently depending on the field type and cardinality. 1550 */ 1551 private interface FieldAccessor { 1552 Object get(GeneratedMessage message); 1553 Object get(GeneratedMessage.Builder builder); 1554 void set(Builder builder, Object value); 1555 Object getRepeated(GeneratedMessage message, int index); 1556 Object getRepeated(GeneratedMessage.Builder builder, int index); 1557 void setRepeated(Builder builder, 1558 int index, Object value); 1559 void addRepeated(Builder builder, Object value); 1560 boolean has(GeneratedMessage message); 1561 boolean has(GeneratedMessage.Builder builder); 1562 int getRepeatedCount(GeneratedMessage message); 1563 int getRepeatedCount(GeneratedMessage.Builder builder); 1564 void clear(Builder builder); 1565 Message.Builder newBuilder(); 1566 Message.Builder getBuilder(GeneratedMessage.Builder builder); 1567 } 1568 1569 // --------------------------------------------------------------- 1570 1571 private static class SingularFieldAccessor implements FieldAccessor { 1572 SingularFieldAccessor( 1573 final FieldDescriptor descriptor, final String camelCaseName, 1574 final Class<? extends GeneratedMessage> messageClass, 1575 final Class<? extends Builder> builderClass) { 1576 getMethod = getMethodOrDie(messageClass, "get" + camelCaseName); 1577 getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName); 1578 type = getMethod.getReturnType(); 1579 setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type); 1580 hasMethod = 1581 getMethodOrDie(messageClass, "has" + camelCaseName); 1582 hasMethodBuilder = 1583 getMethodOrDie(builderClass, "has" + camelCaseName); 1584 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 1585 } 1586 1587 // Note: We use Java reflection to call public methods rather than 1588 // access private fields directly as this avoids runtime security 1589 // checks. 1590 protected final Class<?> type; 1591 protected final Method getMethod; 1592 protected final Method getMethodBuilder; 1593 protected final Method setMethod; 1594 protected final Method hasMethod; 1595 protected final Method hasMethodBuilder; 1596 protected final Method clearMethod; 1597 1598 public Object get(final GeneratedMessage message) { 1599 return invokeOrDie(getMethod, message); 1600 } 1601 public Object get(GeneratedMessage.Builder builder) { 1602 return invokeOrDie(getMethodBuilder, builder); 1603 } 1604 public void set(final Builder builder, final Object value) { 1605 invokeOrDie(setMethod, builder, value); 1606 } 1607 public Object getRepeated(final GeneratedMessage message, 1608 final int index) { 1609 throw new UnsupportedOperationException( 1610 "getRepeatedField() called on a singular field."); 1611 } 1612 public Object getRepeated(GeneratedMessage.Builder builder, int index) { 1613 throw new UnsupportedOperationException( 1614 "getRepeatedField() called on a singular field."); 1615 } 1616 public void setRepeated(final Builder builder, 1617 final int index, final Object value) { 1618 throw new UnsupportedOperationException( 1619 "setRepeatedField() called on a singular field."); 1620 } 1621 public void addRepeated(final Builder builder, final Object value) { 1622 throw new UnsupportedOperationException( 1623 "addRepeatedField() called on a singular field."); 1624 } 1625 public boolean has(final GeneratedMessage message) { 1626 return (Boolean) invokeOrDie(hasMethod, message); 1627 } 1628 public boolean has(GeneratedMessage.Builder builder) { 1629 return (Boolean) invokeOrDie(hasMethodBuilder, builder); 1630 } 1631 public int getRepeatedCount(final GeneratedMessage message) { 1632 throw new UnsupportedOperationException( 1633 "getRepeatedFieldSize() called on a singular field."); 1634 } 1635 public int getRepeatedCount(GeneratedMessage.Builder builder) { 1636 throw new UnsupportedOperationException( 1637 "getRepeatedFieldSize() called on a singular field."); 1638 } 1639 public void clear(final Builder builder) { 1640 invokeOrDie(clearMethod, builder); 1641 } 1642 public Message.Builder newBuilder() { 1643 throw new UnsupportedOperationException( 1644 "newBuilderForField() called on a non-Message type."); 1645 } 1646 public Message.Builder getBuilder(GeneratedMessage.Builder builder) { 1647 throw new UnsupportedOperationException( 1648 "getFieldBuilder() called on a non-Message type."); 1649 } 1650 } 1651 1652 private static class RepeatedFieldAccessor implements FieldAccessor { 1653 protected final Class type; 1654 protected final Method getMethod; 1655 protected final Method getMethodBuilder; 1656 protected final Method getRepeatedMethod; 1657 protected final Method getRepeatedMethodBuilder; 1658 protected final Method setRepeatedMethod; 1659 protected final Method addRepeatedMethod; 1660 protected final Method getCountMethod; 1661 protected final Method getCountMethodBuilder; 1662 protected final Method clearMethod; 1663 1664 RepeatedFieldAccessor( 1665 final FieldDescriptor descriptor, final String camelCaseName, 1666 final Class<? extends GeneratedMessage> messageClass, 1667 final Class<? extends Builder> builderClass) { 1668 getMethod = getMethodOrDie(messageClass, 1669 "get" + camelCaseName + "List"); 1670 getMethodBuilder = getMethodOrDie(builderClass, 1671 "get" + camelCaseName + "List"); 1672 getRepeatedMethod = 1673 getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE); 1674 getRepeatedMethodBuilder = 1675 getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE); 1676 type = getRepeatedMethod.getReturnType(); 1677 setRepeatedMethod = 1678 getMethodOrDie(builderClass, "set" + camelCaseName, 1679 Integer.TYPE, type); 1680 addRepeatedMethod = 1681 getMethodOrDie(builderClass, "add" + camelCaseName, type); 1682 getCountMethod = 1683 getMethodOrDie(messageClass, "get" + camelCaseName + "Count"); 1684 getCountMethodBuilder = 1685 getMethodOrDie(builderClass, "get" + camelCaseName + "Count"); 1686 1687 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 1688 } 1689 1690 public Object get(final GeneratedMessage message) { 1691 return invokeOrDie(getMethod, message); 1692 } 1693 public Object get(GeneratedMessage.Builder builder) { 1694 return invokeOrDie(getMethodBuilder, builder); 1695 } 1696 public void set(final Builder builder, final Object value) { 1697 // Add all the elements individually. This serves two purposes: 1698 // 1) Verifies that each element has the correct type. 1699 // 2) Insures that the caller cannot modify the list later on and 1700 // have the modifications be reflected in the message. 1701 clear(builder); 1702 for (final Object element : (List<?>) value) { 1703 addRepeated(builder, element); 1704 } 1705 } 1706 public Object getRepeated(final GeneratedMessage message, 1707 final int index) { 1708 return invokeOrDie(getRepeatedMethod, message, index); 1709 } 1710 public Object getRepeated(GeneratedMessage.Builder builder, int index) { 1711 return invokeOrDie(getRepeatedMethodBuilder, builder, index); 1712 } 1713 public void setRepeated(final Builder builder, 1714 final int index, final Object value) { 1715 invokeOrDie(setRepeatedMethod, builder, index, value); 1716 } 1717 public void addRepeated(final Builder builder, final Object value) { 1718 invokeOrDie(addRepeatedMethod, builder, value); 1719 } 1720 public boolean has(final GeneratedMessage message) { 1721 throw new UnsupportedOperationException( 1722 "hasField() called on a repeated field."); 1723 } 1724 public boolean has(GeneratedMessage.Builder builder) { 1725 throw new UnsupportedOperationException( 1726 "hasField() called on a repeated field."); 1727 } 1728 public int getRepeatedCount(final GeneratedMessage message) { 1729 return (Integer) invokeOrDie(getCountMethod, message); 1730 } 1731 public int getRepeatedCount(GeneratedMessage.Builder builder) { 1732 return (Integer) invokeOrDie(getCountMethodBuilder, builder); 1733 } 1734 public void clear(final Builder builder) { 1735 invokeOrDie(clearMethod, builder); 1736 } 1737 public Message.Builder newBuilder() { 1738 throw new UnsupportedOperationException( 1739 "newBuilderForField() called on a non-Message type."); 1740 } 1741 public Message.Builder getBuilder(GeneratedMessage.Builder builder) { 1742 throw new UnsupportedOperationException( 1743 "getFieldBuilder() called on a non-Message type."); 1744 } 1745 } 1746 1747 // --------------------------------------------------------------- 1748 1749 private static final class SingularEnumFieldAccessor 1750 extends SingularFieldAccessor { 1751 SingularEnumFieldAccessor( 1752 final FieldDescriptor descriptor, final String camelCaseName, 1753 final Class<? extends GeneratedMessage> messageClass, 1754 final Class<? extends Builder> builderClass) { 1755 super(descriptor, camelCaseName, messageClass, builderClass); 1756 1757 valueOfMethod = getMethodOrDie(type, "valueOf", 1758 EnumValueDescriptor.class); 1759 getValueDescriptorMethod = 1760 getMethodOrDie(type, "getValueDescriptor"); 1761 } 1762 1763 private Method valueOfMethod; 1764 private Method getValueDescriptorMethod; 1765 1766 @Override 1767 public Object get(final GeneratedMessage message) { 1768 return invokeOrDie(getValueDescriptorMethod, super.get(message)); 1769 } 1770 1771 @Override 1772 public Object get(final GeneratedMessage.Builder builder) { 1773 return invokeOrDie(getValueDescriptorMethod, super.get(builder)); 1774 } 1775 1776 @Override 1777 public void set(final Builder builder, final Object value) { 1778 super.set(builder, invokeOrDie(valueOfMethod, null, value)); 1779 } 1780 } 1781 1782 private static final class RepeatedEnumFieldAccessor 1783 extends RepeatedFieldAccessor { 1784 RepeatedEnumFieldAccessor( 1785 final FieldDescriptor descriptor, final String camelCaseName, 1786 final Class<? extends GeneratedMessage> messageClass, 1787 final Class<? extends Builder> builderClass) { 1788 super(descriptor, camelCaseName, messageClass, builderClass); 1789 1790 valueOfMethod = getMethodOrDie(type, "valueOf", 1791 EnumValueDescriptor.class); 1792 getValueDescriptorMethod = 1793 getMethodOrDie(type, "getValueDescriptor"); 1794 } 1795 1796 private final Method valueOfMethod; 1797 private final Method getValueDescriptorMethod; 1798 1799 @Override 1800 @SuppressWarnings("unchecked") 1801 public Object get(final GeneratedMessage message) { 1802 final List newList = new ArrayList(); 1803 for (final Object element : (List) super.get(message)) { 1804 newList.add(invokeOrDie(getValueDescriptorMethod, element)); 1805 } 1806 return Collections.unmodifiableList(newList); 1807 } 1808 1809 @Override 1810 @SuppressWarnings("unchecked") 1811 public Object get(final GeneratedMessage.Builder builder) { 1812 final List newList = new ArrayList(); 1813 for (final Object element : (List) super.get(builder)) { 1814 newList.add(invokeOrDie(getValueDescriptorMethod, element)); 1815 } 1816 return Collections.unmodifiableList(newList); 1817 } 1818 1819 @Override 1820 public Object getRepeated(final GeneratedMessage message, 1821 final int index) { 1822 return invokeOrDie(getValueDescriptorMethod, 1823 super.getRepeated(message, index)); 1824 } 1825 @Override 1826 public Object getRepeated(final GeneratedMessage.Builder builder, 1827 final int index) { 1828 return invokeOrDie(getValueDescriptorMethod, 1829 super.getRepeated(builder, index)); 1830 } 1831 @Override 1832 public void setRepeated(final Builder builder, 1833 final int index, final Object value) { 1834 super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null, 1835 value)); 1836 } 1837 @Override 1838 public void addRepeated(final Builder builder, final Object value) { 1839 super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value)); 1840 } 1841 } 1842 1843 // --------------------------------------------------------------- 1844 1845 private static final class SingularMessageFieldAccessor 1846 extends SingularFieldAccessor { 1847 SingularMessageFieldAccessor( 1848 final FieldDescriptor descriptor, final String camelCaseName, 1849 final Class<? extends GeneratedMessage> messageClass, 1850 final Class<? extends Builder> builderClass) { 1851 super(descriptor, camelCaseName, messageClass, builderClass); 1852 1853 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 1854 getBuilderMethodBuilder = 1855 getMethodOrDie(builderClass, "get" + camelCaseName + "Builder"); 1856 } 1857 1858 private final Method newBuilderMethod; 1859 private final Method getBuilderMethodBuilder; 1860 1861 private Object coerceType(final Object value) { 1862 if (type.isInstance(value)) { 1863 return value; 1864 } else { 1865 // The value is not the exact right message type. However, if it 1866 // is an alternative implementation of the same type -- e.g. a 1867 // DynamicMessage -- we should accept it. In this case we can make 1868 // a copy of the message. 1869 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 1870 .mergeFrom((Message) value).buildPartial(); 1871 } 1872 } 1873 1874 @Override 1875 public void set(final Builder builder, final Object value) { 1876 super.set(builder, coerceType(value)); 1877 } 1878 @Override 1879 public Message.Builder newBuilder() { 1880 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 1881 } 1882 @Override 1883 public Message.Builder getBuilder(GeneratedMessage.Builder builder) { 1884 return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder); 1885 } 1886 } 1887 1888 private static final class RepeatedMessageFieldAccessor 1889 extends RepeatedFieldAccessor { 1890 RepeatedMessageFieldAccessor( 1891 final FieldDescriptor descriptor, final String camelCaseName, 1892 final Class<? extends GeneratedMessage> messageClass, 1893 final Class<? extends Builder> builderClass) { 1894 super(descriptor, camelCaseName, messageClass, builderClass); 1895 1896 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 1897 } 1898 1899 private final Method newBuilderMethod; 1900 1901 private Object coerceType(final Object value) { 1902 if (type.isInstance(value)) { 1903 return value; 1904 } else { 1905 // The value is not the exact right message type. However, if it 1906 // is an alternative implementation of the same type -- e.g. a 1907 // DynamicMessage -- we should accept it. In this case we can make 1908 // a copy of the message. 1909 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 1910 .mergeFrom((Message) value).build(); 1911 } 1912 } 1913 1914 @Override 1915 public void setRepeated(final Builder builder, 1916 final int index, final Object value) { 1917 super.setRepeated(builder, index, coerceType(value)); 1918 } 1919 @Override 1920 public void addRepeated(final Builder builder, final Object value) { 1921 super.addRepeated(builder, coerceType(value)); 1922 } 1923 @Override 1924 public Message.Builder newBuilder() { 1925 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 1926 } 1927 } 1928 } 1929 1930 /** 1931 * Replaces this object in the output stream with a serialized form. 1932 * Part of Java's serialization magic. Generated sub-classes must override 1933 * this method by calling {@code return super.writeReplace();} 1934 * @return a SerializedForm of this message 1935 */ 1936 protected Object writeReplace() throws ObjectStreamException { 1937 return new GeneratedMessageLite.SerializedForm(this); 1938 } 1939 } 1940