1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 package com.google.protobuf; 9 10 import static com.google.protobuf.Internal.checkNotNull; 11 12 import com.google.protobuf.Descriptors.Descriptor; 13 import com.google.protobuf.Descriptors.EnumDescriptor; 14 import com.google.protobuf.Descriptors.EnumValueDescriptor; 15 import com.google.protobuf.Descriptors.FieldDescriptor; 16 import com.google.protobuf.Descriptors.FileDescriptor; 17 import com.google.protobuf.Descriptors.OneofDescriptor; 18 import com.google.protobuf.Internal.BooleanList; 19 import com.google.protobuf.Internal.DoubleList; 20 import com.google.protobuf.Internal.FloatList; 21 import com.google.protobuf.Internal.IntList; 22 import com.google.protobuf.Internal.LongList; 23 import com.google.protobuf.Internal.ProtobufList; 24 import java.io.IOException; 25 import java.io.InputStream; 26 import java.io.ObjectStreamException; 27 import java.io.Serializable; 28 import java.lang.reflect.InvocationTargetException; 29 import java.lang.reflect.Method; 30 import java.util.ArrayList; 31 import java.util.Arrays; 32 import java.util.Collections; 33 import java.util.Iterator; 34 import java.util.List; 35 import java.util.Map; 36 import java.util.SortedMap; 37 import java.util.TreeMap; 38 39 /** 40 * All generated protocol message classes extend this class. This class implements most of the 41 * Message and Builder interfaces using Java reflection. Users can ignore this class and pretend 42 * that generated messages implement the Message interface directly. 43 * 44 * @author kenton@google.com Kenton Varda 45 */ 46 public abstract class GeneratedMessage extends AbstractMessage implements Serializable { 47 private static final long serialVersionUID = 1L; 48 49 /** 50 * For testing. Allows a test to disable the optimization that avoids using field builders for 51 * nested messages until they are requested. By disabling this optimization, existing tests can be 52 * reused to test the field builders. 53 */ 54 protected static boolean alwaysUseFieldBuilders = false; 55 56 /** 57 * For use by generated code only. 58 * 59 * <p>TODO: mark this private and final (breaking change) 60 */ 61 protected UnknownFieldSet unknownFields; 62 GeneratedMessage()63 protected GeneratedMessage() { 64 unknownFields = UnknownFieldSet.getDefaultInstance(); 65 } 66 GeneratedMessage(Builder<?> builder)67 protected GeneratedMessage(Builder<?> builder) { 68 unknownFields = builder.getUnknownFields(); 69 } 70 71 /** TODO: Remove this unnecessary intermediate implementation of this method. */ 72 @Override getParserForType()73 public Parser<? extends GeneratedMessage> getParserForType() { 74 throw new UnsupportedOperationException("This is supposed to be overridden by subclasses."); 75 } 76 77 /** 78 * TODO: Stop using SingleFieldBuilder and remove this setting 79 * 80 * @see #setAlwaysUseFieldBuildersForTesting(boolean) 81 */ enableAlwaysUseFieldBuildersForTesting()82 static void enableAlwaysUseFieldBuildersForTesting() { 83 setAlwaysUseFieldBuildersForTesting(true); 84 } 85 86 /** 87 * For testing. Allows a test to disable/re-enable the optimization that avoids using field 88 * builders for nested messages until they are requested. By disabling this optimization, existing 89 * tests can be reused to test the field builders. See {@link RepeatedFieldBuilder} and {@link 90 * SingleFieldBuilder}. 91 * 92 * <p>TODO: Stop using SingleFieldBuilder and remove this setting 93 */ setAlwaysUseFieldBuildersForTesting(boolean useBuilders)94 static void setAlwaysUseFieldBuildersForTesting(boolean useBuilders) { 95 alwaysUseFieldBuilders = useBuilders; 96 } 97 98 /** 99 * Get the FieldAccessorTable for this type. We can't have the message class pass this in to the 100 * constructor because of bootstrapping trouble with DescriptorProtos. 101 */ internalGetFieldAccessorTable()102 protected abstract FieldAccessorTable internalGetFieldAccessorTable(); 103 104 @Override getDescriptorForType()105 public Descriptor getDescriptorForType() { 106 return internalGetFieldAccessorTable().descriptor; 107 } 108 109 /** 110 * TODO: This method should be removed. It enables parsing directly into an 111 * "immutable" message. Have to leave it for now to support old gencode. 112 * 113 * @deprecated use newBuilder().mergeFrom() instead 114 */ 115 @Deprecated mergeFromAndMakeImmutableInternal( CodedInputStream input, ExtensionRegistryLite extensionRegistry)116 protected void mergeFromAndMakeImmutableInternal( 117 CodedInputStream input, ExtensionRegistryLite extensionRegistry) 118 throws InvalidProtocolBufferException { 119 Schema<GeneratedMessage> schema = Protobuf.getInstance().schemaFor(this); 120 try { 121 schema.mergeFrom(this, CodedInputStreamReader.forCodedInput(input), extensionRegistry); 122 } catch (InvalidProtocolBufferException e) { 123 throw e.setUnfinishedMessage(this); 124 } catch (IOException e) { 125 throw new InvalidProtocolBufferException(e).setUnfinishedMessage(this); 126 } 127 schema.makeImmutable(this); 128 } 129 130 /** 131 * Internal helper to return a modifiable map containing all the fields. The returned Map is 132 * modifiable so that the caller can add additional extension fields to implement {@link 133 * #getAllFields()}. 134 * 135 * @param getBytesForString whether to generate ByteString for string fields 136 */ getAllFieldsMutable(boolean getBytesForString)137 private Map<FieldDescriptor, Object> getAllFieldsMutable(boolean getBytesForString) { 138 final TreeMap<FieldDescriptor, Object> result = new TreeMap<>(); 139 final FieldAccessorTable fieldAccessorTable = internalGetFieldAccessorTable(); 140 141 final Descriptor descriptor = fieldAccessorTable.descriptor; 142 final List<FieldDescriptor> fields = descriptor.getFields(); 143 144 for (int i = 0; i < fields.size(); i++) { 145 FieldDescriptor field = fields.get(i); 146 final OneofDescriptor oneofDescriptor = field.getContainingOneof(); 147 148 /* 149 * If the field is part of a Oneof, then at maximum one field in the Oneof is set 150 * and it is not repeated. There is no need to iterate through the others. 151 */ 152 if (oneofDescriptor != null) { 153 // Skip other fields in the Oneof we know are not set 154 i += oneofDescriptor.getFieldCount() - 1; 155 if (!hasOneof(oneofDescriptor)) { 156 // If no field is set in the Oneof, skip all the fields in the Oneof 157 continue; 158 } 159 // Get the pointer to the only field which is set in the Oneof 160 field = getOneofFieldDescriptor(oneofDescriptor); 161 } else { 162 // If we are not in a Oneof, we need to check if the field is set and if it is repeated 163 if (field.isRepeated()) { 164 final List<?> value = (List<?>) getField(field); 165 if (!value.isEmpty()) { 166 result.put(field, value); 167 } 168 continue; 169 } 170 if (!hasField(field)) { 171 continue; 172 } 173 } 174 // Add the field to the map 175 if (getBytesForString && field.getJavaType() == FieldDescriptor.JavaType.STRING) { 176 result.put(field, getFieldRaw(field)); 177 } else { 178 result.put(field, getField(field)); 179 } 180 } 181 return result; 182 } 183 184 // TODO: compute this at {@code build()} time in the Builder class. 185 @Override isInitialized()186 public boolean isInitialized() { 187 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 188 // Check that all required fields are present. 189 if (field.isRequired()) { 190 if (!hasField(field)) { 191 return false; 192 } 193 } 194 // Check that embedded messages are initialized. 195 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 196 if (field.isRepeated()) { 197 @SuppressWarnings("unchecked") 198 final List<Message> messageList = (List<Message>) getField(field); 199 for (final Message element : messageList) { 200 if (!element.isInitialized()) { 201 return false; 202 } 203 } 204 } else { 205 if (hasField(field) && !((Message) getField(field)).isInitialized()) { 206 return false; 207 } 208 } 209 } 210 } 211 212 return true; 213 } 214 215 @Override getAllFields()216 public Map<FieldDescriptor, Object> getAllFields() { 217 return Collections.unmodifiableMap(getAllFieldsMutable(/* getBytesForString= */ false)); 218 } 219 220 /** 221 * Returns a collection of all the fields in this message which are set and their corresponding 222 * values. A singular ("required" or "optional") field is set iff hasField() returns true for that 223 * field. A "repeated" field is set iff getRepeatedFieldCount() is greater than zero. The values 224 * are exactly what would be returned by calling {@link #getFieldRaw(Descriptors.FieldDescriptor)} 225 * for each field. The map is guaranteed to be a sorted map, so iterating over it will return 226 * fields in order by field number. 227 */ getAllFieldsRaw()228 Map<FieldDescriptor, Object> getAllFieldsRaw() { 229 return Collections.unmodifiableMap(getAllFieldsMutable(/* getBytesForString= */ true)); 230 } 231 232 @Override hasOneof(final OneofDescriptor oneof)233 public boolean hasOneof(final OneofDescriptor oneof) { 234 return internalGetFieldAccessorTable().getOneof(oneof).has(this); 235 } 236 237 @Override getOneofFieldDescriptor(final OneofDescriptor oneof)238 public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) { 239 return internalGetFieldAccessorTable().getOneof(oneof).get(this); 240 } 241 242 @Override hasField(final FieldDescriptor field)243 public boolean hasField(final FieldDescriptor field) { 244 return internalGetFieldAccessorTable().getField(field).has(this); 245 } 246 247 @Override getField(final FieldDescriptor field)248 public Object getField(final FieldDescriptor field) { 249 return internalGetFieldAccessorTable().getField(field).get(this); 250 } 251 252 /** 253 * Obtains the value of the given field, or the default value if it is not set. For primitive 254 * fields, the boxed primitive value is returned. For enum fields, the EnumValueDescriptor for the 255 * value is returned. For embedded message fields, the sub-message is returned. For repeated 256 * fields, a java.util.List is returned. For present string fields, a ByteString is returned 257 * representing the bytes that the field contains. 258 */ getFieldRaw(final FieldDescriptor field)259 Object getFieldRaw(final FieldDescriptor field) { 260 return internalGetFieldAccessorTable().getField(field).getRaw(this); 261 } 262 263 @Override getRepeatedFieldCount(final FieldDescriptor field)264 public int getRepeatedFieldCount(final FieldDescriptor field) { 265 return internalGetFieldAccessorTable().getField(field).getRepeatedCount(this); 266 } 267 268 @Override getRepeatedField(final FieldDescriptor field, final int index)269 public Object getRepeatedField(final FieldDescriptor field, final int index) { 270 return internalGetFieldAccessorTable().getField(field).getRepeated(this, index); 271 } 272 273 // TODO: This method should be final. 274 @Override getUnknownFields()275 public UnknownFieldSet getUnknownFields() { 276 return unknownFields; 277 } 278 279 // TODO: This should go away when Schema classes cannot modify immutable 280 // GeneratedMessage objects anymore. setUnknownFields(UnknownFieldSet unknownFields)281 void setUnknownFields(UnknownFieldSet unknownFields) { 282 this.unknownFields = unknownFields; 283 } 284 285 /** 286 * Called by subclasses to parse an unknown field. 287 * 288 * <p>TODO remove this method 289 * 290 * @return {@code true} unless the tag is an end-group tag. 291 */ parseUnknownField( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, int tag)292 protected boolean parseUnknownField( 293 CodedInputStream input, 294 UnknownFieldSet.Builder unknownFields, 295 ExtensionRegistryLite extensionRegistry, 296 int tag) 297 throws IOException { 298 if (input.shouldDiscardUnknownFields()) { 299 return input.skipField(tag); 300 } 301 return unknownFields.mergeFieldFrom(tag, input); 302 } 303 304 /** 305 * Delegates to parseUnknownField. This method is obsolete, but we must retain it for 306 * compatibility with older generated code. 307 * 308 * <p>TODO remove this method 309 */ parseUnknownFieldProto3( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, int tag)310 protected boolean parseUnknownFieldProto3( 311 CodedInputStream input, 312 UnknownFieldSet.Builder unknownFields, 313 ExtensionRegistryLite extensionRegistry, 314 int tag) 315 throws IOException { 316 return parseUnknownField(input, unknownFields, extensionRegistry, tag); 317 } 318 319 /** Used by generated code. */ 320 @SuppressWarnings("ProtoParseWithRegistry") parseWithIOException(Parser<M> parser, InputStream input)321 protected static <M extends Message> M parseWithIOException(Parser<M> parser, InputStream input) 322 throws IOException { 323 try { 324 return parser.parseFrom(input); 325 } catch (InvalidProtocolBufferException e) { 326 throw e.unwrapIOException(); 327 } 328 } 329 330 /** Used by generated code. */ parseWithIOException( Parser<M> parser, InputStream input, ExtensionRegistryLite extensions)331 protected static <M extends Message> M parseWithIOException( 332 Parser<M> parser, InputStream input, ExtensionRegistryLite extensions) throws IOException { 333 try { 334 return parser.parseFrom(input, extensions); 335 } catch (InvalidProtocolBufferException e) { 336 throw e.unwrapIOException(); 337 } 338 } 339 340 /** Used by generated code. */ 341 @SuppressWarnings("ProtoParseWithRegistry") parseWithIOException( Parser<M> parser, CodedInputStream input)342 protected static <M extends Message> M parseWithIOException( 343 Parser<M> parser, CodedInputStream input) throws IOException { 344 try { 345 return parser.parseFrom(input); 346 } catch (InvalidProtocolBufferException e) { 347 throw e.unwrapIOException(); 348 } 349 } 350 351 /** Used by generated code. */ parseWithIOException( Parser<M> parser, CodedInputStream input, ExtensionRegistryLite extensions)352 protected static <M extends Message> M parseWithIOException( 353 Parser<M> parser, CodedInputStream input, ExtensionRegistryLite extensions) 354 throws IOException { 355 try { 356 return parser.parseFrom(input, extensions); 357 } catch (InvalidProtocolBufferException e) { 358 throw e.unwrapIOException(); 359 } 360 } 361 362 /** Used by generated code. */ 363 @SuppressWarnings("ProtoParseWithRegistry") parseDelimitedWithIOException( Parser<M> parser, InputStream input)364 protected static <M extends Message> M parseDelimitedWithIOException( 365 Parser<M> parser, InputStream input) throws IOException { 366 try { 367 return parser.parseDelimitedFrom(input); 368 } catch (InvalidProtocolBufferException e) { 369 throw e.unwrapIOException(); 370 } 371 } 372 373 /** Used by generated code. */ parseDelimitedWithIOException( Parser<M> parser, InputStream input, ExtensionRegistryLite extensions)374 protected static <M extends Message> M parseDelimitedWithIOException( 375 Parser<M> parser, InputStream input, ExtensionRegistryLite extensions) throws IOException { 376 try { 377 return parser.parseDelimitedFrom(input, extensions); 378 } catch (InvalidProtocolBufferException e) { 379 throw e.unwrapIOException(); 380 } 381 } 382 canUseUnsafe()383 protected static boolean canUseUnsafe() { 384 return UnsafeUtil.hasUnsafeArrayOperations() && UnsafeUtil.hasUnsafeByteBufferOperations(); 385 } 386 emptyIntList()387 protected static IntList emptyIntList() { 388 return IntArrayList.emptyList(); 389 } 390 emptyLongList()391 protected static LongList emptyLongList() { 392 return LongArrayList.emptyList(); 393 } 394 emptyFloatList()395 protected static FloatList emptyFloatList() { 396 return FloatArrayList.emptyList(); 397 } 398 emptyDoubleList()399 protected static DoubleList emptyDoubleList() { 400 return DoubleArrayList.emptyList(); 401 } 402 emptyBooleanList()403 protected static BooleanList emptyBooleanList() { 404 return BooleanArrayList.emptyList(); 405 } 406 makeMutableCopy(ListT list)407 protected static <ListT extends ProtobufList<?>> ListT makeMutableCopy(ListT list) { 408 return makeMutableCopy(list, 0); 409 } 410 411 @SuppressWarnings("unchecked") // Guaranteed by proto runtime. makeMutableCopy( ListT list, int minCapacity)412 protected static <ListT extends ProtobufList<?>> ListT makeMutableCopy( 413 ListT list, int minCapacity) { 414 int size = list.size(); 415 if (minCapacity <= size) { 416 minCapacity = size * 2; 417 } 418 if (minCapacity <= 0) { 419 minCapacity = AbstractProtobufList.DEFAULT_CAPACITY; 420 } 421 422 return (ListT) list.mutableCopyWithCapacity(minCapacity); 423 } 424 425 @SuppressWarnings("unchecked") // The empty list can be safely cast emptyList(Class<T> elementType)426 protected static <T> ProtobufList<T> emptyList(Class<T> elementType) { 427 return (ProtobufList<T>) ProtobufArrayList.emptyList(); 428 } 429 430 @Override writeTo(final CodedOutputStream output)431 public void writeTo(final CodedOutputStream output) throws IOException { 432 MessageReflection.writeMessageTo(this, getAllFieldsRaw(), output, false); 433 } 434 435 @Override getSerializedSize()436 public int getSerializedSize() { 437 int size = memoizedSize; 438 if (size != -1) { 439 return size; 440 } 441 442 memoizedSize = MessageReflection.getSerializedSize( 443 this, getAllFieldsRaw()); 444 return memoizedSize; 445 } 446 447 /** 448 * This class is used to make a generated protected method inaccessible from user's code (e.g., 449 * the {@link #newInstance} method below). When this class is used as a parameter's type in a 450 * generated protected method, the method is visible to user's code in the same package, but since 451 * the constructor of this class is private to protobuf runtime, user's code can't obtain an 452 * instance of this class and as such can't actually make a method call on the protected method. 453 */ 454 protected static final class UnusedPrivateParameter { 455 static final UnusedPrivateParameter INSTANCE = new UnusedPrivateParameter(); 456 UnusedPrivateParameter()457 private UnusedPrivateParameter() {} 458 } 459 460 /** Creates a new instance of this message type. Overridden in the generated code. */ 461 @SuppressWarnings({"unused"}) newInstance(UnusedPrivateParameter unused)462 protected Object newInstance(UnusedPrivateParameter unused) { 463 throw new UnsupportedOperationException("This method must be overridden by the subclass."); 464 } 465 466 /** Builder class for {@link GeneratedMessage}. */ 467 @SuppressWarnings("unchecked") 468 public abstract static class Builder<BuilderT extends Builder<BuilderT>> 469 extends AbstractMessage.Builder<BuilderT> { 470 471 private BuilderParent builderParent; 472 473 private BuilderParentImpl meAsParent; 474 475 // Indicates that we've built a message and so we are now obligated 476 // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener. 477 private boolean isClean; 478 479 /** 480 * This field holds either an {@link UnknownFieldSet} or {@link UnknownFieldSet.Builder}. 481 * 482 * <p>We use an object because it should only be one or the other of those things at a time and 483 * Object is the only common base. This also saves space. 484 * 485 * <p>Conversions are lazy: if {@link #setUnknownFields} is called, this will contain {@link 486 * UnknownFieldSet}. If unknown fields are merged into this builder, the current {@link 487 * UnknownFieldSet} will be converted to a {@link UnknownFieldSet.Builder} and left that way 488 * until either {@link #setUnknownFields} or {@link #buildPartial} or {@link #build} is called. 489 */ 490 private Object unknownFieldsOrBuilder = UnknownFieldSet.getDefaultInstance(); 491 Builder()492 protected Builder() {} 493 Builder(BuilderParent builderParent)494 protected Builder(BuilderParent builderParent) { 495 this.builderParent = builderParent; 496 } 497 498 @Override dispose()499 void dispose() { 500 builderParent = null; 501 } 502 503 /** Called by the subclass when a message is built. */ onBuilt()504 protected void onBuilt() { 505 if (builderParent != null) { 506 markClean(); 507 } 508 } 509 510 /** 511 * Called by the subclass or a builder to notify us that a message was built and may be cached 512 * and therefore invalidations are needed. 513 */ 514 @Override markClean()515 protected void markClean() { 516 this.isClean = true; 517 } 518 519 /** 520 * Gets whether invalidations are needed 521 * 522 * @return whether invalidations are needed 523 */ isClean()524 protected boolean isClean() { 525 return isClean; 526 } 527 528 @Override clone()529 public BuilderT clone() { 530 BuilderT builder = (BuilderT) getDefaultInstanceForType().newBuilderForType(); 531 builder.mergeFrom(buildPartial()); 532 return builder; 533 } 534 535 /** 536 * Called by the initialization and clear code paths to allow subclasses to reset any of their 537 * builtin fields back to the initial values. 538 */ 539 @Override clear()540 public BuilderT clear() { 541 unknownFieldsOrBuilder = UnknownFieldSet.getDefaultInstance(); 542 onChanged(); 543 return (BuilderT) this; 544 } 545 546 /** 547 * Get the FieldAccessorTable for this type. We can't have the message class pass this in to the 548 * constructor because of bootstrapping trouble with DescriptorProtos. 549 */ internalGetFieldAccessorTable()550 protected abstract FieldAccessorTable internalGetFieldAccessorTable(); 551 552 @Override getDescriptorForType()553 public Descriptor getDescriptorForType() { 554 return internalGetFieldAccessorTable().descriptor; 555 } 556 557 @Override getAllFields()558 public Map<FieldDescriptor, Object> getAllFields() { 559 return Collections.unmodifiableMap(getAllFieldsMutable()); 560 } 561 562 /** Internal helper which returns a mutable map. */ getAllFieldsMutable()563 private Map<FieldDescriptor, Object> getAllFieldsMutable() { 564 final TreeMap<FieldDescriptor, Object> result = new TreeMap<>(); 565 final FieldAccessorTable fieldAccessorTable = internalGetFieldAccessorTable(); 566 final Descriptor descriptor = fieldAccessorTable.descriptor; 567 final List<FieldDescriptor> fields = descriptor.getFields(); 568 569 for (int i = 0; i < fields.size(); i++) { 570 FieldDescriptor field = fields.get(i); 571 final OneofDescriptor oneofDescriptor = field.getContainingOneof(); 572 573 /* 574 * If the field is part of a Oneof, then at maximum one field in the Oneof is set 575 * and it is not repeated. There is no need to iterate through the others. 576 */ 577 if (oneofDescriptor != null) { 578 // Skip other fields in the Oneof we know are not set 579 i += oneofDescriptor.getFieldCount() - 1; 580 if (!hasOneof(oneofDescriptor)) { 581 // If no field is set in the Oneof, skip all the fields in the Oneof 582 continue; 583 } 584 // Get the pointer to the only field which is set in the Oneof 585 field = getOneofFieldDescriptor(oneofDescriptor); 586 } else { 587 // If we are not in a Oneof, we need to check if the field is set and if it is repeated 588 if (field.isRepeated()) { 589 final List<?> value = (List<?>) getField(field); 590 if (!value.isEmpty()) { 591 result.put(field, value); 592 } 593 continue; 594 } 595 if (!hasField(field)) { 596 continue; 597 } 598 } 599 // Add the field to the map 600 result.put(field, getField(field)); 601 } 602 return result; 603 } 604 605 @Override newBuilderForField(final FieldDescriptor field)606 public Message.Builder newBuilderForField(final FieldDescriptor field) { 607 return internalGetFieldAccessorTable().getField(field).newBuilder(); 608 } 609 610 @Override getFieldBuilder(final FieldDescriptor field)611 public Message.Builder getFieldBuilder(final FieldDescriptor field) { 612 return internalGetFieldAccessorTable().getField(field).getBuilder(this); 613 } 614 615 @Override getRepeatedFieldBuilder(final FieldDescriptor field, int index)616 public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, int index) { 617 return internalGetFieldAccessorTable().getField(field).getRepeatedBuilder(this, index); 618 } 619 620 @Override hasOneof(final OneofDescriptor oneof)621 public boolean hasOneof(final OneofDescriptor oneof) { 622 return internalGetFieldAccessorTable().getOneof(oneof).has(this); 623 } 624 625 @Override getOneofFieldDescriptor(final OneofDescriptor oneof)626 public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) { 627 return internalGetFieldAccessorTable().getOneof(oneof).get(this); 628 } 629 630 @Override hasField(final FieldDescriptor field)631 public boolean hasField(final FieldDescriptor field) { 632 return internalGetFieldAccessorTable().getField(field).has(this); 633 } 634 635 @Override getField(final FieldDescriptor field)636 public Object getField(final FieldDescriptor field) { 637 Object object = internalGetFieldAccessorTable().getField(field).get(this); 638 if (field.isRepeated()) { 639 // The underlying list object is still modifiable at this point. 640 // Make sure not to expose the modifiable list to the caller. 641 return Collections.unmodifiableList((List<?>) object); 642 } else { 643 return object; 644 } 645 } 646 647 @Override setField(final FieldDescriptor field, final Object value)648 public BuilderT setField(final FieldDescriptor field, final Object value) { 649 internalGetFieldAccessorTable().getField(field).set(this, value); 650 return (BuilderT) this; 651 } 652 653 @Override clearField(final FieldDescriptor field)654 public BuilderT clearField(final FieldDescriptor field) { 655 internalGetFieldAccessorTable().getField(field).clear(this); 656 return (BuilderT) this; 657 } 658 659 @Override clearOneof(final OneofDescriptor oneof)660 public BuilderT clearOneof(final OneofDescriptor oneof) { 661 internalGetFieldAccessorTable().getOneof(oneof).clear(this); 662 return (BuilderT) this; 663 } 664 665 @Override getRepeatedFieldCount(final FieldDescriptor field)666 public int getRepeatedFieldCount(final FieldDescriptor field) { 667 return internalGetFieldAccessorTable().getField(field).getRepeatedCount(this); 668 } 669 670 @Override getRepeatedField(final FieldDescriptor field, final int index)671 public Object getRepeatedField(final FieldDescriptor field, final int index) { 672 return internalGetFieldAccessorTable().getField(field).getRepeated(this, index); 673 } 674 675 @Override setRepeatedField( final FieldDescriptor field, final int index, final Object value)676 public BuilderT setRepeatedField( 677 final FieldDescriptor field, final int index, final Object value) { 678 internalGetFieldAccessorTable().getField(field).setRepeated(this, index, value); 679 return (BuilderT) this; 680 } 681 682 @Override addRepeatedField(final FieldDescriptor field, final Object value)683 public BuilderT addRepeatedField(final FieldDescriptor field, final Object value) { 684 internalGetFieldAccessorTable().getField(field).addRepeated(this, value); 685 return (BuilderT) this; 686 } 687 setUnknownFieldsInternal(final UnknownFieldSet unknownFields)688 private BuilderT setUnknownFieldsInternal(final UnknownFieldSet unknownFields) { 689 unknownFieldsOrBuilder = unknownFields; 690 onChanged(); 691 return (BuilderT) this; 692 } 693 694 @Override setUnknownFields(final UnknownFieldSet unknownFields)695 public BuilderT setUnknownFields(final UnknownFieldSet unknownFields) { 696 return setUnknownFieldsInternal(unknownFields); 697 } 698 699 /** 700 * This method is obsolete, but we must retain it for compatibility with older generated code. 701 */ setUnknownFieldsProto3(final UnknownFieldSet unknownFields)702 protected BuilderT setUnknownFieldsProto3(final UnknownFieldSet unknownFields) { 703 return setUnknownFieldsInternal(unknownFields); 704 } 705 706 @Override mergeUnknownFields(final UnknownFieldSet unknownFields)707 public BuilderT mergeUnknownFields(final UnknownFieldSet unknownFields) { 708 if (UnknownFieldSet.getDefaultInstance().equals(unknownFields)) { 709 return (BuilderT) this; 710 } 711 712 if (UnknownFieldSet.getDefaultInstance().equals(unknownFieldsOrBuilder)) { 713 unknownFieldsOrBuilder = unknownFields; 714 onChanged(); 715 return (BuilderT) this; 716 } 717 718 getUnknownFieldSetBuilder().mergeFrom(unknownFields); 719 onChanged(); 720 return (BuilderT) this; 721 } 722 723 @Override isInitialized()724 public boolean isInitialized() { 725 for (final FieldDescriptor field : getDescriptorForType().getFields()) { 726 // Check that all required fields are present. 727 if (field.isRequired()) { 728 if (!hasField(field)) { 729 return false; 730 } 731 } 732 // Check that embedded messages are initialized. 733 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 734 if (field.isRepeated()) { 735 @SuppressWarnings("unchecked") 736 final List<Message> messageList = (List<Message>) getField(field); 737 for (final Message element : messageList) { 738 if (!element.isInitialized()) { 739 return false; 740 } 741 } 742 } else { 743 if (hasField(field) && !((Message) getField(field)).isInitialized()) { 744 return false; 745 } 746 } 747 } 748 } 749 return true; 750 } 751 752 @Override getUnknownFields()753 public final UnknownFieldSet getUnknownFields() { 754 if (unknownFieldsOrBuilder instanceof UnknownFieldSet) { 755 return (UnknownFieldSet) unknownFieldsOrBuilder; 756 } else { 757 return ((UnknownFieldSet.Builder) unknownFieldsOrBuilder).buildPartial(); 758 } 759 } 760 761 /** 762 * Called by generated subclasses to parse an unknown field. 763 * 764 * @return {@code true} unless the tag is an end-group tag. 765 */ parseUnknownField( CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)766 protected boolean parseUnknownField( 767 CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag) 768 throws IOException { 769 if (input.shouldDiscardUnknownFields()) { 770 return input.skipField(tag); 771 } 772 return getUnknownFieldSetBuilder().mergeFieldFrom(tag, input); 773 } 774 775 /** Called by generated subclasses to add to the unknown field set. */ mergeUnknownLengthDelimitedField(int number, ByteString bytes)776 protected final void mergeUnknownLengthDelimitedField(int number, ByteString bytes) { 777 getUnknownFieldSetBuilder().mergeLengthDelimitedField(number, bytes); 778 } 779 780 /** Called by generated subclasses to add to the unknown field set. */ mergeUnknownVarintField(int number, int value)781 protected final void mergeUnknownVarintField(int number, int value) { 782 getUnknownFieldSetBuilder().mergeVarintField(number, value); 783 } 784 785 @Override getUnknownFieldSetBuilder()786 protected UnknownFieldSet.Builder getUnknownFieldSetBuilder() { 787 if (unknownFieldsOrBuilder instanceof UnknownFieldSet) { 788 unknownFieldsOrBuilder = ((UnknownFieldSet) unknownFieldsOrBuilder).toBuilder(); 789 } 790 onChanged(); 791 return (UnknownFieldSet.Builder) unknownFieldsOrBuilder; 792 } 793 794 @Override setUnknownFieldSetBuilder(UnknownFieldSet.Builder builder)795 protected void setUnknownFieldSetBuilder(UnknownFieldSet.Builder builder) { 796 unknownFieldsOrBuilder = builder; 797 onChanged(); 798 } 799 800 /** 801 * Implementation of {@link BuilderParent} for giving to our children. This small inner class 802 * makes it so we don't publicly expose the BuilderParent methods. 803 */ 804 private class BuilderParentImpl implements BuilderParent { 805 806 @Override markDirty()807 public void markDirty() { 808 onChanged(); 809 } 810 } 811 812 /** 813 * Gets the {@link BuilderParent} for giving to our children. 814 * 815 * @return The builder parent for our children. 816 */ getParentForChildren()817 protected BuilderParent getParentForChildren() { 818 if (meAsParent == null) { 819 meAsParent = new BuilderParentImpl(); 820 } 821 return meAsParent; 822 } 823 824 /** 825 * Called when a builder or one of its nested children has changed and any parent should be 826 * notified of its invalidation. 827 */ onChanged()828 protected final void onChanged() { 829 if (isClean && builderParent != null) { 830 builderParent.markDirty(); 831 832 // Don't keep dispatching invalidations until build is called again. 833 isClean = false; 834 } 835 } 836 837 /** 838 * Gets the map field with the given field number. This method should be overridden in the 839 * generated message class if the message contains map fields. 840 * 841 * <p>Unlike other field types, reflection support for map fields can't be implemented based on 842 * generated public API because we need to access a map field as a list in reflection API but 843 * the generated API only allows us to access it as a map. This method returns the underlying 844 * map field directly and thus enables us to access the map field as a list. 845 */ 846 @SuppressWarnings("unused") internalGetMapFieldReflection(int fieldNumber)847 protected MapFieldReflectionAccessor internalGetMapFieldReflection(int fieldNumber) { 848 return internalGetMapField(fieldNumber); 849 } 850 851 /** TODO: Remove, exists for compatibility with generated code. */ 852 @Deprecated 853 @SuppressWarnings({"unused", "rawtypes"}) internalGetMapField(int fieldNumber)854 protected MapField internalGetMapField(int fieldNumber) { 855 // Note that we can't use descriptor names here because this method will 856 // be called when descriptor is being initialized. 857 throw new IllegalArgumentException("No map fields found in " + getClass().getName()); 858 } 859 860 /** Like {@link #internalGetMapFieldReflection} but return a mutable version. */ 861 @SuppressWarnings("unused") internalGetMutableMapFieldReflection(int fieldNumber)862 protected MapFieldReflectionAccessor internalGetMutableMapFieldReflection(int fieldNumber) { 863 return internalGetMutableMapField(fieldNumber); 864 } 865 866 /** TODO: Remove, exists for compatibility with generated code. */ 867 @Deprecated 868 @SuppressWarnings({"unused", "rawtypes"}) internalGetMutableMapField(int fieldNumber)869 protected MapField internalGetMutableMapField(int fieldNumber) { 870 // Note that we can't use descriptor names here because this method will 871 // be called when descriptor is being initialized. 872 throw new IllegalArgumentException("No map fields found in " + getClass().getName()); 873 } 874 } 875 876 // ================================================================= 877 // Extensions-related stuff 878 879 /** Extends {@link MessageOrBuilder} with extension-related functions. */ 880 public interface ExtendableMessageOrBuilder<MessageT extends ExtendableMessage<MessageT>> 881 extends MessageOrBuilder { 882 // Re-define for return type covariance. 883 @Override getDefaultInstanceForType()884 Message getDefaultInstanceForType(); 885 886 /** Check if a singular extension is present. */ hasExtension(ExtensionLite<? extends MessageT, T> extension)887 <T> boolean hasExtension(ExtensionLite<? extends MessageT, T> extension); 888 889 /** Get the number of elements in a repeated extension. */ getExtensionCount(ExtensionLite<? extends MessageT, List<T>> extension)890 <T> int getExtensionCount(ExtensionLite<? extends MessageT, List<T>> extension); 891 892 /** Get the value of an extension. */ getExtension(ExtensionLite<? extends MessageT, T> extension)893 <T> T getExtension(ExtensionLite<? extends MessageT, T> extension); 894 895 /** Get one element of a repeated extension. */ getExtension(ExtensionLite<? extends MessageT, List<T>> extension, int index)896 <T> T getExtension(ExtensionLite<? extends MessageT, List<T>> extension, int index); 897 } 898 899 /** 900 * Generated message classes for message types that contain extension ranges subclass this. 901 * 902 * <p>This class implements type-safe accessors for extensions. They implement all the same 903 * operations that you can do with normal fields -- e.g. "has", "get", and "getCount" -- but for 904 * extensions. The extensions are identified using instances of the class {@link 905 * GeneratedExtension}; the protocol compiler generates a static instance of this class for every 906 * extension in its input. Through the magic of generics, all is made type-safe. 907 * 908 * <p>For example, imagine you have the {@code .proto} file: 909 * 910 * <pre> 911 * option java_class = "MyProto"; 912 * 913 * message Foo { 914 * extensions 1000 to max; 915 * } 916 * 917 * extend Foo { 918 * optional int32 bar; 919 * } 920 * </pre> 921 * 922 * <p>Then you might write code like: 923 * 924 * <pre> 925 * MyProto.Foo foo = getFoo(); 926 * int i = foo.getExtension(MyProto.bar); 927 * </pre> 928 * 929 * <p>See also {@link ExtendableBuilder}. 930 */ 931 public abstract static class ExtendableMessage<MessageT extends ExtendableMessage<MessageT>> 932 extends GeneratedMessage implements ExtendableMessageOrBuilder<MessageT> { 933 934 private static final long serialVersionUID = 1L; 935 936 private final FieldSet<FieldDescriptor> extensions; 937 ExtendableMessage()938 protected ExtendableMessage() { 939 this.extensions = FieldSet.newFieldSet(); 940 } 941 ExtendableMessage(ExtendableBuilder<MessageT, ?> builder)942 protected ExtendableMessage(ExtendableBuilder<MessageT, ?> builder) { 943 super(builder); 944 this.extensions = builder.buildExtensions(); 945 } 946 verifyExtensionContainingType(final Extension<? extends MessageT, ?> extension)947 private void verifyExtensionContainingType(final Extension<? extends MessageT, ?> extension) { 948 if (extension.getDescriptor().getContainingType() != getDescriptorForType()) { 949 // This can only happen if someone uses unchecked operations. 950 throw new IllegalArgumentException( 951 "Extension is for type \"" 952 + extension.getDescriptor().getContainingType().getFullName() 953 + "\" which does not match message type \"" 954 + getDescriptorForType().getFullName() 955 + "\"."); 956 } 957 } 958 959 /** Check if a singular extension is present. */ 960 @Override hasExtension( final ExtensionLite<? extends MessageT, T> extensionLite)961 public final <T> boolean hasExtension( 962 final ExtensionLite<? extends MessageT, T> extensionLite) { 963 Extension<MessageT, T> extension = checkNotLite(extensionLite); 964 965 verifyExtensionContainingType(extension); 966 return extensions.hasField(extension.getDescriptor()); 967 } 968 969 /** Get the number of elements in a repeated extension. */ 970 @Override getExtensionCount( final ExtensionLite<? extends MessageT, List<T>> extensionLite)971 public final <T> int getExtensionCount( 972 final ExtensionLite<? extends MessageT, List<T>> extensionLite) { 973 Extension<MessageT, List<T>> extension = checkNotLite(extensionLite); 974 975 verifyExtensionContainingType(extension); 976 final FieldDescriptor descriptor = extension.getDescriptor(); 977 return extensions.getRepeatedFieldCount(descriptor); 978 } 979 980 /** Get the value of an extension. */ 981 @Override 982 @SuppressWarnings("unchecked") getExtension(final ExtensionLite<? extends MessageT, T> extensionLite)983 public final <T> T getExtension(final ExtensionLite<? extends MessageT, T> extensionLite) { 984 Extension<MessageT, T> extension = checkNotLite(extensionLite); 985 986 verifyExtensionContainingType(extension); 987 FieldDescriptor descriptor = extension.getDescriptor(); 988 final Object value = extensions.getField(descriptor); 989 if (value == null) { 990 if (descriptor.isRepeated()) { 991 return (T) ProtobufArrayList.emptyList(); 992 } else if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 993 return (T) extension.getMessageDefaultInstance(); 994 } else { 995 return (T) extension.fromReflectionType(descriptor.getDefaultValue()); 996 } 997 } else { 998 return (T) extension.fromReflectionType(value); 999 } 1000 } 1001 1002 /** Get one element of a repeated extension. */ 1003 @Override 1004 @SuppressWarnings("unchecked") getExtension( final ExtensionLite<? extends MessageT, List<T>> extensionLite, final int index)1005 public final <T> T getExtension( 1006 final ExtensionLite<? extends MessageT, List<T>> extensionLite, final int index) { 1007 Extension<MessageT, List<T>> extension = checkNotLite(extensionLite); 1008 1009 verifyExtensionContainingType(extension); 1010 FieldDescriptor descriptor = extension.getDescriptor(); 1011 return (T) 1012 extension.singularFromReflectionType(extensions.getRepeatedField(descriptor, index)); 1013 } 1014 1015 /** Called by subclasses to check if all extensions are initialized. */ extensionsAreInitialized()1016 protected boolean extensionsAreInitialized() { 1017 return extensions.isInitialized(); 1018 } 1019 1020 // TODO: compute this in the builder at {@code build()} time. 1021 @Override isInitialized()1022 public boolean isInitialized() { 1023 return super.isInitialized() && extensionsAreInitialized(); 1024 } 1025 1026 /** 1027 * Used by subclasses to serialize extensions. Extension ranges may be interleaved with field 1028 * numbers, but we must write them in canonical (sorted by field number) order. 1029 * ExtensionSerializer helps us write individual ranges of extensions at once. 1030 */ 1031 protected interface ExtensionSerializer { writeUntil(final int end, final CodedOutputStream output)1032 public void writeUntil(final int end, final CodedOutputStream output) throws IOException; 1033 } 1034 1035 /** No-op implementation that writes nothing, for messages with no extensions. */ 1036 private static final class NoOpExtensionSerializer implements ExtensionSerializer { 1037 // Singleton instance so we can avoid allocating a new one for each message serialization. 1038 private static final NoOpExtensionSerializer INSTANCE = new NoOpExtensionSerializer(); 1039 1040 @Override writeUntil(final int end, final CodedOutputStream output)1041 public void writeUntil(final int end, final CodedOutputStream output) { 1042 // no-op 1043 } 1044 } 1045 1046 /** 1047 * ExtensionSerializer that writes extensions from the FieldSet, for messages with extensions. 1048 */ 1049 protected class ExtensionWriter implements ExtensionSerializer { 1050 // Imagine how much simpler this code would be if Java iterators had 1051 // a way to get the next element without advancing the iterator. 1052 1053 private final Iterator<Map.Entry<FieldDescriptor, Object>> iter = extensions.iterator(); 1054 private Map.Entry<FieldDescriptor, Object> next; 1055 private final boolean messageSetWireFormat; 1056 1057 // TODO: Should be marked private in v5.x.x once GeneratedMessageV3 is removed. ExtensionWriter(final boolean messageSetWireFormat)1058 protected ExtensionWriter(final boolean messageSetWireFormat) { 1059 if (iter.hasNext()) { 1060 next = iter.next(); 1061 } 1062 this.messageSetWireFormat = messageSetWireFormat; 1063 } 1064 1065 @Override writeUntil(final int end, final CodedOutputStream output)1066 public void writeUntil(final int end, final CodedOutputStream output) throws IOException { 1067 while (next != null && next.getKey().getNumber() < end) { 1068 FieldDescriptor descriptor = next.getKey(); 1069 if (messageSetWireFormat 1070 && descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE 1071 && !descriptor.isRepeated()) { 1072 if (next instanceof LazyField.LazyEntry<?>) { 1073 output.writeRawMessageSetExtension( 1074 descriptor.getNumber(), 1075 ((LazyField.LazyEntry<?>) next).getField().toByteString()); 1076 } else { 1077 output.writeMessageSetExtension(descriptor.getNumber(), (Message) next.getValue()); 1078 } 1079 } else { 1080 // TODO: Taken care of following code, it may cause 1081 // problem when we use LazyField for normal fields/extensions. 1082 // Due to the optional field can be duplicated at the end of 1083 // serialized bytes, which will make the serialized size change 1084 // after lazy field parsed. So when we use LazyField globally, 1085 // we need to change the following write method to write cached 1086 // bytes directly rather than write the parsed message. 1087 FieldSet.writeField(descriptor, next.getValue(), output); 1088 } 1089 if (iter.hasNext()) { 1090 next = iter.next(); 1091 } else { 1092 next = null; 1093 } 1094 } 1095 } 1096 } 1097 1098 /** 1099 * For compatibility with older gencode. 1100 * 1101 * <p> TODO Remove this in the next breaking release. 1102 * 1103 * @deprecated Use {@link newExtensionSerializer()} instead. 1104 */ 1105 @Deprecated newExtensionWriter()1106 protected ExtensionWriter newExtensionWriter() { 1107 return new ExtensionWriter(false); 1108 } 1109 newExtensionSerializer()1110 protected ExtensionSerializer newExtensionSerializer() { 1111 // Avoid allocation in the common case of no extensions. 1112 if (extensions.isEmpty()) { 1113 return NoOpExtensionSerializer.INSTANCE; 1114 } 1115 return new ExtensionWriter(false); 1116 } 1117 1118 // TODO: Remove, replace with newMessageSetExtensionSerializer(). newMessageSetExtensionWriter()1119 protected ExtensionWriter newMessageSetExtensionWriter() { 1120 return new ExtensionWriter(true); 1121 } 1122 newMessageSetExtensionSerializer()1123 protected ExtensionSerializer newMessageSetExtensionSerializer() { 1124 // Avoid allocation in the common case of no extensions. 1125 if (extensions.isEmpty()) { 1126 return NoOpExtensionSerializer.INSTANCE; 1127 } 1128 return new ExtensionWriter(true); 1129 } 1130 1131 /** Called by subclasses to compute the size of extensions. */ extensionsSerializedSize()1132 protected int extensionsSerializedSize() { 1133 return extensions.getSerializedSize(); 1134 } 1135 extensionsSerializedSizeAsMessageSet()1136 protected int extensionsSerializedSizeAsMessageSet() { 1137 return extensions.getMessageSetSerializedSize(); 1138 } 1139 1140 // --------------------------------------------------------------- 1141 // Reflection 1142 getExtensionFields()1143 protected Map<FieldDescriptor, Object> getExtensionFields() { 1144 return extensions.getAllFields(); 1145 } 1146 1147 @Override getAllFields()1148 public Map<FieldDescriptor, Object> getAllFields() { 1149 final Map<FieldDescriptor, Object> result = 1150 super.getAllFieldsMutable(/* getBytesForString= */ false); 1151 result.putAll(getExtensionFields()); 1152 return Collections.unmodifiableMap(result); 1153 } 1154 1155 @Override getAllFieldsRaw()1156 public Map<FieldDescriptor, Object> getAllFieldsRaw() { 1157 final Map<FieldDescriptor, Object> result = 1158 super.getAllFieldsMutable(/* getBytesForString= */ false); 1159 result.putAll(getExtensionFields()); 1160 return Collections.unmodifiableMap(result); 1161 } 1162 1163 @Override hasField(final FieldDescriptor field)1164 public boolean hasField(final FieldDescriptor field) { 1165 if (field.isExtension()) { 1166 verifyContainingType(field); 1167 return extensions.hasField(field); 1168 } else { 1169 return super.hasField(field); 1170 } 1171 } 1172 1173 @Override getField(final FieldDescriptor field)1174 public Object getField(final FieldDescriptor field) { 1175 if (field.isExtension()) { 1176 verifyContainingType(field); 1177 final Object value = extensions.getField(field); 1178 if (value == null) { 1179 if (field.isRepeated()) { 1180 return Collections.emptyList(); 1181 } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1182 // Lacking an ExtensionRegistry, we have no way to determine the 1183 // extension's real type, so we return a DynamicMessage. 1184 return DynamicMessage.getDefaultInstance(field.getMessageType()); 1185 } else { 1186 return field.getDefaultValue(); 1187 } 1188 } else { 1189 return value; 1190 } 1191 } else { 1192 return super.getField(field); 1193 } 1194 } 1195 1196 @Override getRepeatedFieldCount(final FieldDescriptor field)1197 public int getRepeatedFieldCount(final FieldDescriptor field) { 1198 if (field.isExtension()) { 1199 verifyContainingType(field); 1200 return extensions.getRepeatedFieldCount(field); 1201 } else { 1202 return super.getRepeatedFieldCount(field); 1203 } 1204 } 1205 1206 @Override getRepeatedField(final FieldDescriptor field, final int index)1207 public Object getRepeatedField(final FieldDescriptor field, final int index) { 1208 if (field.isExtension()) { 1209 verifyContainingType(field); 1210 return extensions.getRepeatedField(field, index); 1211 } else { 1212 return super.getRepeatedField(field, index); 1213 } 1214 } 1215 verifyContainingType(final FieldDescriptor field)1216 private void verifyContainingType(final FieldDescriptor field) { 1217 if (field.getContainingType() != getDescriptorForType()) { 1218 throw new IllegalArgumentException("FieldDescriptor does not match message type."); 1219 } 1220 } 1221 } 1222 1223 /** 1224 * Generated message builders for message types that contain extension ranges subclass this. 1225 * 1226 * <p>This class implements type-safe accessors for extensions. They implement all the same 1227 * operations that you can do with normal fields -- e.g. "get", "set", and "add" -- but for 1228 * extensions. The extensions are identified using instances of the class {@link 1229 * GeneratedExtension}; the protocol compiler generates a static instance of this class for every 1230 * extension in its input. Through the magic of generics, all is made type-safe. 1231 * 1232 * <p>For example, imagine you have the {@code .proto} file: 1233 * 1234 * <pre> 1235 * option java_class = "MyProto"; 1236 * 1237 * message Foo { 1238 * extensions 1000 to max; 1239 * } 1240 * 1241 * extend Foo { 1242 * optional int32 bar; 1243 * } 1244 * </pre> 1245 * 1246 * <p>Then you might write code like: 1247 * 1248 * <pre> 1249 * MyProto.Foo foo = 1250 * MyProto.Foo.newBuilder() 1251 * .setExtension(MyProto.bar, 123) 1252 * .build(); 1253 * </pre> 1254 * 1255 * <p>See also {@link ExtendableMessage}. 1256 */ 1257 @SuppressWarnings("unchecked") 1258 public abstract static class ExtendableBuilder< 1259 MessageT extends ExtendableMessage<MessageT>, 1260 BuilderT extends ExtendableBuilder<MessageT, BuilderT>> 1261 extends Builder<BuilderT> implements ExtendableMessageOrBuilder<MessageT> { 1262 1263 private FieldSet.Builder<FieldDescriptor> extensions; 1264 ExtendableBuilder()1265 protected ExtendableBuilder() {} 1266 ExtendableBuilder(BuilderParent parent)1267 protected ExtendableBuilder(BuilderParent parent) { 1268 super(parent); 1269 } 1270 1271 // For immutable message conversion. internalSetExtensionSet(FieldSet<FieldDescriptor> extensions)1272 void internalSetExtensionSet(FieldSet<FieldDescriptor> extensions) { 1273 this.extensions = FieldSet.Builder.fromFieldSet(extensions); 1274 } 1275 1276 @Override clear()1277 public BuilderT clear() { 1278 extensions = null; 1279 return super.clear(); 1280 } 1281 ensureExtensionsIsMutable()1282 private void ensureExtensionsIsMutable() { 1283 if (extensions == null) { 1284 extensions = FieldSet.newBuilder(); 1285 } 1286 } 1287 verifyExtensionContainingType(final Extension<MessageT, ?> extension)1288 private void verifyExtensionContainingType(final Extension<MessageT, ?> extension) { 1289 if (extension.getDescriptor().getContainingType() != getDescriptorForType()) { 1290 // This can only happen if someone uses unchecked operations. 1291 throw new IllegalArgumentException( 1292 "Extension is for type \"" 1293 + extension.getDescriptor().getContainingType().getFullName() 1294 + "\" which does not match message type \"" 1295 + getDescriptorForType().getFullName() 1296 + "\"."); 1297 } 1298 } 1299 1300 /** Check if a singular extension is present. */ 1301 @Override hasExtension( final ExtensionLite<? extends MessageT, T> extensionLite)1302 public final <T> boolean hasExtension( 1303 final ExtensionLite<? extends MessageT, T> extensionLite) { 1304 Extension<MessageT, T> extension = checkNotLite(extensionLite); 1305 1306 verifyExtensionContainingType(extension); 1307 return extensions != null && extensions.hasField(extension.getDescriptor()); 1308 } 1309 1310 /** Get the number of elements in a repeated extension. */ 1311 @Override getExtensionCount( final ExtensionLite<? extends MessageT, List<T>> extensionLite)1312 public final <T> int getExtensionCount( 1313 final ExtensionLite<? extends MessageT, List<T>> extensionLite) { 1314 Extension<MessageT, List<T>> extension = checkNotLite(extensionLite); 1315 1316 verifyExtensionContainingType(extension); 1317 final FieldDescriptor descriptor = extension.getDescriptor(); 1318 return extensions == null ? 0 : extensions.getRepeatedFieldCount(descriptor); 1319 } 1320 1321 /** Get the value of an extension. */ 1322 @Override getExtension(final ExtensionLite<? extends MessageT, T> extensionLite)1323 public final <T> T getExtension(final ExtensionLite<? extends MessageT, T> extensionLite) { 1324 Extension<MessageT, T> extension = checkNotLite(extensionLite); 1325 1326 verifyExtensionContainingType(extension); 1327 FieldDescriptor descriptor = extension.getDescriptor(); 1328 final Object value = extensions == null ? null : extensions.getField(descriptor); 1329 if (value == null) { 1330 if (descriptor.isRepeated()) { 1331 return (T) Collections.emptyList(); 1332 } else if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1333 return (T) extension.getMessageDefaultInstance(); 1334 } else { 1335 return (T) extension.fromReflectionType(descriptor.getDefaultValue()); 1336 } 1337 } else { 1338 return (T) extension.fromReflectionType(value); 1339 } 1340 } 1341 1342 /** Get one element of a repeated extension. */ 1343 @Override getExtension( final ExtensionLite<? extends MessageT, List<T>> extensionLite, final int index)1344 public final <T> T getExtension( 1345 final ExtensionLite<? extends MessageT, List<T>> extensionLite, final int index) { 1346 Extension<MessageT, List<T>> extension = checkNotLite(extensionLite); 1347 1348 verifyExtensionContainingType(extension); 1349 FieldDescriptor descriptor = extension.getDescriptor(); 1350 if (extensions == null) { 1351 throw new IndexOutOfBoundsException(); 1352 } 1353 return (T) 1354 extension.singularFromReflectionType(extensions.getRepeatedField(descriptor, index)); 1355 } 1356 1357 /** Set the value of an extension. */ setExtension( final ExtensionLite<? extends MessageT, T> extensionLite, final T value)1358 public final <T> BuilderT setExtension( 1359 final ExtensionLite<? extends MessageT, T> extensionLite, final T value) { 1360 Extension<MessageT, T> extension = checkNotLite(extensionLite); 1361 1362 verifyExtensionContainingType(extension); 1363 ensureExtensionsIsMutable(); 1364 final FieldDescriptor descriptor = extension.getDescriptor(); 1365 extensions.setField(descriptor, extension.toReflectionType(value)); 1366 onChanged(); 1367 return (BuilderT) this; 1368 } 1369 1370 /** Set the value of one element of a repeated extension. */ setExtension( final ExtensionLite<? extends MessageT, List<T>> extensionLite, final int index, final T value)1371 public final <T> BuilderT setExtension( 1372 final ExtensionLite<? extends MessageT, List<T>> extensionLite, 1373 final int index, 1374 final T value) { 1375 Extension<MessageT, List<T>> extension = checkNotLite(extensionLite); 1376 1377 verifyExtensionContainingType(extension); 1378 ensureExtensionsIsMutable(); 1379 final FieldDescriptor descriptor = extension.getDescriptor(); 1380 extensions.setRepeatedField(descriptor, index, extension.singularToReflectionType(value)); 1381 onChanged(); 1382 return (BuilderT) this; 1383 } 1384 1385 /** Append a value to a repeated extension. */ addExtension( final ExtensionLite<? extends MessageT, List<T>> extensionLite, final T value)1386 public final <T> BuilderT addExtension( 1387 final ExtensionLite<? extends MessageT, List<T>> extensionLite, final T value) { 1388 Extension<MessageT, List<T>> extension = checkNotLite(extensionLite); 1389 1390 verifyExtensionContainingType(extension); 1391 ensureExtensionsIsMutable(); 1392 final FieldDescriptor descriptor = extension.getDescriptor(); 1393 extensions.addRepeatedField(descriptor, extension.singularToReflectionType(value)); 1394 onChanged(); 1395 return (BuilderT) this; 1396 } 1397 1398 /** Clear an extension. */ clearExtension( final ExtensionLite<? extends MessageT, T> extensionLite)1399 public final <T> BuilderT clearExtension( 1400 final ExtensionLite<? extends MessageT, T> extensionLite) { 1401 Extension<MessageT, T> extension = checkNotLite(extensionLite); 1402 1403 verifyExtensionContainingType(extension); 1404 ensureExtensionsIsMutable(); 1405 extensions.clearField(extension.getDescriptor()); 1406 onChanged(); 1407 return (BuilderT) this; 1408 } 1409 1410 /** Called by subclasses to check if all extensions are initialized. */ extensionsAreInitialized()1411 protected boolean extensionsAreInitialized() { 1412 return extensions == null || extensions.isInitialized(); 1413 } 1414 1415 /** 1416 * Called by the build code path to create a copy of the extensions for building the message. 1417 */ buildExtensions()1418 private FieldSet<FieldDescriptor> buildExtensions() { 1419 return extensions == null 1420 ? (FieldSet<FieldDescriptor>) FieldSet.emptySet() 1421 : extensions.buildPartial(); 1422 } 1423 1424 @Override isInitialized()1425 public boolean isInitialized() { 1426 return super.isInitialized() && extensionsAreInitialized(); 1427 } 1428 1429 // --------------------------------------------------------------- 1430 // Reflection 1431 1432 @Override getAllFields()1433 public Map<FieldDescriptor, Object> getAllFields() { 1434 final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable(); 1435 if (extensions != null) { 1436 result.putAll(extensions.getAllFields()); 1437 } 1438 return Collections.unmodifiableMap(result); 1439 } 1440 1441 @Override getField(final FieldDescriptor field)1442 public Object getField(final FieldDescriptor field) { 1443 if (field.isExtension()) { 1444 verifyContainingType(field); 1445 final Object value = extensions == null ? null : extensions.getField(field); 1446 if (value == null) { 1447 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1448 // Lacking an ExtensionRegistry, we have no way to determine the 1449 // extension's real type, so we return a DynamicMessage. 1450 return DynamicMessage.getDefaultInstance(field.getMessageType()); 1451 } else { 1452 return field.getDefaultValue(); 1453 } 1454 } else { 1455 return value; 1456 } 1457 } else { 1458 return super.getField(field); 1459 } 1460 } 1461 1462 @Override getFieldBuilder(final FieldDescriptor field)1463 public Message.Builder getFieldBuilder(final FieldDescriptor field) { 1464 if (field.isExtension()) { 1465 verifyContainingType(field); 1466 if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { 1467 throw new UnsupportedOperationException( 1468 "getFieldBuilder() called on a non-Message type."); 1469 } 1470 ensureExtensionsIsMutable(); 1471 final Object value = extensions.getFieldAllowBuilders(field); 1472 if (value == null) { 1473 Message.Builder builder = DynamicMessage.newBuilder(field.getMessageType()); 1474 extensions.setField(field, builder); 1475 onChanged(); 1476 return builder; 1477 } else { 1478 if (value instanceof Message.Builder) { 1479 return (Message.Builder) value; 1480 } else if (value instanceof Message) { 1481 Message.Builder builder = ((Message) value).toBuilder(); 1482 extensions.setField(field, builder); 1483 onChanged(); 1484 return builder; 1485 } else { 1486 throw new UnsupportedOperationException( 1487 "getRepeatedFieldBuilder() called on a non-Message type."); 1488 } 1489 } 1490 } else { 1491 return super.getFieldBuilder(field); 1492 } 1493 } 1494 1495 @Override getRepeatedFieldCount(final FieldDescriptor field)1496 public int getRepeatedFieldCount(final FieldDescriptor field) { 1497 if (field.isExtension()) { 1498 verifyContainingType(field); 1499 return extensions == null ? 0 : extensions.getRepeatedFieldCount(field); 1500 } else { 1501 return super.getRepeatedFieldCount(field); 1502 } 1503 } 1504 1505 @Override getRepeatedField(final FieldDescriptor field, final int index)1506 public Object getRepeatedField(final FieldDescriptor field, final int index) { 1507 if (field.isExtension()) { 1508 verifyContainingType(field); 1509 if (extensions == null) { 1510 throw new IndexOutOfBoundsException(); 1511 } 1512 return extensions.getRepeatedField(field, index); 1513 } else { 1514 return super.getRepeatedField(field, index); 1515 } 1516 } 1517 1518 @Override getRepeatedFieldBuilder(final FieldDescriptor field, final int index)1519 public Message.Builder getRepeatedFieldBuilder(final FieldDescriptor field, final int index) { 1520 if (field.isExtension()) { 1521 verifyContainingType(field); 1522 ensureExtensionsIsMutable(); 1523 if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { 1524 throw new UnsupportedOperationException( 1525 "getRepeatedFieldBuilder() called on a non-Message type."); 1526 } 1527 final Object value = extensions.getRepeatedFieldAllowBuilders(field, index); 1528 if (value instanceof Message.Builder) { 1529 return (Message.Builder) value; 1530 } else if (value instanceof Message) { 1531 Message.Builder builder = ((Message) value).toBuilder(); 1532 extensions.setRepeatedField(field, index, builder); 1533 onChanged(); 1534 return builder; 1535 } else { 1536 throw new UnsupportedOperationException( 1537 "getRepeatedFieldBuilder() called on a non-Message type."); 1538 } 1539 } else { 1540 return super.getRepeatedFieldBuilder(field, index); 1541 } 1542 } 1543 1544 @Override hasField(final FieldDescriptor field)1545 public boolean hasField(final FieldDescriptor field) { 1546 if (field.isExtension()) { 1547 verifyContainingType(field); 1548 return extensions != null && extensions.hasField(field); 1549 } else { 1550 return super.hasField(field); 1551 } 1552 } 1553 1554 @Override setField(final FieldDescriptor field, final Object value)1555 public BuilderT setField(final FieldDescriptor field, final Object value) { 1556 if (field.isExtension()) { 1557 verifyContainingType(field); 1558 ensureExtensionsIsMutable(); 1559 extensions.setField(field, value); 1560 onChanged(); 1561 return (BuilderT) this; 1562 } else { 1563 return super.setField(field, value); 1564 } 1565 } 1566 1567 @Override clearField(final FieldDescriptor field)1568 public BuilderT clearField(final FieldDescriptor field) { 1569 if (field.isExtension()) { 1570 verifyContainingType(field); 1571 ensureExtensionsIsMutable(); 1572 extensions.clearField(field); 1573 onChanged(); 1574 return (BuilderT) this; 1575 } else { 1576 return super.clearField(field); 1577 } 1578 } 1579 1580 @Override setRepeatedField( final FieldDescriptor field, final int index, final Object value)1581 public BuilderT setRepeatedField( 1582 final FieldDescriptor field, final int index, final Object value) { 1583 if (field.isExtension()) { 1584 verifyContainingType(field); 1585 ensureExtensionsIsMutable(); 1586 extensions.setRepeatedField(field, index, value); 1587 onChanged(); 1588 return (BuilderT) this; 1589 } else { 1590 return super.setRepeatedField(field, index, value); 1591 } 1592 } 1593 1594 @Override addRepeatedField(final FieldDescriptor field, final Object value)1595 public BuilderT addRepeatedField(final FieldDescriptor field, final Object value) { 1596 if (field.isExtension()) { 1597 verifyContainingType(field); 1598 ensureExtensionsIsMutable(); 1599 extensions.addRepeatedField(field, value); 1600 onChanged(); 1601 return (BuilderT) this; 1602 } else { 1603 return super.addRepeatedField(field, value); 1604 } 1605 } 1606 1607 @Override newBuilderForField(final FieldDescriptor field)1608 public Message.Builder newBuilderForField(final FieldDescriptor field) { 1609 if (field.isExtension()) { 1610 return DynamicMessage.newBuilder(field.getMessageType()); 1611 } else { 1612 return super.newBuilderForField(field); 1613 } 1614 } 1615 1616 // TODO: Should be marked final in v5.x.x once GeneratedMessageV3 is removed. mergeExtensionFields(final ExtendableMessage<?> other)1617 protected void mergeExtensionFields(final ExtendableMessage<?> other) { 1618 if (other.extensions != null) { 1619 ensureExtensionsIsMutable(); 1620 extensions.mergeFrom(other.extensions); 1621 onChanged(); 1622 } 1623 } 1624 1625 @Override parseUnknownField( CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag)1626 protected boolean parseUnknownField( 1627 CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag) 1628 throws IOException { 1629 ensureExtensionsIsMutable(); 1630 return MessageReflection.mergeFieldFrom( 1631 input, 1632 input.shouldDiscardUnknownFields() ? null : getUnknownFieldSetBuilder(), 1633 extensionRegistry, 1634 getDescriptorForType(), 1635 new MessageReflection.ExtensionBuilderAdapter(extensions), 1636 tag); 1637 } 1638 verifyContainingType(final FieldDescriptor field)1639 private void verifyContainingType(final FieldDescriptor field) { 1640 if (field.getContainingType() != getDescriptorForType()) { 1641 throw new IllegalArgumentException("FieldDescriptor does not match message type."); 1642 } 1643 } 1644 } 1645 1646 // ----------------------------------------------------------------- 1647 1648 /** 1649 * Gets the descriptor for an extension. The implementation depends on whether the extension is 1650 * scoped in the top level of a file or scoped in a Message. 1651 */ 1652 interface ExtensionDescriptorRetriever { getDescriptor()1653 FieldDescriptor getDescriptor(); 1654 } 1655 1656 /** For use by generated code only. */ 1657 public static <ContainingT extends Message, T> newMessageScopedGeneratedExtension( final Message scope, final int descriptorIndex, final Class<?> singularType, final Message defaultInstance)1658 GeneratedExtension<ContainingT, T> newMessageScopedGeneratedExtension( 1659 final Message scope, 1660 final int descriptorIndex, 1661 final Class<?> singularType, 1662 final Message defaultInstance) { 1663 // For extensions scoped within a Message, we use the Message to resolve 1664 // the outer class's descriptor, from which the extension descriptor is 1665 // obtained. 1666 return new GeneratedExtension<>( 1667 new CachedDescriptorRetriever() { 1668 @Override 1669 public FieldDescriptor loadDescriptor() { 1670 return scope.getDescriptorForType().getExtensions().get(descriptorIndex); 1671 } 1672 }, 1673 singularType, 1674 defaultInstance, 1675 Extension.ExtensionType.IMMUTABLE); 1676 } 1677 1678 /** For use by generated code only. */ 1679 public static <ContainingT extends Message, T> 1680 GeneratedExtension<ContainingT, T> newFileScopedGeneratedExtension( 1681 final Class<?> singularType, final Message defaultInstance) { 1682 // For extensions scoped within a file, we rely on the outer class's 1683 // static initializer to call internalInit() on the extension when the 1684 // descriptor is available. 1685 return new GeneratedExtension<>( 1686 null, // ExtensionDescriptorRetriever is initialized in internalInit(); 1687 singularType, 1688 defaultInstance, 1689 Extension.ExtensionType.IMMUTABLE); 1690 } 1691 1692 private abstract static class CachedDescriptorRetriever implements ExtensionDescriptorRetriever { 1693 private volatile FieldDescriptor descriptor; 1694 1695 protected abstract FieldDescriptor loadDescriptor(); 1696 1697 @Override 1698 public FieldDescriptor getDescriptor() { 1699 if (descriptor == null) { 1700 FieldDescriptor tmpDescriptor = loadDescriptor(); 1701 synchronized (this) { 1702 if (descriptor == null) { 1703 descriptor = tmpDescriptor; 1704 } 1705 } 1706 } 1707 return descriptor; 1708 } 1709 } 1710 1711 /** 1712 * Type used to represent generated extensions. The protocol compiler generates a static singleton 1713 * instance of this class for each extension. 1714 * 1715 * <p>For example, imagine you have the {@code .proto} file: 1716 * 1717 * <pre> 1718 * option java_class = "MyProto"; 1719 * 1720 * message Foo { 1721 * extensions 1000 to max; 1722 * } 1723 * 1724 * extend Foo { 1725 * optional int32 bar; 1726 * } 1727 * </pre> 1728 * 1729 * <p>Then, {@code MyProto.Foo.bar} has type {@code GeneratedExtension<MyProto.Foo, Integer>}. 1730 * 1731 * <p>In general, users should ignore the details of this type, and simply use these static 1732 * singletons as parameters to the extension accessors defined in {@link ExtendableMessage} and 1733 * {@link ExtendableBuilder}. 1734 */ 1735 public static class GeneratedExtension<ContainingT extends Message, T> 1736 extends Extension<ContainingT, T> { 1737 1738 // We can't always initialize the descriptor of a GeneratedExtension when 1739 // we first construct it due to initialization order difficulties (namely, 1740 // the descriptor may not have been constructed yet, since it is often 1741 // constructed by the initializer of a separate module). 1742 // 1743 // In the case of nested extensions, we initialize the 1744 // ExtensionDescriptorRetriever with an instance that uses the scoping 1745 // Message's default instance to retrieve the extension's descriptor. 1746 // 1747 // In the case of non-nested extensions, we initialize the 1748 // ExtensionDescriptorRetriever to null and rely on the outer class's static 1749 // initializer to call internalInit() after the descriptor has been parsed. 1750 GeneratedExtension( 1751 ExtensionDescriptorRetriever descriptorRetriever, 1752 Class<?> singularType, 1753 Message messageDefaultInstance, 1754 ExtensionType extensionType) { 1755 if (Message.class.isAssignableFrom(singularType) 1756 && !singularType.isInstance(messageDefaultInstance)) { 1757 throw new IllegalArgumentException( 1758 "Bad messageDefaultInstance for " + singularType.getName()); 1759 } 1760 this.descriptorRetriever = descriptorRetriever; 1761 this.singularType = singularType; 1762 this.messageDefaultInstance = messageDefaultInstance; 1763 1764 if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) { 1765 this.enumValueOf = getMethodOrDie(singularType, "valueOf", EnumValueDescriptor.class); 1766 this.enumGetValueDescriptor = getMethodOrDie(singularType, "getValueDescriptor"); 1767 } else { 1768 this.enumValueOf = null; 1769 this.enumGetValueDescriptor = null; 1770 } 1771 this.extensionType = extensionType; 1772 } 1773 1774 /** For use by generated code only. */ 1775 public void internalInit(final FieldDescriptor descriptor) { 1776 if (descriptorRetriever != null) { 1777 throw new IllegalStateException("Already initialized."); 1778 } 1779 descriptorRetriever = 1780 new ExtensionDescriptorRetriever() { 1781 @Override 1782 public FieldDescriptor getDescriptor() { 1783 return descriptor; 1784 } 1785 }; 1786 } 1787 1788 private ExtensionDescriptorRetriever descriptorRetriever; 1789 private final Class<?> singularType; 1790 private final Message messageDefaultInstance; 1791 private final Method enumValueOf; 1792 private final Method enumGetValueDescriptor; 1793 private final ExtensionType extensionType; 1794 1795 @Override 1796 public FieldDescriptor getDescriptor() { 1797 if (descriptorRetriever == null) { 1798 throw new IllegalStateException("getDescriptor() called before internalInit()"); 1799 } 1800 return descriptorRetriever.getDescriptor(); 1801 } 1802 1803 /** 1804 * If the extension is an embedded message or group, returns the default instance of the 1805 * message. 1806 */ 1807 @Override 1808 public Message getMessageDefaultInstance() { 1809 return messageDefaultInstance; 1810 } 1811 1812 @Override 1813 protected ExtensionType getExtensionType() { 1814 return extensionType; 1815 } 1816 1817 /** 1818 * Convert from the type used by the reflection accessors to the type used by native accessors. 1819 * E.g., for enums, the reflection accessors use EnumValueDescriptors but the native accessors 1820 * use the generated enum type. 1821 */ 1822 @Override 1823 protected Object fromReflectionType(final Object value) { 1824 FieldDescriptor descriptor = getDescriptor(); 1825 if (descriptor.isRepeated()) { 1826 if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE 1827 || descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1828 // Must convert the whole list. 1829 final ProtobufArrayList<Object> result = new ProtobufArrayList<>(); 1830 result.ensureCapacity(((List<?>) value).size()); 1831 for (final Object element : (List<?>) value) { 1832 result.add(singularFromReflectionType(element)); 1833 } 1834 result.makeImmutable(); 1835 return result; 1836 } else { 1837 return value; 1838 } 1839 } else { 1840 return singularFromReflectionType(value); 1841 } 1842 } 1843 1844 /** 1845 * Like {@link #fromReflectionType(Object)}, but if the type is a repeated type, this converts a 1846 * single element. 1847 */ 1848 @Override 1849 protected Object singularFromReflectionType(final Object value) { 1850 FieldDescriptor descriptor = getDescriptor(); 1851 switch (descriptor.getJavaType()) { 1852 case MESSAGE: 1853 if (singularType.isInstance(value)) { 1854 return value; 1855 } else { 1856 return messageDefaultInstance.newBuilderForType().mergeFrom((Message) value).build(); 1857 } 1858 case ENUM: 1859 return invokeOrDie(enumValueOf, null, value); 1860 default: 1861 return value; 1862 } 1863 } 1864 1865 /** 1866 * Convert from the type used by the native accessors to the type used by reflection accessors. 1867 * E.g., for enums, the reflection accessors use EnumValueDescriptors but the native accessors 1868 * use the generated enum type. 1869 */ 1870 @Override 1871 protected Object toReflectionType(final Object value) { 1872 FieldDescriptor descriptor = getDescriptor(); 1873 if (descriptor.isRepeated()) { 1874 if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { 1875 // Must convert the whole list. 1876 final List<Object> result = new ArrayList<>(); 1877 for (final Object element : (List<?>) value) { 1878 result.add(singularToReflectionType(element)); 1879 } 1880 return result; 1881 } else { 1882 return value; 1883 } 1884 } else { 1885 return singularToReflectionType(value); 1886 } 1887 } 1888 1889 /** 1890 * Like {@link #toReflectionType(Object)}, but if the type is a repeated type, this converts a 1891 * single element. 1892 */ 1893 @Override 1894 protected Object singularToReflectionType(final Object value) { 1895 FieldDescriptor descriptor = getDescriptor(); 1896 switch (descriptor.getJavaType()) { 1897 case ENUM: 1898 return invokeOrDie(enumGetValueDescriptor, value); 1899 default: 1900 return value; 1901 } 1902 } 1903 1904 @Override 1905 public int getNumber() { 1906 return getDescriptor().getNumber(); 1907 } 1908 1909 @Override 1910 public WireFormat.FieldType getLiteType() { 1911 return getDescriptor().getLiteType(); 1912 } 1913 1914 @Override 1915 public boolean isRepeated() { 1916 return getDescriptor().isRepeated(); 1917 } 1918 1919 @Override 1920 @SuppressWarnings("unchecked") 1921 public T getDefaultValue() { 1922 if (isRepeated()) { 1923 return (T) Collections.emptyList(); 1924 } 1925 if (getDescriptor().getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 1926 return (T) messageDefaultInstance; 1927 } 1928 return (T) singularFromReflectionType(getDescriptor().getDefaultValue()); 1929 } 1930 } 1931 1932 // ================================================================= 1933 1934 /** Calls Class.getMethod and throws a RuntimeException if it fails. */ 1935 private static Method getMethodOrDie( 1936 final Class<?> clazz, final String name, final Class<?>... params) { 1937 try { 1938 return clazz.getMethod(name, params); 1939 } catch (NoSuchMethodException e) { 1940 throw new IllegalStateException( 1941 "Generated message class \"" + clazz.getName() + "\" missing method \"" + name + "\".", 1942 e); 1943 } 1944 } 1945 1946 /** Calls invoke and throws a RuntimeException if it fails. */ 1947 @CanIgnoreReturnValue 1948 private static Object invokeOrDie( 1949 final Method method, final Object object, final Object... params) { 1950 try { 1951 return method.invoke(object, params); 1952 } catch (IllegalAccessException e) { 1953 throw new IllegalStateException( 1954 "Couldn't use Java reflection to implement protocol message reflection.", e); 1955 } catch (InvocationTargetException e) { 1956 final Throwable cause = e.getCause(); 1957 if (cause instanceof RuntimeException) { 1958 throw (RuntimeException) cause; 1959 } else if (cause instanceof Error) { 1960 throw (Error) cause; 1961 } else { 1962 throw new IllegalStateException( 1963 "Unexpected exception thrown by generated accessor method.", cause); 1964 } 1965 } 1966 } 1967 1968 /** 1969 * Gets the map field with the given field number. This method should be overridden in the 1970 * generated message class if the message contains map fields. 1971 * 1972 * <p>Unlike other field types, reflection support for map fields can't be implemented based on 1973 * generated public API because we need to access a map field as a list in reflection API but the 1974 * generated API only allows us to access it as a map. This method returns the underlying map 1975 * field directly and thus enables us to access the map field as a list. 1976 */ 1977 @SuppressWarnings("unused") 1978 protected MapFieldReflectionAccessor internalGetMapFieldReflection(int fieldNumber) { 1979 return internalGetMapField(fieldNumber); 1980 } 1981 1982 /** TODO: Remove, exists for compatibility with generated code. */ 1983 @Deprecated 1984 @SuppressWarnings({"rawtypes", "unused"}) 1985 protected MapField internalGetMapField(int fieldNumber) { 1986 // Note that we can't use descriptor names here because this method will 1987 // be called when descriptor is being initialized. 1988 throw new IllegalArgumentException("No map fields found in " + getClass().getName()); 1989 } 1990 1991 /** 1992 * Users should ignore this class. This class provides the implementation with access to the 1993 * fields of a message object using Java reflection. 1994 */ 1995 // TODO: Should be marked final in v5.x.x once GeneratedMessageV3 is removed. 1996 public static class FieldAccessorTable { 1997 1998 /** 1999 * Construct a FieldAccessorTable for a particular message class. Only one FieldAccessorTable 2000 * should ever be constructed per class. 2001 * 2002 * @param descriptor The type's descriptor. 2003 * @param camelCaseNames The camelcase names of all fields in the message. These are used to 2004 * derive the accessor method names. 2005 * @param messageClass The message type. 2006 * @param builderClass The builder type. 2007 */ 2008 public FieldAccessorTable( 2009 final Descriptor descriptor, 2010 final String[] camelCaseNames, 2011 final Class<? extends GeneratedMessage> messageClass, 2012 final Class<? extends Builder<?>> builderClass) { 2013 this(descriptor, camelCaseNames); 2014 ensureFieldAccessorsInitialized(messageClass, builderClass); 2015 } 2016 2017 /** 2018 * Construct a FieldAccessorTable for a particular message class without initializing 2019 * FieldAccessors. 2020 */ 2021 public FieldAccessorTable(final Descriptor descriptor, final String[] camelCaseNames) { 2022 this.descriptor = descriptor; 2023 this.camelCaseNames = camelCaseNames; 2024 fields = new FieldAccessor[descriptor.getFields().size()]; 2025 oneofs = new OneofAccessor[descriptor.getOneofs().size()]; 2026 initialized = false; 2027 } 2028 2029 /** 2030 * Ensures the field accessors are initialized. This method is thread-safe. 2031 * 2032 * @param messageClass The message type. 2033 * @param builderClass The builder type. 2034 * @return this 2035 */ 2036 public FieldAccessorTable ensureFieldAccessorsInitialized( 2037 Class<? extends GeneratedMessage> messageClass, Class<? extends Builder<?>> builderClass) { 2038 if (initialized) { 2039 return this; 2040 } 2041 synchronized (this) { 2042 if (initialized) { 2043 return this; 2044 } 2045 int fieldsSize = fields.length; 2046 for (int i = 0; i < fieldsSize; i++) { 2047 FieldDescriptor field = descriptor.getFields().get(i); 2048 String containingOneofCamelCaseName = null; 2049 if (field.getContainingOneof() != null) { 2050 int index = fieldsSize + field.getContainingOneof().getIndex(); 2051 if (index < camelCaseNames.length) { 2052 containingOneofCamelCaseName = camelCaseNames[index]; 2053 } 2054 } 2055 if (field.isRepeated()) { 2056 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 2057 if (field.isMapField()) { 2058 fields[i] = new MapFieldAccessor(field, messageClass); 2059 } else { 2060 fields[i] = 2061 new RepeatedMessageFieldAccessor( 2062 field, camelCaseNames[i], messageClass, builderClass); 2063 } 2064 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 2065 fields[i] = 2066 new RepeatedEnumFieldAccessor( 2067 field, camelCaseNames[i], messageClass, builderClass); 2068 } else { 2069 fields[i] = new RepeatedFieldAccessor(camelCaseNames[i], messageClass, builderClass); 2070 } 2071 } else { 2072 if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { 2073 fields[i] = 2074 new SingularMessageFieldAccessor( 2075 field, 2076 camelCaseNames[i], 2077 messageClass, 2078 builderClass, 2079 containingOneofCamelCaseName); 2080 } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) { 2081 fields[i] = 2082 new SingularEnumFieldAccessor( 2083 field, 2084 camelCaseNames[i], 2085 messageClass, 2086 builderClass, 2087 containingOneofCamelCaseName); 2088 } else if (field.getJavaType() == FieldDescriptor.JavaType.STRING) { 2089 fields[i] = 2090 new SingularStringFieldAccessor( 2091 field, 2092 camelCaseNames[i], 2093 messageClass, 2094 builderClass, 2095 containingOneofCamelCaseName); 2096 } else { 2097 fields[i] = 2098 new SingularFieldAccessor( 2099 field, 2100 camelCaseNames[i], 2101 messageClass, 2102 builderClass, 2103 containingOneofCamelCaseName); 2104 } 2105 } 2106 } 2107 2108 for (int i = 0; i < descriptor.getOneofs().size(); i++) { 2109 if (i < descriptor.getRealOneofs().size()) { 2110 oneofs[i] = 2111 new RealOneofAccessor( 2112 descriptor, camelCaseNames[i + fieldsSize], messageClass, builderClass); 2113 } else { 2114 oneofs[i] = new SyntheticOneofAccessor(descriptor, i); 2115 } 2116 } 2117 initialized = true; 2118 camelCaseNames = null; 2119 return this; 2120 } 2121 } 2122 2123 private final Descriptor descriptor; 2124 private final FieldAccessor[] fields; 2125 private String[] camelCaseNames; 2126 private final OneofAccessor[] oneofs; 2127 private volatile boolean initialized; 2128 2129 /** Get the FieldAccessor for a particular field. */ 2130 private FieldAccessor getField(final FieldDescriptor field) { 2131 if (field.getContainingType() != descriptor) { 2132 throw new IllegalArgumentException("FieldDescriptor does not match message type."); 2133 } else if (field.isExtension()) { 2134 // If this type had extensions, it would subclass ExtendableMessage, 2135 // which overrides the reflection interface to handle extensions. 2136 throw new IllegalArgumentException("This type does not have extensions."); 2137 } 2138 return fields[field.getIndex()]; 2139 } 2140 2141 /** Get the OneofAccessor for a particular oneof. */ 2142 private OneofAccessor getOneof(final OneofDescriptor oneof) { 2143 if (oneof.getContainingType() != descriptor) { 2144 throw new IllegalArgumentException("OneofDescriptor does not match message type."); 2145 } 2146 return oneofs[oneof.getIndex()]; 2147 } 2148 2149 /** 2150 * Abstract interface that provides access to a single field. This is implemented differently 2151 * depending on the field type and cardinality. 2152 */ 2153 private interface FieldAccessor { 2154 Object get(GeneratedMessage message); 2155 2156 Object get(GeneratedMessage.Builder<?> builder); 2157 2158 Object getRaw(GeneratedMessage message); 2159 2160 void set(Builder<?> builder, Object value); 2161 2162 Object getRepeated(GeneratedMessage message, int index); 2163 2164 Object getRepeated(GeneratedMessage.Builder<?> builder, int index); 2165 2166 void setRepeated(Builder<?> builder, int index, Object value); 2167 2168 void addRepeated(Builder<?> builder, Object value); 2169 2170 boolean has(GeneratedMessage message); 2171 2172 boolean has(GeneratedMessage.Builder<?> builder); 2173 2174 int getRepeatedCount(GeneratedMessage message); 2175 2176 int getRepeatedCount(GeneratedMessage.Builder<?> builder); 2177 2178 void clear(Builder<?> builder); 2179 2180 Message.Builder newBuilder(); 2181 2182 Message.Builder getBuilder(GeneratedMessage.Builder<?> builder); 2183 2184 Message.Builder getRepeatedBuilder(GeneratedMessage.Builder<?> builder, int index); 2185 } 2186 2187 /** OneofAccessor provides access to a single oneof. */ 2188 private static interface OneofAccessor { 2189 public boolean has(final GeneratedMessage message); 2190 2191 public boolean has(GeneratedMessage.Builder<?> builder); 2192 2193 public FieldDescriptor get(final GeneratedMessage message); 2194 2195 public FieldDescriptor get(GeneratedMessage.Builder<?> builder); 2196 2197 public void clear(final Builder<?> builder); 2198 } 2199 2200 /** RealOneofAccessor provides access to a single real oneof. */ 2201 private static class RealOneofAccessor implements OneofAccessor { 2202 RealOneofAccessor( 2203 final Descriptor descriptor, 2204 final String camelCaseName, 2205 final Class<? extends GeneratedMessage> messageClass, 2206 final Class<? extends Builder<?>> builderClass) { 2207 this.descriptor = descriptor; 2208 caseMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "Case"); 2209 caseMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "Case"); 2210 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 2211 } 2212 2213 private final Descriptor descriptor; 2214 private final Method caseMethod; 2215 private final Method caseMethodBuilder; 2216 private final Method clearMethod; 2217 2218 @Override 2219 public boolean has(final GeneratedMessage message) { 2220 return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() != 0; 2221 } 2222 2223 @Override 2224 public boolean has(GeneratedMessage.Builder<?> builder) { 2225 return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() != 0; 2226 } 2227 2228 @Override 2229 public FieldDescriptor get(final GeneratedMessage message) { 2230 int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); 2231 if (fieldNumber > 0) { 2232 return descriptor.findFieldByNumber(fieldNumber); 2233 } 2234 return null; 2235 } 2236 2237 @Override 2238 public FieldDescriptor get(GeneratedMessage.Builder<?> builder) { 2239 int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); 2240 if (fieldNumber > 0) { 2241 return descriptor.findFieldByNumber(fieldNumber); 2242 } 2243 return null; 2244 } 2245 2246 @Override 2247 public void clear(final Builder<?> builder) { 2248 // TODO: remove the unused variable 2249 Object unused = invokeOrDie(clearMethod, builder); 2250 } 2251 } 2252 2253 /** SyntheticOneofAccessor provides access to a single synthetic oneof. */ 2254 private static class SyntheticOneofAccessor implements OneofAccessor { 2255 SyntheticOneofAccessor(final Descriptor descriptor, final int oneofIndex) { 2256 OneofDescriptor oneofDescriptor = descriptor.getOneofs().get(oneofIndex); 2257 fieldDescriptor = oneofDescriptor.getFields().get(0); 2258 } 2259 2260 private final FieldDescriptor fieldDescriptor; 2261 2262 @Override 2263 public boolean has(final GeneratedMessage message) { 2264 return message.hasField(fieldDescriptor); 2265 } 2266 2267 @Override 2268 public boolean has(GeneratedMessage.Builder<?> builder) { 2269 return builder.hasField(fieldDescriptor); 2270 } 2271 2272 @Override 2273 public FieldDescriptor get(final GeneratedMessage message) { 2274 return message.hasField(fieldDescriptor) ? fieldDescriptor : null; 2275 } 2276 2277 public FieldDescriptor get(GeneratedMessage.Builder<?> builder) { 2278 return builder.hasField(fieldDescriptor) ? fieldDescriptor : null; 2279 } 2280 2281 @Override 2282 public void clear(final Builder<?> builder) { 2283 builder.clearField(fieldDescriptor); 2284 } 2285 } 2286 2287 // --------------------------------------------------------------- 2288 2289 @SuppressWarnings("SameNameButDifferent") 2290 private static class SingularFieldAccessor implements FieldAccessor { 2291 private interface MethodInvoker { 2292 Object get(final GeneratedMessage message); 2293 2294 Object get(GeneratedMessage.Builder<?> builder); 2295 2296 int getOneofFieldNumber(final GeneratedMessage message); 2297 2298 int getOneofFieldNumber(final GeneratedMessage.Builder<?> builder); 2299 2300 void set(final GeneratedMessage.Builder<?> builder, final Object value); 2301 2302 boolean has(final GeneratedMessage message); 2303 2304 boolean has(GeneratedMessage.Builder<?> builder); 2305 2306 void clear(final GeneratedMessage.Builder<?> builder); 2307 } 2308 2309 private static final class ReflectionInvoker implements MethodInvoker { 2310 private final Method getMethod; 2311 private final Method getMethodBuilder; 2312 private final Method setMethod; 2313 private final Method hasMethod; 2314 private final Method hasMethodBuilder; 2315 private final Method clearMethod; 2316 private final Method caseMethod; 2317 private final Method caseMethodBuilder; 2318 2319 ReflectionInvoker( 2320 final String camelCaseName, 2321 final Class<? extends GeneratedMessage> messageClass, 2322 final Class<? extends Builder<?>> builderClass, 2323 final String containingOneofCamelCaseName, 2324 boolean isOneofField, 2325 boolean hasHasMethod) { 2326 getMethod = getMethodOrDie(messageClass, "get" + camelCaseName); 2327 getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName); 2328 Class<?> type = getMethod.getReturnType(); 2329 setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type); 2330 hasMethod = hasHasMethod ? getMethodOrDie(messageClass, "has" + camelCaseName) : null; 2331 hasMethodBuilder = 2332 hasHasMethod ? getMethodOrDie(builderClass, "has" + camelCaseName) : null; 2333 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 2334 caseMethod = 2335 isOneofField 2336 ? getMethodOrDie(messageClass, "get" + containingOneofCamelCaseName + "Case") 2337 : null; 2338 caseMethodBuilder = 2339 isOneofField 2340 ? getMethodOrDie(builderClass, "get" + containingOneofCamelCaseName + "Case") 2341 : null; 2342 } 2343 2344 @Override 2345 public Object get(final GeneratedMessage message) { 2346 return invokeOrDie(getMethod, message); 2347 } 2348 2349 @Override 2350 public Object get(GeneratedMessage.Builder<?> builder) { 2351 return invokeOrDie(getMethodBuilder, builder); 2352 } 2353 2354 @Override 2355 public int getOneofFieldNumber(final GeneratedMessage message) { 2356 return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); 2357 } 2358 2359 @Override 2360 public int getOneofFieldNumber(final GeneratedMessage.Builder<?> builder) { 2361 return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); 2362 } 2363 2364 @Override 2365 public void set(final GeneratedMessage.Builder<?> builder, final Object value) { 2366 // TODO: remove the unused variable 2367 Object unused = invokeOrDie(setMethod, builder, value); 2368 } 2369 2370 @Override 2371 public boolean has(final GeneratedMessage message) { 2372 return (Boolean) invokeOrDie(hasMethod, message); 2373 } 2374 2375 @Override 2376 public boolean has(GeneratedMessage.Builder<?> builder) { 2377 return (Boolean) invokeOrDie(hasMethodBuilder, builder); 2378 } 2379 2380 @Override 2381 public void clear(final GeneratedMessage.Builder<?> builder) { 2382 // TODO: remove the unused variable 2383 Object unused = invokeOrDie(clearMethod, builder); 2384 } 2385 } 2386 2387 SingularFieldAccessor( 2388 final FieldDescriptor descriptor, 2389 final String camelCaseName, 2390 final Class<? extends GeneratedMessage> messageClass, 2391 final Class<? extends Builder<?>> builderClass, 2392 final String containingOneofCamelCaseName) { 2393 isOneofField = 2394 descriptor.getRealContainingOneof() != null; 2395 hasHasMethod = descriptor.hasPresence(); 2396 ReflectionInvoker reflectionInvoker = 2397 new ReflectionInvoker( 2398 camelCaseName, 2399 messageClass, 2400 builderClass, 2401 containingOneofCamelCaseName, 2402 isOneofField, 2403 hasHasMethod); 2404 field = descriptor; 2405 type = reflectionInvoker.getMethod.getReturnType(); 2406 invoker = getMethodInvoker(reflectionInvoker); 2407 } 2408 2409 static MethodInvoker getMethodInvoker(ReflectionInvoker accessor) { 2410 return accessor; 2411 } 2412 2413 // Note: We use Java reflection to call public methods rather than 2414 // access private fields directly as this avoids runtime security 2415 // checks. 2416 protected final Class<?> type; 2417 protected final FieldDescriptor field; 2418 protected final boolean isOneofField; 2419 protected final boolean hasHasMethod; 2420 protected final MethodInvoker invoker; 2421 2422 @Override 2423 public Object get(final GeneratedMessage message) { 2424 return invoker.get(message); 2425 } 2426 2427 @Override 2428 public Object get(GeneratedMessage.Builder<?> builder) { 2429 return invoker.get(builder); 2430 } 2431 2432 @Override 2433 public Object getRaw(final GeneratedMessage message) { 2434 return get(message); 2435 } 2436 2437 @Override 2438 public void set(final Builder<?> builder, final Object value) { 2439 invoker.set(builder, value); 2440 } 2441 2442 @Override 2443 public Object getRepeated(final GeneratedMessage message, final int index) { 2444 throw new UnsupportedOperationException("getRepeatedField() called on a singular field."); 2445 } 2446 2447 @Override 2448 public Object getRepeated(GeneratedMessage.Builder<?> builder, int index) { 2449 throw new UnsupportedOperationException("getRepeatedField() called on a singular field."); 2450 } 2451 2452 @Override 2453 public void setRepeated(final Builder<?> builder, final int index, final Object value) { 2454 throw new UnsupportedOperationException("setRepeatedField() called on a singular field."); 2455 } 2456 2457 @Override 2458 public void addRepeated(final Builder<?> builder, final Object value) { 2459 throw new UnsupportedOperationException("addRepeatedField() called on a singular field."); 2460 } 2461 2462 @Override 2463 public boolean has(final GeneratedMessage message) { 2464 if (!hasHasMethod) { 2465 if (isOneofField) { 2466 return invoker.getOneofFieldNumber(message) == field.getNumber(); 2467 } 2468 return !get(message).equals(field.getDefaultValue()); 2469 } 2470 return invoker.has(message); 2471 } 2472 2473 @Override 2474 public boolean has(GeneratedMessage.Builder<?> builder) { 2475 if (!hasHasMethod) { 2476 if (isOneofField) { 2477 return invoker.getOneofFieldNumber(builder) == field.getNumber(); 2478 } 2479 return !get(builder).equals(field.getDefaultValue()); 2480 } 2481 return invoker.has(builder); 2482 } 2483 2484 @Override 2485 public int getRepeatedCount(final GeneratedMessage message) { 2486 throw new UnsupportedOperationException( 2487 "getRepeatedFieldSize() called on a singular field."); 2488 } 2489 2490 @Override 2491 public int getRepeatedCount(GeneratedMessage.Builder<?> builder) { 2492 throw new UnsupportedOperationException( 2493 "getRepeatedFieldSize() called on a singular field."); 2494 } 2495 2496 @Override 2497 public void clear(final Builder<?> builder) { 2498 invoker.clear(builder); 2499 } 2500 2501 @Override 2502 public Message.Builder newBuilder() { 2503 throw new UnsupportedOperationException( 2504 "newBuilderForField() called on a non-Message type."); 2505 } 2506 2507 @Override 2508 public Message.Builder getBuilder(GeneratedMessage.Builder<?> builder) { 2509 throw new UnsupportedOperationException("getFieldBuilder() called on a non-Message type."); 2510 } 2511 2512 @Override 2513 public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder<?> builder, int index) { 2514 throw new UnsupportedOperationException( 2515 "getRepeatedFieldBuilder() called on a non-Message type."); 2516 } 2517 } 2518 2519 @SuppressWarnings("SameNameButDifferent") 2520 private static class RepeatedFieldAccessor implements FieldAccessor { 2521 interface MethodInvoker { 2522 Object get(final GeneratedMessage message); 2523 2524 Object get(GeneratedMessage.Builder<?> builder); 2525 2526 Object getRepeated(final GeneratedMessage message, final int index); 2527 2528 Object getRepeated(GeneratedMessage.Builder<?> builder, int index); 2529 2530 void setRepeated( 2531 final GeneratedMessage.Builder<?> builder, final int index, final Object value); 2532 2533 void addRepeated(final GeneratedMessage.Builder<?> builder, final Object value); 2534 2535 int getRepeatedCount(final GeneratedMessage message); 2536 2537 int getRepeatedCount(GeneratedMessage.Builder<?> builder); 2538 2539 void clear(final GeneratedMessage.Builder<?> builder); 2540 } 2541 2542 private static final class ReflectionInvoker implements MethodInvoker { 2543 private final Method getMethod; 2544 private final Method getMethodBuilder; 2545 private final Method getRepeatedMethod; 2546 private final Method getRepeatedMethodBuilder; 2547 private final Method setRepeatedMethod; 2548 private final Method addRepeatedMethod; 2549 private final Method getCountMethod; 2550 private final Method getCountMethodBuilder; 2551 private final Method clearMethod; 2552 2553 ReflectionInvoker( 2554 final String camelCaseName, 2555 final Class<? extends GeneratedMessage> messageClass, 2556 final Class<? extends Builder<?>> builderClass) { 2557 getMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "List"); 2558 getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "List"); 2559 getRepeatedMethod = getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE); 2560 getRepeatedMethodBuilder = 2561 getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE); 2562 Class<?> type = getRepeatedMethod.getReturnType(); 2563 setRepeatedMethod = 2564 getMethodOrDie(builderClass, "set" + camelCaseName, Integer.TYPE, type); 2565 addRepeatedMethod = getMethodOrDie(builderClass, "add" + camelCaseName, type); 2566 getCountMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "Count"); 2567 getCountMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "Count"); 2568 clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName); 2569 } 2570 2571 @Override 2572 public Object get(final GeneratedMessage message) { 2573 return invokeOrDie(getMethod, message); 2574 } 2575 2576 @Override 2577 public Object get(GeneratedMessage.Builder<?> builder) { 2578 return invokeOrDie(getMethodBuilder, builder); 2579 } 2580 2581 @Override 2582 public Object getRepeated(final GeneratedMessage message, final int index) { 2583 return invokeOrDie(getRepeatedMethod, message, index); 2584 } 2585 2586 @Override 2587 public Object getRepeated(GeneratedMessage.Builder<?> builder, int index) { 2588 return invokeOrDie(getRepeatedMethodBuilder, builder, index); 2589 } 2590 2591 @Override 2592 public void setRepeated( 2593 final GeneratedMessage.Builder<?> builder, final int index, final Object value) { 2594 // TODO: remove the unused variable 2595 Object unused = invokeOrDie(setRepeatedMethod, builder, index, value); 2596 } 2597 2598 @Override 2599 public void addRepeated(final GeneratedMessage.Builder<?> builder, final Object value) { 2600 // TODO: remove the unused variable 2601 Object unused = invokeOrDie(addRepeatedMethod, builder, value); 2602 } 2603 2604 @Override 2605 public int getRepeatedCount(final GeneratedMessage message) { 2606 return (Integer) invokeOrDie(getCountMethod, message); 2607 } 2608 2609 @Override 2610 public int getRepeatedCount(GeneratedMessage.Builder<?> builder) { 2611 return (Integer) invokeOrDie(getCountMethodBuilder, builder); 2612 } 2613 2614 @Override 2615 public void clear(final GeneratedMessage.Builder<?> builder) { 2616 // TODO: remove the unused variable 2617 Object unused = invokeOrDie(clearMethod, builder); 2618 } 2619 } 2620 2621 protected final Class<?> type; 2622 protected final MethodInvoker invoker; 2623 2624 RepeatedFieldAccessor( 2625 final String camelCaseName, 2626 final Class<? extends GeneratedMessage> messageClass, 2627 final Class<? extends Builder<?>> builderClass) { 2628 ReflectionInvoker reflectionInvoker = 2629 new ReflectionInvoker(camelCaseName, messageClass, builderClass); 2630 type = reflectionInvoker.getRepeatedMethod.getReturnType(); 2631 invoker = getMethodInvoker(reflectionInvoker); 2632 } 2633 2634 static MethodInvoker getMethodInvoker(ReflectionInvoker accessor) { 2635 return accessor; 2636 } 2637 2638 @Override 2639 public Object get(final GeneratedMessage message) { 2640 return invoker.get(message); 2641 } 2642 2643 @Override 2644 public Object get(GeneratedMessage.Builder<?> builder) { 2645 return invoker.get(builder); 2646 } 2647 2648 @Override 2649 public Object getRaw(final GeneratedMessage message) { 2650 return get(message); 2651 } 2652 2653 @Override 2654 public void set(final Builder<?> builder, final Object value) { 2655 // Add all the elements individually. This serves two purposes: 2656 // 1) Verifies that each element has the correct type. 2657 // 2) Insures that the caller cannot modify the list later on and 2658 // have the modifications be reflected in the message. 2659 clear(builder); 2660 for (final Object element : (List<?>) value) { 2661 addRepeated(builder, element); 2662 } 2663 } 2664 2665 @Override 2666 public Object getRepeated(final GeneratedMessage message, final int index) { 2667 return invoker.getRepeated(message, index); 2668 } 2669 2670 @Override 2671 public Object getRepeated(GeneratedMessage.Builder<?> builder, int index) { 2672 return invoker.getRepeated(builder, index); 2673 } 2674 2675 @Override 2676 public void setRepeated(final Builder<?> builder, final int index, final Object value) { 2677 invoker.setRepeated(builder, index, value); 2678 } 2679 2680 @Override 2681 public void addRepeated(final Builder<?> builder, final Object value) { 2682 invoker.addRepeated(builder, value); 2683 } 2684 2685 @Override 2686 public boolean has(final GeneratedMessage message) { 2687 throw new UnsupportedOperationException("hasField() called on a repeated field."); 2688 } 2689 2690 @Override 2691 public boolean has(GeneratedMessage.Builder<?> builder) { 2692 throw new UnsupportedOperationException("hasField() called on a repeated field."); 2693 } 2694 2695 @Override 2696 public int getRepeatedCount(final GeneratedMessage message) { 2697 return invoker.getRepeatedCount(message); 2698 } 2699 2700 @Override 2701 public int getRepeatedCount(GeneratedMessage.Builder<?> builder) { 2702 return invoker.getRepeatedCount(builder); 2703 } 2704 2705 @Override 2706 public void clear(final Builder<?> builder) { 2707 invoker.clear(builder); 2708 } 2709 2710 @Override 2711 public Message.Builder newBuilder() { 2712 throw new UnsupportedOperationException( 2713 "newBuilderForField() called on a non-Message type."); 2714 } 2715 2716 @Override 2717 public Message.Builder getBuilder(GeneratedMessage.Builder<?> builder) { 2718 throw new UnsupportedOperationException("getFieldBuilder() called on a non-Message type."); 2719 } 2720 2721 @Override 2722 public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder<?> builder, int index) { 2723 throw new UnsupportedOperationException( 2724 "getRepeatedFieldBuilder() called on a non-Message type."); 2725 } 2726 } 2727 2728 private static class MapFieldAccessor implements FieldAccessor { 2729 MapFieldAccessor( 2730 final FieldDescriptor descriptor, final Class<? extends GeneratedMessage> messageClass) { 2731 field = descriptor; 2732 Method getDefaultInstanceMethod = getMethodOrDie(messageClass, "getDefaultInstance"); 2733 MapFieldReflectionAccessor defaultMapField = 2734 getMapField((GeneratedMessage) invokeOrDie(getDefaultInstanceMethod, null)); 2735 mapEntryMessageDefaultInstance = defaultMapField.getMapEntryMessageDefaultInstance(); 2736 } 2737 2738 private final FieldDescriptor field; 2739 private final Message mapEntryMessageDefaultInstance; 2740 2741 private MapFieldReflectionAccessor getMapField(GeneratedMessage message) { 2742 return message.internalGetMapFieldReflection(field.getNumber()); 2743 } 2744 2745 private MapFieldReflectionAccessor getMapField(GeneratedMessage.Builder<?> builder) { 2746 return builder.internalGetMapFieldReflection(field.getNumber()); 2747 } 2748 2749 private MapFieldReflectionAccessor getMutableMapField(GeneratedMessage.Builder<?> builder) { 2750 return builder.internalGetMutableMapFieldReflection(field.getNumber()); 2751 } 2752 2753 private Message coerceType(Message value) { 2754 if (value == null) { 2755 return null; 2756 } 2757 if (mapEntryMessageDefaultInstance.getClass().isInstance(value)) { 2758 return value; 2759 } 2760 // The value is not the exact right message type. However, if it 2761 // is an alternative implementation of the same type -- e.g. a 2762 // DynamicMessage -- we should accept it. In this case we can make 2763 // a copy of the message. 2764 return mapEntryMessageDefaultInstance.toBuilder().mergeFrom(value).build(); 2765 } 2766 2767 @Override 2768 public Object get(GeneratedMessage message) { 2769 List<Object> result = new ArrayList<>(); 2770 for (int i = 0; i < getRepeatedCount(message); i++) { 2771 result.add(getRepeated(message, i)); 2772 } 2773 return Collections.unmodifiableList(result); 2774 } 2775 2776 @Override 2777 public Object get(Builder<?> builder) { 2778 List<Object> result = new ArrayList<>(); 2779 for (int i = 0; i < getRepeatedCount(builder); i++) { 2780 result.add(getRepeated(builder, i)); 2781 } 2782 return Collections.unmodifiableList(result); 2783 } 2784 2785 @Override 2786 public Object getRaw(GeneratedMessage message) { 2787 return get(message); 2788 } 2789 2790 @Override 2791 public void set(Builder<?> builder, Object value) { 2792 clear(builder); 2793 for (Object entry : (List<?>) value) { 2794 addRepeated(builder, entry); 2795 } 2796 } 2797 2798 @Override 2799 public Object getRepeated(GeneratedMessage message, int index) { 2800 return getMapField(message).getList().get(index); 2801 } 2802 2803 @Override 2804 public Object getRepeated(Builder<?> builder, int index) { 2805 return getMapField(builder).getList().get(index); 2806 } 2807 2808 @Override 2809 public void setRepeated(Builder<?> builder, int index, Object value) { 2810 getMutableMapField(builder).getMutableList().set(index, coerceType((Message) value)); 2811 } 2812 2813 @Override 2814 public void addRepeated(Builder<?> builder, Object value) { 2815 getMutableMapField(builder).getMutableList().add(coerceType((Message) value)); 2816 } 2817 2818 @Override 2819 public boolean has(GeneratedMessage message) { 2820 throw new UnsupportedOperationException("hasField() is not supported for repeated fields."); 2821 } 2822 2823 @Override 2824 public boolean has(Builder<?> builder) { 2825 throw new UnsupportedOperationException("hasField() is not supported for repeated fields."); 2826 } 2827 2828 @Override 2829 public int getRepeatedCount(GeneratedMessage message) { 2830 return getMapField(message).getList().size(); 2831 } 2832 2833 @Override 2834 public int getRepeatedCount(Builder<?> builder) { 2835 return getMapField(builder).getList().size(); 2836 } 2837 2838 @Override 2839 public void clear(Builder<?> builder) { 2840 getMutableMapField(builder).getMutableList().clear(); 2841 } 2842 2843 @Override 2844 public Message.Builder newBuilder() { 2845 return mapEntryMessageDefaultInstance.newBuilderForType(); 2846 } 2847 2848 @Override 2849 public Message.Builder getBuilder(Builder<?> builder) { 2850 throw new UnsupportedOperationException("Nested builder not supported for map fields."); 2851 } 2852 2853 @Override 2854 public Message.Builder getRepeatedBuilder(Builder<?> builder, int index) { 2855 throw new UnsupportedOperationException("Map fields cannot be repeated"); 2856 } 2857 } 2858 2859 // --------------------------------------------------------------- 2860 2861 private static final class SingularEnumFieldAccessor extends SingularFieldAccessor { 2862 SingularEnumFieldAccessor( 2863 final FieldDescriptor descriptor, 2864 final String camelCaseName, 2865 final Class<? extends GeneratedMessage> messageClass, 2866 final Class<? extends Builder<?>> builderClass, 2867 final String containingOneofCamelCaseName) { 2868 super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName); 2869 2870 enumDescriptor = descriptor.getEnumType(); 2871 2872 valueOfMethod = getMethodOrDie(type, "valueOf", EnumValueDescriptor.class); 2873 getValueDescriptorMethod = getMethodOrDie(type, "getValueDescriptor"); 2874 2875 supportUnknownEnumValue = !descriptor.legacyEnumFieldTreatedAsClosed(); 2876 if (supportUnknownEnumValue) { 2877 getValueMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "Value"); 2878 getValueMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "Value"); 2879 setValueMethod = getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class); 2880 } 2881 } 2882 2883 private final EnumDescriptor enumDescriptor; 2884 2885 private final Method valueOfMethod; 2886 private final Method getValueDescriptorMethod; 2887 2888 private final boolean supportUnknownEnumValue; 2889 private Method getValueMethod; 2890 private Method getValueMethodBuilder; 2891 private Method setValueMethod; 2892 2893 @Override 2894 public Object get(final GeneratedMessage message) { 2895 if (supportUnknownEnumValue) { 2896 int value = (Integer) invokeOrDie(getValueMethod, message); 2897 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2898 } 2899 return invokeOrDie(getValueDescriptorMethod, super.get(message)); 2900 } 2901 2902 @Override 2903 public Object get(final GeneratedMessage.Builder<?> builder) { 2904 if (supportUnknownEnumValue) { 2905 int value = (Integer) invokeOrDie(getValueMethodBuilder, builder); 2906 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2907 } 2908 return invokeOrDie(getValueDescriptorMethod, super.get(builder)); 2909 } 2910 2911 @Override 2912 public void set(final Builder<?> builder, final Object value) { 2913 if (supportUnknownEnumValue) { 2914 // TODO: remove the unused variable 2915 Object unused = 2916 invokeOrDie(setValueMethod, builder, ((EnumValueDescriptor) value).getNumber()); 2917 return; 2918 } 2919 super.set(builder, invokeOrDie(valueOfMethod, null, value)); 2920 } 2921 } 2922 2923 private static final class RepeatedEnumFieldAccessor extends RepeatedFieldAccessor { 2924 RepeatedEnumFieldAccessor( 2925 final FieldDescriptor descriptor, 2926 final String camelCaseName, 2927 final Class<? extends GeneratedMessage> messageClass, 2928 final Class<? extends Builder<?>> builderClass) { 2929 super(camelCaseName, messageClass, builderClass); 2930 2931 enumDescriptor = descriptor.getEnumType(); 2932 2933 valueOfMethod = getMethodOrDie(type, "valueOf", EnumValueDescriptor.class); 2934 getValueDescriptorMethod = getMethodOrDie(type, "getValueDescriptor"); 2935 2936 supportUnknownEnumValue = !descriptor.legacyEnumFieldTreatedAsClosed(); 2937 if (supportUnknownEnumValue) { 2938 getRepeatedValueMethod = 2939 getMethodOrDie(messageClass, "get" + camelCaseName + "Value", int.class); 2940 getRepeatedValueMethodBuilder = 2941 getMethodOrDie(builderClass, "get" + camelCaseName + "Value", int.class); 2942 setRepeatedValueMethod = 2943 getMethodOrDie(builderClass, "set" + camelCaseName + "Value", int.class, int.class); 2944 addRepeatedValueMethod = 2945 getMethodOrDie(builderClass, "add" + camelCaseName + "Value", int.class); 2946 } 2947 } 2948 2949 private final EnumDescriptor enumDescriptor; 2950 2951 private final Method valueOfMethod; 2952 private final Method getValueDescriptorMethod; 2953 2954 private final boolean supportUnknownEnumValue; 2955 2956 private Method getRepeatedValueMethod; 2957 private Method getRepeatedValueMethodBuilder; 2958 private Method setRepeatedValueMethod; 2959 private Method addRepeatedValueMethod; 2960 2961 @Override 2962 public Object get(final GeneratedMessage message) { 2963 final List<Object> newList = new ArrayList<>(); 2964 final int size = getRepeatedCount(message); 2965 for (int i = 0; i < size; i++) { 2966 newList.add(getRepeated(message, i)); 2967 } 2968 return Collections.unmodifiableList(newList); 2969 } 2970 2971 @Override 2972 public Object get(final GeneratedMessage.Builder<?> builder) { 2973 final List<Object> newList = new ArrayList<>(); 2974 final int size = getRepeatedCount(builder); 2975 for (int i = 0; i < size; i++) { 2976 newList.add(getRepeated(builder, i)); 2977 } 2978 return Collections.unmodifiableList(newList); 2979 } 2980 2981 @Override 2982 public Object getRepeated(final GeneratedMessage message, final int index) { 2983 if (supportUnknownEnumValue) { 2984 int value = (Integer) invokeOrDie(getRepeatedValueMethod, message, index); 2985 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2986 } 2987 return invokeOrDie(getValueDescriptorMethod, super.getRepeated(message, index)); 2988 } 2989 2990 @Override 2991 public Object getRepeated(final GeneratedMessage.Builder<?> builder, final int index) { 2992 if (supportUnknownEnumValue) { 2993 int value = (Integer) invokeOrDie(getRepeatedValueMethodBuilder, builder, index); 2994 return enumDescriptor.findValueByNumberCreatingIfUnknown(value); 2995 } 2996 return invokeOrDie(getValueDescriptorMethod, super.getRepeated(builder, index)); 2997 } 2998 2999 @Override 3000 public void setRepeated(final Builder<?> builder, final int index, final Object value) { 3001 if (supportUnknownEnumValue) { 3002 // TODO: remove the unused variable 3003 Object unused = 3004 invokeOrDie( 3005 setRepeatedValueMethod, 3006 builder, 3007 index, 3008 ((EnumValueDescriptor) value).getNumber()); 3009 return; 3010 } 3011 super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null, value)); 3012 } 3013 3014 @Override 3015 public void addRepeated(final Builder<?> builder, final Object value) { 3016 if (supportUnknownEnumValue) { 3017 // TODO: remove the unused variable 3018 Object unused = 3019 invokeOrDie( 3020 addRepeatedValueMethod, builder, ((EnumValueDescriptor) value).getNumber()); 3021 return; 3022 } 3023 super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value)); 3024 } 3025 } 3026 3027 // --------------------------------------------------------------- 3028 3029 /** 3030 * Field accessor for string fields. 3031 * 3032 * <p>This class makes getFooBytes() and setFooBytes() available for reflection API so that 3033 * reflection based serialize/parse functions can access the raw bytes of the field to preserve 3034 * non-UTF8 bytes in the string. 3035 * 3036 * <p>This ensures the serialize/parse round-trip safety, which is important for servers which 3037 * forward messages. 3038 */ 3039 private static final class SingularStringFieldAccessor extends SingularFieldAccessor { 3040 SingularStringFieldAccessor( 3041 final FieldDescriptor descriptor, 3042 final String camelCaseName, 3043 final Class<? extends GeneratedMessage> messageClass, 3044 final Class<? extends Builder<?>> builderClass, 3045 final String containingOneofCamelCaseName) { 3046 super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName); 3047 getBytesMethod = getMethodOrDie(messageClass, "get" + camelCaseName + "Bytes"); 3048 setBytesMethodBuilder = 3049 getMethodOrDie(builderClass, "set" + camelCaseName + "Bytes", ByteString.class); 3050 } 3051 3052 private final Method getBytesMethod; 3053 private final Method setBytesMethodBuilder; 3054 3055 @Override 3056 public Object getRaw(final GeneratedMessage message) { 3057 return invokeOrDie(getBytesMethod, message); 3058 } 3059 3060 @Override 3061 public void set(GeneratedMessage.Builder<?> builder, Object value) { 3062 if (value instanceof ByteString) { 3063 // TODO: remove the unused variable 3064 Object unused = invokeOrDie(setBytesMethodBuilder, builder, value); 3065 } else { 3066 super.set(builder, value); 3067 } 3068 } 3069 } 3070 3071 // --------------------------------------------------------------- 3072 3073 private static final class SingularMessageFieldAccessor extends SingularFieldAccessor { 3074 SingularMessageFieldAccessor( 3075 final FieldDescriptor descriptor, 3076 final String camelCaseName, 3077 final Class<? extends GeneratedMessage> messageClass, 3078 final Class<? extends Builder<?>> builderClass, 3079 final String containingOneofCamelCaseName) { 3080 super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName); 3081 3082 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 3083 getBuilderMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName + "Builder"); 3084 } 3085 3086 private final Method newBuilderMethod; 3087 private final Method getBuilderMethodBuilder; 3088 3089 private Object coerceType(final Object value) { 3090 if (type.isInstance(value)) { 3091 return value; 3092 } else { 3093 // The value is not the exact right message type. However, if it 3094 // is an alternative implementation of the same type -- e.g. a 3095 // DynamicMessage -- we should accept it. In this case we can make 3096 // a copy of the message. 3097 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 3098 .mergeFrom((Message) value) 3099 .buildPartial(); 3100 } 3101 } 3102 3103 @Override 3104 public void set(final Builder<?> builder, final Object value) { 3105 super.set(builder, coerceType(value)); 3106 } 3107 3108 @Override 3109 public Message.Builder newBuilder() { 3110 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 3111 } 3112 3113 @Override 3114 public Message.Builder getBuilder(GeneratedMessage.Builder<?> builder) { 3115 return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder); 3116 } 3117 } 3118 3119 private static final class RepeatedMessageFieldAccessor extends RepeatedFieldAccessor { 3120 RepeatedMessageFieldAccessor( 3121 final FieldDescriptor descriptor, 3122 final String camelCaseName, 3123 final Class<? extends GeneratedMessage> messageClass, 3124 final Class<? extends Builder<?>> builderClass) { 3125 super(camelCaseName, messageClass, builderClass); 3126 3127 newBuilderMethod = getMethodOrDie(type, "newBuilder"); 3128 getBuilderMethodBuilder = 3129 getMethodOrDie(builderClass, "get" + camelCaseName + "Builder", Integer.TYPE); 3130 } 3131 3132 private final Method newBuilderMethod; 3133 private final Method getBuilderMethodBuilder; 3134 3135 private Object coerceType(final Object value) { 3136 if (type.isInstance(value)) { 3137 return value; 3138 } else { 3139 // The value is not the exact right message type. However, if it 3140 // is an alternative implementation of the same type -- e.g. a 3141 // DynamicMessage -- we should accept it. In this case we can make 3142 // a copy of the message. 3143 return ((Message.Builder) invokeOrDie(newBuilderMethod, null)) 3144 .mergeFrom((Message) value) 3145 .build(); 3146 } 3147 } 3148 3149 @Override 3150 public void setRepeated(final Builder<?> builder, final int index, final Object value) { 3151 super.setRepeated(builder, index, coerceType(value)); 3152 } 3153 3154 @Override 3155 public void addRepeated(final Builder<?> builder, final Object value) { 3156 super.addRepeated(builder, coerceType(value)); 3157 } 3158 3159 @Override 3160 public Message.Builder newBuilder() { 3161 return (Message.Builder) invokeOrDie(newBuilderMethod, null); 3162 } 3163 3164 @Override 3165 public Message.Builder getRepeatedBuilder( 3166 final GeneratedMessage.Builder<?> builder, final int index) { 3167 return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder, index); 3168 } 3169 } 3170 } 3171 3172 /** 3173 * Replaces this object in the output stream with a serialized form. Part of Java's serialization 3174 * magic. Generated sub-classes must override this method by calling {@code return 3175 * super.writeReplace();} 3176 * 3177 * @return a SerializedForm of this message 3178 */ 3179 protected Object writeReplace() throws ObjectStreamException { 3180 return new GeneratedMessageLite.SerializedForm(this); 3181 } 3182 3183 /** 3184 * Checks that the {@link Extension} is non-Lite and returns it as a {@link GeneratedExtension}. 3185 */ 3186 private static <MessageT extends ExtendableMessage<MessageT>, T> 3187 Extension<MessageT, T> checkNotLite(ExtensionLite<? extends MessageT, T> extension) { 3188 if (extension.isLite()) { 3189 throw new IllegalArgumentException("Expected non-lite extension."); 3190 } 3191 3192 return (Extension<MessageT, T>) extension; 3193 } 3194 3195 protected static boolean isStringEmpty(final Object value) { 3196 if (value instanceof String) { 3197 return ((String) value).isEmpty(); 3198 } else { 3199 return ((ByteString) value).isEmpty(); 3200 } 3201 } 3202 3203 protected static int computeStringSize(final int fieldNumber, final Object value) { 3204 if (value instanceof String) { 3205 return CodedOutputStream.computeStringSize(fieldNumber, (String) value); 3206 } else { 3207 return CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) value); 3208 } 3209 } 3210 3211 protected static int computeStringSizeNoTag(final Object value) { 3212 if (value instanceof String) { 3213 return CodedOutputStream.computeStringSizeNoTag((String) value); 3214 } else { 3215 return CodedOutputStream.computeBytesSizeNoTag((ByteString) value); 3216 } 3217 } 3218 3219 protected static void writeString( 3220 CodedOutputStream output, final int fieldNumber, final Object value) throws IOException { 3221 if (value instanceof String) { 3222 output.writeString(fieldNumber, (String) value); 3223 } else { 3224 output.writeBytes(fieldNumber, (ByteString) value); 3225 } 3226 } 3227 3228 protected static void writeStringNoTag(CodedOutputStream output, final Object value) 3229 throws IOException { 3230 if (value instanceof String) { 3231 output.writeStringNoTag((String) value); 3232 } else { 3233 output.writeBytesNoTag((ByteString) value); 3234 } 3235 } 3236 3237 protected static <V> void serializeIntegerMapTo( 3238 CodedOutputStream out, 3239 MapField<Integer, V> field, 3240 MapEntry<Integer, V> defaultEntry, 3241 int fieldNumber) 3242 throws IOException { 3243 Map<Integer, V> m = field.getMap(); 3244 if (!out.isSerializationDeterministic()) { 3245 serializeMapTo(out, m, defaultEntry, fieldNumber); 3246 return; 3247 } 3248 // Sorting the unboxed keys and then look up the values during serialization is 2x faster 3249 // than sorting map entries with a custom comparator directly. 3250 int[] keys = new int[m.size()]; 3251 int index = 0; 3252 for (int k : m.keySet()) { 3253 keys[index++] = k; 3254 } 3255 Arrays.sort(keys); 3256 for (int key : keys) { 3257 out.writeMessage( 3258 fieldNumber, defaultEntry.newBuilderForType().setKey(key).setValue(m.get(key)).build()); 3259 } 3260 } 3261 3262 protected static <V> void serializeLongMapTo( 3263 CodedOutputStream out, 3264 MapField<Long, V> field, 3265 MapEntry<Long, V> defaultEntry, 3266 int fieldNumber) 3267 throws IOException { 3268 Map<Long, V> m = field.getMap(); 3269 if (!out.isSerializationDeterministic()) { 3270 serializeMapTo(out, m, defaultEntry, fieldNumber); 3271 return; 3272 } 3273 3274 long[] keys = new long[m.size()]; 3275 int index = 0; 3276 for (long k : m.keySet()) { 3277 keys[index++] = k; 3278 } 3279 Arrays.sort(keys); 3280 for (long key : keys) { 3281 out.writeMessage( 3282 fieldNumber, defaultEntry.newBuilderForType().setKey(key).setValue(m.get(key)).build()); 3283 } 3284 } 3285 3286 protected static <V> void serializeStringMapTo( 3287 CodedOutputStream out, 3288 MapField<String, V> field, 3289 MapEntry<String, V> defaultEntry, 3290 int fieldNumber) 3291 throws IOException { 3292 Map<String, V> m = field.getMap(); 3293 if (!out.isSerializationDeterministic()) { 3294 serializeMapTo(out, m, defaultEntry, fieldNumber); 3295 return; 3296 } 3297 3298 // Sorting the String keys and then look up the values during serialization is 25% faster than 3299 // sorting map entries with a custom comparator directly. 3300 String[] keys = new String[m.size()]; 3301 keys = m.keySet().toArray(keys); 3302 Arrays.sort(keys); 3303 for (String key : keys) { 3304 out.writeMessage( 3305 fieldNumber, defaultEntry.newBuilderForType().setKey(key).setValue(m.get(key)).build()); 3306 } 3307 } 3308 3309 protected static <V> void serializeBooleanMapTo( 3310 CodedOutputStream out, 3311 MapField<Boolean, V> field, 3312 MapEntry<Boolean, V> defaultEntry, 3313 int fieldNumber) 3314 throws IOException { 3315 Map<Boolean, V> m = field.getMap(); 3316 if (!out.isSerializationDeterministic()) { 3317 serializeMapTo(out, m, defaultEntry, fieldNumber); 3318 return; 3319 } 3320 maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, false); 3321 maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, true); 3322 } 3323 3324 private static <V> void maybeSerializeBooleanEntryTo( 3325 CodedOutputStream out, 3326 Map<Boolean, V> m, 3327 MapEntry<Boolean, V> defaultEntry, 3328 int fieldNumber, 3329 boolean key) 3330 throws IOException { 3331 if (m.containsKey(key)) { 3332 out.writeMessage( 3333 fieldNumber, defaultEntry.newBuilderForType().setKey(key).setValue(m.get(key)).build()); 3334 } 3335 } 3336 3337 /** Serialize the map using the iteration order. */ 3338 private static <K, V> void serializeMapTo( 3339 CodedOutputStream out, Map<K, V> m, MapEntry<K, V> defaultEntry, int fieldNumber) 3340 throws IOException { 3341 for (Map.Entry<K, V> entry : m.entrySet()) { 3342 out.writeMessage( 3343 fieldNumber, 3344 defaultEntry 3345 .newBuilderForType() 3346 .setKey(entry.getKey()) 3347 .setValue(entry.getValue()) 3348 .build()); 3349 } 3350 } 3351 } 3352