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