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.lang.reflect.Method; 39 import java.lang.reflect.InvocationTargetException; 40 import java.util.ArrayList; 41 import java.util.Collections; 42 import java.util.Iterator; 43 import java.util.List; 44 import java.util.Map; 45 import java.util.TreeMap; 46 47 /** 48 * All generated protocol message classes extend this class. This class 49 * implements most of the Message and Builder interfaces using Java reflection. 50 * Users can ignore this class and pretend that generated messages implement 51 * the Message interface directly. 52 * 53 * @author kenton (at) google.com Kenton Varda 54 */ 55 public abstract class GeneratedMessage extends AbstractMessage { 56 protected GeneratedMessage() {} 57 58 private UnknownFieldSet unknownFields = UnknownFieldSet.getDefaultInstance(); 59 60 /** 61 * Get the FieldAccessorTable for this type. We can't have the message 62 * class pass this in to the constructor because of bootstrapping trouble 63 * with DescriptorProtos. 64 */ 65 protected abstract FieldAccessorTable internalGetFieldAccessorTable(); 66 67 public Descriptor getDescriptorForType() { 68 return internalGetFieldAccessorTable().descriptor; 69 } 70 71 /** Internal helper which returns a mutable map. */ 72 private Map<FieldDescriptor, Object> getAllFieldsMutable() { 73 final TreeMap<FieldDescriptor, Object> result = 74 new TreeMap<FieldDescriptor, Object>(); 75 final Descriptor descriptor = internalGetFieldAccessorTable().descriptor; 76 for (final FieldDescriptor field : descriptor.getFields()) { 77 if (field.isRepeated()) { 78 final List value = (List) getField(field); 79 if (!value.isEmpty()) { 80 result.put(field, value); 81 } 82 } else { 83 if (hasField(field)) { 84 result.put(field, getField(field)); 85 } 86 } 87 } 88 return result; 89 } 90 91 @Override 92 public boolean isInitialized() { 93 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 94 // Check that all required fields are present. 95 if (field.isRequired()) { 96 if (!hasField(field)) { 97 return false; 98 } 99 } 100 // Check that embedded messages are initialized. 101 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 102 if (field.isRepeated()) { 103 @SuppressWarnings("unchecked") final 104 List<Message> messageList = (List<Message>) getField(field); 105 for (final Message element : messageList) { 106 if (!element.isInitialized()) { 107 return false; 108 } 109 } 110 } else { 111 if (hasField(field) && !((Message) getField(field)).isInitialized()) { 112 return false; 113 } 114 } 115 } 116 } 117 118 return true; 119 } 120 121 public Map<FieldDescriptor, Object> getAllFields() { 122 return Collections.unmodifiableMap(getAllFieldsMutable()); 123 } 124 125 public boolean hasField(final FieldDescriptor field) { 126 return internalGetFieldAccessorTable().getField(field).has(this); 127 } 128 129 public Object getField(final FieldDescriptor field) { 130 return internalGetFieldAccessorTable().getField(field).get(this); 131 } 132 133 public int getRepeatedFieldCount(final FieldDescriptor field) { 134 return internalGetFieldAccessorTable().getField(field) 135 .getRepeatedCount(this); 136 } 137 138 public Object getRepeatedField(final FieldDescriptor field, final int index) { 139 return internalGetFieldAccessorTable().getField(field) 140 .getRepeated(this, index); 141 } 142 143 public final UnknownFieldSet getUnknownFields() { 144 return unknownFields; 145 } 146 147 @SuppressWarnings("unchecked") 148 public abstract static class Builder <BuilderType extends Builder> 149 extends AbstractMessage.Builder<BuilderType> { 150 protected Builder() {} 151 152 // This is implemented here only to work around an apparent bug in the 153 // Java compiler and/or build system. See bug #1898463. The mere presence 154 // of this dummy clone() implementation makes it go away. 155 @Override 156 public BuilderType clone() { 157 throw new UnsupportedOperationException( 158 "This is supposed to be overridden by subclasses."); 159 } 160 161 /** 162 * Get the message being built. We don't just pass this to the 163 * constructor because it becomes null when build() is called. 164 */ 165 protected abstract GeneratedMessage internalGetResult(); 166 167 /** 168 * Get the FieldAccessorTable for this type. We can't have the message 169 * class pass this in to the constructor because of bootstrapping trouble 170 * with DescriptorProtos. 171 */ 172 private FieldAccessorTable internalGetFieldAccessorTable() { 173 return internalGetResult().internalGetFieldAccessorTable(); 174 } 175 176 public Descriptor getDescriptorForType() { 177 return internalGetFieldAccessorTable().descriptor; 178 } 179 180 public Map<FieldDescriptor, Object> getAllFields() { 181 return internalGetResult().getAllFields(); 182 } 183 184 public Message.Builder newBuilderForField( 185 final FieldDescriptor field) { 186 return internalGetFieldAccessorTable().getField(field).newBuilder(); 187 } 188 189 public boolean hasField(final FieldDescriptor field) { 190 return internalGetResult().hasField(field); 191 } 192 193 public Object getField(final FieldDescriptor field) { 194 if (field.isRepeated()) { 195 // The underlying list object is still modifiable at this point. 196 // Make sure not to expose the modifiable list to the caller. 197 return Collections.unmodifiableList( 198 (List) internalGetResult().getField(field)); 199 } else { 200 return internalGetResult().getField(field); 201 } 202 } 203 204 public BuilderType setField(final FieldDescriptor field, 205 final Object value) { 206 internalGetFieldAccessorTable().getField(field).set(this, value); 207 return (BuilderType) this; 208 } 209 210 public BuilderType clearField(final FieldDescriptor field) { 211 internalGetFieldAccessorTable().getField(field).clear(this); 212 return (BuilderType) this; 213 } 214 215 public int getRepeatedFieldCount(final FieldDescriptor field) { 216 return internalGetResult().getRepeatedFieldCount(field); 217 } 218 219 public Object getRepeatedField(final FieldDescriptor field, 220 final int index) { 221 return internalGetResult().getRepeatedField(field, index); 222 } 223 224 public BuilderType setRepeatedField(final FieldDescriptor field, 225 final int index, final Object value) { 226 internalGetFieldAccessorTable().getField(field) 227 .setRepeated(this, index, value); 228 return (BuilderType) this; 229 } 230 231 public BuilderType addRepeatedField(final FieldDescriptor field, 232 final Object value) { 233 internalGetFieldAccessorTable().getField(field).addRepeated(this, value); 234 return (BuilderType) this; 235 } 236 237 public final UnknownFieldSet getUnknownFields() { 238 return internalGetResult().unknownFields; 239 } 240 241 public final BuilderType setUnknownFields( 242 final UnknownFieldSet unknownFields) { 243 internalGetResult().unknownFields = unknownFields; 244 return (BuilderType) this; 245 } 246 247 @Override 248 public final BuilderType mergeUnknownFields( 249 final UnknownFieldSet unknownFields) { 250 final GeneratedMessage result = internalGetResult(); 251 result.unknownFields = 252 UnknownFieldSet.newBuilder(result.unknownFields) 253 .mergeFrom(unknownFields) 254 .build(); 255 return (BuilderType) this; 256 } 257 258 public boolean isInitialized() { 259 return internalGetResult().isInitialized(); 260 } 261 262 /** 263 * Called by subclasses to parse an unknown field. 264 * @return {@code true} unless the tag is an end-group tag. 265 */ 266 protected boolean parseUnknownField( 267 final CodedInputStream input, 268 final UnknownFieldSet.Builder unknownFields, 269 final ExtensionRegistryLite extensionRegistry, 270 final int tag) throws IOException { 271 return unknownFields.mergeFieldFrom(tag, input); 272 } 273 } 274 275 // ================================================================= 276 // Extensions-related stuff 277 278 /** 279 * Generated message classes for message types that contain extension ranges 280 * subclass this. 281 * 282 * <p>This class implements type-safe accessors for extensions. They 283 * implement all the same operations that you can do with normal fields -- 284 * e.g. "has", "get", and "getCount" -- but for extensions. The extensions 285 * are identified using instances of the class {@link GeneratedExtension}; 286 * the protocol compiler generates a static instance of this class for every 287 * extension in its input. Through the magic of generics, all is made 288 * type-safe. 289 * 290 * <p>For example, imagine you have the {@code .proto} file: 291 * 292 * <pre> 293 * option java_class = "MyProto"; 294 * 295 * message Foo { 296 * extensions 1000 to max; 297 * } 298 * 299 * extend Foo { 300 * optional int32 bar; 301 * } 302 * </pre> 303 * 304 * <p>Then you might write code like: 305 * 306 * <pre> 307 * MyProto.Foo foo = getFoo(); 308 * int i = foo.getExtension(MyProto.bar); 309 * </pre> 310 * 311 * <p>See also {@link ExtendableBuilder}. 312 */ 313 public abstract static class ExtendableMessage< 314 MessageType extends ExtendableMessage> 315 extends GeneratedMessage { 316 protected ExtendableMessage() {} 317 private final FieldSet<FieldDescriptor> extensions = FieldSet.newFieldSet(); 318 319 private void verifyExtensionContainingType( 320 final GeneratedExtension<MessageType, ?> extension) { 321 if (extension.getDescriptor().getContainingType() != 322 getDescriptorForType()) { 323 // This can only happen if someone uses unchecked operations. 324 throw new IllegalArgumentException( 325 "Extension is for type \"" + 326 extension.getDescriptor().getContainingType().getFullName() + 327 "\" which does not match message type \"" + 328 getDescriptorForType().getFullName() + "\"."); 329 } 330 } 331 332 /** Check if a singular extension is present. */ 333 public final boolean hasExtension( 334 final GeneratedExtension<MessageType, ?> extension) { 335 verifyExtensionContainingType(extension); 336 return extensions.hasField(extension.getDescriptor()); 337 } 338 339 /** Get the number of elements in a repeated extension. */ 340 public final <Type> int getExtensionCount( 341 final GeneratedExtension<MessageType, List<Type>> extension) { 342 verifyExtensionContainingType(extension); 343 final FieldDescriptor descriptor = extension.getDescriptor(); 344 return extensions.getRepeatedFieldCount(descriptor); 345 } 346 347 /** Get the value of an extension. */ 348 @SuppressWarnings("unchecked") 349 public final <Type> Type getExtension( 350 final GeneratedExtension<MessageType, Type> extension) { 351 verifyExtensionContainingType(extension); 352 FieldDescriptor descriptor = extension.getDescriptor(); 353 final Object value = extensions.getField(descriptor); 354 if (value == null) { 355 if (descriptor.isRepeated()) { 356 return (Type) Collections.emptyList(); 357 } else if (descriptor.getJavaType() == 358 FieldDescriptor.JavaType.MESSAGE) { 359 return (Type) extension.getMessageDefaultInstance(); 360 } else { 361 return (Type) extension.fromReflectionType( 362 descriptor.getDefaultValue()); 363 } 364 } else { 365 return (Type) extension.fromReflectionType(value); 366 } 367 } 368 369 /** Get one element of a repeated extension. */ 370 @SuppressWarnings("unchecked") 371 public final <Type> Type getExtension( 372 final GeneratedExtension<MessageType, List<Type>> extension, 373 final int index) { 374 verifyExtensionContainingType(extension); 375 FieldDescriptor descriptor = extension.getDescriptor(); 376 return (Type) extension.singularFromReflectionType( 377 extensions.getRepeatedField(descriptor, index)); 378 } 379 380 /** Called by subclasses to check if all extensions are initialized. */ 381 protected boolean extensionsAreInitialized() { 382 return extensions.isInitialized(); 383 } 384 385 @Override 386 public boolean isInitialized() { 387 return super.isInitialized() && extensionsAreInitialized(); 388 } 389 390 /** 391 * Used by subclasses to serialize extensions. Extension ranges may be 392 * interleaved with field numbers, but we must write them in canonical 393 * (sorted by field number) order. ExtensionWriter helps us write 394 * individual ranges of extensions at once. 395 */ 396 protected class ExtensionWriter { 397 // Imagine how much simpler this code would be if Java iterators had 398 // a way to get the next element without advancing the iterator. 399 400 private final Iterator<Map.Entry<FieldDescriptor, Object>> iter = 401 extensions.iterator(); 402 private Map.Entry<FieldDescriptor, Object> next; 403 private final boolean messageSetWireFormat; 404 405 private ExtensionWriter(final boolean messageSetWireFormat) { 406 if (iter.hasNext()) { 407 next = iter.next(); 408 } 409 this.messageSetWireFormat = messageSetWireFormat; 410 } 411 412 public void writeUntil(final int end, final CodedOutputStream output) 413 throws IOException { 414 while (next != null && next.getKey().getNumber() < end) { 415 FieldDescriptor descriptor = next.getKey(); 416 if (messageSetWireFormat && descriptor.getLiteJavaType() == 417 WireFormat.JavaType.MESSAGE && 418 !descriptor.isRepeated()) { 419 output.writeMessageSetExtension(descriptor.getNumber(), 420 (Message) next.getValue()); 421 } else { 422 FieldSet.writeField(descriptor, next.getValue(), output); 423 } 424 if (iter.hasNext()) { 425 next = iter.next(); 426 } else { 427 next = null; 428 } 429 } 430 } 431 } 432 433 protected ExtensionWriter newExtensionWriter() { 434 return new ExtensionWriter(false); 435 } 436 protected ExtensionWriter newMessageSetExtensionWriter() { 437 return new ExtensionWriter(true); 438 } 439 440 /** Called by subclasses to compute the size of extensions. */ 441 protected int extensionsSerializedSize() { 442 return extensions.getSerializedSize(); 443 } 444 protected int extensionsSerializedSizeAsMessageSet() { 445 return extensions.getMessageSetSerializedSize(); 446 } 447 448 // --------------------------------------------------------------- 449 // Reflection 450 451 @Override 452 public Map<FieldDescriptor, Object> getAllFields() { 453 final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable(); 454 result.putAll(extensions.getAllFields()); 455 return Collections.unmodifiableMap(result); 456 } 457 458 @Override 459 public boolean hasField(final FieldDescriptor field) { 460 if (field.isExtension()) { 461 verifyContainingType(field); 462 return extensions.hasField(field); 463 } else { 464 return super.hasField(field); 465 } 466 } 467 468 @Override 469 public Object getField(final FieldDescriptor field) { 470 if (field.isExtension()) { 471 verifyContainingType(field); 472 final Object value = extensions.getField(field); 473 if (value == null) { 474 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 475 // Lacking an ExtensionRegistry, we have no way to determine the 476 // extension's real type, so we return a DynamicMessage. 477 return DynamicMessage.getDefaultInstance(field.getMessageType()); 478 } else { 479 return field.getDefaultValue(); 480 } 481 } else { 482 return value; 483 } 484 } else { 485 return super.getField(field); 486 } 487 } 488 489 @Override 490 public int getRepeatedFieldCount(final FieldDescriptor field) { 491 if (field.isExtension()) { 492 verifyContainingType(field); 493 return extensions.getRepeatedFieldCount(field); 494 } else { 495 return super.getRepeatedFieldCount(field); 496 } 497 } 498 499 @Override 500 public Object getRepeatedField(final FieldDescriptor field, 501 final int index) { 502 if (field.isExtension()) { 503 verifyContainingType(field); 504 return extensions.getRepeatedField(field, index); 505 } else { 506 return super.getRepeatedField(field, index); 507 } 508 } 509 510 private void verifyContainingType(final FieldDescriptor field) { 511 if (field.getContainingType() != getDescriptorForType()) { 512 throw new IllegalArgumentException( 513 "FieldDescriptor does not match message type."); 514 } 515 } 516 } 517 518 /** 519 * Generated message builders for message types that contain extension ranges 520 * subclass this. 521 * 522 * <p>This class implements type-safe accessors for extensions. They 523 * implement all the same operations that you can do with normal fields -- 524 * e.g. "get", "set", and "add" -- but for extensions. The extensions are 525 * identified using instances of the class {@link GeneratedExtension}; the 526 * protocol compiler generates a static instance of this class for every 527 * extension in its input. Through the magic of generics, all is made 528 * type-safe. 529 * 530 * <p>For example, imagine you have the {@code .proto} file: 531 * 532 * <pre> 533 * option java_class = "MyProto"; 534 * 535 * message Foo { 536 * extensions 1000 to max; 537 * } 538 * 539 * extend Foo { 540 * optional int32 bar; 541 * } 542 * </pre> 543 * 544 * <p>Then you might write code like: 545 * 546 * <pre> 547 * MyProto.Foo foo = 548 * MyProto.Foo.newBuilder() 549 * .setExtension(MyProto.bar, 123) 550 * .build(); 551 * </pre> 552 * 553 * <p>See also {@link ExtendableMessage}. 554 */ 555 @SuppressWarnings("unchecked") 556 public abstract static class ExtendableBuilder< 557 MessageType extends ExtendableMessage, 558 BuilderType extends ExtendableBuilder> 559 extends Builder<BuilderType> { 560 protected ExtendableBuilder() {} 561 562 // This is implemented here only to work around an apparent bug in the 563 // Java compiler and/or build system. See bug #1898463. The mere presence 564 // of this dummy clone() implementation makes it go away. 565 @Override 566 public BuilderType clone() { 567 throw new UnsupportedOperationException( 568 "This is supposed to be overridden by subclasses."); 569 } 570 571 @Override 572 protected abstract ExtendableMessage<MessageType> internalGetResult(); 573 574 /** Check if a singular extension is present. */ 575 public final boolean hasExtension( 576 final GeneratedExtension<MessageType, ?> extension) { 577 return internalGetResult().hasExtension(extension); 578 } 579 580 /** Get the number of elements in a repeated extension. */ 581 public final <Type> int getExtensionCount( 582 final GeneratedExtension<MessageType, List<Type>> extension) { 583 return internalGetResult().getExtensionCount(extension); 584 } 585 586 /** Get the value of an extension. */ 587 public final <Type> Type getExtension( 588 final GeneratedExtension<MessageType, Type> extension) { 589 return internalGetResult().getExtension(extension); 590 } 591 592 /** Get one element of a repeated extension. */ 593 public final <Type> Type getExtension( 594 final GeneratedExtension<MessageType, List<Type>> extension, 595 final int index) { 596 return internalGetResult().getExtension(extension, index); 597 } 598 599 /** Set the value of an extension. */ 600 public final <Type> BuilderType setExtension( 601 final GeneratedExtension<MessageType, Type> extension, 602 final Type value) { 603 final ExtendableMessage<MessageType> message = internalGetResult(); 604 message.verifyExtensionContainingType(extension); 605 final FieldDescriptor descriptor = extension.getDescriptor(); 606 message.extensions.setField(descriptor, 607 extension.toReflectionType(value)); 608 return (BuilderType) this; 609 } 610 611 /** Set the value of one element of a repeated extension. */ 612 public final <Type> BuilderType setExtension( 613 final GeneratedExtension<MessageType, List<Type>> extension, 614 final int index, final Type value) { 615 final ExtendableMessage<MessageType> message = internalGetResult(); 616 message.verifyExtensionContainingType(extension); 617 final FieldDescriptor descriptor = extension.getDescriptor(); 618 message.extensions.setRepeatedField( 619 descriptor, index, 620 extension.singularToReflectionType(value)); 621 return (BuilderType) this; 622 } 623 624 /** Append a value to a repeated extension. */ 625 public final <Type> BuilderType addExtension( 626 final GeneratedExtension<MessageType, List<Type>> extension, 627 final Type value) { 628 final ExtendableMessage<MessageType> message = internalGetResult(); 629 message.verifyExtensionContainingType(extension); 630 final FieldDescriptor descriptor = extension.getDescriptor(); 631 message.extensions.addRepeatedField( 632 descriptor, extension.singularToReflectionType(value)); 633 return (BuilderType) this; 634 } 635 636 /** Clear an extension. */ 637 public final <Type> BuilderType clearExtension( 638 final GeneratedExtension<MessageType, ?> extension) { 639 final ExtendableMessage<MessageType> message = internalGetResult(); 640 message.verifyExtensionContainingType(extension); 641 message.extensions.clearField(extension.getDescriptor()); 642 return (BuilderType) this; 643 } 644 645 /** 646 * Called by subclasses to parse an unknown field or an extension. 647 * @return {@code true} unless the tag is an end-group tag. 648 */ 649 @Override 650 protected boolean parseUnknownField( 651 final CodedInputStream input, 652 final UnknownFieldSet.Builder unknownFields, 653 final ExtensionRegistryLite extensionRegistry, 654 final int tag) throws IOException { 655 final ExtendableMessage<MessageType> message = internalGetResult(); 656 return AbstractMessage.Builder.mergeFieldFrom( 657 input, unknownFields, extensionRegistry, this, tag); 658 } 659 660 // --------------------------------------------------------------- 661 // Reflection 662 663 // We don't have to override the get*() methods here because they already 664 // just forward to the underlying message. 665 666 @Override 667 public BuilderType setField(final FieldDescriptor field, 668 final Object value) { 669 if (field.isExtension()) { 670 final ExtendableMessage<MessageType> message = internalGetResult(); 671 message.verifyContainingType(field); 672 message.extensions.setField(field, value); 673 return (BuilderType) this; 674 } else { 675 return super.setField(field, value); 676 } 677 } 678 679 @Override 680 public BuilderType clearField(final FieldDescriptor field) { 681 if (field.isExtension()) { 682 final ExtendableMessage<MessageType> message = internalGetResult(); 683 message.verifyContainingType(field); 684 message.extensions.clearField(field); 685 return (BuilderType) this; 686 } else { 687 return super.clearField(field); 688 } 689 } 690 691 @Override 692 public BuilderType setRepeatedField(final FieldDescriptor field, 693 final int index, final Object value) { 694 if (field.isExtension()) { 695 final ExtendableMessage<MessageType> message = internalGetResult(); 696 message.verifyContainingType(field); 697 message.extensions.setRepeatedField(field, index, value); 698 return (BuilderType) this; 699 } else { 700 return super.setRepeatedField(field, index, value); 701 } 702 } 703 704 @Override 705 public BuilderType addRepeatedField(final FieldDescriptor field, 706 final Object value) { 707 if (field.isExtension()) { 708 final ExtendableMessage<MessageType> message = internalGetResult(); 709 message.verifyContainingType(field); 710 message.extensions.addRepeatedField(field, value); 711 return (BuilderType) this; 712 } else { 713 return super.addRepeatedField(field, value); 714 } 715 } 716 717 protected final void mergeExtensionFields(final ExtendableMessage other) { 718 internalGetResult().extensions.mergeFrom(other.extensions); 719 } 720 } 721 722 // ----------------------------------------------------------------- 723 724 /** For use by generated code only. */ 725 public static <ContainingType extends Message, Type> 726 GeneratedExtension<ContainingType, Type> 727 newGeneratedExtension() { 728 return new GeneratedExtension<ContainingType, Type>(); 729 } 730 731 /** 732 * Type used to represent generated extensions. The protocol compiler 733 * generates a static singleton instance of this class for each extension. 734 * 735 * <p>For example, imagine you have the {@code .proto} file: 736 * 737 * <pre> 738 * option java_class = "MyProto"; 739 * 740 * message Foo { 741 * extensions 1000 to max; 742 * } 743 * 744 * extend Foo { 745 * optional int32 bar; 746 * } 747 * </pre> 748 * 749 * <p>Then, {@code MyProto.Foo.bar} has type 750 * {@code GeneratedExtension<MyProto.Foo, Integer>}. 751 * 752 * <p>In general, users should ignore the details of this type, and simply use 753 * these static singletons as parameters to the extension accessors defined 754 * in {@link ExtendableMessage} and {@link ExtendableBuilder}. 755 */ 756 public static final class GeneratedExtension< 757 ContainingType extends Message, Type> { 758 // TODO(kenton): Find ways to avoid using Java reflection within this 759 // class. Also try to avoid suppressing unchecked warnings. 760 761 // We can't always initialize a GeneratedExtension when we first construct 762 // it due to initialization order difficulties (namely, the descriptor may 763 // not have been constructed yet, since it is often constructed by the 764 // initializer of a separate module). So, we construct an uninitialized 765 // GeneratedExtension once, then call internalInit() on it later. Generated 766 // code will always call internalInit() on all extensions as part of the 767 // static initialization code, and internalInit() throws an exception if 768 // called more than once, so this method is useless to users. 769 private GeneratedExtension() {} 770 771 /** For use by generated code only. */ 772 public void internalInit(final FieldDescriptor descriptor, 773 final Class type) { 774 if (this.descriptor != null) { 775 throw new IllegalStateException("Already initialized."); 776 } 777 778 if (!descriptor.isExtension()) { 779 throw new IllegalArgumentException( 780 "GeneratedExtension given a regular (non-extension) field."); 781 } 782 783 this.descriptor = descriptor; 784 this.type = type; 785 786 switch (descriptor.getJavaType()) { 787 case MESSAGE: 788 enumValueOf = null; 789 enumGetValueDescriptor = null; 790 messageDefaultInstance = 791 (Message) invokeOrDie(getMethodOrDie(type, "getDefaultInstance"), 792 null); 793 if (messageDefaultInstance == null) { 794 throw new IllegalStateException( 795 type.getName() + ".getDefaultInstance() returned null."); 796 } 797 break; 798 case ENUM: 799 enumValueOf = getMethodOrDie(type, "valueOf", 800 EnumValueDescriptor.class); 801 enumGetValueDescriptor = getMethodOrDie(type, "getValueDescriptor"); 802 messageDefaultInstance = null; 803 break; 804 default: 805 enumValueOf = null; 806 enumGetValueDescriptor = null; 807 messageDefaultInstance = null; 808 break; 809 } 810 } 811 812 private FieldDescriptor descriptor; 813 private Class type; 814 private Method enumValueOf; 815 private Method enumGetValueDescriptor; 816 private Message messageDefaultInstance; 817 818 public FieldDescriptor getDescriptor() { return descriptor; } 819 820 /** 821 * If the extension is an embedded message or group, returns the default 822 * instance of the message. 823 */ 824 @SuppressWarnings("unchecked") 825 public Message getMessageDefaultInstance() { 826 return messageDefaultInstance; 827 } 828 829 /** 830 * Convert from the type used by the reflection accessors to the type used 831 * by native accessors. E.g., for enums, the reflection accessors use 832 * EnumValueDescriptors but the native accessors use the generated enum 833 * type. 834 */ 835 @SuppressWarnings("unchecked") 836 private Object fromReflectionType(final Object value) { 837 if (descriptor.isRepeated()) { 838 if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE || 839 descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { 840 // Must convert the whole list. 841 final List result = new ArrayList(); 842 for (final Object element : (List) value) { 843 result.add(singularFromReflectionType(element)); 844 } 845 return result; 846 } else { 847 return value; 848 } 849 } else { 850 return singularFromReflectionType(value); 851 } 852 } 853 854 /** 855 * Like {@link #fromReflectionType(Object)}, but if the type is a repeated 856 * type, this converts a single element. 857 */ 858 private Object singularFromReflectionType(final Object value) { 859 switch (descriptor.getJavaType()) { 860 case MESSAGE: 861 if (type.isInstance(value)) { 862 return value; 863 } else { 864 // It seems the copy of the embedded message stored inside the 865 // extended message is not of the exact type the user was 866 // expecting. This can happen if a user defines a 867 // GeneratedExtension manually and gives it a different type. 868 // This should not happen in normal use. But, to be nice, we'll 869 // copy the message to whatever type the caller was expecting. 870 return messageDefaultInstance.newBuilderForType() 871 .mergeFrom((Message) value).build(); 872 } 873 case ENUM: 874 return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value); 875 default: 876 return value; 877 } 878 } 879 880 /** 881 * Convert from the type used by the native accessors to the type used 882 * by reflection accessors. E.g., for enums, the reflection accessors use 883 * EnumValueDescriptors but the native accessors use the generated enum 884 * type. 885 */ 886 @SuppressWarnings("unchecked") 887 private Object toReflectionType(final Object value) { 888 if (descriptor.isRepeated()) { 889 if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { 890 // Must convert the whole list. 891 final List result = new ArrayList(); 892 for (final Object element : (List) value) { 893 result.add(singularToReflectionType(element)); 894 } 895 return result; 896 } else { 897 return value; 898 } 899 } else { 900 return singularToReflectionType(value); 901 } 902 } 903 904 /** 905 * Like {@link #toReflectionType(Object)}, but if the type is a repeated 906 * type, this converts a single element. 907 */ 908 private Object singularToReflectionType(final Object value) { 909 switch (descriptor.getJavaType()) { 910 case ENUM: 911 return invokeOrDie(enumGetValueDescriptor, value); 912 default: 913 return value; 914 } 915 } 916 } 917 918 // ================================================================= 919 920 /** Calls Class.getMethod and throws a RuntimeException if it fails. */ 921 @SuppressWarnings("unchecked") 922 private static Method getMethodOrDie( 923 final Class clazz, final String name, final Class... params) { 924 try { 925 return clazz.getMethod(name, params); 926 } catch (NoSuchMethodException e) { 927 throw new RuntimeException( 928 "Generated message class \"" + clazz.getName() + 929 "\" missing method \"" + name + "\".", e); 930 } 931 } 932 933 /** Calls invoke and throws a RuntimeException if it fails. */ 934 private static Object invokeOrDie( 935 final Method method, final Object object, final Object... params) { 936 try { 937 return method.invoke(object, params); 938 } catch (IllegalAccessException e) { 939 throw new RuntimeException( 940 "Couldn't use Java reflection to implement protocol message " + 941 "reflection.", e); 942 } catch (InvocationTargetException e) { 943 final Throwable cause = e.getCause(); 944 if (cause instanceof RuntimeException) { 945 throw (RuntimeException) cause; 946 } else if (cause instanceof Error) { 947 throw (Error) cause; 948 } else { 949 throw new RuntimeException( 950 "Unexpected exception thrown by generated accessor method.", cause); 951 } 952 } 953 } 954 955 /** 956 * Users should ignore this class. This class provides the implementation 957 * with access to the fields of a message object using Java reflection. 958 */ 959 public static final class FieldAccessorTable { 960 961 /** 962 * Construct a FieldAccessorTable for a particular message class. Only 963 * one FieldAccessorTable should ever be constructed per class. 964 * 965 * @param descriptor The type's descriptor. 966 * @param camelCaseNames The camelcase names of all fields in the message. 967 * These are used to derive the accessor method names. 968 * @param messageClass The message type. 969 * @param builderClass The builder type. 970 */ 971 public FieldAccessorTable( 972 final Descriptor descriptor, 973 final String[] camelCaseNames, 974 final Class<? extends GeneratedMessage> messageClass, 975 final Class<? extends Builder> builderClass) { 976 this.descriptor = descriptor; 977 fields = new FieldAccessor[descriptor.getFields().size()]; 978 979 for (int i = 0; i < fields.length; i++) { 980 final FieldDescriptor field = descriptor.getFields().get(i); 981 if (field.isRepeated()) { 982 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 983 fields[i] = new RepeatedMessageFieldAccessor( 984 field, camelCaseNames[i], messageClass, builderClass); 985 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 986 fields[i] = new RepeatedEnumFieldAccessor( 987 field, camelCaseNames[i], messageClass, builderClass); 988 } else { 989 fields[i] = new RepeatedFieldAccessor( 990 field, camelCaseNames[i], messageClass, builderClass); 991 } 992 } else { 993 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 994 fields[i] = new SingularMessageFieldAccessor( 995 field, camelCaseNames[i], messageClass, builderClass); 996 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 997 fields[i] = new SingularEnumFieldAccessor( 998 field, camelCaseNames[i], messageClass, builderClass); 999 } else { 1000 fields[i] = new SingularFieldAccessor( 1001 field, camelCaseNames[i], messageClass, builderClass); 1002 } 1003 } 1004 } 1005 } 1006 1007 private final Descriptor descriptor; 1008 private final FieldAccessor[] fields; 1009 1010 /** Get the FieldAccessor for a particular field. */ 1011 private FieldAccessor getField(final FieldDescriptor field) { 1012 if (field.getContainingType() != descriptor) { 1013 throw new IllegalArgumentException( 1014 "FieldDescriptor does not match message type."); 1015 } else if (field.isExtension()) { 1016 // If this type had extensions, it would subclass ExtendableMessage, 1017 // which overrides the reflection interface to handle extensions. 1018 throw new IllegalArgumentException( 1019 "This type does not have extensions."); 1020 } 1021 return fields[field.getIndex()]; 1022 } 1023 1024 /** 1025 * Abstract interface that provides access to a single field. This is 1026 * implemented differently depending on the field type and cardinality. 1027 */ 1028 private interface FieldAccessor { 1029 Object get(GeneratedMessage message); 1030 void set(Builder builder, Object value); 1031 Object getRepeated(GeneratedMessage message, int index); 1032 void setRepeated(Builder builder, 1033 int index, Object value); 1034 void addRepeated(Builder builder, Object value); 1035 boolean has(GeneratedMessage message); 1036 int getRepeatedCount(GeneratedMessage message); 1037 void clear(Builder builder); 1038 Message.Builder newBuilder(); 1039 } 1040 1041 // --------------------------------------------------------------- 1042 1043 private static class SingularFieldAccessor implements FieldAccessor { 1044 SingularFieldAccessor( 1045 final FieldDescriptor descriptor, final String camelCaseName, 1046 final Class<? extends GeneratedMessage> messageClass, 1047 final Class<? extends Builder> builderClass) { 1048 getMethod = getMethodOrDie(messageClass, "get" + camelCaseName); 1049 type = getMethod.getReturnType(); 1050 setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type); 1051 hasMethod = 1052 getMethodOrDie(messageClass, "has" + camelCaseName); 1053 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 1054 } 1055 1056 // Note: We use Java reflection to call public methods rather than 1057 // access private fields directly as this avoids runtime security 1058 // checks. 1059 protected final Class type; 1060 protected final Method getMethod; 1061 protected final Method setMethod; 1062 protected final Method hasMethod; 1063 protected final Method clearMethod; 1064 1065 public Object get(final GeneratedMessage message) { 1066 return invokeOrDie(getMethod, message); 1067 } 1068 public void set(final Builder builder, final Object value) { 1069 invokeOrDie(setMethod, builder, value); 1070 } 1071 public Object getRepeated(final GeneratedMessage message, 1072 final int index) { 1073 throw new UnsupportedOperationException( 1074 "getRepeatedField() called on a singular field."); 1075 } 1076 public void setRepeated(final Builder builder, 1077 final int index, final Object value) { 1078 throw new UnsupportedOperationException( 1079 "setRepeatedField() called on a singular field."); 1080 } 1081 public void addRepeated(final Builder builder, final Object value) { 1082 throw new UnsupportedOperationException( 1083 "addRepeatedField() called on a singular field."); 1084 } 1085 public boolean has(final GeneratedMessage message) { 1086 return (Boolean) invokeOrDie(hasMethod, message); 1087 } 1088 public int getRepeatedCount(final GeneratedMessage message) { 1089 throw new UnsupportedOperationException( 1090 "getRepeatedFieldSize() called on a singular field."); 1091 } 1092 public void clear(final Builder builder) { 1093 invokeOrDie(clearMethod, builder); 1094 } 1095 public Message.Builder newBuilder() { 1096 throw new UnsupportedOperationException( 1097 "newBuilderForField() called on a non-Message type."); 1098 } 1099 } 1100 1101 private static class RepeatedFieldAccessor implements FieldAccessor { 1102 RepeatedFieldAccessor( 1103 final FieldDescriptor descriptor, final String camelCaseName, 1104 final Class<? extends GeneratedMessage> messageClass, 1105 final Class<? extends Builder> builderClass) { 1106 getMethod = getMethodOrDie(messageClass, 1107 "get" + camelCaseName + "List"); 1108 1109 getRepeatedMethod = 1110 getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE); 1111 type = getRepeatedMethod.getReturnType(); 1112 setRepeatedMethod = 1113 getMethodOrDie(builderClass, "set" + camelCaseName, 1114 Integer.TYPE, type); 1115 addRepeatedMethod = 1116 getMethodOrDie(builderClass, "add" + camelCaseName, type); 1117 getCountMethod = 1118 getMethodOrDie(messageClass, "get" + camelCaseName + "Count"); 1119 1120 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 1121 } 1122 1123 protected final Class type; 1124 protected final Method getMethod; 1125 protected final Method getRepeatedMethod; 1126 protected final Method setRepeatedMethod; 1127 protected final Method addRepeatedMethod; 1128 protected final Method getCountMethod; 1129 protected final Method clearMethod; 1130 1131 public Object get(final GeneratedMessage message) { 1132 return invokeOrDie(getMethod, message); 1133 } 1134 public void set(final Builder builder, final Object value) { 1135 // Add all the elements individually. This serves two purposes: 1136 // 1) Verifies that each element has the correct type. 1137 // 2) Insures that the caller cannot modify the list later on and 1138 // have the modifications be reflected in the message. 1139 clear(builder); 1140 for (final Object element : (List) value) { 1141 addRepeated(builder, element); 1142 } 1143 } 1144 public Object getRepeated(final GeneratedMessage message, 1145 final int index) { 1146 return invokeOrDie(getRepeatedMethod, message, index); 1147 } 1148 public void setRepeated(final Builder builder, 1149 final int index, final Object value) { 1150 invokeOrDie(setRepeatedMethod, builder, index, value); 1151 } 1152 public void addRepeated(final Builder builder, final Object value) { 1153 invokeOrDie(addRepeatedMethod, builder, value); 1154 } 1155 public boolean has(final GeneratedMessage message) { 1156 throw new UnsupportedOperationException( 1157 "hasField() called on a singular field."); 1158 } 1159 public int getRepeatedCount(final GeneratedMessage message) { 1160 return (Integer) invokeOrDie(getCountMethod, message); 1161 } 1162 public void clear(final Builder builder) { 1163 invokeOrDie(clearMethod, builder); 1164 } 1165 public Message.Builder newBuilder() { 1166 throw new UnsupportedOperationException( 1167 "newBuilderForField() called on a non-Message type."); 1168 } 1169 } 1170 1171 // --------------------------------------------------------------- 1172 1173 private static final class SingularEnumFieldAccessor 1174 extends SingularFieldAccessor { 1175 SingularEnumFieldAccessor( 1176 final FieldDescriptor descriptor, final String camelCaseName, 1177 final Class<? extends GeneratedMessage> messageClass, 1178 final Class<? extends Builder> builderClass) { 1179 super(descriptor, camelCaseName, messageClass, builderClass); 1180 1181 valueOfMethod = getMethodOrDie(type, "valueOf", 1182 EnumValueDescriptor.class); 1183 getValueDescriptorMethod = 1184 getMethodOrDie(type, "getValueDescriptor"); 1185 } 1186 1187 private Method valueOfMethod; 1188 private Method getValueDescriptorMethod; 1189 1190 @Override 1191 public Object get(final GeneratedMessage message) { 1192 return invokeOrDie(getValueDescriptorMethod, super.get(message)); 1193 } 1194 @Override 1195 public void set(final Builder builder, final Object value) { 1196 super.set(builder, invokeOrDie(valueOfMethod, null, value)); 1197 } 1198 } 1199 1200 private static final class RepeatedEnumFieldAccessor 1201 extends RepeatedFieldAccessor { 1202 RepeatedEnumFieldAccessor( 1203 final FieldDescriptor descriptor, final String camelCaseName, 1204 final Class<? extends GeneratedMessage> messageClass, 1205 final Class<? extends Builder> builderClass) { 1206 super(descriptor, camelCaseName, messageClass, builderClass); 1207 1208 valueOfMethod = getMethodOrDie(type, "valueOf", 1209 EnumValueDescriptor.class); 1210 getValueDescriptorMethod = 1211 getMethodOrDie(type, "getValueDescriptor"); 1212 } 1213 1214 private final Method valueOfMethod; 1215 private final Method getValueDescriptorMethod; 1216 1217 @Override 1218 @SuppressWarnings("unchecked") 1219 public Object get(final GeneratedMessage message) { 1220 final List newList = new ArrayList(); 1221 for (final Object element : (List) super.get(message)) { 1222 newList.add(invokeOrDie(getValueDescriptorMethod, element)); 1223 } 1224 return Collections.unmodifiableList(newList); 1225 } 1226 @Override 1227 public Object getRepeated(final GeneratedMessage message, 1228 final int index) { 1229 return invokeOrDie(getValueDescriptorMethod, 1230 super.getRepeated(message, index)); 1231 } 1232 @Override 1233 public void setRepeated(final Builder builder, 1234 final int index, final Object value) { 1235 super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null, 1236 value)); 1237 } 1238 @Override 1239 public void addRepeated(final Builder builder, final Object value) { 1240 super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value)); 1241 } 1242 } 1243 1244 // --------------------------------------------------------------- 1245 1246 private static final class SingularMessageFieldAccessor 1247 extends SingularFieldAccessor { 1248 SingularMessageFieldAccessor( 1249 final FieldDescriptor descriptor, final String camelCaseName, 1250 final Class<? extends GeneratedMessage> messageClass, 1251 final Class<? extends Builder> builderClass) { 1252 super(descriptor, camelCaseName, messageClass, builderClass); 1253 1254 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 1255 } 1256 1257 private final Method newBuilderMethod; 1258 1259 private Object coerceType(final Object value) { 1260 if (type.isInstance(value)) { 1261 return value; 1262 } else { 1263 // The value is not the exact right message type. However, if it 1264 // is an alternative implementation of the same type -- e.g. a 1265 // DynamicMessage -- we should accept it. In this case we can make 1266 // a copy of the message. 1267 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 1268 .mergeFrom((Message) value).build(); 1269 } 1270 } 1271 1272 @Override 1273 public void set(final Builder builder, final Object value) { 1274 super.set(builder, coerceType(value)); 1275 } 1276 @Override 1277 public Message.Builder newBuilder() { 1278 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 1279 } 1280 } 1281 1282 private static final class RepeatedMessageFieldAccessor 1283 extends RepeatedFieldAccessor { 1284 RepeatedMessageFieldAccessor( 1285 final FieldDescriptor descriptor, final String camelCaseName, 1286 final Class<? extends GeneratedMessage> messageClass, 1287 final Class<? extends Builder> builderClass) { 1288 super(descriptor, camelCaseName, messageClass, builderClass); 1289 1290 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 1291 } 1292 1293 private final Method newBuilderMethod; 1294 1295 private Object coerceType(final Object value) { 1296 if (type.isInstance(value)) { 1297 return value; 1298 } else { 1299 // The value is not the exact right message type. However, if it 1300 // is an alternative implementation of the same type -- e.g. a 1301 // DynamicMessage -- we should accept it. In this case we can make 1302 // a copy of the message. 1303 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 1304 .mergeFrom((Message) value).build(); 1305 } 1306 } 1307 1308 @Override 1309 public void setRepeated(final Builder builder, 1310 final int index, final Object value) { 1311 super.setRepeated(builder, index, coerceType(value)); 1312 } 1313 @Override 1314 public void addRepeated(final Builder builder, final Object value) { 1315 super.addRepeated(builder, coerceType(value)); 1316 } 1317 @Override 1318 public Message.Builder newBuilder() { 1319 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 1320 } 1321 } 1322 } 1323 } 1324