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