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