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.util.Collections; 35 import java.util.Iterator; 36 import java.util.List; 37 import java.util.Map; 38 39 /** 40 * Lite version of {@link GeneratedMessage}. 41 * 42 * @author kenton@google.com Kenton Varda 43 */ 44 public abstract class GeneratedMessageLite extends AbstractMessageLite { GeneratedMessageLite()45 protected GeneratedMessageLite() {} 46 47 @SuppressWarnings("unchecked") 48 public abstract static class Builder<MessageType extends GeneratedMessageLite, 49 BuilderType extends Builder> 50 extends AbstractMessageLite.Builder<BuilderType> { Builder()51 protected Builder() {} 52 53 // This is implemented here only to work around an apparent bug in the 54 // Java compiler and/or build system. See bug #1898463. The mere presence 55 // of this dummy clone() implementation makes it go away. 56 @Override clone()57 public BuilderType clone() { 58 throw new UnsupportedOperationException( 59 "This is supposed to be overridden by subclasses."); 60 } 61 62 /** All subclasses implement this. */ mergeFrom(MessageType message)63 public abstract BuilderType mergeFrom(MessageType message); 64 65 // Defined here for return type covariance. getDefaultInstanceForType()66 public abstract MessageType getDefaultInstanceForType(); 67 68 /** 69 * Get the message being built. We don't just pass this to the 70 * constructor because it becomes null when build() is called. 71 */ internalGetResult()72 protected abstract MessageType internalGetResult(); 73 74 /** 75 * Called by subclasses to parse an unknown field. 76 * @return {@code true} unless the tag is an end-group tag. 77 */ parseUnknownField( final CodedInputStream input, final ExtensionRegistryLite extensionRegistry, final int tag)78 protected boolean parseUnknownField( 79 final CodedInputStream input, 80 final ExtensionRegistryLite extensionRegistry, 81 final int tag) throws IOException { 82 return input.skipField(tag); 83 } 84 } 85 86 // ================================================================= 87 // Extensions-related stuff 88 89 /** 90 * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}. 91 */ 92 public abstract static class ExtendableMessage< 93 MessageType extends ExtendableMessage<MessageType>> 94 extends GeneratedMessageLite { ExtendableMessage()95 protected ExtendableMessage() {} 96 private final FieldSet<ExtensionDescriptor> extensions = 97 FieldSet.newFieldSet(); 98 verifyExtensionContainingType( final GeneratedExtension<MessageType, ?> extension)99 private void verifyExtensionContainingType( 100 final GeneratedExtension<MessageType, ?> extension) { 101 if (extension.getContainingTypeDefaultInstance() != 102 getDefaultInstanceForType()) { 103 // This can only happen if someone uses unchecked operations. 104 throw new IllegalArgumentException( 105 "This extension is for a different message type. Please make " + 106 "sure that you are not suppressing any generics type warnings."); 107 } 108 } 109 110 /** Check if a singular extension is present. */ hasExtension( final GeneratedExtension<MessageType, ?> extension)111 public final boolean hasExtension( 112 final GeneratedExtension<MessageType, ?> extension) { 113 verifyExtensionContainingType(extension); 114 return extensions.hasField(extension.descriptor); 115 } 116 117 /** Get the number of elements in a repeated extension. */ getExtensionCount( final GeneratedExtension<MessageType, List<Type>> extension)118 public final <Type> int getExtensionCount( 119 final GeneratedExtension<MessageType, List<Type>> extension) { 120 verifyExtensionContainingType(extension); 121 return extensions.getRepeatedFieldCount(extension.descriptor); 122 } 123 124 /** Get the value of an extension. */ 125 @SuppressWarnings("unchecked") getExtension( final GeneratedExtension<MessageType, Type> extension)126 public final <Type> Type getExtension( 127 final GeneratedExtension<MessageType, Type> extension) { 128 verifyExtensionContainingType(extension); 129 final Object value = extensions.getField(extension.descriptor); 130 if (value == null) { 131 return extension.defaultValue; 132 } else { 133 return (Type) value; 134 } 135 } 136 137 /** Get one element of a repeated extension. */ 138 @SuppressWarnings("unchecked") getExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index)139 public final <Type> Type getExtension( 140 final GeneratedExtension<MessageType, List<Type>> extension, 141 final int index) { 142 verifyExtensionContainingType(extension); 143 return (Type) extensions.getRepeatedField(extension.descriptor, index); 144 } 145 146 /** Called by subclasses to check if all extensions are initialized. */ extensionsAreInitialized()147 protected boolean extensionsAreInitialized() { 148 return extensions.isInitialized(); 149 } 150 151 /** 152 * Used by subclasses to serialize extensions. Extension ranges may be 153 * interleaved with field numbers, but we must write them in canonical 154 * (sorted by field number) order. ExtensionWriter helps us write 155 * individual ranges of extensions at once. 156 */ 157 protected class ExtensionWriter { 158 // Imagine how much simpler this code would be if Java iterators had 159 // a way to get the next element without advancing the iterator. 160 161 private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter = 162 extensions.iterator(); 163 private Map.Entry<ExtensionDescriptor, Object> next; 164 private final boolean messageSetWireFormat; 165 ExtensionWriter(boolean messageSetWireFormat)166 private ExtensionWriter(boolean messageSetWireFormat) { 167 if (iter.hasNext()) { 168 next = iter.next(); 169 } 170 this.messageSetWireFormat = messageSetWireFormat; 171 } 172 writeUntil(final int end, final CodedOutputStream output)173 public void writeUntil(final int end, final CodedOutputStream output) 174 throws IOException { 175 while (next != null && next.getKey().getNumber() < end) { 176 ExtensionDescriptor extension = next.getKey(); 177 if (messageSetWireFormat && extension.getLiteJavaType() == 178 WireFormat.JavaType.MESSAGE && 179 !extension.isRepeated()) { 180 output.writeMessageSetExtension(extension.getNumber(), 181 (MessageLite) next.getValue()); 182 } else { 183 FieldSet.writeField(extension, next.getValue(), output); 184 } 185 if (iter.hasNext()) { 186 next = iter.next(); 187 } else { 188 next = null; 189 } 190 } 191 } 192 } 193 newExtensionWriter()194 protected ExtensionWriter newExtensionWriter() { 195 return new ExtensionWriter(false); 196 } newMessageSetExtensionWriter()197 protected ExtensionWriter newMessageSetExtensionWriter() { 198 return new ExtensionWriter(true); 199 } 200 201 /** Called by subclasses to compute the size of extensions. */ extensionsSerializedSize()202 protected int extensionsSerializedSize() { 203 return extensions.getSerializedSize(); 204 } extensionsSerializedSizeAsMessageSet()205 protected int extensionsSerializedSizeAsMessageSet() { 206 return extensions.getMessageSetSerializedSize(); 207 } 208 } 209 210 /** 211 * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}. 212 */ 213 @SuppressWarnings("unchecked") 214 public abstract static class ExtendableBuilder< 215 MessageType extends ExtendableMessage<MessageType>, 216 BuilderType extends ExtendableBuilder<MessageType, BuilderType>> 217 extends Builder<MessageType, BuilderType> { ExtendableBuilder()218 protected ExtendableBuilder() {} 219 220 // This is implemented here only to work around an apparent bug in the 221 // Java compiler and/or build system. See bug #1898463. The mere presence 222 // of this dummy clone() implementation makes it go away. 223 @Override clone()224 public BuilderType clone() { 225 throw new UnsupportedOperationException( 226 "This is supposed to be overridden by subclasses."); 227 } 228 229 @Override internalGetResult()230 protected abstract MessageType internalGetResult(); 231 232 /** Check if a singular extension is present. */ hasExtension( final GeneratedExtension<MessageType, ?> extension)233 public final boolean hasExtension( 234 final GeneratedExtension<MessageType, ?> extension) { 235 return internalGetResult().hasExtension(extension); 236 } 237 238 /** Get the number of elements in a repeated extension. */ getExtensionCount( final GeneratedExtension<MessageType, List<Type>> extension)239 public final <Type> int getExtensionCount( 240 final GeneratedExtension<MessageType, List<Type>> extension) { 241 return internalGetResult().getExtensionCount(extension); 242 } 243 244 /** Get the value of an extension. */ getExtension( final GeneratedExtension<MessageType, Type> extension)245 public final <Type> Type getExtension( 246 final GeneratedExtension<MessageType, Type> extension) { 247 return internalGetResult().getExtension(extension); 248 } 249 250 /** Get one element of a repeated extension. */ getExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index)251 public final <Type> Type getExtension( 252 final GeneratedExtension<MessageType, List<Type>> extension, 253 final int index) { 254 return internalGetResult().getExtension(extension, index); 255 } 256 257 /** Set the value of an extension. */ setExtension( final GeneratedExtension<MessageType, Type> extension, final Type value)258 public final <Type> BuilderType setExtension( 259 final GeneratedExtension<MessageType, Type> extension, 260 final Type value) { 261 final ExtendableMessage<MessageType> message = internalGetResult(); 262 message.verifyExtensionContainingType(extension); 263 message.extensions.setField(extension.descriptor, value); 264 return (BuilderType) this; 265 } 266 267 /** Set the value of one element of a repeated extension. */ setExtension( final GeneratedExtension<MessageType, List<Type>> extension, final int index, final Type value)268 public final <Type> BuilderType setExtension( 269 final GeneratedExtension<MessageType, List<Type>> extension, 270 final int index, final Type value) { 271 final ExtendableMessage<MessageType> message = internalGetResult(); 272 message.verifyExtensionContainingType(extension); 273 message.extensions.setRepeatedField(extension.descriptor, index, value); 274 return (BuilderType) this; 275 } 276 277 /** Append a value to a repeated extension. */ addExtension( final GeneratedExtension<MessageType, List<Type>> extension, final Type value)278 public final <Type> BuilderType addExtension( 279 final GeneratedExtension<MessageType, List<Type>> extension, 280 final Type value) { 281 final ExtendableMessage<MessageType> message = internalGetResult(); 282 message.verifyExtensionContainingType(extension); 283 message.extensions.addRepeatedField(extension.descriptor, value); 284 return (BuilderType) this; 285 } 286 287 /** Clear an extension. */ clearExtension( final GeneratedExtension<MessageType, ?> extension)288 public final <Type> BuilderType clearExtension( 289 final GeneratedExtension<MessageType, ?> extension) { 290 final ExtendableMessage<MessageType> message = internalGetResult(); 291 message.verifyExtensionContainingType(extension); 292 message.extensions.clearField(extension.descriptor); 293 return (BuilderType) this; 294 } 295 296 /** 297 * Called by subclasses to parse an unknown field or an extension. 298 * @return {@code true} unless the tag is an end-group tag. 299 */ 300 @Override parseUnknownField( final CodedInputStream input, final ExtensionRegistryLite extensionRegistry, final int tag)301 protected boolean parseUnknownField( 302 final CodedInputStream input, 303 final ExtensionRegistryLite extensionRegistry, 304 final int tag) throws IOException { 305 final FieldSet<ExtensionDescriptor> extensions = 306 ((ExtendableMessage) internalGetResult()).extensions; 307 308 final int wireType = WireFormat.getTagWireType(tag); 309 final int fieldNumber = WireFormat.getTagFieldNumber(tag); 310 311 final GeneratedExtension<MessageType, ?> extension = 312 extensionRegistry.findLiteExtensionByNumber( 313 getDefaultInstanceForType(), fieldNumber); 314 315 boolean unknown = false; 316 boolean packed = false; 317 if (extension == null) { 318 unknown = true; // Unknown field. 319 } else if (wireType == FieldSet.getWireFormatForFieldType( 320 extension.descriptor.getLiteType(), 321 false /* isPacked */)) { 322 packed = false; // Normal, unpacked value. 323 } else if (extension.descriptor.isRepeated && 324 extension.descriptor.type.isPackable() && 325 wireType == FieldSet.getWireFormatForFieldType( 326 extension.descriptor.getLiteType(), 327 true /* isPacked */)) { 328 packed = true; // Packed value. 329 } else { 330 unknown = true; // Wrong wire type. 331 } 332 333 if (unknown) { // Unknown field or wrong wire type. Skip. 334 return input.skipField(tag); 335 } 336 337 if (packed) { 338 final int length = input.readRawVarint32(); 339 final int limit = input.pushLimit(length); 340 if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { 341 while (input.getBytesUntilLimit() > 0) { 342 final int rawValue = input.readEnum(); 343 final Object value = 344 extension.descriptor.getEnumType().findValueByNumber(rawValue); 345 if (value == null) { 346 // If the number isn't recognized as a valid value for this 347 // enum, drop it (don't even add it to unknownFields). 348 return true; 349 } 350 extensions.addRepeatedField(extension.descriptor, value); 351 } 352 } else { 353 while (input.getBytesUntilLimit() > 0) { 354 final Object value = 355 FieldSet.readPrimitiveField(input, 356 extension.descriptor.getLiteType()); 357 extensions.addRepeatedField(extension.descriptor, value); 358 } 359 } 360 input.popLimit(limit); 361 } else { 362 final Object value; 363 switch (extension.descriptor.getLiteJavaType()) { 364 case MESSAGE: { 365 MessageLite.Builder subBuilder = null; 366 if (!extension.descriptor.isRepeated()) { 367 MessageLite existingValue = 368 (MessageLite) extensions.getField(extension.descriptor); 369 if (existingValue != null) { 370 subBuilder = existingValue.toBuilder(); 371 } 372 } 373 if (subBuilder == null) { 374 subBuilder = extension.messageDefaultInstance.newBuilderForType(); 375 } 376 if (extension.descriptor.getLiteType() == 377 WireFormat.FieldType.GROUP) { 378 input.readGroup(extension.getNumber(), 379 subBuilder, extensionRegistry); 380 } else { 381 input.readMessage(subBuilder, extensionRegistry); 382 } 383 value = subBuilder.build(); 384 break; 385 } 386 case ENUM: 387 final int rawValue = input.readEnum(); 388 value = extension.descriptor.getEnumType() 389 .findValueByNumber(rawValue); 390 // If the number isn't recognized as a valid value for this enum, 391 // drop it. 392 if (value == null) { 393 return true; 394 } 395 break; 396 default: 397 value = FieldSet.readPrimitiveField(input, 398 extension.descriptor.getLiteType()); 399 break; 400 } 401 402 if (extension.descriptor.isRepeated()) { 403 extensions.addRepeatedField(extension.descriptor, value); 404 } else { 405 extensions.setField(extension.descriptor, value); 406 } 407 } 408 409 return true; 410 } 411 mergeExtensionFields(final MessageType other)412 protected final void mergeExtensionFields(final MessageType other) { 413 ((ExtendableMessage) internalGetResult()).extensions.mergeFrom( 414 ((ExtendableMessage) other).extensions); 415 } 416 } 417 418 // ----------------------------------------------------------------- 419 420 /** For use by generated code only. */ 421 public static <ContainingType extends MessageLite, Type> 422 GeneratedExtension<ContainingType, Type> newGeneratedExtension()423 newGeneratedExtension() { 424 return new GeneratedExtension<ContainingType, Type>(); 425 } 426 427 private static final class ExtensionDescriptor 428 implements FieldSet.FieldDescriptorLite< 429 ExtensionDescriptor> { ExtensionDescriptor( final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type, final boolean isRepeated, final boolean isPacked)430 private ExtensionDescriptor( 431 final Internal.EnumLiteMap<?> enumTypeMap, 432 final int number, 433 final WireFormat.FieldType type, 434 final boolean isRepeated, 435 final boolean isPacked) { 436 this.enumTypeMap = enumTypeMap; 437 this.number = number; 438 this.type = type; 439 this.isRepeated = isRepeated; 440 this.isPacked = isPacked; 441 } 442 443 private final Internal.EnumLiteMap<?> enumTypeMap; 444 private final int number; 445 private final WireFormat.FieldType type; 446 private final boolean isRepeated; 447 private final boolean isPacked; 448 getNumber()449 public int getNumber() { 450 return number; 451 } 452 getLiteType()453 public WireFormat.FieldType getLiteType() { 454 return type; 455 } 456 getLiteJavaType()457 public WireFormat.JavaType getLiteJavaType() { 458 return type.getJavaType(); 459 } 460 isRepeated()461 public boolean isRepeated() { 462 return isRepeated; 463 } 464 isPacked()465 public boolean isPacked() { 466 return isPacked; 467 } 468 getEnumType()469 public Internal.EnumLiteMap<?> getEnumType() { 470 return enumTypeMap; 471 } 472 473 @SuppressWarnings("unchecked") internalMergeFrom( MessageLite.Builder to, MessageLite from)474 public MessageLite.Builder internalMergeFrom( 475 MessageLite.Builder to, MessageLite from) { 476 return ((Builder) to).mergeFrom((GeneratedMessageLite) from); 477 } 478 compareTo(ExtensionDescriptor other)479 public int compareTo(ExtensionDescriptor other) { 480 return number - other.number; 481 } 482 } 483 484 /** 485 * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}. 486 * 487 * Users should ignore the contents of this class and only use objects of 488 * this type as parameters to extension accessors and ExtensionRegistry.add(). 489 */ 490 public static final class GeneratedExtension< 491 ContainingType extends MessageLite, Type> { 492 // We can't always initialize a GeneratedExtension when we first construct 493 // it due to initialization order difficulties (namely, the default 494 // instances may not have been constructed yet). So, we construct an 495 // uninitialized GeneratedExtension once, then call internalInit() on it 496 // later. Generated code will always call internalInit() on all extensions 497 // as part of the static initialization code, and internalInit() throws an 498 // exception if called more than once, so this method is useless to users. GeneratedExtension()499 private GeneratedExtension() {} 500 internalInit( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final ExtensionDescriptor descriptor)501 private void internalInit( 502 final ContainingType containingTypeDefaultInstance, 503 final Type defaultValue, 504 final MessageLite messageDefaultInstance, 505 final ExtensionDescriptor descriptor) { 506 this.containingTypeDefaultInstance = containingTypeDefaultInstance; 507 this.defaultValue = defaultValue; 508 this.messageDefaultInstance = messageDefaultInstance; 509 this.descriptor = descriptor; 510 } 511 512 /** For use by generated code only. */ internalInitSingular( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type)513 public void internalInitSingular( 514 final ContainingType containingTypeDefaultInstance, 515 final Type defaultValue, 516 final MessageLite messageDefaultInstance, 517 final Internal.EnumLiteMap<?> enumTypeMap, 518 final int number, 519 final WireFormat.FieldType type) { 520 internalInit( 521 containingTypeDefaultInstance, defaultValue, messageDefaultInstance, 522 new ExtensionDescriptor(enumTypeMap, number, type, 523 false /* isRepeated */, false /* isPacked */)); 524 } 525 526 /** For use by generated code only. */ internalInitRepeated( final ContainingType containingTypeDefaultInstance, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap<?> enumTypeMap, final int number, final WireFormat.FieldType type, final boolean isPacked)527 public void internalInitRepeated( 528 final ContainingType containingTypeDefaultInstance, 529 final MessageLite messageDefaultInstance, 530 final Internal.EnumLiteMap<?> enumTypeMap, 531 final int number, 532 final WireFormat.FieldType type, 533 final boolean isPacked) { 534 internalInit( 535 containingTypeDefaultInstance, (Type) Collections.emptyList(), 536 messageDefaultInstance, 537 new ExtensionDescriptor( 538 enumTypeMap, number, type, true /* isRepeated */, isPacked)); 539 } 540 541 private ContainingType containingTypeDefaultInstance; 542 private Type defaultValue; 543 private MessageLite messageDefaultInstance; 544 private ExtensionDescriptor descriptor; 545 546 /** 547 * Default instance of the type being extended, used to identify that type. 548 */ getContainingTypeDefaultInstance()549 public ContainingType getContainingTypeDefaultInstance() { 550 return containingTypeDefaultInstance; 551 } 552 553 /** Get the field number. */ getNumber()554 public int getNumber() { 555 return descriptor.getNumber(); 556 } 557 558 /** 559 * If the extension is an embedded message, this is the default instance of 560 * that type. 561 */ getMessageDefaultInstance()562 public MessageLite getMessageDefaultInstance() { 563 return messageDefaultInstance; 564 } 565 } 566 } 567