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 (at) google.com Kenton Varda 43 */ 44 public abstract class GeneratedMessageLite extends AbstractMessageLite { 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> { 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 57 public BuilderType clone() { 58 throw new UnsupportedOperationException( 59 "This is supposed to be overridden by subclasses."); 60 } 61 62 /** All subclasses implement this. */ 63 public abstract BuilderType mergeFrom(MessageType message); 64 65 // Defined here for return type covariance. 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 */ 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 */ 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 { 95 protected ExtendableMessage() {} 96 private final FieldSet<ExtensionDescriptor> extensions = 97 FieldSet.newFieldSet(); 98 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. */ 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. */ 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") 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") 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. */ 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 166 private ExtensionWriter(boolean messageSetWireFormat) { 167 if (iter.hasNext()) { 168 next = iter.next(); 169 } 170 this.messageSetWireFormat = messageSetWireFormat; 171 } 172 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 194 protected ExtensionWriter newExtensionWriter() { 195 return new ExtensionWriter(false); 196 } 197 protected ExtensionWriter newMessageSetExtensionWriter() { 198 return new ExtensionWriter(true); 199 } 200 201 /** Called by subclasses to compute the size of extensions. */ 202 protected int extensionsSerializedSize() { 203 return extensions.getSerializedSize(); 204 } 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> { 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 224 public BuilderType clone() { 225 throw new UnsupportedOperationException( 226 "This is supposed to be overridden by subclasses."); 227 } 228 229 @Override 230 protected abstract MessageType internalGetResult(); 231 232 /** Check if a singular extension is present. */ 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. */ 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. */ 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. */ 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. */ 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. */ 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. */ 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. */ 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 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 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> 423 newGeneratedExtension() { 424 return new GeneratedExtension<ContainingType, Type>(); 425 } 426 427 private static final class ExtensionDescriptor 428 implements FieldSet.FieldDescriptorLite< 429 ExtensionDescriptor> { 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 449 public int getNumber() { 450 return number; 451 } 452 453 public WireFormat.FieldType getLiteType() { 454 return type; 455 } 456 457 public WireFormat.JavaType getLiteJavaType() { 458 return type.getJavaType(); 459 } 460 461 public boolean isRepeated() { 462 return isRepeated; 463 } 464 465 public boolean isPacked() { 466 return isPacked; 467 } 468 469 public Internal.EnumLiteMap<?> getEnumType() { 470 return enumTypeMap; 471 } 472 473 @SuppressWarnings("unchecked") 474 public MessageLite.Builder internalMergeFrom( 475 MessageLite.Builder to, MessageLite from) { 476 return ((Builder) to).mergeFrom((GeneratedMessageLite) from); 477 } 478 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. 499 private GeneratedExtension() {} 500 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. */ 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. */ 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 */ 549 public ContainingType getContainingTypeDefaultInstance() { 550 return containingTypeDefaultInstance; 551 } 552 553 /** Get the field number. */ 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 */ 562 public MessageLite getMessageDefaultInstance() { 563 return messageDefaultInstance; 564 } 565 } 566 } 567