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 java.io.IOException; 34 import java.io.ObjectStreamException; 35 import java.io.Serializable; 36 import java.lang.reflect.InvocationTargetException; 37 import java.lang.reflect.Method; 38 import java.util.Collections; 39 import java.util.Iterator; 40 import java.util.List; 41 import java.util.Map; 42 43 /** 44 * Lite version of {@link GeneratedMessage}. 45 * 46 * @author kenton@google.com Kenton Varda 47 */ 48 public abstract class GeneratedMessageLite extends AbstractMessageLite 49 implements Serializable { 50 private static final long serialVersionUID = 1L; 51 GeneratedMessageLite()52 protected GeneratedMessageLite() { 53 } 54 GeneratedMessageLite(Builder builder)55 protected GeneratedMessageLite(Builder builder) { 56 } 57 getParserForType()58 public Parser<? extends MessageLite> getParserForType() { 59 throw new UnsupportedOperationException( 60 "This is supposed to be overridden by subclasses."); 61 } 62 63 /** 64 * Called by subclasses to parse an unknown field. 65 * @return {@code true} unless the tag is an end-group tag. 66 */ parseUnknownField( CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)67 protected boolean parseUnknownField( 68 CodedInputStream input, 69 ExtensionRegistryLite extensionRegistry, 70 int tag) throws IOException { 71 return input.skipField(tag); 72 } 73 74 /** 75 * Used by parsing constructors in generated classes. 76 */ makeExtensionsImmutable()77 protected void makeExtensionsImmutable() { 78 // Noop for messages without extensions. 79 } 80 81 @SuppressWarnings("unchecked") 82 public abstract static class Builder<MessageType extends GeneratedMessageLite, 83 BuilderType extends Builder> 84 extends AbstractMessageLite.Builder<BuilderType> { Builder()85 protected Builder() {} 86 87 //@Override (Java 1.6 override semantics, but we must support 1.5) clear()88 public BuilderType clear() { 89 return (BuilderType) this; 90 } 91 92 // This is implemented here only to work around an apparent bug in the 93 // Java compiler and/or build system. See bug #1898463. The mere presence 94 // of this dummy clone() implementation makes it go away. 95 @Override clone()96 public BuilderType clone() { 97 throw new UnsupportedOperationException( 98 "This is supposed to be overridden by subclasses."); 99 } 100 101 /** All subclasses implement this. */ mergeFrom(MessageType message)102 public abstract BuilderType mergeFrom(MessageType message); 103 104 // Defined here for return type covariance. getDefaultInstanceForType()105 public abstract MessageType getDefaultInstanceForType(); 106 107 /** 108 * Called by subclasses to parse an unknown field. 109 * @return {@code true} unless the tag is an end-group tag. 110 */ parseUnknownField( CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)111 protected boolean parseUnknownField( 112 CodedInputStream input, 113 ExtensionRegistryLite extensionRegistry, 114 int tag) throws IOException { 115 return input.skipField(tag); 116 } 117 } 118 119 // ================================================================= 120 // Extensions-related stuff 121 122 /** 123 * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}. 124 */ 125 public interface ExtendableMessageOrBuilder< 126 MessageType extends ExtendableMessage> extends MessageLiteOrBuilder { 127 128 /** Check if a singular extension is present. */ hasExtension( GeneratedExtension<MessageType, Type> extension)129 <Type> boolean hasExtension( 130 GeneratedExtension<MessageType, Type> extension); 131 132 /** Get the number of elements in a repeated extension. */ getExtensionCount( GeneratedExtension<MessageType, List<Type>> extension)133 <Type> int getExtensionCount( 134 GeneratedExtension<MessageType, List<Type>> extension); 135 136 /** Get the value of an extension. */ getExtension(GeneratedExtension<MessageType, Type> extension)137 <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension); 138 139 /** Get one element of a repeated extension. */ getExtension( GeneratedExtension<MessageType, List<Type>> extension, int index)140 <Type> Type getExtension( 141 GeneratedExtension<MessageType, List<Type>> extension, 142 int index); 143 } 144 145 /** 146 * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}. 147 */ 148 public abstract static class ExtendableMessage< 149 MessageType extends ExtendableMessage<MessageType>> 150 extends GeneratedMessageLite 151 implements ExtendableMessageOrBuilder<MessageType> { 152 153 private final FieldSet<ExtensionDescriptor> extensions; 154 ExtendableMessage()155 protected ExtendableMessage() { 156 this.extensions = FieldSet.newFieldSet(); 157 } 158 ExtendableMessage(ExtendableBuilder<MessageType, ?> builder)159 protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) { 160 this.extensions = builder.buildExtensions(); 161 } 162 verifyExtensionContainingType( final GeneratedExtension<MessageType, ?> extension)163 private void verifyExtensionContainingType( 164 final GeneratedExtension<MessageType, ?> extension) { 165 if (extension.getContainingTypeDefaultInstance() != 166 getDefaultInstanceForType()) { 167 // This can only happen if someone uses unchecked operations. 168 throw new IllegalArgumentException( 169 "This extension is for a different message type. Please make " + 170 "sure that you are not suppressing any generics type warnings."); 171 } 172 } 173 174 /** Check if a singular extension is present. */ 175 //@Override (Java 1.6 override semantics, but we must support 1.5) hasExtension( final GeneratedExtension<MessageType, Type> extension)176 public final <Type> boolean hasExtension( 177 final GeneratedExtension<MessageType, Type> extension) { 178 verifyExtensionContainingType(extension); 179 return extensions.hasField(extension.descriptor); 180 } 181 182 /** Get the number of elements in a repeated extension. */ 183 //@Override (Java 1.6 override semantics, but we must support 1.5) getExtensionCount( final GeneratedExtension<MessageType, List<Type>> extension)184 public final <Type> int getExtensionCount( 185 final GeneratedExtension<MessageType, List<Type>> extension) { 186 verifyExtensionContainingType(extension); 187 return extensions.getRepeatedFieldCount(extension.descriptor); 188 } 189 190 /** Get the value of an extension. */ 191 //@Override (Java 1.6 override semantics, but we must support 1.5) 192 @SuppressWarnings("unchecked") getExtension( final GeneratedExtension<MessageType, Type> extension)193 public final <Type> Type getExtension( 194 final GeneratedExtension<MessageType, Type> extension) { 195 verifyExtensionContainingType(extension); 196 final Object value = extensions.getField(extension.descriptor); 197 if (value == null) { 198 return extension.defaultValue; 199 } else { 200 return (Type) value; 201 } 202 } 203 204 /** Get one element of a repeated extension. */ 205 //@Override (Java 1.6 override semantics, but we must support 1.5) 206 @SuppressWarnings("unchecked") getExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index)207 public final <Type> Type getExtension( 208 final GeneratedExtension<MessageType, List<Type>> extension, 209 final int index) { 210 verifyExtensionContainingType(extension); 211 return (Type) extensions.getRepeatedField(extension.descriptor, index); 212 } 213 214 /** Called by subclasses to check if all extensions are initialized. */ extensionsAreInitialized()215 protected boolean extensionsAreInitialized() { 216 return extensions.isInitialized(); 217 } 218 219 /** 220 * Called by subclasses to parse an unknown field or an extension. 221 * @return {@code true} unless the tag is an end-group tag. 222 */ 223 @Override parseUnknownField( CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)224 protected boolean parseUnknownField( 225 CodedInputStream input, 226 ExtensionRegistryLite extensionRegistry, 227 int tag) throws IOException { 228 return GeneratedMessageLite.parseUnknownField( 229 extensions, 230 getDefaultInstanceForType(), 231 input, 232 extensionRegistry, 233 tag); 234 } 235 236 /** 237 * Used by parsing constructors in generated classes. 238 */ 239 @Override makeExtensionsImmutable()240 protected void makeExtensionsImmutable() { 241 extensions.makeImmutable(); 242 } 243 244 /** 245 * Used by subclasses to serialize extensions. Extension ranges may be 246 * interleaved with field numbers, but we must write them in canonical 247 * (sorted by field number) order. ExtensionWriter helps us write 248 * individual ranges of extensions at once. 249 */ 250 protected class ExtensionWriter { 251 // Imagine how much simpler this code would be if Java iterators had 252 // a way to get the next element without advancing the iterator. 253 254 private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter = 255 extensions.iterator(); 256 private Map.Entry<ExtensionDescriptor, Object> next; 257 private final boolean messageSetWireFormat; 258 ExtensionWriter(boolean messageSetWireFormat)259 private ExtensionWriter(boolean messageSetWireFormat) { 260 if (iter.hasNext()) { 261 next = iter.next(); 262 } 263 this.messageSetWireFormat = messageSetWireFormat; 264 } 265 writeUntil(final int end, final CodedOutputStream output)266 public void writeUntil(final int end, final CodedOutputStream output) 267 throws IOException { 268 while (next != null && next.getKey().getNumber() < end) { 269 ExtensionDescriptor extension = next.getKey(); 270 if (messageSetWireFormat && extension.getLiteJavaType() == 271 WireFormat.JavaType.MESSAGE && 272 !extension.isRepeated()) { 273 output.writeMessageSetExtension(extension.getNumber(), 274 (MessageLite) next.getValue()); 275 } else { 276 FieldSet.writeField(extension, next.getValue(), output); 277 } 278 if (iter.hasNext()) { 279 next = iter.next(); 280 } else { 281 next = null; 282 } 283 } 284 } 285 } 286 newExtensionWriter()287 protected ExtensionWriter newExtensionWriter() { 288 return new ExtensionWriter(false); 289 } newMessageSetExtensionWriter()290 protected ExtensionWriter newMessageSetExtensionWriter() { 291 return new ExtensionWriter(true); 292 } 293 294 /** Called by subclasses to compute the size of extensions. */ extensionsSerializedSize()295 protected int extensionsSerializedSize() { 296 return extensions.getSerializedSize(); 297 } extensionsSerializedSizeAsMessageSet()298 protected int extensionsSerializedSizeAsMessageSet() { 299 return extensions.getMessageSetSerializedSize(); 300 } 301 } 302 303 /** 304 * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}. 305 */ 306 @SuppressWarnings("unchecked") 307 public abstract static class ExtendableBuilder< 308 MessageType extends ExtendableMessage<MessageType>, 309 BuilderType extends ExtendableBuilder<MessageType, BuilderType>> 310 extends Builder<MessageType, BuilderType> 311 implements ExtendableMessageOrBuilder<MessageType> { ExtendableBuilder()312 protected ExtendableBuilder() {} 313 314 private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet(); 315 private boolean extensionsIsMutable; 316 317 @Override clear()318 public BuilderType clear() { 319 extensions.clear(); 320 extensionsIsMutable = false; 321 return super.clear(); 322 } 323 ensureExtensionsIsMutable()324 private void ensureExtensionsIsMutable() { 325 if (!extensionsIsMutable) { 326 extensions = extensions.clone(); 327 extensionsIsMutable = true; 328 } 329 } 330 331 /** 332 * Called by the build code path to create a copy of the extensions for 333 * building the message. 334 */ buildExtensions()335 private FieldSet<ExtensionDescriptor> buildExtensions() { 336 extensions.makeImmutable(); 337 extensionsIsMutable = false; 338 return extensions; 339 } 340 verifyExtensionContainingType( final GeneratedExtension<MessageType, ?> extension)341 private void verifyExtensionContainingType( 342 final GeneratedExtension<MessageType, ?> extension) { 343 if (extension.getContainingTypeDefaultInstance() != 344 getDefaultInstanceForType()) { 345 // This can only happen if someone uses unchecked operations. 346 throw new IllegalArgumentException( 347 "This extension is for a different message type. Please make " + 348 "sure that you are not suppressing any generics type warnings."); 349 } 350 } 351 352 /** Check if a singular extension is present. */ 353 //@Override (Java 1.6 override semantics, but we must support 1.5) hasExtension( final GeneratedExtension<MessageType, Type> extension)354 public final <Type> boolean hasExtension( 355 final GeneratedExtension<MessageType, Type> extension) { 356 verifyExtensionContainingType(extension); 357 return extensions.hasField(extension.descriptor); 358 } 359 360 /** Get the number of elements in a repeated extension. */ 361 //@Override (Java 1.6 override semantics, but we must support 1.5) getExtensionCount( final GeneratedExtension<MessageType, List<Type>> extension)362 public final <Type> int getExtensionCount( 363 final GeneratedExtension<MessageType, List<Type>> extension) { 364 verifyExtensionContainingType(extension); 365 return extensions.getRepeatedFieldCount(extension.descriptor); 366 } 367 368 /** Get the value of an extension. */ 369 //@Override (Java 1.6 override semantics, but we must support 1.5) 370 @SuppressWarnings("unchecked") getExtension( final GeneratedExtension<MessageType, Type> extension)371 public final <Type> Type getExtension( 372 final GeneratedExtension<MessageType, Type> extension) { 373 verifyExtensionContainingType(extension); 374 final Object value = extensions.getField(extension.descriptor); 375 if (value == null) { 376 return extension.defaultValue; 377 } else { 378 return (Type) value; 379 } 380 } 381 382 /** Get one element of a repeated extension. */ 383 @SuppressWarnings("unchecked") 384 //@Override (Java 1.6 override semantics, but we must support 1.5) getExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index)385 public final <Type> Type getExtension( 386 final GeneratedExtension<MessageType, List<Type>> extension, 387 final int index) { 388 verifyExtensionContainingType(extension); 389 return (Type) extensions.getRepeatedField(extension.descriptor, index); 390 } 391 392 // This is implemented here only to work around an apparent bug in the 393 // Java compiler and/or build system. See bug #1898463. The mere presence 394 // of this dummy clone() implementation makes it go away. 395 @Override clone()396 public BuilderType clone() { 397 throw new UnsupportedOperationException( 398 "This is supposed to be overridden by subclasses."); 399 } 400 401 /** Set the value of an extension. */ setExtension( final GeneratedExtension<MessageType, Type> extension, final Type value)402 public final <Type> BuilderType setExtension( 403 final GeneratedExtension<MessageType, Type> extension, 404 final Type value) { 405 verifyExtensionContainingType(extension); 406 ensureExtensionsIsMutable(); 407 extensions.setField(extension.descriptor, value); 408 return (BuilderType) this; 409 } 410 411 /** Set the value of one element of a repeated extension. */ setExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index, final Type value)412 public final <Type> BuilderType setExtension( 413 final GeneratedExtension<MessageType, List<Type>> extension, 414 final int index, final Type value) { 415 verifyExtensionContainingType(extension); 416 ensureExtensionsIsMutable(); 417 extensions.setRepeatedField(extension.descriptor, index, value); 418 return (BuilderType) this; 419 } 420 421 /** Append a value to a repeated extension. */ addExtension( final GeneratedExtension<MessageType, List<Type>> extension, final Type value)422 public final <Type> BuilderType addExtension( 423 final GeneratedExtension<MessageType, List<Type>> extension, 424 final Type value) { 425 verifyExtensionContainingType(extension); 426 ensureExtensionsIsMutable(); 427 extensions.addRepeatedField(extension.descriptor, value); 428 return (BuilderType) this; 429 } 430 431 /** Clear an extension. */ clearExtension( final GeneratedExtension<MessageType, ?> extension)432 public final <Type> BuilderType clearExtension( 433 final GeneratedExtension<MessageType, ?> extension) { 434 verifyExtensionContainingType(extension); 435 ensureExtensionsIsMutable(); 436 extensions.clearField(extension.descriptor); 437 return (BuilderType) this; 438 } 439 440 /** Called by subclasses to check if all extensions are initialized. */ extensionsAreInitialized()441 protected boolean extensionsAreInitialized() { 442 return extensions.isInitialized(); 443 } 444 445 /** 446 * Called by subclasses to parse an unknown field or an extension. 447 * @return {@code true} unless the tag is an end-group tag. 448 */ 449 @Override parseUnknownField( CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)450 protected boolean parseUnknownField( 451 CodedInputStream input, 452 ExtensionRegistryLite extensionRegistry, 453 int tag) throws IOException { 454 ensureExtensionsIsMutable(); 455 return GeneratedMessageLite.parseUnknownField( 456 extensions, 457 getDefaultInstanceForType(), 458 input, 459 extensionRegistry, 460 tag); 461 } 462 mergeExtensionFields(final MessageType other)463 protected final void mergeExtensionFields(final MessageType other) { 464 ensureExtensionsIsMutable(); 465 extensions.mergeFrom(((ExtendableMessage) other).extensions); 466 } 467 } 468 469 // ----------------------------------------------------------------- 470 471 /** 472 * Parse an unknown field or an extension. 473 * @return {@code true} unless the tag is an end-group tag. 474 */ 475 private static <MessageType extends MessageLite> parseUnknownField( FieldSet<ExtensionDescriptor> extensions, MessageType defaultInstance, CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)476 boolean parseUnknownField( 477 FieldSet<ExtensionDescriptor> extensions, 478 MessageType defaultInstance, 479 CodedInputStream input, 480 ExtensionRegistryLite extensionRegistry, 481 int tag) throws IOException { 482 int wireType = WireFormat.getTagWireType(tag); 483 int fieldNumber = WireFormat.getTagFieldNumber(tag); 484 485 GeneratedExtension<MessageType, ?> extension = 486 extensionRegistry.findLiteExtensionByNumber( 487 defaultInstance, fieldNumber); 488 489 boolean unknown = false; 490 boolean packed = false; 491 if (extension == null) { 492 unknown = true; // Unknown field. 493 } else if (wireType == FieldSet.getWireFormatForFieldType( 494 extension.descriptor.getLiteType(), 495 false /* isPacked */)) { 496 packed = false; // Normal, unpacked value. 497 } else if (extension.descriptor.isRepeated && 498 extension.descriptor.type.isPackable() && 499 wireType == FieldSet.getWireFormatForFieldType( 500 extension.descriptor.getLiteType(), 501 true /* isPacked */)) { 502 packed = true; // Packed value. 503 } else { 504 unknown = true; // Wrong wire type. 505 } 506 507 if (unknown) { // Unknown field or wrong wire type. Skip. 508 return input.skipField(tag); 509 } 510 511 if (packed) { 512 int length = input.readRawVarint32(); 513 int limit = input.pushLimit(length); 514 if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { 515 while (input.getBytesUntilLimit() > 0) { 516 int rawValue = input.readEnum(); 517 Object value = 518 extension.descriptor.getEnumType().findValueByNumber(rawValue); 519 if (value == null) { 520 // If the number isn't recognized as a valid value for this 521 // enum, drop it (don't even add it to unknownFields). 522 return true; 523 } 524 extensions.addRepeatedField(extension.descriptor, value); 525 } 526 } else { 527 while (input.getBytesUntilLimit() > 0) { 528 Object value = 529 FieldSet.readPrimitiveField(input, 530 extension.descriptor.getLiteType()); 531 extensions.addRepeatedField(extension.descriptor, value); 532 } 533 } 534 input.popLimit(limit); 535 } else { 536 Object value; 537 switch (extension.descriptor.getLiteJavaType()) { 538 case MESSAGE: { 539 MessageLite.Builder subBuilder = null; 540 if (!extension.descriptor.isRepeated()) { 541 MessageLite existingValue = 542 (MessageLite) extensions.getField(extension.descriptor); 543 if (existingValue != null) { 544 subBuilder = existingValue.toBuilder(); 545 } 546 } 547 if (subBuilder == null) { 548 subBuilder = extension.messageDefaultInstance.newBuilderForType(); 549 } 550 if (extension.descriptor.getLiteType() == 551 WireFormat.FieldType.GROUP) { 552 input.readGroup(extension.getNumber(), 553 subBuilder, extensionRegistry); 554 } else { 555 input.readMessage(subBuilder, extensionRegistry); 556 } 557 value = subBuilder.build(); 558 break; 559 } 560 case ENUM: 561 int rawValue = input.readEnum(); 562 value = extension.descriptor.getEnumType() 563 .findValueByNumber(rawValue); 564 // If the number isn't recognized as a valid value for this enum, 565 // drop it. 566 if (value == null) { 567 return true; 568 } 569 break; 570 default: 571 value = FieldSet.readPrimitiveField(input, 572 extension.descriptor.getLiteType()); 573 break; 574 } 575 576 if (extension.descriptor.isRepeated()) { 577 extensions.addRepeatedField(extension.descriptor, value); 578 } else { 579 extensions.setField(extension.descriptor, value); 580 } 581 } 582 583 return true; 584 } 585 586 // ----------------------------------------------------------------- 587 588 /** For use by generated code only. */ 589 public static <ContainingType extends MessageLite, Type> 590 GeneratedExtension<ContainingType, Type> newSingularGeneratedExtension( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type)591 newSingularGeneratedExtension( 592 final ContainingType containingTypeDefaultInstance, 593 final Type defaultValue, 594 final MessageLite messageDefaultInstance, 595 final Internal.EnumLiteMap<?> enumTypeMap, 596 final int number, 597 final WireFormat.FieldType type) { 598 return new GeneratedExtension<ContainingType, Type>( 599 containingTypeDefaultInstance, 600 defaultValue, 601 messageDefaultInstance, 602 new ExtensionDescriptor(enumTypeMap, number, type, 603 false /* isRepeated */, 604 false /* isPacked */)); 605 } 606 607 /** For use by generated code only. */ 608 public static <ContainingType extends MessageLite, Type> 609 GeneratedExtension<ContainingType, Type> newRepeatedGeneratedExtension( final ContainingType containingTypeDefaultInstance, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type, final boolean isPacked)610 newRepeatedGeneratedExtension( 611 final ContainingType containingTypeDefaultInstance, 612 final MessageLite messageDefaultInstance, 613 final Internal.EnumLiteMap<?> enumTypeMap, 614 final int number, 615 final WireFormat.FieldType type, 616 final boolean isPacked) { 617 @SuppressWarnings("unchecked") // Subclasses ensure Type is a List 618 Type emptyList = (Type) Collections.emptyList(); 619 return new GeneratedExtension<ContainingType, Type>( 620 containingTypeDefaultInstance, 621 emptyList, 622 messageDefaultInstance, 623 new ExtensionDescriptor( 624 enumTypeMap, number, type, true /* isRepeated */, isPacked)); 625 } 626 627 private static final class ExtensionDescriptor 628 implements FieldSet.FieldDescriptorLite< 629 ExtensionDescriptor> { ExtensionDescriptor( final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type, final boolean isRepeated, final boolean isPacked)630 private ExtensionDescriptor( 631 final Internal.EnumLiteMap<?> enumTypeMap, 632 final int number, 633 final WireFormat.FieldType type, 634 final boolean isRepeated, 635 final boolean isPacked) { 636 this.enumTypeMap = enumTypeMap; 637 this.number = number; 638 this.type = type; 639 this.isRepeated = isRepeated; 640 this.isPacked = isPacked; 641 } 642 643 private final Internal.EnumLiteMap<?> enumTypeMap; 644 private final int number; 645 private final WireFormat.FieldType type; 646 private final boolean isRepeated; 647 private final boolean isPacked; 648 getNumber()649 public int getNumber() { 650 return number; 651 } 652 getLiteType()653 public WireFormat.FieldType getLiteType() { 654 return type; 655 } 656 getLiteJavaType()657 public WireFormat.JavaType getLiteJavaType() { 658 return type.getJavaType(); 659 } 660 isRepeated()661 public boolean isRepeated() { 662 return isRepeated; 663 } 664 isPacked()665 public boolean isPacked() { 666 return isPacked; 667 } 668 getEnumType()669 public Internal.EnumLiteMap<?> getEnumType() { 670 return enumTypeMap; 671 } 672 673 @SuppressWarnings("unchecked") internalMergeFrom( MessageLite.Builder to, MessageLite from)674 public MessageLite.Builder internalMergeFrom( 675 MessageLite.Builder to, MessageLite from) { 676 return ((Builder) to).mergeFrom((GeneratedMessageLite) from); 677 } 678 compareTo(ExtensionDescriptor other)679 public int compareTo(ExtensionDescriptor other) { 680 return number - other.number; 681 } 682 } 683 684 /** 685 * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}. 686 * 687 * Users should ignore the contents of this class and only use objects of 688 * this type as parameters to extension accessors and ExtensionRegistry.add(). 689 */ 690 public static final class GeneratedExtension< 691 ContainingType extends MessageLite, Type> { 692 GeneratedExtension( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final ExtensionDescriptor descriptor)693 private GeneratedExtension( 694 final ContainingType containingTypeDefaultInstance, 695 final Type defaultValue, 696 final MessageLite messageDefaultInstance, 697 final ExtensionDescriptor descriptor) { 698 // Defensive checks to verify the correct initialization order of 699 // GeneratedExtensions and their related GeneratedMessages. 700 if (containingTypeDefaultInstance == null) { 701 throw new IllegalArgumentException( 702 "Null containingTypeDefaultInstance"); 703 } 704 if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE && 705 messageDefaultInstance == null) { 706 throw new IllegalArgumentException( 707 "Null messageDefaultInstance"); 708 } 709 this.containingTypeDefaultInstance = containingTypeDefaultInstance; 710 this.defaultValue = defaultValue; 711 this.messageDefaultInstance = messageDefaultInstance; 712 this.descriptor = descriptor; 713 } 714 715 private final ContainingType containingTypeDefaultInstance; 716 private final Type defaultValue; 717 private final MessageLite messageDefaultInstance; 718 private final ExtensionDescriptor descriptor; 719 720 /** 721 * Default instance of the type being extended, used to identify that type. 722 */ getContainingTypeDefaultInstance()723 public ContainingType getContainingTypeDefaultInstance() { 724 return containingTypeDefaultInstance; 725 } 726 727 /** Get the field number. */ getNumber()728 public int getNumber() { 729 return descriptor.getNumber(); 730 } 731 732 /** 733 * If the extension is an embedded message, this is the default instance of 734 * that type. 735 */ getMessageDefaultInstance()736 public MessageLite getMessageDefaultInstance() { 737 return messageDefaultInstance; 738 } 739 } 740 741 /** 742 * A serialized (serializable) form of the generated message. Stores the 743 * message as a class name and a byte array. 744 */ 745 static final class SerializedForm implements Serializable { 746 private static final long serialVersionUID = 0L; 747 748 private String messageClassName; 749 private byte[] asBytes; 750 751 /** 752 * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}. 753 * @param regularForm the message to serialize 754 */ SerializedForm(MessageLite regularForm)755 SerializedForm(MessageLite regularForm) { 756 messageClassName = regularForm.getClass().getName(); 757 asBytes = regularForm.toByteArray(); 758 } 759 760 /** 761 * When read from an ObjectInputStream, this method converts this object 762 * back to the regular form. Part of Java's serialization magic. 763 * @return a GeneratedMessage of the type that was serialized 764 */ 765 @SuppressWarnings("unchecked") readResolve()766 protected Object readResolve() throws ObjectStreamException { 767 try { 768 Class messageClass = Class.forName(messageClassName); 769 Method newBuilder = messageClass.getMethod("newBuilder"); 770 MessageLite.Builder builder = 771 (MessageLite.Builder) newBuilder.invoke(null); 772 builder.mergeFrom(asBytes); 773 return builder.buildPartial(); 774 } catch (ClassNotFoundException e) { 775 throw new RuntimeException("Unable to find proto buffer class", e); 776 } catch (NoSuchMethodException e) { 777 throw new RuntimeException("Unable to find newBuilder method", e); 778 } catch (IllegalAccessException e) { 779 throw new RuntimeException("Unable to call newBuilder method", e); 780 } catch (InvocationTargetException e) { 781 throw new RuntimeException("Error calling newBuilder", e.getCause()); 782 } catch (InvalidProtocolBufferException e) { 783 throw new RuntimeException("Unable to understand proto buffer", e); 784 } 785 } 786 } 787 788 /** 789 * Replaces this object in the output stream with a serialized form. 790 * Part of Java's serialization magic. Generated sub-classes must override 791 * this method by calling {@code return super.writeReplace();} 792 * @return a SerializedForm of this message 793 */ writeReplace()794 protected Object writeReplace() throws ObjectStreamException { 795 return new SerializedForm(this); 796 } 797 } 798