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