1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 package com.google.protobuf; 9 10 import static com.google.protobuf.ArrayDecoders.decodeBoolList; 11 import static com.google.protobuf.ArrayDecoders.decodeBytes; 12 import static com.google.protobuf.ArrayDecoders.decodeBytesList; 13 import static com.google.protobuf.ArrayDecoders.decodeDouble; 14 import static com.google.protobuf.ArrayDecoders.decodeDoubleList; 15 import static com.google.protobuf.ArrayDecoders.decodeExtensionOrUnknownField; 16 import static com.google.protobuf.ArrayDecoders.decodeFixed32; 17 import static com.google.protobuf.ArrayDecoders.decodeFixed32List; 18 import static com.google.protobuf.ArrayDecoders.decodeFixed64; 19 import static com.google.protobuf.ArrayDecoders.decodeFixed64List; 20 import static com.google.protobuf.ArrayDecoders.decodeFloat; 21 import static com.google.protobuf.ArrayDecoders.decodeFloatList; 22 import static com.google.protobuf.ArrayDecoders.decodeGroupList; 23 import static com.google.protobuf.ArrayDecoders.decodeMessageField; 24 import static com.google.protobuf.ArrayDecoders.decodeMessageList; 25 import static com.google.protobuf.ArrayDecoders.decodePackedBoolList; 26 import static com.google.protobuf.ArrayDecoders.decodePackedDoubleList; 27 import static com.google.protobuf.ArrayDecoders.decodePackedFixed32List; 28 import static com.google.protobuf.ArrayDecoders.decodePackedFixed64List; 29 import static com.google.protobuf.ArrayDecoders.decodePackedFloatList; 30 import static com.google.protobuf.ArrayDecoders.decodePackedSInt32List; 31 import static com.google.protobuf.ArrayDecoders.decodePackedSInt64List; 32 import static com.google.protobuf.ArrayDecoders.decodePackedVarint32List; 33 import static com.google.protobuf.ArrayDecoders.decodePackedVarint64List; 34 import static com.google.protobuf.ArrayDecoders.decodeSInt32List; 35 import static com.google.protobuf.ArrayDecoders.decodeSInt64List; 36 import static com.google.protobuf.ArrayDecoders.decodeString; 37 import static com.google.protobuf.ArrayDecoders.decodeStringList; 38 import static com.google.protobuf.ArrayDecoders.decodeStringListRequireUtf8; 39 import static com.google.protobuf.ArrayDecoders.decodeStringRequireUtf8; 40 import static com.google.protobuf.ArrayDecoders.decodeUnknownField; 41 import static com.google.protobuf.ArrayDecoders.decodeVarint32; 42 import static com.google.protobuf.ArrayDecoders.decodeVarint32List; 43 import static com.google.protobuf.ArrayDecoders.decodeVarint64; 44 import static com.google.protobuf.ArrayDecoders.decodeVarint64List; 45 import static com.google.protobuf.ArrayDecoders.mergeGroupField; 46 import static com.google.protobuf.ArrayDecoders.mergeMessageField; 47 import static com.google.protobuf.ArrayDecoders.skipField; 48 49 import com.google.protobuf.ArrayDecoders.Registers; 50 import com.google.protobuf.ByteString.CodedBuilder; 51 import com.google.protobuf.FieldSet.FieldDescriptorLite; 52 import com.google.protobuf.Internal.EnumVerifier; 53 import com.google.protobuf.Internal.ProtobufList; 54 import com.google.protobuf.MapEntryLite.Metadata; 55 import java.io.IOException; 56 import java.lang.reflect.Field; 57 import java.util.Arrays; 58 import java.util.Iterator; 59 import java.util.List; 60 import java.util.Map; 61 62 /** Schema used for standard messages. */ 63 @CheckReturnValue 64 final class MessageSchema<T> implements Schema<T> { 65 private static final int INTS_PER_FIELD = 3; 66 private static final int OFFSET_BITS = 20; 67 private static final int OFFSET_MASK = 0XFFFFF; 68 private static final int FIELD_TYPE_MASK = 0x0FF00000; 69 private static final int REQUIRED_MASK = 0x10000000; 70 private static final int ENFORCE_UTF8_MASK = 0x20000000; 71 private static final int LEGACY_ENUM_IS_CLOSED_MASK = 0x80000000; 72 private static final int NO_PRESENCE_SENTINEL = -1 & OFFSET_MASK; 73 private static final int[] EMPTY_INT_ARRAY = new int[0]; 74 75 /** 76 * Bit masks for field type extra feature bits encoded in Java gencode via 77 * GetExperimentalJavaFieldType in helpers.cc. 78 */ 79 private static final int REQUIRED_BIT = 0x100; 80 81 private static final int UTF8_CHECK_BIT = 0x200; 82 private static final int CHECK_INITIALIZED_BIT = 0x400; 83 private static final int LEGACY_ENUM_IS_CLOSED_BIT = 0x800; 84 private static final int HAS_HAS_BIT = 0x1000; 85 86 /** An offset applied to the field type ID for scalar fields that are a member of a oneof. */ 87 static final int ONEOF_TYPE_OFFSET = 51 /* FieldType.MAP + 1 */; 88 89 /** 90 * Keep a direct reference to the unsafe object so we don't need to go through the UnsafeUtil 91 * wrapper for every call. 92 */ 93 private static final sun.misc.Unsafe UNSAFE = UnsafeUtil.getUnsafe(); 94 95 /** 96 * Holds all information for accessing the message fields. The layout is as follows (field 97 * positions are relative to the offset of the start of the field in the buffer): 98 * 99 * <p> 100 * 101 * <pre> 102 * buffer[i] 103 * [ 0 - 3] unused 104 * [ 4 - 31] field number 105 * 106 * buffer[i+1] 107 * [32 - 33] unused 108 * [34 - 34] whether UTF-8 enforcement should be applied to a string field. 109 * [35 - 35] whether the field is required 110 * [36 - 43] field type / for oneof: field type + {@link #ONEOF_TYPE_OFFSET} 111 * [44 - 63] field offset / oneof value field offset 112 * 113 * buffer[i+2] 114 * [64 - 69] unused 115 * [70 - 75] field presence mask shift (unused for oneof/repeated fields) 116 * [76 - 95] presence field offset / oneof case field offset / cached size field offset 117 * </pre> 118 * 119 * Offset refer to the field offsets returned by Unsafe.objectFieldOffset() for reflective access 120 * to corresponding field. 121 * 122 * <p>Note that presence field offset can only use 20 bits - 1. All bits set to 1 is the sentinel 123 * value for non-presence. This is not validated at runtime, we simply assume message layouts will 124 * not exceed 1MB (assuming ~10 bytes per field, that implies 100k fields which should hit other 125 * javac limits first). This corresponds to a shared bitFieldN_, which must have the field 126 * presence mask shift applied to get the corresponding field's presence. 127 */ 128 private final int[] buffer; 129 130 /** 131 * Holds object references for fields. For each field entry in {@code buffer}, there are two 132 * corresponding entries in this array. The content is different from different field types: 133 * 134 * <pre> 135 * Map fields: 136 * objects[pos] = map default entry instance 137 * objects[pos + 1] = EnumVerifier if map value is enum, or message class reference if map 138 * value is message. 139 * Message fields: 140 * objects[pos] = null or cached message schema 141 * objects[pos + 1] = message class reference 142 * Enum fields: 143 * objects[pos] = null 144 * objects[pos + 1] = EnumVerifier 145 * </pre> 146 */ 147 private final Object[] objects; 148 149 private final int minFieldNumber; 150 private final int maxFieldNumber; 151 152 private final MessageLite defaultInstance; 153 private final boolean hasExtensions; 154 private final boolean lite; 155 // TODO: Make both full-runtime and lite-runtime support cached field size. 156 private final boolean useCachedSizeField; 157 158 /** Represents [checkInitialized positions, map field positions, repeated field offsets]. */ 159 private final int[] intArray; 160 161 /** 162 * Values at indices 0 -> checkInitializedCount in intArray are positions to check for 163 * initialization. 164 */ 165 private final int checkInitializedCount; 166 167 /** 168 * Values at indices checkInitializedCount -> repeatedFieldOffsetStart are map positions. 169 * Everything after that are repeated field offsets. 170 */ 171 private final int repeatedFieldOffsetStart; 172 173 private final NewInstanceSchema newInstanceSchema; 174 private final ListFieldSchema listFieldSchema; 175 private final UnknownFieldSchema<?, ?> unknownFieldSchema; 176 private final ExtensionSchema<?> extensionSchema; 177 private final MapFieldSchema mapFieldSchema; 178 MessageSchema( int[] buffer, Object[] objects, int minFieldNumber, int maxFieldNumber, MessageLite defaultInstance, boolean useCachedSizeField, int[] intArray, int checkInitialized, int mapFieldPositions, NewInstanceSchema newInstanceSchema, ListFieldSchema listFieldSchema, UnknownFieldSchema<?, ?> unknownFieldSchema, ExtensionSchema<?> extensionSchema, MapFieldSchema mapFieldSchema)179 private MessageSchema( 180 int[] buffer, 181 Object[] objects, 182 int minFieldNumber, 183 int maxFieldNumber, 184 MessageLite defaultInstance, 185 boolean useCachedSizeField, 186 int[] intArray, 187 int checkInitialized, 188 int mapFieldPositions, 189 NewInstanceSchema newInstanceSchema, 190 ListFieldSchema listFieldSchema, 191 UnknownFieldSchema<?, ?> unknownFieldSchema, 192 ExtensionSchema<?> extensionSchema, 193 MapFieldSchema mapFieldSchema) { 194 this.buffer = buffer; 195 this.objects = objects; 196 this.minFieldNumber = minFieldNumber; 197 this.maxFieldNumber = maxFieldNumber; 198 199 this.lite = defaultInstance instanceof GeneratedMessageLite; 200 this.hasExtensions = extensionSchema != null && extensionSchema.hasExtensions(defaultInstance); 201 this.useCachedSizeField = useCachedSizeField; 202 203 this.intArray = intArray; 204 this.checkInitializedCount = checkInitialized; 205 this.repeatedFieldOffsetStart = mapFieldPositions; 206 207 this.newInstanceSchema = newInstanceSchema; 208 this.listFieldSchema = listFieldSchema; 209 this.unknownFieldSchema = unknownFieldSchema; 210 this.extensionSchema = extensionSchema; 211 this.defaultInstance = defaultInstance; 212 this.mapFieldSchema = mapFieldSchema; 213 } 214 newSchema( Class<T> messageClass, MessageInfo messageInfo, NewInstanceSchema newInstanceSchema, ListFieldSchema listFieldSchema, UnknownFieldSchema<?, ?> unknownFieldSchema, ExtensionSchema<?> extensionSchema, MapFieldSchema mapFieldSchema)215 static <T> MessageSchema<T> newSchema( 216 Class<T> messageClass, 217 MessageInfo messageInfo, 218 NewInstanceSchema newInstanceSchema, 219 ListFieldSchema listFieldSchema, 220 UnknownFieldSchema<?, ?> unknownFieldSchema, 221 ExtensionSchema<?> extensionSchema, 222 MapFieldSchema mapFieldSchema) { 223 if (messageInfo instanceof RawMessageInfo) { 224 return newSchemaForRawMessageInfo( 225 (RawMessageInfo) messageInfo, 226 newInstanceSchema, 227 listFieldSchema, 228 unknownFieldSchema, 229 extensionSchema, 230 mapFieldSchema); 231 232 } else { 233 return newSchemaForMessageInfo( 234 (StructuralMessageInfo) messageInfo, 235 newInstanceSchema, 236 listFieldSchema, 237 unknownFieldSchema, 238 extensionSchema, 239 mapFieldSchema); 240 } 241 } 242 newSchemaForRawMessageInfo( RawMessageInfo messageInfo, NewInstanceSchema newInstanceSchema, ListFieldSchema listFieldSchema, UnknownFieldSchema<?, ?> unknownFieldSchema, ExtensionSchema<?> extensionSchema, MapFieldSchema mapFieldSchema)243 static <T> MessageSchema<T> newSchemaForRawMessageInfo( 244 RawMessageInfo messageInfo, 245 NewInstanceSchema newInstanceSchema, 246 ListFieldSchema listFieldSchema, 247 UnknownFieldSchema<?, ?> unknownFieldSchema, 248 ExtensionSchema<?> extensionSchema, 249 MapFieldSchema mapFieldSchema) { 250 String info = messageInfo.getStringInfo(); 251 final int length = info.length(); 252 int i = 0; 253 254 int next = info.charAt(i++); 255 if (next >= 0xD800) { 256 int result = next & 0x1FFF; 257 int shift = 13; 258 while ((next = info.charAt(i++)) >= 0xD800) { 259 result |= (next & 0x1FFF) << shift; 260 shift += 13; 261 } 262 next = result | (next << shift); 263 } 264 final int unusedFlags = next; 265 266 next = info.charAt(i++); 267 if (next >= 0xD800) { 268 int result = next & 0x1FFF; 269 int shift = 13; 270 while ((next = info.charAt(i++)) >= 0xD800) { 271 result |= (next & 0x1FFF) << shift; 272 shift += 13; 273 } 274 next = result | (next << shift); 275 } 276 final int fieldCount = next; 277 278 final int oneofCount; 279 final int hasBitsCount; 280 final int minFieldNumber; 281 final int maxFieldNumber; 282 final int numEntries; 283 final int mapFieldCount; 284 final int repeatedFieldCount; 285 final int checkInitialized; 286 final int[] intArray; 287 int objectsPosition; 288 if (fieldCount == 0) { 289 oneofCount = 0; 290 hasBitsCount = 0; 291 minFieldNumber = 0; 292 maxFieldNumber = 0; 293 numEntries = 0; 294 mapFieldCount = 0; 295 repeatedFieldCount = 0; 296 checkInitialized = 0; 297 intArray = EMPTY_INT_ARRAY; 298 objectsPosition = 0; 299 } else { 300 next = info.charAt(i++); 301 if (next >= 0xD800) { 302 int result = next & 0x1FFF; 303 int shift = 13; 304 while ((next = info.charAt(i++)) >= 0xD800) { 305 result |= (next & 0x1FFF) << shift; 306 shift += 13; 307 } 308 next = result | (next << shift); 309 } 310 oneofCount = next; 311 312 next = info.charAt(i++); 313 if (next >= 0xD800) { 314 int result = next & 0x1FFF; 315 int shift = 13; 316 while ((next = info.charAt(i++)) >= 0xD800) { 317 result |= (next & 0x1FFF) << shift; 318 shift += 13; 319 } 320 next = result | (next << shift); 321 } 322 hasBitsCount = next; 323 324 next = info.charAt(i++); 325 if (next >= 0xD800) { 326 int result = next & 0x1FFF; 327 int shift = 13; 328 while ((next = info.charAt(i++)) >= 0xD800) { 329 result |= (next & 0x1FFF) << shift; 330 shift += 13; 331 } 332 next = result | (next << shift); 333 } 334 minFieldNumber = next; 335 336 next = info.charAt(i++); 337 if (next >= 0xD800) { 338 int result = next & 0x1FFF; 339 int shift = 13; 340 while ((next = info.charAt(i++)) >= 0xD800) { 341 result |= (next & 0x1FFF) << shift; 342 shift += 13; 343 } 344 next = result | (next << shift); 345 } 346 maxFieldNumber = next; 347 348 next = info.charAt(i++); 349 if (next >= 0xD800) { 350 int result = next & 0x1FFF; 351 int shift = 13; 352 while ((next = info.charAt(i++)) >= 0xD800) { 353 result |= (next & 0x1FFF) << shift; 354 shift += 13; 355 } 356 next = result | (next << shift); 357 } 358 numEntries = next; 359 360 next = info.charAt(i++); 361 if (next >= 0xD800) { 362 int result = next & 0x1FFF; 363 int shift = 13; 364 while ((next = info.charAt(i++)) >= 0xD800) { 365 result |= (next & 0x1FFF) << shift; 366 shift += 13; 367 } 368 next = result | (next << shift); 369 } 370 mapFieldCount = next; 371 372 next = info.charAt(i++); 373 if (next >= 0xD800) { 374 int result = next & 0x1FFF; 375 int shift = 13; 376 while ((next = info.charAt(i++)) >= 0xD800) { 377 result |= (next & 0x1FFF) << shift; 378 shift += 13; 379 } 380 next = result | (next << shift); 381 } 382 repeatedFieldCount = next; 383 384 next = info.charAt(i++); 385 if (next >= 0xD800) { 386 int result = next & 0x1FFF; 387 int shift = 13; 388 while ((next = info.charAt(i++)) >= 0xD800) { 389 result |= (next & 0x1FFF) << shift; 390 shift += 13; 391 } 392 next = result | (next << shift); 393 } 394 checkInitialized = next; 395 intArray = new int[checkInitialized + mapFieldCount + repeatedFieldCount]; 396 // Field objects are after a list of (oneof, oneofCase) pairs + a list of hasbits fields. 397 objectsPosition = oneofCount * 2 + hasBitsCount; 398 } 399 400 final sun.misc.Unsafe unsafe = UNSAFE; 401 final Object[] messageInfoObjects = messageInfo.getObjects(); 402 int checkInitializedPosition = 0; 403 final Class<?> messageClass = messageInfo.getDefaultInstance().getClass(); 404 int[] buffer = new int[numEntries * INTS_PER_FIELD]; 405 Object[] objects = new Object[numEntries * 2]; 406 407 int mapFieldIndex = checkInitialized; 408 int repeatedFieldIndex = checkInitialized + mapFieldCount; 409 410 int bufferIndex = 0; 411 while (i < length) { 412 final int fieldNumber; 413 final int fieldTypeWithExtraBits; 414 final int fieldType; 415 416 next = info.charAt(i++); 417 if (next >= 0xD800) { 418 int result = next & 0x1FFF; 419 int shift = 13; 420 while ((next = info.charAt(i++)) >= 0xD800) { 421 result |= (next & 0x1FFF) << shift; 422 shift += 13; 423 } 424 next = result | (next << shift); 425 } 426 fieldNumber = next; 427 428 next = info.charAt(i++); 429 if (next >= 0xD800) { 430 int result = next & 0x1FFF; 431 int shift = 13; 432 while ((next = info.charAt(i++)) >= 0xD800) { 433 result |= (next & 0x1FFF) << shift; 434 shift += 13; 435 } 436 next = result | (next << shift); 437 } 438 fieldTypeWithExtraBits = next; 439 fieldType = fieldTypeWithExtraBits & 0xFF; 440 441 if ((fieldTypeWithExtraBits & CHECK_INITIALIZED_BIT) != 0) { 442 intArray[checkInitializedPosition++] = bufferIndex; 443 } 444 445 final int fieldOffset; 446 final int presenceMaskShift; 447 final int presenceFieldOffset; 448 449 // Oneof 450 if (fieldType >= ONEOF_TYPE_OFFSET) { 451 next = info.charAt(i++); 452 if (next >= 0xD800) { 453 int result = next & 0x1FFF; 454 int shift = 13; 455 while ((next = info.charAt(i++)) >= 0xD800) { 456 result |= (next & 0x1FFF) << shift; 457 shift += 13; 458 } 459 next = result | (next << shift); 460 } 461 int oneofIndex = next; 462 463 final int oneofFieldType = fieldType - ONEOF_TYPE_OFFSET; 464 if (oneofFieldType == 9 /* FieldType.MESSAGE */ 465 || oneofFieldType == 17 /* FieldType.GROUP */) { 466 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; 467 } else if (oneofFieldType == 12 /* FieldType.ENUM */) { 468 // TODO: Remove proto2 check once legacy gencode not setting this bit 469 // no longer needs to be supported. 470 if (messageInfo.getSyntax().equals(ProtoSyntax.PROTO2) 471 || (fieldTypeWithExtraBits & LEGACY_ENUM_IS_CLOSED_BIT) != 0) { 472 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; 473 } 474 } 475 476 final java.lang.reflect.Field oneofField; 477 int index = oneofIndex * 2; 478 Object o = messageInfoObjects[index]; 479 if (o instanceof java.lang.reflect.Field) { 480 oneofField = (java.lang.reflect.Field) o; 481 } else { 482 oneofField = reflectField(messageClass, (String) o); 483 // Memoize java.lang.reflect.Field instances for oneof/hasbits fields, since they're 484 // potentially used for many Protobuf fields. Since there's a 1-1 mapping from the 485 // Protobuf field to the Java Field for non-oneofs, there's no benefit for memoizing 486 // those. 487 messageInfoObjects[index] = oneofField; 488 } 489 490 fieldOffset = (int) unsafe.objectFieldOffset(oneofField); 491 492 final java.lang.reflect.Field oneofCaseField; 493 index++; 494 o = messageInfoObjects[index]; 495 if (o instanceof java.lang.reflect.Field) { 496 oneofCaseField = (java.lang.reflect.Field) o; 497 } else { 498 oneofCaseField = reflectField(messageClass, (String) o); 499 messageInfoObjects[index] = oneofCaseField; 500 } 501 502 presenceFieldOffset = (int) unsafe.objectFieldOffset(oneofCaseField); 503 presenceMaskShift = 0; 504 } else { 505 Field field = reflectField(messageClass, (String) messageInfoObjects[objectsPosition++]); 506 if (fieldType == 9 /* FieldType.MESSAGE */ || fieldType == 17 /* FieldType.GROUP */) { 507 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = field.getType(); 508 } else if (fieldType == 27 /* FieldType.MESSAGE_LIST */ 509 || fieldType == 49 /* FieldType.GROUP_LIST */) { 510 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; 511 } else if (fieldType == 12 /* FieldType.ENUM */ 512 || fieldType == 30 /* FieldType.ENUM_LIST */ 513 || fieldType == 44 /* FieldType.ENUM_LIST_PACKED */) { 514 // TODO: Remove proto2 check once legacy gencode not setting this bit 515 // no longer needs to be supported. 516 if (messageInfo.getSyntax() == ProtoSyntax.PROTO2 517 || (fieldTypeWithExtraBits & LEGACY_ENUM_IS_CLOSED_BIT) != 0) { 518 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; 519 } 520 } else if (fieldType == 50 /* FieldType.MAP */) { 521 intArray[mapFieldIndex++] = bufferIndex; 522 objects[bufferIndex / INTS_PER_FIELD * 2] = messageInfoObjects[objectsPosition++]; 523 if ((fieldTypeWithExtraBits & LEGACY_ENUM_IS_CLOSED_BIT) != 0) { 524 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageInfoObjects[objectsPosition++]; 525 } 526 } 527 528 fieldOffset = (int) unsafe.objectFieldOffset(field); 529 boolean hasHasBit = (fieldTypeWithExtraBits & HAS_HAS_BIT) != 0; 530 if (hasHasBit && fieldType <= 17 /* FieldType.GROUP */) { 531 next = info.charAt(i++); 532 if (next >= 0xD800) { 533 int result = next & 0x1FFF; 534 int shift = 13; 535 while ((next = info.charAt(i++)) >= 0xD800) { 536 result |= (next & 0x1FFF) << shift; 537 shift += 13; 538 } 539 next = result | (next << shift); 540 } 541 int hasBitsIndex = next; 542 543 final java.lang.reflect.Field hasBitsField; 544 int index = oneofCount * 2 + hasBitsIndex / 32; 545 Object o = messageInfoObjects[index]; 546 if (o instanceof java.lang.reflect.Field) { 547 hasBitsField = (java.lang.reflect.Field) o; 548 } else { 549 hasBitsField = reflectField(messageClass, (String) o); 550 messageInfoObjects[index] = hasBitsField; 551 } 552 553 presenceFieldOffset = (int) unsafe.objectFieldOffset(hasBitsField); 554 presenceMaskShift = hasBitsIndex % 32; 555 } else { 556 presenceFieldOffset = NO_PRESENCE_SENTINEL; 557 presenceMaskShift = 0; 558 } 559 560 if (fieldType >= 18 && fieldType <= 49) { 561 // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to 562 // 49 (GROUP_LIST). 563 intArray[repeatedFieldIndex++] = fieldOffset; 564 } 565 } 566 567 buffer[bufferIndex++] = fieldNumber; 568 buffer[bufferIndex++] = 569 ((fieldTypeWithExtraBits & UTF8_CHECK_BIT) != 0 ? ENFORCE_UTF8_MASK : 0) 570 | ((fieldTypeWithExtraBits & REQUIRED_BIT) != 0 ? REQUIRED_MASK : 0) 571 | ((fieldTypeWithExtraBits & LEGACY_ENUM_IS_CLOSED_BIT) != 0 572 ? LEGACY_ENUM_IS_CLOSED_MASK 573 : 0) 574 | (fieldType << OFFSET_BITS) 575 | fieldOffset; 576 buffer[bufferIndex++] = (presenceMaskShift << OFFSET_BITS) | presenceFieldOffset; 577 } 578 579 return new MessageSchema<T>( 580 buffer, 581 objects, 582 minFieldNumber, 583 maxFieldNumber, 584 messageInfo.getDefaultInstance(), 585 /* useCachedSizeField= */ false, 586 intArray, 587 checkInitialized, 588 checkInitialized + mapFieldCount, 589 newInstanceSchema, 590 listFieldSchema, 591 unknownFieldSchema, 592 extensionSchema, 593 mapFieldSchema); 594 } 595 reflectField(Class<?> messageClass, String fieldName)596 private static java.lang.reflect.Field reflectField(Class<?> messageClass, String fieldName) { 597 try { 598 return messageClass.getDeclaredField(fieldName); 599 } catch (NoSuchFieldException e) { 600 // Some Samsung devices lie about what fields are present via the getDeclaredField API so 601 // we do the for loop properly that they seem to have messed up... 602 java.lang.reflect.Field[] fields = messageClass.getDeclaredFields(); 603 for (java.lang.reflect.Field field : fields) { 604 if (fieldName.equals(field.getName())) { 605 return field; 606 } 607 } 608 609 // If we make it here, the runtime still lies about what we know to be true at compile 610 // time. We throw to alert server monitoring for further remediation. 611 throw new RuntimeException( 612 "Field " 613 + fieldName 614 + " for " 615 + messageClass.getName() 616 + " not found. Known fields are " 617 + Arrays.toString(fields)); 618 } 619 } 620 newSchemaForMessageInfo( StructuralMessageInfo messageInfo, NewInstanceSchema newInstanceSchema, ListFieldSchema listFieldSchema, UnknownFieldSchema<?, ?> unknownFieldSchema, ExtensionSchema<?> extensionSchema, MapFieldSchema mapFieldSchema)621 static <T> MessageSchema<T> newSchemaForMessageInfo( 622 StructuralMessageInfo messageInfo, 623 NewInstanceSchema newInstanceSchema, 624 ListFieldSchema listFieldSchema, 625 UnknownFieldSchema<?, ?> unknownFieldSchema, 626 ExtensionSchema<?> extensionSchema, 627 MapFieldSchema mapFieldSchema) { 628 FieldInfo[] fis = messageInfo.getFields(); 629 final int minFieldNumber; 630 final int maxFieldNumber; 631 if (fis.length == 0) { 632 minFieldNumber = 0; 633 maxFieldNumber = 0; 634 } else { 635 minFieldNumber = fis[0].getFieldNumber(); 636 maxFieldNumber = fis[fis.length - 1].getFieldNumber(); 637 } 638 639 final int numEntries = fis.length; 640 641 int[] buffer = new int[numEntries * INTS_PER_FIELD]; 642 Object[] objects = new Object[numEntries * 2]; 643 644 int mapFieldCount = 0; 645 int repeatedFieldCount = 0; 646 for (FieldInfo fi : fis) { 647 if (fi.getType() == FieldType.MAP) { 648 mapFieldCount++; 649 } else if (fi.getType().id() >= 18 && fi.getType().id() <= 49) { 650 // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to 651 // 49 (GROUP_LIST). 652 repeatedFieldCount++; 653 } 654 } 655 int[] mapFieldPositions = mapFieldCount > 0 ? new int[mapFieldCount] : null; 656 int[] repeatedFieldOffsets = repeatedFieldCount > 0 ? new int[repeatedFieldCount] : null; 657 mapFieldCount = 0; 658 repeatedFieldCount = 0; 659 660 int[] checkInitialized = messageInfo.getCheckInitialized(); 661 if (checkInitialized == null) { 662 checkInitialized = EMPTY_INT_ARRAY; 663 } 664 int checkInitializedIndex = 0; 665 // Fill in the manifest data from the descriptors. 666 int fieldIndex = 0; 667 for (int bufferIndex = 0; fieldIndex < fis.length; bufferIndex += INTS_PER_FIELD) { 668 final FieldInfo fi = fis[fieldIndex]; 669 final int fieldNumber = fi.getFieldNumber(); 670 671 // We found the entry for the next field. Store the entry in the manifest for 672 // this field and increment the field index. 673 storeFieldData(fi, buffer, bufferIndex, objects); 674 675 // Convert field number to index 676 if (checkInitializedIndex < checkInitialized.length 677 && checkInitialized[checkInitializedIndex] == fieldNumber) { 678 checkInitialized[checkInitializedIndex++] = bufferIndex; 679 } 680 681 if (fi.getType() == FieldType.MAP) { 682 mapFieldPositions[mapFieldCount++] = bufferIndex; 683 } else if (fi.getType().id() >= 18 && fi.getType().id() <= 49) { 684 // Field types of repeated fields are in a consecutive range from 18 (DOUBLE_LIST) to 685 // 49 (GROUP_LIST). 686 repeatedFieldOffsets[repeatedFieldCount++] = 687 (int) UnsafeUtil.objectFieldOffset(fi.getField()); 688 } 689 690 fieldIndex++; 691 } 692 693 if (mapFieldPositions == null) { 694 mapFieldPositions = EMPTY_INT_ARRAY; 695 } 696 if (repeatedFieldOffsets == null) { 697 repeatedFieldOffsets = EMPTY_INT_ARRAY; 698 } 699 int combinedLength = 700 checkInitialized.length + mapFieldPositions.length + repeatedFieldOffsets.length; 701 int[] combined; 702 if (combinedLength > 0) { 703 combined = new int[combinedLength]; 704 System.arraycopy(checkInitialized, 0, combined, 0, checkInitialized.length); 705 System.arraycopy( 706 mapFieldPositions, 0, combined, checkInitialized.length, mapFieldPositions.length); 707 System.arraycopy( 708 repeatedFieldOffsets, 709 0, 710 combined, 711 checkInitialized.length + mapFieldPositions.length, 712 repeatedFieldOffsets.length); 713 } else { 714 combined = EMPTY_INT_ARRAY; 715 } 716 717 return new MessageSchema<T>( 718 buffer, 719 objects, 720 minFieldNumber, 721 maxFieldNumber, 722 messageInfo.getDefaultInstance(), 723 /* useCachedSizeField= */ true, 724 combined, 725 checkInitialized.length, 726 checkInitialized.length + mapFieldPositions.length, 727 newInstanceSchema, 728 listFieldSchema, 729 unknownFieldSchema, 730 extensionSchema, 731 mapFieldSchema); 732 } 733 storeFieldData( FieldInfo fi, int[] buffer, int bufferIndex, Object[] objects)734 private static void storeFieldData( 735 FieldInfo fi, int[] buffer, int bufferIndex, Object[] objects) { 736 final int fieldOffset; 737 final int typeId; 738 final int presenceMaskShift; 739 final int presenceFieldOffset; 740 741 OneofInfo oneof = fi.getOneof(); 742 if (oneof != null) { 743 typeId = fi.getType().id() + ONEOF_TYPE_OFFSET; 744 fieldOffset = (int) UnsafeUtil.objectFieldOffset(oneof.getValueField()); 745 presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(oneof.getCaseField()); 746 presenceMaskShift = 0; 747 } else { 748 FieldType type = fi.getType(); 749 fieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getField()); 750 typeId = type.id(); 751 if (!type.isList() && !type.isMap()) { 752 Field presenceField = fi.getPresenceField(); 753 if (presenceField == null) { 754 presenceFieldOffset = NO_PRESENCE_SENTINEL; 755 } else { 756 presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(presenceField); 757 } 758 presenceMaskShift = Integer.numberOfTrailingZeros(fi.getPresenceMask()); 759 } else { 760 if (fi.getCachedSizeField() == null) { 761 presenceFieldOffset = 0; 762 presenceMaskShift = 0; 763 } else { 764 presenceFieldOffset = (int) UnsafeUtil.objectFieldOffset(fi.getCachedSizeField()); 765 presenceMaskShift = 0; 766 } 767 } 768 } 769 770 buffer[bufferIndex] = fi.getFieldNumber(); 771 buffer[bufferIndex + 1] = 772 (fi.isEnforceUtf8() ? ENFORCE_UTF8_MASK : 0) 773 | (fi.isRequired() ? REQUIRED_MASK : 0) 774 | (typeId << OFFSET_BITS) 775 | fieldOffset; 776 buffer[bufferIndex + 2] = (presenceMaskShift << OFFSET_BITS) | presenceFieldOffset; 777 778 Object messageFieldClass = fi.getMessageFieldClass(); 779 if (fi.getMapDefaultEntry() != null) { 780 objects[bufferIndex / INTS_PER_FIELD * 2] = fi.getMapDefaultEntry(); 781 if (messageFieldClass != null) { 782 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageFieldClass; 783 } else if (fi.getEnumVerifier() != null) { 784 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = fi.getEnumVerifier(); 785 } 786 } else { 787 if (messageFieldClass != null) { 788 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = messageFieldClass; 789 } else if (fi.getEnumVerifier() != null) { 790 objects[bufferIndex / INTS_PER_FIELD * 2 + 1] = fi.getEnumVerifier(); 791 } 792 } 793 } 794 795 @SuppressWarnings("unchecked") 796 @Override newInstance()797 public T newInstance() { 798 return (T) newInstanceSchema.newInstance(defaultInstance); 799 } 800 801 @Override equals(T message, T other)802 public boolean equals(T message, T other) { 803 final int bufferLength = buffer.length; 804 for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) { 805 if (!equals(message, other, pos)) { 806 return false; 807 } 808 } 809 810 Object messageUnknown = unknownFieldSchema.getFromMessage(message); 811 Object otherUnknown = unknownFieldSchema.getFromMessage(other); 812 if (!messageUnknown.equals(otherUnknown)) { 813 return false; 814 } 815 816 if (hasExtensions) { 817 FieldSet<?> messageExtensions = extensionSchema.getExtensions(message); 818 FieldSet<?> otherExtensions = extensionSchema.getExtensions(other); 819 return messageExtensions.equals(otherExtensions); 820 } 821 return true; 822 } 823 equals(T message, T other, int pos)824 private boolean equals(T message, T other, int pos) { 825 final int typeAndOffset = typeAndOffsetAt(pos); 826 final long offset = offset(typeAndOffset); 827 828 switch (type(typeAndOffset)) { 829 case 0: // DOUBLE: 830 return arePresentForEquals(message, other, pos) 831 && Double.doubleToLongBits(UnsafeUtil.getDouble(message, offset)) 832 == Double.doubleToLongBits(UnsafeUtil.getDouble(other, offset)); 833 case 1: // FLOAT: 834 return arePresentForEquals(message, other, pos) 835 && Float.floatToIntBits(UnsafeUtil.getFloat(message, offset)) 836 == Float.floatToIntBits(UnsafeUtil.getFloat(other, offset)); 837 case 2: // INT64: 838 return arePresentForEquals(message, other, pos) 839 && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset); 840 case 3: // UINT64: 841 return arePresentForEquals(message, other, pos) 842 && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset); 843 case 4: // INT32: 844 return arePresentForEquals(message, other, pos) 845 && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset); 846 case 5: // FIXED64: 847 return arePresentForEquals(message, other, pos) 848 && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset); 849 case 6: // FIXED32: 850 return arePresentForEquals(message, other, pos) 851 && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset); 852 case 7: // BOOL: 853 return arePresentForEquals(message, other, pos) 854 && UnsafeUtil.getBoolean(message, offset) == UnsafeUtil.getBoolean(other, offset); 855 case 8: // STRING: 856 return arePresentForEquals(message, other, pos) 857 && SchemaUtil.safeEquals( 858 UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset)); 859 case 9: // MESSAGE: 860 return arePresentForEquals(message, other, pos) 861 && SchemaUtil.safeEquals( 862 UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset)); 863 case 10: // BYTES: 864 return arePresentForEquals(message, other, pos) 865 && SchemaUtil.safeEquals( 866 UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset)); 867 case 11: // UINT32: 868 return arePresentForEquals(message, other, pos) 869 && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset); 870 case 12: // ENUM: 871 return arePresentForEquals(message, other, pos) 872 && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset); 873 case 13: // SFIXED32: 874 return arePresentForEquals(message, other, pos) 875 && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset); 876 case 14: // SFIXED64: 877 return arePresentForEquals(message, other, pos) 878 && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset); 879 case 15: // SINT32: 880 return arePresentForEquals(message, other, pos) 881 && UnsafeUtil.getInt(message, offset) == UnsafeUtil.getInt(other, offset); 882 case 16: // SINT64: 883 return arePresentForEquals(message, other, pos) 884 && UnsafeUtil.getLong(message, offset) == UnsafeUtil.getLong(other, offset); 885 case 17: // GROUP: 886 return arePresentForEquals(message, other, pos) 887 && SchemaUtil.safeEquals( 888 UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset)); 889 890 case 18: // DOUBLE_LIST: 891 case 19: // FLOAT_LIST: 892 case 20: // INT64_LIST: 893 case 21: // UINT64_LIST: 894 case 22: // INT32_LIST: 895 case 23: // FIXED64_LIST: 896 case 24: // FIXED32_LIST: 897 case 25: // BOOL_LIST: 898 case 26: // STRING_LIST: 899 case 27: // MESSAGE_LIST: 900 case 28: // BYTES_LIST: 901 case 29: // UINT32_LIST: 902 case 30: // ENUM_LIST: 903 case 31: // SFIXED32_LIST: 904 case 32: // SFIXED64_LIST: 905 case 33: // SINT32_LIST: 906 case 34: // SINT64_LIST: 907 case 35: // DOUBLE_LIST_PACKED: 908 case 36: // FLOAT_LIST_PACKED: 909 case 37: // INT64_LIST_PACKED: 910 case 38: // UINT64_LIST_PACKED: 911 case 39: // INT32_LIST_PACKED: 912 case 40: // FIXED64_LIST_PACKED: 913 case 41: // FIXED32_LIST_PACKED: 914 case 42: // BOOL_LIST_PACKED: 915 case 43: // UINT32_LIST_PACKED: 916 case 44: // ENUM_LIST_PACKED: 917 case 45: // SFIXED32_LIST_PACKED: 918 case 46: // SFIXED64_LIST_PACKED: 919 case 47: // SINT32_LIST_PACKED: 920 case 48: // SINT64_LIST_PACKED: 921 case 49: // GROUP_LIST: 922 return SchemaUtil.safeEquals( 923 UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset)); 924 case 50: // MAP: 925 return SchemaUtil.safeEquals( 926 UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset)); 927 case 51: // ONEOF_DOUBLE: 928 case 52: // ONEOF_FLOAT: 929 case 53: // ONEOF_INT64: 930 case 54: // ONEOF_UINT64: 931 case 55: // ONEOF_INT32: 932 case 56: // ONEOF_FIXED64: 933 case 57: // ONEOF_FIXED32: 934 case 58: // ONEOF_BOOL: 935 case 59: // ONEOF_STRING: 936 case 60: // ONEOF_MESSAGE: 937 case 61: // ONEOF_BYTES: 938 case 62: // ONEOF_UINT32: 939 case 63: // ONEOF_ENUM: 940 case 64: // ONEOF_SFIXED32: 941 case 65: // ONEOF_SFIXED64: 942 case 66: // ONEOF_SINT32: 943 case 67: // ONEOF_SINT64: 944 case 68: // ONEOF_GROUP: 945 return isOneofCaseEqual(message, other, pos) 946 && SchemaUtil.safeEquals( 947 UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(other, offset)); 948 default: 949 // Assume it's an empty entry - just go to the next entry. 950 return true; 951 } 952 } 953 954 @Override hashCode(T message)955 public int hashCode(T message) { 956 int hashCode = 0; 957 final int bufferLength = buffer.length; 958 for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) { 959 final int typeAndOffset = typeAndOffsetAt(pos); 960 final int entryNumber = numberAt(pos); 961 962 final long offset = offset(typeAndOffset); 963 964 switch (type(typeAndOffset)) { 965 case 0: // DOUBLE: 966 hashCode = 967 (hashCode * 53) 968 + Internal.hashLong( 969 Double.doubleToLongBits(UnsafeUtil.getDouble(message, offset))); 970 break; 971 case 1: // FLOAT: 972 hashCode = (hashCode * 53) + Float.floatToIntBits(UnsafeUtil.getFloat(message, offset)); 973 break; 974 case 2: // INT64: 975 hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset)); 976 break; 977 case 3: // UINT64: 978 hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset)); 979 break; 980 case 4: // INT32: 981 hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset)); 982 break; 983 case 5: // FIXED64: 984 hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset)); 985 break; 986 case 6: // FIXED32: 987 hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset)); 988 break; 989 case 7: // BOOL: 990 hashCode = (hashCode * 53) + Internal.hashBoolean(UnsafeUtil.getBoolean(message, offset)); 991 break; 992 case 8: // STRING: 993 hashCode = (hashCode * 53) + ((String) UnsafeUtil.getObject(message, offset)).hashCode(); 994 break; 995 case 9: // MESSAGE: 996 { 997 int protoHash = 37; 998 Object submessage = UnsafeUtil.getObject(message, offset); 999 if (submessage != null) { 1000 protoHash = submessage.hashCode(); 1001 } 1002 hashCode = (53 * hashCode) + protoHash; 1003 break; 1004 } 1005 case 10: // BYTES: 1006 hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode(); 1007 break; 1008 case 11: // UINT32: 1009 hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset)); 1010 break; 1011 case 12: // ENUM: 1012 hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset)); 1013 break; 1014 case 13: // SFIXED32: 1015 hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset)); 1016 break; 1017 case 14: // SFIXED64: 1018 hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset)); 1019 break; 1020 case 15: // SINT32: 1021 hashCode = (hashCode * 53) + (UnsafeUtil.getInt(message, offset)); 1022 break; 1023 case 16: // SINT64: 1024 hashCode = (hashCode * 53) + Internal.hashLong(UnsafeUtil.getLong(message, offset)); 1025 break; 1026 1027 case 17: // GROUP: 1028 { 1029 int protoHash = 37; 1030 Object submessage = UnsafeUtil.getObject(message, offset); 1031 if (submessage != null) { 1032 protoHash = submessage.hashCode(); 1033 } 1034 hashCode = (53 * hashCode) + protoHash; 1035 break; 1036 } 1037 case 18: // DOUBLE_LIST: 1038 case 19: // FLOAT_LIST: 1039 case 20: // INT64_LIST: 1040 case 21: // UINT64_LIST: 1041 case 22: // INT32_LIST: 1042 case 23: // FIXED64_LIST: 1043 case 24: // FIXED32_LIST: 1044 case 25: // BOOL_LIST: 1045 case 26: // STRING_LIST: 1046 case 27: // MESSAGE_LIST: 1047 case 28: // BYTES_LIST: 1048 case 29: // UINT32_LIST: 1049 case 30: // ENUM_LIST: 1050 case 31: // SFIXED32_LIST: 1051 case 32: // SFIXED64_LIST: 1052 case 33: // SINT32_LIST: 1053 case 34: // SINT64_LIST: 1054 case 35: // DOUBLE_LIST_PACKED: 1055 case 36: // FLOAT_LIST_PACKED: 1056 case 37: // INT64_LIST_PACKED: 1057 case 38: // UINT64_LIST_PACKED: 1058 case 39: // INT32_LIST_PACKED: 1059 case 40: // FIXED64_LIST_PACKED: 1060 case 41: // FIXED32_LIST_PACKED: 1061 case 42: // BOOL_LIST_PACKED: 1062 case 43: // UINT32_LIST_PACKED: 1063 case 44: // ENUM_LIST_PACKED: 1064 case 45: // SFIXED32_LIST_PACKED: 1065 case 46: // SFIXED64_LIST_PACKED: 1066 case 47: // SINT32_LIST_PACKED: 1067 case 48: // SINT64_LIST_PACKED: 1068 case 49: // GROUP_LIST: 1069 hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode(); 1070 break; 1071 case 50: // MAP: 1072 hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode(); 1073 break; 1074 case 51: // ONEOF_DOUBLE: 1075 if (isOneofPresent(message, entryNumber, pos)) { 1076 hashCode = 1077 (hashCode * 53) 1078 + Internal.hashLong(Double.doubleToLongBits(oneofDoubleAt(message, offset))); 1079 } 1080 break; 1081 case 52: // ONEOF_FLOAT: 1082 if (isOneofPresent(message, entryNumber, pos)) { 1083 hashCode = (hashCode * 53) + Float.floatToIntBits(oneofFloatAt(message, offset)); 1084 } 1085 break; 1086 case 53: // ONEOF_INT64: 1087 if (isOneofPresent(message, entryNumber, pos)) { 1088 hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset)); 1089 } 1090 break; 1091 case 54: // ONEOF_UINT64: 1092 if (isOneofPresent(message, entryNumber, pos)) { 1093 hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset)); 1094 } 1095 break; 1096 case 55: // ONEOF_INT32: 1097 if (isOneofPresent(message, entryNumber, pos)) { 1098 hashCode = (hashCode * 53) + (oneofIntAt(message, offset)); 1099 } 1100 break; 1101 case 56: // ONEOF_FIXED64: 1102 if (isOneofPresent(message, entryNumber, pos)) { 1103 hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset)); 1104 } 1105 break; 1106 case 57: // ONEOF_FIXED32: 1107 if (isOneofPresent(message, entryNumber, pos)) { 1108 hashCode = (hashCode * 53) + (oneofIntAt(message, offset)); 1109 } 1110 break; 1111 case 58: // ONEOF_BOOL: 1112 if (isOneofPresent(message, entryNumber, pos)) { 1113 hashCode = (hashCode * 53) + Internal.hashBoolean(oneofBooleanAt(message, offset)); 1114 } 1115 break; 1116 case 59: // ONEOF_STRING: 1117 if (isOneofPresent(message, entryNumber, pos)) { 1118 hashCode = 1119 (hashCode * 53) + ((String) UnsafeUtil.getObject(message, offset)).hashCode(); 1120 } 1121 break; 1122 case 60: // ONEOF_MESSAGE: 1123 if (isOneofPresent(message, entryNumber, pos)) { 1124 Object submessage = UnsafeUtil.getObject(message, offset); 1125 hashCode = (53 * hashCode) + submessage.hashCode(); 1126 } 1127 break; 1128 case 61: // ONEOF_BYTES: 1129 if (isOneofPresent(message, entryNumber, pos)) { 1130 hashCode = (hashCode * 53) + UnsafeUtil.getObject(message, offset).hashCode(); 1131 } 1132 break; 1133 case 62: // ONEOF_UINT32: 1134 if (isOneofPresent(message, entryNumber, pos)) { 1135 hashCode = (hashCode * 53) + (oneofIntAt(message, offset)); 1136 } 1137 break; 1138 case 63: // ONEOF_ENUM: 1139 if (isOneofPresent(message, entryNumber, pos)) { 1140 hashCode = (hashCode * 53) + (oneofIntAt(message, offset)); 1141 } 1142 break; 1143 case 64: // ONEOF_SFIXED32: 1144 if (isOneofPresent(message, entryNumber, pos)) { 1145 hashCode = (hashCode * 53) + (oneofIntAt(message, offset)); 1146 } 1147 break; 1148 case 65: // ONEOF_SFIXED64: 1149 if (isOneofPresent(message, entryNumber, pos)) { 1150 hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset)); 1151 } 1152 break; 1153 case 66: // ONEOF_SINT32: 1154 if (isOneofPresent(message, entryNumber, pos)) { 1155 hashCode = (hashCode * 53) + (oneofIntAt(message, offset)); 1156 } 1157 break; 1158 case 67: // ONEOF_SINT64: 1159 if (isOneofPresent(message, entryNumber, pos)) { 1160 hashCode = (hashCode * 53) + Internal.hashLong(oneofLongAt(message, offset)); 1161 } 1162 break; 1163 case 68: // ONEOF_GROUP: 1164 if (isOneofPresent(message, entryNumber, pos)) { 1165 Object submessage = UnsafeUtil.getObject(message, offset); 1166 hashCode = (53 * hashCode) + submessage.hashCode(); 1167 } 1168 break; 1169 default: 1170 // Assume it's an empty entry - just go to the next entry. 1171 break; 1172 } 1173 } 1174 1175 hashCode = (hashCode * 53) + unknownFieldSchema.getFromMessage(message).hashCode(); 1176 1177 if (hasExtensions) { 1178 hashCode = (hashCode * 53) + extensionSchema.getExtensions(message).hashCode(); 1179 } 1180 1181 return hashCode; 1182 } 1183 1184 @Override mergeFrom(T message, T other)1185 public void mergeFrom(T message, T other) { 1186 checkMutable(message); 1187 if (other == null) { 1188 throw new NullPointerException(); 1189 } 1190 for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) { 1191 // A separate method allows for better JIT optimizations 1192 mergeSingleField(message, other, i); 1193 } 1194 1195 SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other); 1196 1197 if (hasExtensions) { 1198 SchemaUtil.mergeExtensions(extensionSchema, message, other); 1199 } 1200 } 1201 mergeSingleField(T message, T other, int pos)1202 private void mergeSingleField(T message, T other, int pos) { 1203 final int typeAndOffset = typeAndOffsetAt(pos); 1204 final long offset = offset(typeAndOffset); 1205 final int number = numberAt(pos); 1206 1207 switch (type(typeAndOffset)) { 1208 case 0: // DOUBLE: 1209 if (isFieldPresent(other, pos)) { 1210 UnsafeUtil.putDouble(message, offset, UnsafeUtil.getDouble(other, offset)); 1211 setFieldPresent(message, pos); 1212 } 1213 break; 1214 case 1: // FLOAT: 1215 if (isFieldPresent(other, pos)) { 1216 UnsafeUtil.putFloat(message, offset, UnsafeUtil.getFloat(other, offset)); 1217 setFieldPresent(message, pos); 1218 } 1219 break; 1220 case 2: // INT64: 1221 if (isFieldPresent(other, pos)) { 1222 UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset)); 1223 setFieldPresent(message, pos); 1224 } 1225 break; 1226 case 3: // UINT64: 1227 if (isFieldPresent(other, pos)) { 1228 UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset)); 1229 setFieldPresent(message, pos); 1230 } 1231 break; 1232 case 4: // INT32: 1233 if (isFieldPresent(other, pos)) { 1234 UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset)); 1235 setFieldPresent(message, pos); 1236 } 1237 break; 1238 case 5: // FIXED64: 1239 if (isFieldPresent(other, pos)) { 1240 UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset)); 1241 setFieldPresent(message, pos); 1242 } 1243 break; 1244 case 6: // FIXED32: 1245 if (isFieldPresent(other, pos)) { 1246 UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset)); 1247 setFieldPresent(message, pos); 1248 } 1249 break; 1250 case 7: // BOOL: 1251 if (isFieldPresent(other, pos)) { 1252 UnsafeUtil.putBoolean(message, offset, UnsafeUtil.getBoolean(other, offset)); 1253 setFieldPresent(message, pos); 1254 } 1255 break; 1256 case 8: // STRING: 1257 if (isFieldPresent(other, pos)) { 1258 UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset)); 1259 setFieldPresent(message, pos); 1260 } 1261 break; 1262 case 9: // MESSAGE: 1263 mergeMessage(message, other, pos); 1264 break; 1265 case 10: // BYTES: 1266 if (isFieldPresent(other, pos)) { 1267 UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset)); 1268 setFieldPresent(message, pos); 1269 } 1270 break; 1271 case 11: // UINT32: 1272 if (isFieldPresent(other, pos)) { 1273 UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset)); 1274 setFieldPresent(message, pos); 1275 } 1276 break; 1277 case 12: // ENUM: 1278 if (isFieldPresent(other, pos)) { 1279 UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset)); 1280 setFieldPresent(message, pos); 1281 } 1282 break; 1283 case 13: // SFIXED32: 1284 if (isFieldPresent(other, pos)) { 1285 UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset)); 1286 setFieldPresent(message, pos); 1287 } 1288 break; 1289 case 14: // SFIXED64: 1290 if (isFieldPresent(other, pos)) { 1291 UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset)); 1292 setFieldPresent(message, pos); 1293 } 1294 break; 1295 case 15: // SINT32: 1296 if (isFieldPresent(other, pos)) { 1297 UnsafeUtil.putInt(message, offset, UnsafeUtil.getInt(other, offset)); 1298 setFieldPresent(message, pos); 1299 } 1300 break; 1301 case 16: // SINT64: 1302 if (isFieldPresent(other, pos)) { 1303 UnsafeUtil.putLong(message, offset, UnsafeUtil.getLong(other, offset)); 1304 setFieldPresent(message, pos); 1305 } 1306 break; 1307 case 17: // GROUP: 1308 mergeMessage(message, other, pos); 1309 break; 1310 case 18: // DOUBLE_LIST: 1311 case 19: // FLOAT_LIST: 1312 case 20: // INT64_LIST: 1313 case 21: // UINT64_LIST: 1314 case 22: // INT32_LIST: 1315 case 23: // FIXED64_LIST: 1316 case 24: // FIXED32_LIST: 1317 case 25: // BOOL_LIST: 1318 case 26: // STRING_LIST: 1319 case 27: // MESSAGE_LIST: 1320 case 28: // BYTES_LIST: 1321 case 29: // UINT32_LIST: 1322 case 30: // ENUM_LIST: 1323 case 31: // SFIXED32_LIST: 1324 case 32: // SFIXED64_LIST: 1325 case 33: // SINT32_LIST: 1326 case 34: // SINT64_LIST: 1327 case 35: // DOUBLE_LIST_PACKED: 1328 case 36: // FLOAT_LIST_PACKED: 1329 case 37: // INT64_LIST_PACKED: 1330 case 38: // UINT64_LIST_PACKED: 1331 case 39: // INT32_LIST_PACKED: 1332 case 40: // FIXED64_LIST_PACKED: 1333 case 41: // FIXED32_LIST_PACKED: 1334 case 42: // BOOL_LIST_PACKED: 1335 case 43: // UINT32_LIST_PACKED: 1336 case 44: // ENUM_LIST_PACKED: 1337 case 45: // SFIXED32_LIST_PACKED: 1338 case 46: // SFIXED64_LIST_PACKED: 1339 case 47: // SINT32_LIST_PACKED: 1340 case 48: // SINT64_LIST_PACKED: 1341 case 49: // GROUP_LIST: 1342 listFieldSchema.mergeListsAt(message, other, offset); 1343 break; 1344 case 50: // MAP: 1345 SchemaUtil.mergeMap(mapFieldSchema, message, other, offset); 1346 break; 1347 case 51: // ONEOF_DOUBLE: 1348 case 52: // ONEOF_FLOAT: 1349 case 53: // ONEOF_INT64: 1350 case 54: // ONEOF_UINT64: 1351 case 55: // ONEOF_INT32: 1352 case 56: // ONEOF_FIXED64: 1353 case 57: // ONEOF_FIXED32: 1354 case 58: // ONEOF_BOOL: 1355 case 59: // ONEOF_STRING: 1356 if (isOneofPresent(other, number, pos)) { 1357 UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset)); 1358 setOneofPresent(message, number, pos); 1359 } 1360 break; 1361 1362 case 60: // ONEOF_MESSAGE: 1363 mergeOneofMessage(message, other, pos); 1364 break; 1365 case 61: // ONEOF_BYTES: 1366 case 62: // ONEOF_UINT32: 1367 case 63: // ONEOF_ENUM: 1368 case 64: // ONEOF_SFIXED32: 1369 case 65: // ONEOF_SFIXED64: 1370 case 66: // ONEOF_SINT32: 1371 case 67: // ONEOF_SINT64: 1372 if (isOneofPresent(other, number, pos)) { 1373 UnsafeUtil.putObject(message, offset, UnsafeUtil.getObject(other, offset)); 1374 setOneofPresent(message, number, pos); 1375 } 1376 break; 1377 case 68: // ONEOF_GROUP: 1378 mergeOneofMessage(message, other, pos); 1379 break; 1380 default: 1381 break; 1382 } 1383 } 1384 mergeMessage(T targetParent, T sourceParent, int pos)1385 private void mergeMessage(T targetParent, T sourceParent, int pos) { 1386 if (!isFieldPresent(sourceParent, pos)) { 1387 return; 1388 } 1389 1390 final int typeAndOffset = typeAndOffsetAt(pos); 1391 final long offset = offset(typeAndOffset); 1392 1393 final Object source = UNSAFE.getObject(sourceParent, offset); 1394 if (source == null) { 1395 throw new IllegalStateException( 1396 "Source subfield " + numberAt(pos) + " is present but null: " + sourceParent); 1397 } 1398 1399 final Schema fieldSchema = getMessageFieldSchema(pos); 1400 if (!isFieldPresent(targetParent, pos)) { 1401 if (!isMutable(source)) { 1402 // Can safely share source if it is immutable 1403 UNSAFE.putObject(targetParent, offset, source); 1404 } else { 1405 // Make a safetey copy of source 1406 final Object copyOfSource = fieldSchema.newInstance(); 1407 fieldSchema.mergeFrom(copyOfSource, source); 1408 UNSAFE.putObject(targetParent, offset, copyOfSource); 1409 } 1410 setFieldPresent(targetParent, pos); 1411 return; 1412 } 1413 1414 // Sub-message is present, merge from source 1415 Object target = UNSAFE.getObject(targetParent, offset); 1416 if (!isMutable(target)) { 1417 Object newInstance = fieldSchema.newInstance(); 1418 fieldSchema.mergeFrom(newInstance, target); 1419 UNSAFE.putObject(targetParent, offset, newInstance); 1420 target = newInstance; 1421 } 1422 fieldSchema.mergeFrom(target, source); 1423 } 1424 mergeOneofMessage(T targetParent, T sourceParent, int pos)1425 private void mergeOneofMessage(T targetParent, T sourceParent, int pos) { 1426 int number = numberAt(pos); 1427 if (!isOneofPresent(sourceParent, number, pos)) { 1428 return; 1429 } 1430 1431 long offset = offset(typeAndOffsetAt(pos)); 1432 final Object source = UNSAFE.getObject(sourceParent, offset); 1433 if (source == null) { 1434 throw new IllegalStateException( 1435 "Source subfield " + numberAt(pos) + " is present but null: " + sourceParent); 1436 } 1437 1438 final Schema fieldSchema = getMessageFieldSchema(pos); 1439 if (!isOneofPresent(targetParent, number, pos)) { 1440 if (!isMutable(source)) { 1441 // Can safely share source if it is immutable 1442 UNSAFE.putObject(targetParent, offset, source); 1443 } else { 1444 // Make a safety copy of theirs 1445 final Object copyOfSource = fieldSchema.newInstance(); 1446 fieldSchema.mergeFrom(copyOfSource, source); 1447 UNSAFE.putObject(targetParent, offset, copyOfSource); 1448 } 1449 setOneofPresent(targetParent, number, pos); 1450 return; 1451 } 1452 1453 // Sub-message is present, merge from source 1454 Object target = UNSAFE.getObject(targetParent, offset); 1455 if (!isMutable(target)) { 1456 Object newInstance = fieldSchema.newInstance(); 1457 fieldSchema.mergeFrom(newInstance, target); 1458 UNSAFE.putObject(targetParent, offset, newInstance); 1459 target = newInstance; 1460 } 1461 fieldSchema.mergeFrom(target, source); 1462 } 1463 1464 @Override 1465 @SuppressWarnings("unchecked") // Field type checks guarantee type casts from Unsafe. getSerializedSize(T message)1466 public int getSerializedSize(T message) { 1467 int size = 0; 1468 1469 final sun.misc.Unsafe unsafe = UNSAFE; 1470 int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; 1471 int currentPresenceField = 0; 1472 for (int i = 0; i < buffer.length; i += INTS_PER_FIELD) { 1473 final int typeAndOffset = typeAndOffsetAt(i); 1474 final int fieldType = type(typeAndOffset); 1475 final int number = numberAt(i); 1476 1477 int presenceMask = 0; 1478 int presenceMaskAndOffset = buffer[i + 2]; 1479 final int presenceOrCachedSizeFieldOffset = presenceMaskAndOffset & OFFSET_MASK; 1480 if (fieldType <= 17) { 1481 // Performance optimization to cache the presence field which is shared for multiple 1482 // fields. 1483 // TODO: Improve caching for case when fields alternate between having and not 1484 // having presence by caching presence field for last field with presence only. 1485 if (presenceOrCachedSizeFieldOffset != currentPresenceFieldOffset) { 1486 currentPresenceFieldOffset = presenceOrCachedSizeFieldOffset; 1487 currentPresenceField = 1488 currentPresenceFieldOffset == NO_PRESENCE_SENTINEL 1489 ? 0 1490 : unsafe.getInt(message, (long) currentPresenceFieldOffset); 1491 } 1492 // Mask for presence bit of the current field from the shared presence field. 1493 presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); 1494 } 1495 1496 final long offset = offset(typeAndOffset); 1497 final int cachedSizeOffset = 1498 fieldType >= FieldType.DOUBLE_LIST_PACKED.id() 1499 && fieldType <= FieldType.SINT64_LIST_PACKED.id() 1500 ? presenceOrCachedSizeFieldOffset 1501 : 0; 1502 1503 switch (fieldType) { 1504 case 0: // DOUBLE: 1505 if (isFieldPresent( 1506 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1507 size += CodedOutputStream.computeDoubleSize(number, 0); 1508 } 1509 break; 1510 case 1: // FLOAT: 1511 if (isFieldPresent( 1512 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1513 size += CodedOutputStream.computeFloatSize(number, 0); 1514 } 1515 break; 1516 case 2: // INT64: 1517 if (isFieldPresent( 1518 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1519 size += CodedOutputStream.computeInt64Size(number, unsafe.getLong(message, offset)); 1520 } 1521 break; 1522 case 3: // UINT64: 1523 if (isFieldPresent( 1524 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1525 size += CodedOutputStream.computeUInt64Size(number, unsafe.getLong(message, offset)); 1526 } 1527 break; 1528 case 4: // INT32: 1529 if (isFieldPresent( 1530 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1531 size += CodedOutputStream.computeInt32Size(number, unsafe.getInt(message, offset)); 1532 } 1533 break; 1534 case 5: // FIXED64: 1535 if (isFieldPresent( 1536 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1537 size += CodedOutputStream.computeFixed64Size(number, 0); 1538 } 1539 break; 1540 case 6: // FIXED32: 1541 if (isFieldPresent( 1542 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1543 size += CodedOutputStream.computeFixed32Size(number, 0); 1544 } 1545 break; 1546 case 7: // BOOL: 1547 if (isFieldPresent( 1548 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1549 size += CodedOutputStream.computeBoolSize(number, true); 1550 } 1551 break; 1552 case 8: // STRING: 1553 if (isFieldPresent( 1554 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1555 Object value = unsafe.getObject(message, offset); 1556 if (value instanceof ByteString) { 1557 size += CodedOutputStream.computeBytesSize(number, (ByteString) value); 1558 } else { 1559 size += CodedOutputStream.computeStringSize(number, (String) value); 1560 } 1561 } 1562 break; 1563 case 9: // MESSAGE: 1564 if (isFieldPresent( 1565 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1566 Object value = unsafe.getObject(message, offset); 1567 size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i)); 1568 } 1569 break; 1570 case 10: // BYTES: 1571 if (isFieldPresent( 1572 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1573 ByteString value = (ByteString) unsafe.getObject(message, offset); 1574 size += CodedOutputStream.computeBytesSize(number, value); 1575 } 1576 break; 1577 case 11: // UINT32: 1578 if (isFieldPresent( 1579 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1580 size += CodedOutputStream.computeUInt32Size(number, unsafe.getInt(message, offset)); 1581 } 1582 break; 1583 case 12: // ENUM: 1584 if (isFieldPresent( 1585 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1586 size += CodedOutputStream.computeEnumSize(number, unsafe.getInt(message, offset)); 1587 } 1588 break; 1589 case 13: // SFIXED32: 1590 if (isFieldPresent( 1591 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1592 size += CodedOutputStream.computeSFixed32Size(number, 0); 1593 } 1594 break; 1595 case 14: // SFIXED64: 1596 if (isFieldPresent( 1597 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1598 size += CodedOutputStream.computeSFixed64Size(number, 0); 1599 } 1600 break; 1601 case 15: // SINT32: 1602 if (isFieldPresent( 1603 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1604 size += CodedOutputStream.computeSInt32Size(number, unsafe.getInt(message, offset)); 1605 } 1606 break; 1607 case 16: // SINT64: 1608 if (isFieldPresent( 1609 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1610 size += CodedOutputStream.computeSInt64Size(number, unsafe.getLong(message, offset)); 1611 } 1612 break; 1613 case 17: // GROUP: 1614 if (isFieldPresent( 1615 message, i, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 1616 size += 1617 CodedOutputStream.computeGroupSize( 1618 number, 1619 (MessageLite) unsafe.getObject(message, offset), 1620 getMessageFieldSchema(i)); 1621 } 1622 break; 1623 case 18: // DOUBLE_LIST: 1624 size += 1625 SchemaUtil.computeSizeFixed64List( 1626 number, (List<?>) unsafe.getObject(message, offset), false); 1627 break; 1628 case 19: // FLOAT_LIST: 1629 size += 1630 SchemaUtil.computeSizeFixed32List( 1631 number, (List<?>) unsafe.getObject(message, offset), false); 1632 break; 1633 case 20: // INT64_LIST: 1634 size += 1635 SchemaUtil.computeSizeInt64List( 1636 number, (List<Long>) unsafe.getObject(message, offset), false); 1637 break; 1638 case 21: // UINT64_LIST: 1639 size += 1640 SchemaUtil.computeSizeUInt64List( 1641 number, (List<Long>) unsafe.getObject(message, offset), false); 1642 break; 1643 case 22: // INT32_LIST: 1644 size += 1645 SchemaUtil.computeSizeInt32List( 1646 number, (List<Integer>) unsafe.getObject(message, offset), false); 1647 break; 1648 case 23: // FIXED64_LIST: 1649 size += 1650 SchemaUtil.computeSizeFixed64List( 1651 number, (List<?>) unsafe.getObject(message, offset), false); 1652 break; 1653 case 24: // FIXED32_LIST: 1654 size += 1655 SchemaUtil.computeSizeFixed32List( 1656 number, (List<?>) unsafe.getObject(message, offset), false); 1657 break; 1658 case 25: // BOOL_LIST: 1659 size += 1660 SchemaUtil.computeSizeBoolList( 1661 number, (List<?>) unsafe.getObject(message, offset), false); 1662 break; 1663 case 26: // STRING_LIST: 1664 size += 1665 SchemaUtil.computeSizeStringList(number, (List<?>) unsafe.getObject(message, offset)); 1666 break; 1667 case 27: // MESSAGE_LIST: 1668 size += 1669 SchemaUtil.computeSizeMessageList( 1670 number, (List<?>) unsafe.getObject(message, offset), getMessageFieldSchema(i)); 1671 break; 1672 case 28: // BYTES_LIST: 1673 size += 1674 SchemaUtil.computeSizeByteStringList( 1675 number, (List<ByteString>) unsafe.getObject(message, offset)); 1676 break; 1677 case 29: // UINT32_LIST: 1678 size += 1679 SchemaUtil.computeSizeUInt32List( 1680 number, (List<Integer>) unsafe.getObject(message, offset), false); 1681 break; 1682 case 30: // ENUM_LIST: 1683 size += 1684 SchemaUtil.computeSizeEnumList( 1685 number, (List<Integer>) unsafe.getObject(message, offset), false); 1686 break; 1687 case 31: // SFIXED32_LIST: 1688 size += 1689 SchemaUtil.computeSizeFixed32List( 1690 number, (List<Integer>) unsafe.getObject(message, offset), false); 1691 break; 1692 case 32: // SFIXED64_LIST: 1693 size += 1694 SchemaUtil.computeSizeFixed64List( 1695 number, (List<Long>) unsafe.getObject(message, offset), false); 1696 break; 1697 case 33: // SINT32_LIST: 1698 size += 1699 SchemaUtil.computeSizeSInt32List( 1700 number, (List<Integer>) unsafe.getObject(message, offset), false); 1701 break; 1702 case 34: // SINT64_LIST: 1703 size += 1704 SchemaUtil.computeSizeSInt64List( 1705 number, (List<Long>) unsafe.getObject(message, offset), false); 1706 break; 1707 case 35: 1708 { // DOUBLE_LIST_PACKED: 1709 int fieldSize = 1710 SchemaUtil.computeSizeFixed64ListNoTag( 1711 (List<Double>) unsafe.getObject(message, offset)); 1712 if (fieldSize > 0) { 1713 if (useCachedSizeField) { 1714 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1715 } 1716 size += 1717 CodedOutputStream.computeTagSize(number) 1718 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1719 + fieldSize; 1720 } 1721 break; 1722 } 1723 case 36: 1724 { // FLOAT_LIST_PACKED: 1725 int fieldSize = 1726 SchemaUtil.computeSizeFixed32ListNoTag( 1727 (List<Float>) unsafe.getObject(message, offset)); 1728 if (fieldSize > 0) { 1729 if (useCachedSizeField) { 1730 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1731 } 1732 size += 1733 CodedOutputStream.computeTagSize(number) 1734 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1735 + fieldSize; 1736 } 1737 break; 1738 } 1739 case 37: 1740 { // INT64_LIST_PACKED: 1741 int fieldSize = 1742 SchemaUtil.computeSizeInt64ListNoTag( 1743 (List<Long>) unsafe.getObject(message, offset)); 1744 if (fieldSize > 0) { 1745 if (useCachedSizeField) { 1746 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1747 } 1748 size += 1749 CodedOutputStream.computeTagSize(number) 1750 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1751 + fieldSize; 1752 } 1753 break; 1754 } 1755 case 38: 1756 { // UINT64_LIST_PACKED: 1757 int fieldSize = 1758 SchemaUtil.computeSizeUInt64ListNoTag( 1759 (List<Long>) unsafe.getObject(message, offset)); 1760 if (fieldSize > 0) { 1761 if (useCachedSizeField) { 1762 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1763 } 1764 size += 1765 CodedOutputStream.computeTagSize(number) 1766 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1767 + fieldSize; 1768 } 1769 break; 1770 } 1771 case 39: 1772 { // INT32_LIST_PACKED: 1773 int fieldSize = 1774 SchemaUtil.computeSizeInt32ListNoTag( 1775 (List<Integer>) unsafe.getObject(message, offset)); 1776 if (fieldSize > 0) { 1777 if (useCachedSizeField) { 1778 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1779 } 1780 size += 1781 CodedOutputStream.computeTagSize(number) 1782 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1783 + fieldSize; 1784 } 1785 break; 1786 } 1787 case 40: 1788 { // FIXED64_LIST_PACKED: 1789 int fieldSize = 1790 SchemaUtil.computeSizeFixed64ListNoTag( 1791 (List<Long>) unsafe.getObject(message, offset)); 1792 if (fieldSize > 0) { 1793 if (useCachedSizeField) { 1794 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1795 } 1796 size += 1797 CodedOutputStream.computeTagSize(number) 1798 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1799 + fieldSize; 1800 } 1801 break; 1802 } 1803 case 41: 1804 { // FIXED32_LIST_PACKED: 1805 int fieldSize = 1806 SchemaUtil.computeSizeFixed32ListNoTag( 1807 (List<Integer>) unsafe.getObject(message, offset)); 1808 if (fieldSize > 0) { 1809 if (useCachedSizeField) { 1810 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1811 } 1812 size += 1813 CodedOutputStream.computeTagSize(number) 1814 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1815 + fieldSize; 1816 } 1817 break; 1818 } 1819 case 42: 1820 { // BOOL_LIST_PACKED: 1821 int fieldSize = 1822 SchemaUtil.computeSizeBoolListNoTag( 1823 (List<Boolean>) unsafe.getObject(message, offset)); 1824 if (fieldSize > 0) { 1825 if (useCachedSizeField) { 1826 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1827 } 1828 size += 1829 CodedOutputStream.computeTagSize(number) 1830 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1831 + fieldSize; 1832 } 1833 break; 1834 } 1835 case 43: 1836 { // UINT32_LIST_PACKED: 1837 int fieldSize = 1838 SchemaUtil.computeSizeUInt32ListNoTag( 1839 (List<Integer>) unsafe.getObject(message, offset)); 1840 if (fieldSize > 0) { 1841 if (useCachedSizeField) { 1842 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1843 } 1844 size += 1845 CodedOutputStream.computeTagSize(number) 1846 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1847 + fieldSize; 1848 } 1849 break; 1850 } 1851 case 44: 1852 { // ENUM_LIST_PACKED: 1853 int fieldSize = 1854 SchemaUtil.computeSizeEnumListNoTag( 1855 (List<Integer>) unsafe.getObject(message, offset)); 1856 if (fieldSize > 0) { 1857 if (useCachedSizeField) { 1858 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1859 } 1860 size += 1861 CodedOutputStream.computeTagSize(number) 1862 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1863 + fieldSize; 1864 } 1865 break; 1866 } 1867 case 45: 1868 { // SFIXED32_LIST_PACKED: 1869 int fieldSize = 1870 SchemaUtil.computeSizeFixed32ListNoTag( 1871 (List<Integer>) unsafe.getObject(message, offset)); 1872 if (fieldSize > 0) { 1873 if (useCachedSizeField) { 1874 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1875 } 1876 size += 1877 CodedOutputStream.computeTagSize(number) 1878 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1879 + fieldSize; 1880 } 1881 break; 1882 } 1883 case 46: 1884 { // SFIXED64_LIST_PACKED: 1885 int fieldSize = 1886 SchemaUtil.computeSizeFixed64ListNoTag( 1887 (List<Long>) unsafe.getObject(message, offset)); 1888 if (fieldSize > 0) { 1889 if (useCachedSizeField) { 1890 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1891 } 1892 size += 1893 CodedOutputStream.computeTagSize(number) 1894 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1895 + fieldSize; 1896 } 1897 break; 1898 } 1899 case 47: 1900 { // SINT32_LIST_PACKED: 1901 int fieldSize = 1902 SchemaUtil.computeSizeSInt32ListNoTag( 1903 (List<Integer>) unsafe.getObject(message, offset)); 1904 if (fieldSize > 0) { 1905 if (useCachedSizeField) { 1906 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1907 } 1908 size += 1909 CodedOutputStream.computeTagSize(number) 1910 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1911 + fieldSize; 1912 } 1913 break; 1914 } 1915 case 48: 1916 { // SINT64_LIST_PACKED: 1917 int fieldSize = 1918 SchemaUtil.computeSizeSInt64ListNoTag( 1919 (List<Long>) unsafe.getObject(message, offset)); 1920 if (fieldSize > 0) { 1921 if (useCachedSizeField) { 1922 unsafe.putInt(message, (long) cachedSizeOffset, fieldSize); 1923 } 1924 size += 1925 CodedOutputStream.computeTagSize(number) 1926 + CodedOutputStream.computeUInt32SizeNoTag(fieldSize) 1927 + fieldSize; 1928 } 1929 break; 1930 } 1931 case 49: // GROUP_LIST: 1932 size += 1933 SchemaUtil.computeSizeGroupList( 1934 number, 1935 (List<MessageLite>) unsafe.getObject(message, offset), 1936 getMessageFieldSchema(i)); 1937 break; 1938 case 50: // MAP: 1939 // TODO: Use schema cache. 1940 size += 1941 mapFieldSchema.getSerializedSize( 1942 number, unsafe.getObject(message, offset), getMapFieldDefaultEntry(i)); 1943 break; 1944 case 51: // ONEOF_DOUBLE: 1945 if (isOneofPresent(message, number, i)) { 1946 size += CodedOutputStream.computeDoubleSize(number, 0); 1947 } 1948 break; 1949 case 52: // ONEOF_FLOAT: 1950 if (isOneofPresent(message, number, i)) { 1951 size += CodedOutputStream.computeFloatSize(number, 0); 1952 } 1953 break; 1954 case 53: // ONEOF_INT64: 1955 if (isOneofPresent(message, number, i)) { 1956 size += CodedOutputStream.computeInt64Size(number, oneofLongAt(message, offset)); 1957 } 1958 break; 1959 case 54: // ONEOF_UINT64: 1960 if (isOneofPresent(message, number, i)) { 1961 size += CodedOutputStream.computeUInt64Size(number, oneofLongAt(message, offset)); 1962 } 1963 break; 1964 case 55: // ONEOF_INT32: 1965 if (isOneofPresent(message, number, i)) { 1966 size += CodedOutputStream.computeInt32Size(number, oneofIntAt(message, offset)); 1967 } 1968 break; 1969 case 56: // ONEOF_FIXED64: 1970 if (isOneofPresent(message, number, i)) { 1971 size += CodedOutputStream.computeFixed64Size(number, 0); 1972 } 1973 break; 1974 case 57: // ONEOF_FIXED32: 1975 if (isOneofPresent(message, number, i)) { 1976 size += CodedOutputStream.computeFixed32Size(number, 0); 1977 } 1978 break; 1979 case 58: // ONEOF_BOOL: 1980 if (isOneofPresent(message, number, i)) { 1981 size += CodedOutputStream.computeBoolSize(number, true); 1982 } 1983 break; 1984 case 59: // ONEOF_STRING: 1985 if (isOneofPresent(message, number, i)) { 1986 Object value = unsafe.getObject(message, offset); 1987 if (value instanceof ByteString) { 1988 size += CodedOutputStream.computeBytesSize(number, (ByteString) value); 1989 } else { 1990 size += CodedOutputStream.computeStringSize(number, (String) value); 1991 } 1992 } 1993 break; 1994 case 60: // ONEOF_MESSAGE: 1995 if (isOneofPresent(message, number, i)) { 1996 Object value = unsafe.getObject(message, offset); 1997 size += SchemaUtil.computeSizeMessage(number, value, getMessageFieldSchema(i)); 1998 } 1999 break; 2000 case 61: // ONEOF_BYTES: 2001 if (isOneofPresent(message, number, i)) { 2002 size += 2003 CodedOutputStream.computeBytesSize( 2004 number, (ByteString) unsafe.getObject(message, offset)); 2005 } 2006 break; 2007 case 62: // ONEOF_UINT32: 2008 if (isOneofPresent(message, number, i)) { 2009 size += CodedOutputStream.computeUInt32Size(number, oneofIntAt(message, offset)); 2010 } 2011 break; 2012 case 63: // ONEOF_ENUM: 2013 if (isOneofPresent(message, number, i)) { 2014 size += CodedOutputStream.computeEnumSize(number, oneofIntAt(message, offset)); 2015 } 2016 break; 2017 case 64: // ONEOF_SFIXED32: 2018 if (isOneofPresent(message, number, i)) { 2019 size += CodedOutputStream.computeSFixed32Size(number, 0); 2020 } 2021 break; 2022 case 65: // ONEOF_SFIXED64: 2023 if (isOneofPresent(message, number, i)) { 2024 size += CodedOutputStream.computeSFixed64Size(number, 0); 2025 } 2026 break; 2027 case 66: // ONEOF_SINT32: 2028 if (isOneofPresent(message, number, i)) { 2029 size += CodedOutputStream.computeSInt32Size(number, oneofIntAt(message, offset)); 2030 } 2031 break; 2032 case 67: // ONEOF_SINT64: 2033 if (isOneofPresent(message, number, i)) { 2034 size += CodedOutputStream.computeSInt64Size(number, oneofLongAt(message, offset)); 2035 } 2036 break; 2037 case 68: // ONEOF_GROUP: 2038 if (isOneofPresent(message, number, i)) { 2039 size += 2040 CodedOutputStream.computeGroupSize( 2041 number, 2042 (MessageLite) unsafe.getObject(message, offset), 2043 getMessageFieldSchema(i)); 2044 } 2045 break; 2046 default: 2047 // Assume it's an empty entry. 2048 } 2049 } 2050 2051 size += getUnknownFieldsSerializedSize(unknownFieldSchema, message); 2052 2053 if (hasExtensions) { 2054 size += extensionSchema.getExtensions(message).getSerializedSize(); 2055 } 2056 2057 return size; 2058 } 2059 getUnknownFieldsSerializedSize( UnknownFieldSchema<UT, UB> schema, T message)2060 private <UT, UB> int getUnknownFieldsSerializedSize( 2061 UnknownFieldSchema<UT, UB> schema, T message) { 2062 UT unknowns = schema.getFromMessage(message); 2063 return schema.getSerializedSize(unknowns); 2064 } 2065 2066 @Override 2067 // TODO: Consider serializing oneof fields last so that only one entry per 2068 // oneof is actually serialized. This would mean that we would violate the serialization order 2069 // contract. It should also be noted that Go currently does this. writeTo(T message, Writer writer)2070 public void writeTo(T message, Writer writer) throws IOException { 2071 if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) { 2072 writeFieldsInDescendingOrder(message, writer); 2073 } else { 2074 writeFieldsInAscendingOrder(message, writer); 2075 } 2076 } 2077 2078 @SuppressWarnings("unchecked") writeFieldsInAscendingOrder(T message, Writer writer)2079 private void writeFieldsInAscendingOrder(T message, Writer writer) throws IOException { 2080 Iterator<? extends Map.Entry<?, ?>> extensionIterator = null; 2081 Map.Entry nextExtension = null; 2082 if (hasExtensions) { 2083 FieldSet<?> extensions = extensionSchema.getExtensions(message); 2084 if (!extensions.isEmpty()) { 2085 extensionIterator = extensions.iterator(); 2086 nextExtension = extensionIterator.next(); 2087 } 2088 } 2089 2090 int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; 2091 int currentPresenceField = 0; 2092 final int bufferLength = buffer.length; 2093 final sun.misc.Unsafe unsafe = UNSAFE; 2094 for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) { 2095 final int typeAndOffset = typeAndOffsetAt(pos); 2096 final int number = numberAt(pos); 2097 final int fieldType = type(typeAndOffset); 2098 2099 int presenceMask = 0; 2100 if (fieldType <= 17) { 2101 int presenceMaskAndOffset = buffer[pos + 2]; 2102 final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; 2103 2104 // Performance optimization to cache the presence field which is shared for multiple 2105 // fields. 2106 // TODO: Improve caching for case when fields alternate between having and not 2107 // having presence by caching presence field for last field with presence only. 2108 if (presenceFieldOffset != currentPresenceFieldOffset) { 2109 currentPresenceFieldOffset = presenceFieldOffset; 2110 currentPresenceField = 2111 currentPresenceFieldOffset == NO_PRESENCE_SENTINEL 2112 ? 0 2113 : unsafe.getInt(message, (long) presenceFieldOffset); 2114 } 2115 // Mask for presence bit of the current field from the shared presence field. 2116 presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); 2117 } 2118 2119 // Write any extensions that need to be written before the current field. 2120 while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) <= number) { 2121 extensionSchema.serializeExtension(writer, nextExtension); 2122 nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null; 2123 } 2124 final long offset = offset(typeAndOffset); 2125 2126 switch (fieldType) { 2127 case 0: // DOUBLE: 2128 if (isFieldPresent( 2129 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2130 writer.writeDouble(number, doubleAt(message, offset)); 2131 } 2132 break; 2133 case 1: // FLOAT: 2134 if (isFieldPresent( 2135 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2136 writer.writeFloat(number, floatAt(message, offset)); 2137 } 2138 break; 2139 case 2: // INT64: 2140 if (isFieldPresent( 2141 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2142 writer.writeInt64(number, unsafe.getLong(message, offset)); 2143 } 2144 break; 2145 case 3: // UINT64: 2146 if (isFieldPresent( 2147 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2148 writer.writeUInt64(number, unsafe.getLong(message, offset)); 2149 } 2150 break; 2151 case 4: // INT32: 2152 if (isFieldPresent( 2153 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2154 writer.writeInt32(number, unsafe.getInt(message, offset)); 2155 } 2156 break; 2157 case 5: // FIXED64: 2158 if (isFieldPresent( 2159 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2160 writer.writeFixed64(number, unsafe.getLong(message, offset)); 2161 } 2162 break; 2163 case 6: // FIXED32: 2164 if (isFieldPresent( 2165 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2166 writer.writeFixed32(number, unsafe.getInt(message, offset)); 2167 } 2168 break; 2169 case 7: // BOOL: 2170 if (isFieldPresent( 2171 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2172 writer.writeBool(number, booleanAt(message, offset)); 2173 } 2174 break; 2175 case 8: // STRING: 2176 if (isFieldPresent( 2177 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2178 writeString(number, unsafe.getObject(message, offset), writer); 2179 } 2180 break; 2181 case 9: // MESSAGE: 2182 if (isFieldPresent( 2183 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2184 Object value = unsafe.getObject(message, offset); 2185 writer.writeMessage(number, value, getMessageFieldSchema(pos)); 2186 } 2187 break; 2188 case 10: // BYTES: 2189 if (isFieldPresent( 2190 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2191 writer.writeBytes(number, (ByteString) unsafe.getObject(message, offset)); 2192 } 2193 break; 2194 case 11: // UINT32: 2195 if (isFieldPresent( 2196 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2197 writer.writeUInt32(number, unsafe.getInt(message, offset)); 2198 } 2199 break; 2200 case 12: // ENUM: 2201 if (isFieldPresent( 2202 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2203 writer.writeEnum(number, unsafe.getInt(message, offset)); 2204 } 2205 break; 2206 case 13: // SFIXED32: 2207 if (isFieldPresent( 2208 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2209 writer.writeSFixed32(number, unsafe.getInt(message, offset)); 2210 } 2211 break; 2212 case 14: // SFIXED64: 2213 if (isFieldPresent( 2214 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2215 writer.writeSFixed64(number, unsafe.getLong(message, offset)); 2216 } 2217 break; 2218 case 15: // SINT32: 2219 if (isFieldPresent( 2220 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2221 writer.writeSInt32(number, unsafe.getInt(message, offset)); 2222 } 2223 break; 2224 case 16: // SINT64: 2225 if (isFieldPresent( 2226 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2227 writer.writeSInt64(number, unsafe.getLong(message, offset)); 2228 } 2229 break; 2230 case 17: // GROUP: 2231 if (isFieldPresent( 2232 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 2233 writer.writeGroup( 2234 number, unsafe.getObject(message, offset), getMessageFieldSchema(pos)); 2235 } 2236 break; 2237 case 18: // DOUBLE_LIST: 2238 SchemaUtil.writeDoubleList( 2239 numberAt(pos), (List<Double>) unsafe.getObject(message, offset), writer, false); 2240 break; 2241 case 19: // FLOAT_LIST: 2242 SchemaUtil.writeFloatList( 2243 numberAt(pos), (List<Float>) unsafe.getObject(message, offset), writer, false); 2244 break; 2245 case 20: // INT64_LIST: 2246 SchemaUtil.writeInt64List( 2247 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false); 2248 break; 2249 case 21: // UINT64_LIST: 2250 SchemaUtil.writeUInt64List( 2251 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false); 2252 break; 2253 case 22: // INT32_LIST: 2254 SchemaUtil.writeInt32List( 2255 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false); 2256 break; 2257 case 23: // FIXED64_LIST: 2258 SchemaUtil.writeFixed64List( 2259 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false); 2260 break; 2261 case 24: // FIXED32_LIST: 2262 SchemaUtil.writeFixed32List( 2263 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false); 2264 break; 2265 case 25: // BOOL_LIST: 2266 SchemaUtil.writeBoolList( 2267 numberAt(pos), (List<Boolean>) unsafe.getObject(message, offset), writer, false); 2268 break; 2269 case 26: // STRING_LIST: 2270 SchemaUtil.writeStringList( 2271 numberAt(pos), (List<String>) unsafe.getObject(message, offset), writer); 2272 break; 2273 case 27: // MESSAGE_LIST: 2274 SchemaUtil.writeMessageList( 2275 numberAt(pos), 2276 (List<?>) unsafe.getObject(message, offset), 2277 writer, 2278 getMessageFieldSchema(pos)); 2279 break; 2280 case 28: // BYTES_LIST: 2281 SchemaUtil.writeBytesList( 2282 numberAt(pos), (List<ByteString>) unsafe.getObject(message, offset), writer); 2283 break; 2284 case 29: // UINT32_LIST: 2285 SchemaUtil.writeUInt32List( 2286 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false); 2287 break; 2288 case 30: // ENUM_LIST: 2289 SchemaUtil.writeEnumList( 2290 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false); 2291 break; 2292 case 31: // SFIXED32_LIST: 2293 SchemaUtil.writeSFixed32List( 2294 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false); 2295 break; 2296 case 32: // SFIXED64_LIST: 2297 SchemaUtil.writeSFixed64List( 2298 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false); 2299 break; 2300 case 33: // SINT32_LIST: 2301 SchemaUtil.writeSInt32List( 2302 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, false); 2303 break; 2304 case 34: // SINT64_LIST: 2305 SchemaUtil.writeSInt64List( 2306 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, false); 2307 break; 2308 case 35: // DOUBLE_LIST_PACKED: 2309 // TODO: Make use of cached field size to speed up serialization. 2310 SchemaUtil.writeDoubleList( 2311 numberAt(pos), (List<Double>) unsafe.getObject(message, offset), writer, true); 2312 break; 2313 case 36: // FLOAT_LIST_PACKED: 2314 SchemaUtil.writeFloatList( 2315 numberAt(pos), (List<Float>) unsafe.getObject(message, offset), writer, true); 2316 break; 2317 case 37: // INT64_LIST_PACKED: 2318 SchemaUtil.writeInt64List( 2319 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true); 2320 break; 2321 case 38: // UINT64_LIST_PACKED: 2322 SchemaUtil.writeUInt64List( 2323 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true); 2324 break; 2325 case 39: // INT32_LIST_PACKED: 2326 SchemaUtil.writeInt32List( 2327 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true); 2328 break; 2329 case 40: // FIXED64_LIST_PACKED: 2330 SchemaUtil.writeFixed64List( 2331 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true); 2332 break; 2333 case 41: // FIXED32_LIST_PACKED: 2334 SchemaUtil.writeFixed32List( 2335 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true); 2336 2337 break; 2338 case 42: // BOOL_LIST_PACKED: 2339 SchemaUtil.writeBoolList( 2340 numberAt(pos), (List<Boolean>) unsafe.getObject(message, offset), writer, true); 2341 break; 2342 case 43: // UINT32_LIST_PACKED: 2343 SchemaUtil.writeUInt32List( 2344 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true); 2345 break; 2346 case 44: // ENUM_LIST_PACKED: 2347 SchemaUtil.writeEnumList( 2348 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true); 2349 break; 2350 case 45: // SFIXED32_LIST_PACKED: 2351 SchemaUtil.writeSFixed32List( 2352 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true); 2353 break; 2354 case 46: // SFIXED64_LIST_PACKED: 2355 SchemaUtil.writeSFixed64List( 2356 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true); 2357 break; 2358 case 47: // SINT32_LIST_PACKED: 2359 SchemaUtil.writeSInt32List( 2360 numberAt(pos), (List<Integer>) unsafe.getObject(message, offset), writer, true); 2361 break; 2362 case 48: // SINT64_LIST_PACKED: 2363 SchemaUtil.writeSInt64List( 2364 numberAt(pos), (List<Long>) unsafe.getObject(message, offset), writer, true); 2365 break; 2366 case 49: // GROUP_LIST: 2367 SchemaUtil.writeGroupList( 2368 numberAt(pos), 2369 (List<?>) unsafe.getObject(message, offset), 2370 writer, 2371 getMessageFieldSchema(pos)); 2372 break; 2373 case 50: // MAP: 2374 // TODO: Use schema cache. 2375 writeMapHelper(writer, number, unsafe.getObject(message, offset), pos); 2376 break; 2377 case 51: // ONEOF_DOUBLE: 2378 if (isOneofPresent(message, number, pos)) { 2379 writer.writeDouble(number, oneofDoubleAt(message, offset)); 2380 } 2381 break; 2382 case 52: // ONEOF_FLOAT: 2383 if (isOneofPresent(message, number, pos)) { 2384 writer.writeFloat(number, oneofFloatAt(message, offset)); 2385 } 2386 break; 2387 case 53: // ONEOF_INT64: 2388 if (isOneofPresent(message, number, pos)) { 2389 writer.writeInt64(number, oneofLongAt(message, offset)); 2390 } 2391 break; 2392 case 54: // ONEOF_UINT64: 2393 if (isOneofPresent(message, number, pos)) { 2394 writer.writeUInt64(number, oneofLongAt(message, offset)); 2395 } 2396 break; 2397 case 55: // ONEOF_INT32: 2398 if (isOneofPresent(message, number, pos)) { 2399 writer.writeInt32(number, oneofIntAt(message, offset)); 2400 } 2401 break; 2402 case 56: // ONEOF_FIXED64: 2403 if (isOneofPresent(message, number, pos)) { 2404 writer.writeFixed64(number, oneofLongAt(message, offset)); 2405 } 2406 break; 2407 case 57: // ONEOF_FIXED32: 2408 if (isOneofPresent(message, number, pos)) { 2409 writer.writeFixed32(number, oneofIntAt(message, offset)); 2410 } 2411 break; 2412 case 58: // ONEOF_BOOL: 2413 if (isOneofPresent(message, number, pos)) { 2414 writer.writeBool(number, oneofBooleanAt(message, offset)); 2415 } 2416 break; 2417 case 59: // ONEOF_STRING: 2418 if (isOneofPresent(message, number, pos)) { 2419 writeString(number, unsafe.getObject(message, offset), writer); 2420 } 2421 break; 2422 case 60: // ONEOF_MESSAGE: 2423 if (isOneofPresent(message, number, pos)) { 2424 Object value = unsafe.getObject(message, offset); 2425 writer.writeMessage(number, value, getMessageFieldSchema(pos)); 2426 } 2427 break; 2428 case 61: // ONEOF_BYTES: 2429 if (isOneofPresent(message, number, pos)) { 2430 writer.writeBytes(number, (ByteString) unsafe.getObject(message, offset)); 2431 } 2432 break; 2433 case 62: // ONEOF_UINT32: 2434 if (isOneofPresent(message, number, pos)) { 2435 writer.writeUInt32(number, oneofIntAt(message, offset)); 2436 } 2437 break; 2438 case 63: // ONEOF_ENUM: 2439 if (isOneofPresent(message, number, pos)) { 2440 writer.writeEnum(number, oneofIntAt(message, offset)); 2441 } 2442 break; 2443 case 64: // ONEOF_SFIXED32: 2444 if (isOneofPresent(message, number, pos)) { 2445 writer.writeSFixed32(number, oneofIntAt(message, offset)); 2446 } 2447 break; 2448 case 65: // ONEOF_SFIXED64: 2449 if (isOneofPresent(message, number, pos)) { 2450 writer.writeSFixed64(number, oneofLongAt(message, offset)); 2451 } 2452 break; 2453 case 66: // ONEOF_SINT32: 2454 if (isOneofPresent(message, number, pos)) { 2455 writer.writeSInt32(number, oneofIntAt(message, offset)); 2456 } 2457 break; 2458 case 67: // ONEOF_SINT64: 2459 if (isOneofPresent(message, number, pos)) { 2460 writer.writeSInt64(number, oneofLongAt(message, offset)); 2461 } 2462 break; 2463 case 68: // ONEOF_GROUP: 2464 if (isOneofPresent(message, number, pos)) { 2465 writer.writeGroup( 2466 number, unsafe.getObject(message, offset), getMessageFieldSchema(pos)); 2467 } 2468 break; 2469 default: 2470 // Assume it's an empty entry - just go to the next entry. 2471 break; 2472 } 2473 } 2474 while (nextExtension != null) { 2475 extensionSchema.serializeExtension(writer, nextExtension); 2476 nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null; 2477 } 2478 writeUnknownInMessageTo(unknownFieldSchema, message, writer); 2479 } 2480 2481 @SuppressWarnings("unchecked") writeFieldsInDescendingOrder(T message, Writer writer)2482 private void writeFieldsInDescendingOrder(T message, Writer writer) throws IOException { 2483 writeUnknownInMessageTo(unknownFieldSchema, message, writer); 2484 2485 Iterator<? extends Map.Entry<?, ?>> extensionIterator = null; 2486 Map.Entry nextExtension = null; 2487 if (hasExtensions) { 2488 FieldSet<?> extensions = extensionSchema.getExtensions(message); 2489 if (!extensions.isEmpty()) { 2490 extensionIterator = extensions.descendingIterator(); 2491 nextExtension = extensionIterator.next(); 2492 } 2493 } 2494 2495 for (int pos = buffer.length - INTS_PER_FIELD; pos >= 0; pos -= INTS_PER_FIELD) { 2496 final int typeAndOffset = typeAndOffsetAt(pos); 2497 final int number = numberAt(pos); 2498 2499 // Write any extensions that need to be written before the current field. 2500 while (nextExtension != null && extensionSchema.extensionNumber(nextExtension) > number) { 2501 extensionSchema.serializeExtension(writer, nextExtension); 2502 nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null; 2503 } 2504 2505 switch (type(typeAndOffset)) { 2506 case 0: // DOUBLE: 2507 if (isFieldPresent(message, pos)) { 2508 writer.writeDouble(number, doubleAt(message, offset(typeAndOffset))); 2509 } 2510 break; 2511 case 1: // FLOAT: 2512 if (isFieldPresent(message, pos)) { 2513 writer.writeFloat(number, floatAt(message, offset(typeAndOffset))); 2514 } 2515 break; 2516 case 2: // INT64: 2517 if (isFieldPresent(message, pos)) { 2518 writer.writeInt64(number, longAt(message, offset(typeAndOffset))); 2519 } 2520 break; 2521 case 3: // UINT64: 2522 if (isFieldPresent(message, pos)) { 2523 writer.writeUInt64(number, longAt(message, offset(typeAndOffset))); 2524 } 2525 break; 2526 case 4: // INT32: 2527 if (isFieldPresent(message, pos)) { 2528 writer.writeInt32(number, intAt(message, offset(typeAndOffset))); 2529 } 2530 break; 2531 case 5: // FIXED64: 2532 if (isFieldPresent(message, pos)) { 2533 writer.writeFixed64(number, longAt(message, offset(typeAndOffset))); 2534 } 2535 break; 2536 case 6: // FIXED32: 2537 if (isFieldPresent(message, pos)) { 2538 writer.writeFixed32(number, intAt(message, offset(typeAndOffset))); 2539 } 2540 break; 2541 case 7: // BOOL: 2542 if (isFieldPresent(message, pos)) { 2543 writer.writeBool(number, booleanAt(message, offset(typeAndOffset))); 2544 } 2545 break; 2546 case 8: // STRING: 2547 if (isFieldPresent(message, pos)) { 2548 writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer); 2549 } 2550 break; 2551 case 9: // MESSAGE: 2552 if (isFieldPresent(message, pos)) { 2553 Object value = UnsafeUtil.getObject(message, offset(typeAndOffset)); 2554 writer.writeMessage(number, value, getMessageFieldSchema(pos)); 2555 } 2556 break; 2557 case 10: // BYTES: 2558 if (isFieldPresent(message, pos)) { 2559 writer.writeBytes( 2560 number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset))); 2561 } 2562 break; 2563 case 11: // UINT32: 2564 if (isFieldPresent(message, pos)) { 2565 writer.writeUInt32(number, intAt(message, offset(typeAndOffset))); 2566 } 2567 break; 2568 case 12: // ENUM: 2569 if (isFieldPresent(message, pos)) { 2570 writer.writeEnum(number, intAt(message, offset(typeAndOffset))); 2571 } 2572 break; 2573 case 13: // SFIXED32: 2574 if (isFieldPresent(message, pos)) { 2575 writer.writeSFixed32(number, intAt(message, offset(typeAndOffset))); 2576 } 2577 break; 2578 case 14: // SFIXED64: 2579 if (isFieldPresent(message, pos)) { 2580 writer.writeSFixed64(number, longAt(message, offset(typeAndOffset))); 2581 } 2582 break; 2583 case 15: // SINT32: 2584 if (isFieldPresent(message, pos)) { 2585 writer.writeSInt32(number, intAt(message, offset(typeAndOffset))); 2586 } 2587 break; 2588 case 16: // SINT64: 2589 if (isFieldPresent(message, pos)) { 2590 writer.writeSInt64(number, longAt(message, offset(typeAndOffset))); 2591 } 2592 break; 2593 case 17: // GROUP: 2594 if (isFieldPresent(message, pos)) { 2595 writer.writeGroup( 2596 number, 2597 UnsafeUtil.getObject(message, offset(typeAndOffset)), 2598 getMessageFieldSchema(pos)); 2599 } 2600 break; 2601 case 18: // DOUBLE_LIST: 2602 SchemaUtil.writeDoubleList( 2603 numberAt(pos), 2604 (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2605 writer, 2606 false); 2607 break; 2608 case 19: // FLOAT_LIST: 2609 SchemaUtil.writeFloatList( 2610 numberAt(pos), 2611 (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2612 writer, 2613 false); 2614 break; 2615 case 20: // INT64_LIST: 2616 SchemaUtil.writeInt64List( 2617 numberAt(pos), 2618 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2619 writer, 2620 false); 2621 break; 2622 case 21: // UINT64_LIST: 2623 SchemaUtil.writeUInt64List( 2624 numberAt(pos), 2625 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2626 writer, 2627 false); 2628 break; 2629 case 22: // INT32_LIST: 2630 SchemaUtil.writeInt32List( 2631 numberAt(pos), 2632 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2633 writer, 2634 false); 2635 break; 2636 case 23: // FIXED64_LIST: 2637 SchemaUtil.writeFixed64List( 2638 numberAt(pos), 2639 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2640 writer, 2641 false); 2642 break; 2643 case 24: // FIXED32_LIST: 2644 SchemaUtil.writeFixed32List( 2645 numberAt(pos), 2646 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2647 writer, 2648 false); 2649 break; 2650 case 25: // BOOL_LIST: 2651 SchemaUtil.writeBoolList( 2652 numberAt(pos), 2653 (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2654 writer, 2655 false); 2656 break; 2657 case 26: // STRING_LIST: 2658 SchemaUtil.writeStringList( 2659 numberAt(pos), 2660 (List<String>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2661 writer); 2662 break; 2663 case 27: // MESSAGE_LIST: 2664 SchemaUtil.writeMessageList( 2665 numberAt(pos), 2666 (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2667 writer, 2668 getMessageFieldSchema(pos)); 2669 break; 2670 case 28: // BYTES_LIST: 2671 SchemaUtil.writeBytesList( 2672 numberAt(pos), 2673 (List<ByteString>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2674 writer); 2675 break; 2676 case 29: // UINT32_LIST: 2677 SchemaUtil.writeUInt32List( 2678 numberAt(pos), 2679 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2680 writer, 2681 false); 2682 break; 2683 case 30: // ENUM_LIST: 2684 SchemaUtil.writeEnumList( 2685 numberAt(pos), 2686 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2687 writer, 2688 false); 2689 break; 2690 case 31: // SFIXED32_LIST: 2691 SchemaUtil.writeSFixed32List( 2692 numberAt(pos), 2693 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2694 writer, 2695 false); 2696 break; 2697 case 32: // SFIXED64_LIST: 2698 SchemaUtil.writeSFixed64List( 2699 numberAt(pos), 2700 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2701 writer, 2702 false); 2703 break; 2704 case 33: // SINT32_LIST: 2705 SchemaUtil.writeSInt32List( 2706 numberAt(pos), 2707 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2708 writer, 2709 false); 2710 break; 2711 case 34: // SINT64_LIST: 2712 SchemaUtil.writeSInt64List( 2713 numberAt(pos), 2714 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2715 writer, 2716 false); 2717 break; 2718 case 35: // DOUBLE_LIST_PACKED: 2719 SchemaUtil.writeDoubleList( 2720 numberAt(pos), 2721 (List<Double>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2722 writer, 2723 true); 2724 break; 2725 case 36: // FLOAT_LIST_PACKED: 2726 SchemaUtil.writeFloatList( 2727 numberAt(pos), 2728 (List<Float>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2729 writer, 2730 true); 2731 break; 2732 case 37: // INT64_LIST_PACKED: 2733 SchemaUtil.writeInt64List( 2734 numberAt(pos), 2735 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2736 writer, 2737 true); 2738 break; 2739 case 38: // UINT64_LIST_PACKED: 2740 SchemaUtil.writeUInt64List( 2741 numberAt(pos), 2742 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2743 writer, 2744 true); 2745 break; 2746 case 39: // INT32_LIST_PACKED: 2747 SchemaUtil.writeInt32List( 2748 numberAt(pos), 2749 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2750 writer, 2751 true); 2752 break; 2753 case 40: // FIXED64_LIST_PACKED: 2754 SchemaUtil.writeFixed64List( 2755 numberAt(pos), 2756 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2757 writer, 2758 true); 2759 break; 2760 case 41: // FIXED32_LIST_PACKED: 2761 SchemaUtil.writeFixed32List( 2762 numberAt(pos), 2763 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2764 writer, 2765 true); 2766 2767 break; 2768 case 42: // BOOL_LIST_PACKED: 2769 SchemaUtil.writeBoolList( 2770 numberAt(pos), 2771 (List<Boolean>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2772 writer, 2773 true); 2774 break; 2775 case 43: // UINT32_LIST_PACKED: 2776 SchemaUtil.writeUInt32List( 2777 numberAt(pos), 2778 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2779 writer, 2780 true); 2781 break; 2782 case 44: // ENUM_LIST_PACKED: 2783 SchemaUtil.writeEnumList( 2784 numberAt(pos), 2785 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2786 writer, 2787 true); 2788 break; 2789 case 45: // SFIXED32_LIST_PACKED: 2790 SchemaUtil.writeSFixed32List( 2791 numberAt(pos), 2792 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2793 writer, 2794 true); 2795 break; 2796 case 46: // SFIXED64_LIST_PACKED: 2797 SchemaUtil.writeSFixed64List( 2798 numberAt(pos), 2799 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2800 writer, 2801 true); 2802 break; 2803 case 47: // SINT32_LIST_PACKED: 2804 SchemaUtil.writeSInt32List( 2805 numberAt(pos), 2806 (List<Integer>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2807 writer, 2808 true); 2809 break; 2810 case 48: // SINT64_LIST_PACKED: 2811 SchemaUtil.writeSInt64List( 2812 numberAt(pos), 2813 (List<Long>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2814 writer, 2815 true); 2816 break; 2817 case 49: // GROUP_LIST: 2818 SchemaUtil.writeGroupList( 2819 numberAt(pos), 2820 (List<?>) UnsafeUtil.getObject(message, offset(typeAndOffset)), 2821 writer, 2822 getMessageFieldSchema(pos)); 2823 break; 2824 case 50: // MAP: 2825 // TODO: Use schema cache. 2826 writeMapHelper(writer, number, UnsafeUtil.getObject(message, offset(typeAndOffset)), pos); 2827 break; 2828 case 51: // ONEOF_DOUBLE: 2829 if (isOneofPresent(message, number, pos)) { 2830 writer.writeDouble(number, oneofDoubleAt(message, offset(typeAndOffset))); 2831 } 2832 break; 2833 case 52: // ONEOF_FLOAT: 2834 if (isOneofPresent(message, number, pos)) { 2835 writer.writeFloat(number, oneofFloatAt(message, offset(typeAndOffset))); 2836 } 2837 break; 2838 case 53: // ONEOF_INT64: 2839 if (isOneofPresent(message, number, pos)) { 2840 writer.writeInt64(number, oneofLongAt(message, offset(typeAndOffset))); 2841 } 2842 break; 2843 case 54: // ONEOF_UINT64: 2844 if (isOneofPresent(message, number, pos)) { 2845 writer.writeUInt64(number, oneofLongAt(message, offset(typeAndOffset))); 2846 } 2847 break; 2848 case 55: // ONEOF_INT32: 2849 if (isOneofPresent(message, number, pos)) { 2850 writer.writeInt32(number, oneofIntAt(message, offset(typeAndOffset))); 2851 } 2852 break; 2853 case 56: // ONEOF_FIXED64: 2854 if (isOneofPresent(message, number, pos)) { 2855 writer.writeFixed64(number, oneofLongAt(message, offset(typeAndOffset))); 2856 } 2857 break; 2858 case 57: // ONEOF_FIXED32: 2859 if (isOneofPresent(message, number, pos)) { 2860 writer.writeFixed32(number, oneofIntAt(message, offset(typeAndOffset))); 2861 } 2862 break; 2863 case 58: // ONEOF_BOOL: 2864 if (isOneofPresent(message, number, pos)) { 2865 writer.writeBool(number, oneofBooleanAt(message, offset(typeAndOffset))); 2866 } 2867 break; 2868 case 59: // ONEOF_STRING: 2869 if (isOneofPresent(message, number, pos)) { 2870 writeString(number, UnsafeUtil.getObject(message, offset(typeAndOffset)), writer); 2871 } 2872 break; 2873 case 60: // ONEOF_MESSAGE: 2874 if (isOneofPresent(message, number, pos)) { 2875 Object value = UnsafeUtil.getObject(message, offset(typeAndOffset)); 2876 writer.writeMessage(number, value, getMessageFieldSchema(pos)); 2877 } 2878 break; 2879 case 61: // ONEOF_BYTES: 2880 if (isOneofPresent(message, number, pos)) { 2881 writer.writeBytes( 2882 number, (ByteString) UnsafeUtil.getObject(message, offset(typeAndOffset))); 2883 } 2884 break; 2885 case 62: // ONEOF_UINT32: 2886 if (isOneofPresent(message, number, pos)) { 2887 writer.writeUInt32(number, oneofIntAt(message, offset(typeAndOffset))); 2888 } 2889 break; 2890 case 63: // ONEOF_ENUM: 2891 if (isOneofPresent(message, number, pos)) { 2892 writer.writeEnum(number, oneofIntAt(message, offset(typeAndOffset))); 2893 } 2894 break; 2895 case 64: // ONEOF_SFIXED32: 2896 if (isOneofPresent(message, number, pos)) { 2897 writer.writeSFixed32(number, oneofIntAt(message, offset(typeAndOffset))); 2898 } 2899 break; 2900 case 65: // ONEOF_SFIXED64: 2901 if (isOneofPresent(message, number, pos)) { 2902 writer.writeSFixed64(number, oneofLongAt(message, offset(typeAndOffset))); 2903 } 2904 break; 2905 case 66: // ONEOF_SINT32: 2906 if (isOneofPresent(message, number, pos)) { 2907 writer.writeSInt32(number, oneofIntAt(message, offset(typeAndOffset))); 2908 } 2909 break; 2910 case 67: // ONEOF_SINT64: 2911 if (isOneofPresent(message, number, pos)) { 2912 writer.writeSInt64(number, oneofLongAt(message, offset(typeAndOffset))); 2913 } 2914 break; 2915 case 68: // ONEOF_GROUP: 2916 if (isOneofPresent(message, number, pos)) { 2917 writer.writeGroup( 2918 number, 2919 UnsafeUtil.getObject(message, offset(typeAndOffset)), 2920 getMessageFieldSchema(pos)); 2921 } 2922 break; 2923 default: 2924 break; 2925 } 2926 } 2927 while (nextExtension != null) { 2928 extensionSchema.serializeExtension(writer, nextExtension); 2929 nextExtension = extensionIterator.hasNext() ? extensionIterator.next() : null; 2930 } 2931 } 2932 2933 @SuppressWarnings("unchecked") writeMapHelper(Writer writer, int number, Object mapField, int pos)2934 private <K, V> void writeMapHelper(Writer writer, int number, Object mapField, int pos) 2935 throws IOException { 2936 if (mapField != null) { 2937 writer.writeMap( 2938 number, 2939 (MapEntryLite.Metadata<K, V>) mapFieldSchema.forMapMetadata(getMapFieldDefaultEntry(pos)), 2940 (Map<K, V>) mapFieldSchema.forMapData(mapField)); 2941 } 2942 } 2943 writeUnknownInMessageTo( UnknownFieldSchema<UT, UB> schema, T message, Writer writer)2944 private <UT, UB> void writeUnknownInMessageTo( 2945 UnknownFieldSchema<UT, UB> schema, T message, Writer writer) throws IOException { 2946 schema.writeTo(schema.getFromMessage(message), writer); 2947 } 2948 2949 @Override mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)2950 public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry) 2951 throws IOException { 2952 if (extensionRegistry == null) { 2953 throw new NullPointerException(); 2954 } 2955 checkMutable(message); 2956 mergeFromHelper(unknownFieldSchema, extensionSchema, message, reader, extensionRegistry); 2957 } 2958 2959 /** 2960 * A helper method for wildcard capture of {@code unknownFieldSchema}. See: 2961 * https://docs.oracle.com/javase/tutorial/java/generics/capture.html 2962 */ mergeFromHelper( UnknownFieldSchema<UT, UB> unknownFieldSchema, ExtensionSchema<ET> extensionSchema, T message, Reader reader, ExtensionRegistryLite extensionRegistry)2963 private <UT, UB, ET extends FieldDescriptorLite<ET>> void mergeFromHelper( 2964 UnknownFieldSchema<UT, UB> unknownFieldSchema, 2965 ExtensionSchema<ET> extensionSchema, 2966 T message, 2967 Reader reader, 2968 ExtensionRegistryLite extensionRegistry) 2969 throws IOException { 2970 UB unknownFields = null; 2971 FieldSet<ET> extensions = null; 2972 try { 2973 while (true) { 2974 final int number = reader.getFieldNumber(); 2975 final int pos = positionForFieldNumber(number); 2976 if (pos < 0) { 2977 if (number == Reader.READ_DONE) { 2978 return; 2979 } 2980 // Check if it's an extension. 2981 Object extension = 2982 !hasExtensions 2983 ? null 2984 : extensionSchema.findExtensionByNumber( 2985 extensionRegistry, defaultInstance, number); 2986 if (extension != null) { 2987 if (extensions == null) { 2988 extensions = extensionSchema.getMutableExtensions(message); 2989 } 2990 unknownFields = 2991 extensionSchema.parseExtension( 2992 message, 2993 reader, 2994 extension, 2995 extensionRegistry, 2996 extensions, 2997 unknownFields, 2998 unknownFieldSchema); 2999 continue; 3000 } 3001 if (unknownFieldSchema.shouldDiscardUnknownFields(reader)) { 3002 if (reader.skipField()) { 3003 continue; 3004 } 3005 } else { 3006 if (unknownFields == null) { 3007 unknownFields = unknownFieldSchema.getBuilderFromMessage(message); 3008 } 3009 // Unknown field. 3010 if (unknownFieldSchema.mergeOneFieldFrom( 3011 unknownFields, reader, /* currentDepth= */ 0)) { 3012 continue; 3013 } 3014 } 3015 // Done reading. 3016 return; 3017 } 3018 final int typeAndOffset = typeAndOffsetAt(pos); 3019 3020 try { 3021 switch (type(typeAndOffset)) { 3022 case 0: // DOUBLE: 3023 UnsafeUtil.putDouble(message, offset(typeAndOffset), reader.readDouble()); 3024 setFieldPresent(message, pos); 3025 break; 3026 case 1: // FLOAT: 3027 UnsafeUtil.putFloat(message, offset(typeAndOffset), reader.readFloat()); 3028 setFieldPresent(message, pos); 3029 break; 3030 case 2: // INT64: 3031 UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readInt64()); 3032 setFieldPresent(message, pos); 3033 break; 3034 case 3: // UINT64: 3035 UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readUInt64()); 3036 setFieldPresent(message, pos); 3037 break; 3038 case 4: // INT32: 3039 UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readInt32()); 3040 setFieldPresent(message, pos); 3041 break; 3042 case 5: // FIXED64: 3043 UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readFixed64()); 3044 setFieldPresent(message, pos); 3045 break; 3046 case 6: // FIXED32: 3047 UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readFixed32()); 3048 setFieldPresent(message, pos); 3049 break; 3050 case 7: // BOOL: 3051 UnsafeUtil.putBoolean(message, offset(typeAndOffset), reader.readBool()); 3052 setFieldPresent(message, pos); 3053 break; 3054 case 8: // STRING: 3055 readString(message, typeAndOffset, reader); 3056 setFieldPresent(message, pos); 3057 break; 3058 case 9: 3059 { // MESSAGE: 3060 final MessageLite current = (MessageLite) mutableMessageFieldForMerge(message, pos); 3061 reader.mergeMessageField( 3062 current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry); 3063 storeMessageField(message, pos, current); 3064 break; 3065 } 3066 case 10: // BYTES: 3067 UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes()); 3068 setFieldPresent(message, pos); 3069 break; 3070 case 11: // UINT32: 3071 UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readUInt32()); 3072 setFieldPresent(message, pos); 3073 break; 3074 case 12: // ENUM: 3075 { 3076 int enumValue = reader.readEnum(); 3077 EnumVerifier enumVerifier = getEnumFieldVerifier(pos); 3078 if (enumVerifier == null || enumVerifier.isInRange(enumValue)) { 3079 UnsafeUtil.putInt(message, offset(typeAndOffset), enumValue); 3080 setFieldPresent(message, pos); 3081 } else { 3082 unknownFields = 3083 SchemaUtil.storeUnknownEnum( 3084 message, number, enumValue, unknownFields, unknownFieldSchema); 3085 } 3086 break; 3087 } 3088 case 13: // SFIXED32: 3089 UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readSFixed32()); 3090 setFieldPresent(message, pos); 3091 break; 3092 case 14: // SFIXED64: 3093 UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readSFixed64()); 3094 setFieldPresent(message, pos); 3095 break; 3096 case 15: // SINT32: 3097 UnsafeUtil.putInt(message, offset(typeAndOffset), reader.readSInt32()); 3098 setFieldPresent(message, pos); 3099 break; 3100 case 16: // SINT64: 3101 UnsafeUtil.putLong(message, offset(typeAndOffset), reader.readSInt64()); 3102 setFieldPresent(message, pos); 3103 break; 3104 case 17: 3105 { // GROUP: 3106 final MessageLite current = (MessageLite) mutableMessageFieldForMerge(message, pos); 3107 reader.mergeGroupField( 3108 current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry); 3109 storeMessageField(message, pos, current); 3110 break; 3111 } 3112 case 18: // DOUBLE_LIST: 3113 reader.readDoubleList( 3114 listFieldSchema.<Double>mutableListAt(message, offset(typeAndOffset))); 3115 break; 3116 case 19: // FLOAT_LIST: 3117 reader.readFloatList( 3118 listFieldSchema.<Float>mutableListAt(message, offset(typeAndOffset))); 3119 break; 3120 case 20: // INT64_LIST: 3121 reader.readInt64List( 3122 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3123 break; 3124 case 21: // UINT64_LIST: 3125 reader.readUInt64List( 3126 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3127 break; 3128 case 22: // INT32_LIST: 3129 reader.readInt32List( 3130 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3131 break; 3132 case 23: // FIXED64_LIST: 3133 reader.readFixed64List( 3134 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3135 break; 3136 case 24: // FIXED32_LIST: 3137 reader.readFixed32List( 3138 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3139 break; 3140 case 25: // BOOL_LIST: 3141 reader.readBoolList( 3142 listFieldSchema.<Boolean>mutableListAt(message, offset(typeAndOffset))); 3143 break; 3144 case 26: // STRING_LIST: 3145 readStringList(message, typeAndOffset, reader); 3146 break; 3147 case 27: 3148 { // MESSAGE_LIST: 3149 readMessageList( 3150 message, 3151 typeAndOffset, 3152 reader, 3153 (Schema<T>) getMessageFieldSchema(pos), 3154 extensionRegistry); 3155 break; 3156 } 3157 case 28: // BYTES_LIST: 3158 reader.readBytesList( 3159 listFieldSchema.<ByteString>mutableListAt(message, offset(typeAndOffset))); 3160 break; 3161 case 29: // UINT32_LIST: 3162 reader.readUInt32List( 3163 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3164 break; 3165 case 30: // ENUM_LIST: 3166 { 3167 List<Integer> enumList = 3168 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)); 3169 reader.readEnumList(enumList); 3170 unknownFields = 3171 SchemaUtil.filterUnknownEnumList( 3172 message, 3173 number, 3174 enumList, 3175 getEnumFieldVerifier(pos), 3176 unknownFields, 3177 unknownFieldSchema); 3178 break; 3179 } 3180 case 31: // SFIXED32_LIST: 3181 reader.readSFixed32List( 3182 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3183 break; 3184 case 32: // SFIXED64_LIST: 3185 reader.readSFixed64List( 3186 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3187 break; 3188 case 33: // SINT32_LIST: 3189 reader.readSInt32List( 3190 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3191 break; 3192 case 34: // SINT64_LIST: 3193 reader.readSInt64List( 3194 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3195 break; 3196 case 35: // DOUBLE_LIST_PACKED: 3197 reader.readDoubleList( 3198 listFieldSchema.<Double>mutableListAt(message, offset(typeAndOffset))); 3199 break; 3200 case 36: // FLOAT_LIST_PACKED: 3201 reader.readFloatList( 3202 listFieldSchema.<Float>mutableListAt(message, offset(typeAndOffset))); 3203 break; 3204 case 37: // INT64_LIST_PACKED: 3205 reader.readInt64List( 3206 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3207 break; 3208 case 38: // UINT64_LIST_PACKED: 3209 reader.readUInt64List( 3210 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3211 break; 3212 case 39: // INT32_LIST_PACKED: 3213 reader.readInt32List( 3214 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3215 break; 3216 case 40: // FIXED64_LIST_PACKED: 3217 reader.readFixed64List( 3218 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3219 break; 3220 case 41: // FIXED32_LIST_PACKED: 3221 reader.readFixed32List( 3222 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3223 break; 3224 case 42: // BOOL_LIST_PACKED: 3225 reader.readBoolList( 3226 listFieldSchema.<Boolean>mutableListAt(message, offset(typeAndOffset))); 3227 break; 3228 case 43: // UINT32_LIST_PACKED: 3229 reader.readUInt32List( 3230 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3231 break; 3232 case 44: // ENUM_LIST_PACKED: 3233 { 3234 List<Integer> enumList = 3235 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset)); 3236 reader.readEnumList(enumList); 3237 unknownFields = 3238 SchemaUtil.filterUnknownEnumList( 3239 message, 3240 number, 3241 enumList, 3242 getEnumFieldVerifier(pos), 3243 unknownFields, 3244 unknownFieldSchema); 3245 break; 3246 } 3247 case 45: // SFIXED32_LIST_PACKED: 3248 reader.readSFixed32List( 3249 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3250 break; 3251 case 46: // SFIXED64_LIST_PACKED: 3252 reader.readSFixed64List( 3253 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3254 break; 3255 case 47: // SINT32_LIST_PACKED: 3256 reader.readSInt32List( 3257 listFieldSchema.<Integer>mutableListAt(message, offset(typeAndOffset))); 3258 break; 3259 case 48: // SINT64_LIST_PACKED: 3260 reader.readSInt64List( 3261 listFieldSchema.<Long>mutableListAt(message, offset(typeAndOffset))); 3262 break; 3263 case 49: 3264 { // GROUP_LIST: 3265 readGroupList( 3266 message, 3267 offset(typeAndOffset), 3268 reader, 3269 (Schema<T>) getMessageFieldSchema(pos), 3270 extensionRegistry); 3271 break; 3272 } 3273 case 50: // MAP: 3274 mergeMap(message, pos, getMapFieldDefaultEntry(pos), extensionRegistry, reader); 3275 break; 3276 case 51: // ONEOF_DOUBLE: 3277 UnsafeUtil.putObject( 3278 message, offset(typeAndOffset), Double.valueOf(reader.readDouble())); 3279 setOneofPresent(message, number, pos); 3280 break; 3281 case 52: // ONEOF_FLOAT: 3282 UnsafeUtil.putObject( 3283 message, offset(typeAndOffset), Float.valueOf(reader.readFloat())); 3284 setOneofPresent(message, number, pos); 3285 break; 3286 case 53: // ONEOF_INT64: 3287 UnsafeUtil.putObject( 3288 message, offset(typeAndOffset), Long.valueOf(reader.readInt64())); 3289 setOneofPresent(message, number, pos); 3290 break; 3291 case 54: // ONEOF_UINT64: 3292 UnsafeUtil.putObject( 3293 message, offset(typeAndOffset), Long.valueOf(reader.readUInt64())); 3294 setOneofPresent(message, number, pos); 3295 break; 3296 case 55: // ONEOF_INT32: 3297 UnsafeUtil.putObject( 3298 message, offset(typeAndOffset), Integer.valueOf(reader.readInt32())); 3299 setOneofPresent(message, number, pos); 3300 break; 3301 case 56: // ONEOF_FIXED64: 3302 UnsafeUtil.putObject( 3303 message, offset(typeAndOffset), Long.valueOf(reader.readFixed64())); 3304 setOneofPresent(message, number, pos); 3305 break; 3306 case 57: // ONEOF_FIXED32: 3307 UnsafeUtil.putObject( 3308 message, offset(typeAndOffset), Integer.valueOf(reader.readFixed32())); 3309 setOneofPresent(message, number, pos); 3310 break; 3311 case 58: // ONEOF_BOOL: 3312 UnsafeUtil.putObject( 3313 message, offset(typeAndOffset), Boolean.valueOf(reader.readBool())); 3314 setOneofPresent(message, number, pos); 3315 break; 3316 case 59: // ONEOF_STRING: 3317 readString(message, typeAndOffset, reader); 3318 setOneofPresent(message, number, pos); 3319 break; 3320 case 60: 3321 { // ONEOF_MESSAGE: 3322 final MessageLite current = 3323 (MessageLite) mutableOneofMessageFieldForMerge(message, number, pos); 3324 reader.mergeMessageField( 3325 current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry); 3326 storeOneofMessageField(message, number, pos, current); 3327 break; 3328 } 3329 case 61: // ONEOF_BYTES: 3330 UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes()); 3331 setOneofPresent(message, number, pos); 3332 break; 3333 case 62: // ONEOF_UINT32: 3334 UnsafeUtil.putObject( 3335 message, offset(typeAndOffset), Integer.valueOf(reader.readUInt32())); 3336 setOneofPresent(message, number, pos); 3337 break; 3338 case 63: // ONEOF_ENUM: 3339 { 3340 int enumValue = reader.readEnum(); 3341 EnumVerifier enumVerifier = getEnumFieldVerifier(pos); 3342 if (enumVerifier == null || enumVerifier.isInRange(enumValue)) { 3343 UnsafeUtil.putObject(message, offset(typeAndOffset), enumValue); 3344 setOneofPresent(message, number, pos); 3345 } else { 3346 unknownFields = 3347 SchemaUtil.storeUnknownEnum( 3348 message, number, enumValue, unknownFields, unknownFieldSchema); 3349 } 3350 break; 3351 } 3352 case 64: // ONEOF_SFIXED32: 3353 UnsafeUtil.putObject( 3354 message, offset(typeAndOffset), Integer.valueOf(reader.readSFixed32())); 3355 setOneofPresent(message, number, pos); 3356 break; 3357 case 65: // ONEOF_SFIXED64: 3358 UnsafeUtil.putObject( 3359 message, offset(typeAndOffset), Long.valueOf(reader.readSFixed64())); 3360 setOneofPresent(message, number, pos); 3361 break; 3362 case 66: // ONEOF_SINT32: 3363 UnsafeUtil.putObject( 3364 message, offset(typeAndOffset), Integer.valueOf(reader.readSInt32())); 3365 setOneofPresent(message, number, pos); 3366 break; 3367 case 67: // ONEOF_SINT64: 3368 UnsafeUtil.putObject( 3369 message, offset(typeAndOffset), Long.valueOf(reader.readSInt64())); 3370 setOneofPresent(message, number, pos); 3371 break; 3372 case 68: 3373 { // ONEOF_GROUP: 3374 final MessageLite current = 3375 (MessageLite) mutableOneofMessageFieldForMerge(message, number, pos); 3376 reader.mergeGroupField( 3377 current, (Schema<MessageLite>) getMessageFieldSchema(pos), extensionRegistry); 3378 storeOneofMessageField(message, number, pos, current); 3379 break; 3380 } 3381 default: 3382 // Assume we've landed on an empty entry. Treat it as an unknown field. 3383 if (unknownFields == null) { 3384 unknownFields = unknownFieldSchema.getBuilderFromMessage(message); 3385 } 3386 if (!unknownFieldSchema.mergeOneFieldFrom( 3387 unknownFields, reader, /* currentDepth= */ 0)) { 3388 return; 3389 } 3390 break; 3391 } 3392 } catch (InvalidProtocolBufferException.InvalidWireTypeException e) { 3393 // Treat fields with an invalid wire type as unknown fields 3394 // (i.e. same as the default case). 3395 if (unknownFieldSchema.shouldDiscardUnknownFields(reader)) { 3396 if (!reader.skipField()) { 3397 return; 3398 } 3399 } else { 3400 if (unknownFields == null) { 3401 unknownFields = unknownFieldSchema.getBuilderFromMessage(message); 3402 } 3403 if (!unknownFieldSchema.mergeOneFieldFrom( 3404 unknownFields, reader, /* currentDepth= */ 0)) { 3405 return; 3406 } 3407 } 3408 } 3409 } 3410 } finally { 3411 for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) { 3412 unknownFields = 3413 filterMapUnknownEnumValues( 3414 message, intArray[i], unknownFields, unknownFieldSchema, message); 3415 } 3416 if (unknownFields != null) { 3417 unknownFieldSchema.setBuilderToMessage(message, unknownFields); 3418 } 3419 } 3420 } 3421 3422 @SuppressWarnings("ReferenceEquality") getMutableUnknownFields(Object message)3423 static UnknownFieldSetLite getMutableUnknownFields(Object message) { 3424 // TODO decide if we're keeping support for Full in schema classes and handle this 3425 // better. 3426 UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields; 3427 if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) { 3428 unknownFields = UnknownFieldSetLite.newInstance(); 3429 ((GeneratedMessageLite) message).unknownFields = unknownFields; 3430 } 3431 return unknownFields; 3432 } 3433 3434 /** Decodes a map entry key or value. Stores result in registers.object1. */ decodeMapEntryValue( byte[] data, int position, int limit, WireFormat.FieldType fieldType, Class<?> messageType, Registers registers)3435 private int decodeMapEntryValue( 3436 byte[] data, 3437 int position, 3438 int limit, 3439 WireFormat.FieldType fieldType, 3440 Class<?> messageType, 3441 Registers registers) 3442 throws IOException { 3443 switch (fieldType) { 3444 case BOOL: 3445 position = decodeVarint64(data, position, registers); 3446 registers.object1 = registers.long1 != 0; 3447 break; 3448 case BYTES: 3449 position = decodeBytes(data, position, registers); 3450 break; 3451 case DOUBLE: 3452 registers.object1 = decodeDouble(data, position); 3453 position += 8; 3454 break; 3455 case FIXED32: 3456 case SFIXED32: 3457 registers.object1 = decodeFixed32(data, position); 3458 position += 4; 3459 break; 3460 case FIXED64: 3461 case SFIXED64: 3462 registers.object1 = decodeFixed64(data, position); 3463 position += 8; 3464 break; 3465 case FLOAT: 3466 registers.object1 = decodeFloat(data, position); 3467 position += 4; 3468 break; 3469 case ENUM: 3470 case INT32: 3471 case UINT32: 3472 position = decodeVarint32(data, position, registers); 3473 registers.object1 = registers.int1; 3474 break; 3475 case INT64: 3476 case UINT64: 3477 position = decodeVarint64(data, position, registers); 3478 registers.object1 = registers.long1; 3479 break; 3480 case MESSAGE: 3481 position = 3482 decodeMessageField( 3483 Protobuf.getInstance().schemaFor(messageType), data, position, limit, registers); 3484 break; 3485 case SINT32: 3486 position = decodeVarint32(data, position, registers); 3487 registers.object1 = CodedInputStream.decodeZigZag32(registers.int1); 3488 break; 3489 case SINT64: 3490 position = decodeVarint64(data, position, registers); 3491 registers.object1 = CodedInputStream.decodeZigZag64(registers.long1); 3492 break; 3493 case STRING: 3494 position = decodeStringRequireUtf8(data, position, registers); 3495 break; 3496 default: 3497 throw new RuntimeException("unsupported field type."); 3498 } 3499 return position; 3500 } 3501 3502 /** Decodes a map entry. */ decodeMapEntry( byte[] data, int position, int limit, MapEntryLite.Metadata<K, V> metadata, Map<K, V> target, Registers registers)3503 private <K, V> int decodeMapEntry( 3504 byte[] data, 3505 int position, 3506 int limit, 3507 MapEntryLite.Metadata<K, V> metadata, 3508 Map<K, V> target, 3509 Registers registers) 3510 throws IOException { 3511 position = decodeVarint32(data, position, registers); 3512 final int length = registers.int1; 3513 if (length < 0 || length > limit - position) { 3514 throw InvalidProtocolBufferException.truncatedMessage(); 3515 } 3516 final int end = position + length; 3517 K key = metadata.defaultKey; 3518 V value = metadata.defaultValue; 3519 while (position < end) { 3520 int tag = data[position++]; 3521 if (tag < 0) { 3522 position = decodeVarint32(tag, data, position, registers); 3523 tag = registers.int1; 3524 } 3525 final int fieldNumber = tag >>> 3; 3526 final int wireType = tag & 0x7; 3527 switch (fieldNumber) { 3528 case 1: 3529 if (wireType == metadata.keyType.getWireType()) { 3530 position = 3531 decodeMapEntryValue(data, position, limit, metadata.keyType, null, registers); 3532 key = (K) registers.object1; 3533 continue; 3534 } 3535 break; 3536 case 2: 3537 if (wireType == metadata.valueType.getWireType()) { 3538 position = 3539 decodeMapEntryValue( 3540 data, 3541 position, 3542 limit, 3543 metadata.valueType, 3544 metadata.defaultValue.getClass(), 3545 registers); 3546 value = (V) registers.object1; 3547 continue; 3548 } 3549 break; 3550 default: 3551 break; 3552 } 3553 position = skipField(tag, data, position, limit, registers); 3554 } 3555 if (position != end) { 3556 throw InvalidProtocolBufferException.parseFailure(); 3557 } 3558 target.put(key, value); 3559 return end; 3560 } 3561 3562 @SuppressWarnings("ReferenceEquality") parseRepeatedField( T message, byte[] data, int position, int limit, int tag, int number, int wireType, int bufferPosition, long typeAndOffset, int fieldType, long fieldOffset, Registers registers)3563 private int parseRepeatedField( 3564 T message, 3565 byte[] data, 3566 int position, 3567 int limit, 3568 int tag, 3569 int number, 3570 int wireType, 3571 int bufferPosition, 3572 long typeAndOffset, 3573 int fieldType, 3574 long fieldOffset, 3575 Registers registers) 3576 throws IOException { 3577 ProtobufList<?> list = (ProtobufList<?>) UNSAFE.getObject(message, fieldOffset); 3578 if (!list.isModifiable()) { 3579 final int size = list.size(); 3580 list = list.mutableCopyWithCapacity(size * 2); 3581 UNSAFE.putObject(message, fieldOffset, list); 3582 } 3583 switch (fieldType) { 3584 case 18: // DOUBLE_LIST: 3585 case 35: // DOUBLE_LIST_PACKED: 3586 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3587 position = decodePackedDoubleList(data, position, list, registers); 3588 } else if (wireType == WireFormat.WIRETYPE_FIXED64) { 3589 position = decodeDoubleList(tag, data, position, limit, list, registers); 3590 } 3591 break; 3592 case 19: // FLOAT_LIST: 3593 case 36: // FLOAT_LIST_PACKED: 3594 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3595 position = decodePackedFloatList(data, position, list, registers); 3596 } else if (wireType == WireFormat.WIRETYPE_FIXED32) { 3597 position = decodeFloatList(tag, data, position, limit, list, registers); 3598 } 3599 break; 3600 case 20: // INT64_LIST: 3601 case 21: // UINT64_LIST: 3602 case 37: // INT64_LIST_PACKED: 3603 case 38: // UINT64_LIST_PACKED: 3604 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3605 position = decodePackedVarint64List(data, position, list, registers); 3606 } else if (wireType == WireFormat.WIRETYPE_VARINT) { 3607 position = decodeVarint64List(tag, data, position, limit, list, registers); 3608 } 3609 break; 3610 case 22: // INT32_LIST: 3611 case 29: // UINT32_LIST: 3612 case 39: // INT32_LIST_PACKED: 3613 case 43: // UINT32_LIST_PACKED: 3614 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3615 position = decodePackedVarint32List(data, position, list, registers); 3616 } else if (wireType == WireFormat.WIRETYPE_VARINT) { 3617 position = decodeVarint32List(tag, data, position, limit, list, registers); 3618 } 3619 break; 3620 case 23: // FIXED64_LIST: 3621 case 32: // SFIXED64_LIST: 3622 case 40: // FIXED64_LIST_PACKED: 3623 case 46: // SFIXED64_LIST_PACKED: 3624 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3625 position = decodePackedFixed64List(data, position, list, registers); 3626 } else if (wireType == WireFormat.WIRETYPE_FIXED64) { 3627 position = decodeFixed64List(tag, data, position, limit, list, registers); 3628 } 3629 break; 3630 case 24: // FIXED32_LIST: 3631 case 31: // SFIXED32_LIST: 3632 case 41: // FIXED32_LIST_PACKED: 3633 case 45: // SFIXED32_LIST_PACKED: 3634 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3635 position = decodePackedFixed32List(data, position, list, registers); 3636 } else if (wireType == WireFormat.WIRETYPE_FIXED32) { 3637 position = decodeFixed32List(tag, data, position, limit, list, registers); 3638 } 3639 break; 3640 case 25: // BOOL_LIST: 3641 case 42: // BOOL_LIST_PACKED: 3642 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3643 position = decodePackedBoolList(data, position, list, registers); 3644 } else if (wireType == WireFormat.WIRETYPE_VARINT) { 3645 position = decodeBoolList(tag, data, position, limit, list, registers); 3646 } 3647 break; 3648 case 26: // STRING_LIST: 3649 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3650 if ((typeAndOffset & ENFORCE_UTF8_MASK) == 0) { 3651 position = decodeStringList(tag, data, position, limit, list, registers); 3652 } else { 3653 position = decodeStringListRequireUtf8(tag, data, position, limit, list, registers); 3654 } 3655 } 3656 break; 3657 case 27: // MESSAGE_LIST: 3658 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3659 position = 3660 decodeMessageList( 3661 getMessageFieldSchema(bufferPosition), 3662 tag, 3663 data, 3664 position, 3665 limit, 3666 list, 3667 registers); 3668 } 3669 break; 3670 case 28: // BYTES_LIST: 3671 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3672 position = decodeBytesList(tag, data, position, limit, list, registers); 3673 } 3674 break; 3675 case 30: // ENUM_LIST: 3676 case 44: // ENUM_LIST_PACKED: 3677 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3678 position = decodePackedVarint32List(data, position, list, registers); 3679 } else if (wireType == WireFormat.WIRETYPE_VARINT) { 3680 position = decodeVarint32List(tag, data, position, limit, list, registers); 3681 } else { 3682 break; 3683 } 3684 SchemaUtil.filterUnknownEnumList( 3685 message, 3686 number, 3687 (ProtobufList<Integer>) list, 3688 getEnumFieldVerifier(bufferPosition), 3689 null, 3690 (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema); 3691 break; 3692 case 33: // SINT32_LIST: 3693 case 47: // SINT32_LIST_PACKED: 3694 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3695 position = decodePackedSInt32List(data, position, list, registers); 3696 } else if (wireType == WireFormat.WIRETYPE_VARINT) { 3697 position = decodeSInt32List(tag, data, position, limit, list, registers); 3698 } 3699 break; 3700 case 34: // SINT64_LIST: 3701 case 48: // SINT64_LIST_PACKED: 3702 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3703 position = decodePackedSInt64List(data, position, list, registers); 3704 } else if (wireType == WireFormat.WIRETYPE_VARINT) { 3705 position = decodeSInt64List(tag, data, position, limit, list, registers); 3706 } 3707 break; 3708 case 49: // GROUP_LIST: 3709 if (wireType == WireFormat.WIRETYPE_START_GROUP) { 3710 position = 3711 decodeGroupList( 3712 getMessageFieldSchema(bufferPosition), 3713 tag, 3714 data, 3715 position, 3716 limit, 3717 list, 3718 registers); 3719 } 3720 break; 3721 default: 3722 break; 3723 } 3724 return position; 3725 } 3726 parseMapField( T message, byte[] data, int position, int limit, int bufferPosition, long fieldOffset, Registers registers)3727 private <K, V> int parseMapField( 3728 T message, 3729 byte[] data, 3730 int position, 3731 int limit, 3732 int bufferPosition, 3733 long fieldOffset, 3734 Registers registers) 3735 throws IOException { 3736 final sun.misc.Unsafe unsafe = UNSAFE; 3737 Object mapDefaultEntry = getMapFieldDefaultEntry(bufferPosition); 3738 Object mapField = unsafe.getObject(message, fieldOffset); 3739 if (mapFieldSchema.isImmutable(mapField)) { 3740 Object oldMapField = mapField; 3741 mapField = mapFieldSchema.newMapField(mapDefaultEntry); 3742 mapFieldSchema.mergeFrom(mapField, oldMapField); 3743 unsafe.putObject(message, fieldOffset, mapField); 3744 } 3745 return decodeMapEntry( 3746 data, 3747 position, 3748 limit, 3749 (Metadata<K, V>) mapFieldSchema.forMapMetadata(mapDefaultEntry), 3750 (Map<K, V>) mapFieldSchema.forMutableMapData(mapField), 3751 registers); 3752 } 3753 parseOneofField( T message, byte[] data, int position, int limit, int tag, int number, int wireType, int typeAndOffset, int fieldType, long fieldOffset, int bufferPosition, Registers registers)3754 private int parseOneofField( 3755 T message, 3756 byte[] data, 3757 int position, 3758 int limit, 3759 int tag, 3760 int number, 3761 int wireType, 3762 int typeAndOffset, 3763 int fieldType, 3764 long fieldOffset, 3765 int bufferPosition, 3766 Registers registers) 3767 throws IOException { 3768 final sun.misc.Unsafe unsafe = UNSAFE; 3769 final long oneofCaseOffset = buffer[bufferPosition + 2] & OFFSET_MASK; 3770 switch (fieldType) { 3771 case 51: // ONEOF_DOUBLE: 3772 if (wireType == WireFormat.WIRETYPE_FIXED64) { 3773 unsafe.putObject(message, fieldOffset, decodeDouble(data, position)); 3774 position += 8; 3775 unsafe.putInt(message, oneofCaseOffset, number); 3776 } 3777 break; 3778 case 52: // ONEOF_FLOAT: 3779 if (wireType == WireFormat.WIRETYPE_FIXED32) { 3780 unsafe.putObject(message, fieldOffset, decodeFloat(data, position)); 3781 position += 4; 3782 unsafe.putInt(message, oneofCaseOffset, number); 3783 } 3784 break; 3785 case 53: // ONEOF_INT64: 3786 case 54: // ONEOF_UINT64: 3787 if (wireType == WireFormat.WIRETYPE_VARINT) { 3788 position = decodeVarint64(data, position, registers); 3789 unsafe.putObject(message, fieldOffset, registers.long1); 3790 unsafe.putInt(message, oneofCaseOffset, number); 3791 } 3792 break; 3793 case 55: // ONEOF_INT32: 3794 case 62: // ONEOF_UINT32: 3795 if (wireType == WireFormat.WIRETYPE_VARINT) { 3796 position = decodeVarint32(data, position, registers); 3797 unsafe.putObject(message, fieldOffset, registers.int1); 3798 unsafe.putInt(message, oneofCaseOffset, number); 3799 } 3800 break; 3801 case 56: // ONEOF_FIXED64: 3802 case 65: // ONEOF_SFIXED64: 3803 if (wireType == WireFormat.WIRETYPE_FIXED64) { 3804 unsafe.putObject(message, fieldOffset, decodeFixed64(data, position)); 3805 position += 8; 3806 unsafe.putInt(message, oneofCaseOffset, number); 3807 } 3808 break; 3809 case 57: // ONEOF_FIXED32: 3810 case 64: // ONEOF_SFIXED32: 3811 if (wireType == WireFormat.WIRETYPE_FIXED32) { 3812 unsafe.putObject(message, fieldOffset, decodeFixed32(data, position)); 3813 position += 4; 3814 unsafe.putInt(message, oneofCaseOffset, number); 3815 } 3816 break; 3817 case 58: // ONEOF_BOOL: 3818 if (wireType == WireFormat.WIRETYPE_VARINT) { 3819 position = decodeVarint64(data, position, registers); 3820 unsafe.putObject(message, fieldOffset, registers.long1 != 0); 3821 unsafe.putInt(message, oneofCaseOffset, number); 3822 } 3823 break; 3824 case 59: // ONEOF_STRING: 3825 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3826 position = decodeVarint32(data, position, registers); 3827 final int length = registers.int1; 3828 if (length == 0) { 3829 unsafe.putObject(message, fieldOffset, ""); 3830 } else { 3831 if ((typeAndOffset & ENFORCE_UTF8_MASK) != 0 3832 && !Utf8.isValidUtf8(data, position, position + length)) { 3833 throw InvalidProtocolBufferException.invalidUtf8(); 3834 } 3835 final String value = new String(data, position, length, Internal.UTF_8); 3836 unsafe.putObject(message, fieldOffset, value); 3837 position += length; 3838 } 3839 unsafe.putInt(message, oneofCaseOffset, number); 3840 } 3841 break; 3842 case 60: // ONEOF_MESSAGE: 3843 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3844 final Object current = mutableOneofMessageFieldForMerge(message, number, bufferPosition); 3845 position = 3846 mergeMessageField( 3847 current, getMessageFieldSchema(bufferPosition), data, position, limit, registers); 3848 storeOneofMessageField(message, number, bufferPosition, current); 3849 } 3850 break; 3851 case 61: // ONEOF_BYTES: 3852 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 3853 position = decodeBytes(data, position, registers); 3854 unsafe.putObject(message, fieldOffset, registers.object1); 3855 unsafe.putInt(message, oneofCaseOffset, number); 3856 } 3857 break; 3858 case 63: // ONEOF_ENUM: 3859 if (wireType == WireFormat.WIRETYPE_VARINT) { 3860 position = decodeVarint32(data, position, registers); 3861 final int enumValue = registers.int1; 3862 EnumVerifier enumVerifier = getEnumFieldVerifier(bufferPosition); 3863 if (enumVerifier == null || enumVerifier.isInRange(enumValue)) { 3864 unsafe.putObject(message, fieldOffset, enumValue); 3865 unsafe.putInt(message, oneofCaseOffset, number); 3866 } else { 3867 // UnknownFieldSetLite requires varint to be represented as Long. 3868 getMutableUnknownFields(message).storeField(tag, (long) enumValue); 3869 } 3870 } 3871 break; 3872 case 66: // ONEOF_SINT32: 3873 if (wireType == WireFormat.WIRETYPE_VARINT) { 3874 position = decodeVarint32(data, position, registers); 3875 unsafe.putObject(message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1)); 3876 unsafe.putInt(message, oneofCaseOffset, number); 3877 } 3878 break; 3879 case 67: // ONEOF_SINT64: 3880 if (wireType == WireFormat.WIRETYPE_VARINT) { 3881 position = decodeVarint64(data, position, registers); 3882 unsafe.putObject(message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1)); 3883 unsafe.putInt(message, oneofCaseOffset, number); 3884 } 3885 break; 3886 case 68: // ONEOF_GROUP: 3887 if (wireType == WireFormat.WIRETYPE_START_GROUP) { 3888 final Object current = mutableOneofMessageFieldForMerge(message, number, bufferPosition); 3889 final int endTag = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP; 3890 position = 3891 mergeGroupField( 3892 current, 3893 getMessageFieldSchema(bufferPosition), 3894 data, 3895 position, 3896 limit, 3897 endTag, 3898 registers); 3899 storeOneofMessageField(message, number, bufferPosition, current); 3900 } 3901 break; 3902 default: 3903 break; 3904 } 3905 return position; 3906 } 3907 getMessageFieldSchema(int pos)3908 private Schema getMessageFieldSchema(int pos) { 3909 final int index = pos / INTS_PER_FIELD * 2; 3910 Schema schema = (Schema) objects[index]; 3911 if (schema != null) { 3912 return schema; 3913 } 3914 schema = Protobuf.getInstance().schemaFor((Class) objects[index + 1]); 3915 objects[index] = schema; 3916 return schema; 3917 } 3918 getMapFieldDefaultEntry(int pos)3919 private Object getMapFieldDefaultEntry(int pos) { 3920 return objects[pos / INTS_PER_FIELD * 2]; 3921 } 3922 getEnumFieldVerifier(int pos)3923 private EnumVerifier getEnumFieldVerifier(int pos) { 3924 return (EnumVerifier) objects[pos / INTS_PER_FIELD * 2 + 1]; 3925 } 3926 3927 /** 3928 * Parses a message and returns the position after the message/group. If it's parsing a 3929 * LENGTH_PREFIXED message (endDelimited == 0), returns limit if parsing is successful; If it's 3930 * parsing a DELIMITED message aka group (endDelimited != 0), parsing ends when a tag == 3931 * endDelimited is encountered and the position after that tag is returned. 3932 */ 3933 @CanIgnoreReturnValue parseMessage( T message, byte[] data, int position, int limit, int endDelimited, Registers registers)3934 int parseMessage( 3935 T message, byte[] data, int position, int limit, int endDelimited, Registers registers) 3936 throws IOException { 3937 checkMutable(message); 3938 final sun.misc.Unsafe unsafe = UNSAFE; 3939 int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; 3940 int currentPresenceField = 0; 3941 int tag = 0; 3942 int oldNumber = -1; 3943 int pos = 0; 3944 while (position < limit) { 3945 tag = data[position++]; 3946 if (tag < 0) { 3947 position = decodeVarint32(tag, data, position, registers); 3948 tag = registers.int1; 3949 } 3950 final int number = tag >>> 3; 3951 final int wireType = tag & 0x7; 3952 if (number > oldNumber) { 3953 pos = positionForFieldNumber(number, pos / INTS_PER_FIELD); 3954 } else { 3955 pos = positionForFieldNumber(number); 3956 } 3957 oldNumber = number; 3958 if (pos == -1) { 3959 // need to reset 3960 pos = 0; 3961 } else { 3962 final int typeAndOffset = buffer[pos + 1]; 3963 final int fieldType = type(typeAndOffset); 3964 final long fieldOffset = offset(typeAndOffset); 3965 if (fieldType <= 17) { 3966 // Fields with explicit presence (i.e. optional) have has-bits. 3967 final int presenceMaskAndOffset = buffer[pos + 2]; 3968 final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); 3969 final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; 3970 // We cache the 32-bit presence integer value and only write it back when parsing a field 3971 // using a different presence integer. 3972 if (presenceFieldOffset != currentPresenceFieldOffset) { 3973 if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { 3974 unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField); 3975 } 3976 currentPresenceFieldOffset = presenceFieldOffset; 3977 // For fields without presence, we unconditionally write and discard 3978 // the data. 3979 currentPresenceField = 3980 presenceFieldOffset == NO_PRESENCE_SENTINEL 3981 ? 0 3982 : unsafe.getInt(message, (long) presenceFieldOffset); 3983 } 3984 switch (fieldType) { 3985 case 0: // DOUBLE 3986 if (wireType == WireFormat.WIRETYPE_FIXED64) { 3987 UnsafeUtil.putDouble(message, fieldOffset, decodeDouble(data, position)); 3988 position += 8; 3989 currentPresenceField |= presenceMask; 3990 continue; 3991 } 3992 break; 3993 case 1: // FLOAT 3994 if (wireType == WireFormat.WIRETYPE_FIXED32) { 3995 UnsafeUtil.putFloat(message, fieldOffset, decodeFloat(data, position)); 3996 position += 4; 3997 currentPresenceField |= presenceMask; 3998 continue; 3999 } 4000 break; 4001 case 2: // INT64 4002 case 3: // UINT64 4003 if (wireType == WireFormat.WIRETYPE_VARINT) { 4004 position = decodeVarint64(data, position, registers); 4005 unsafe.putLong(message, fieldOffset, registers.long1); 4006 currentPresenceField |= presenceMask; 4007 continue; 4008 } 4009 break; 4010 case 4: // INT32 4011 case 11: // UINT32 4012 if (wireType == WireFormat.WIRETYPE_VARINT) { 4013 position = decodeVarint32(data, position, registers); 4014 unsafe.putInt(message, fieldOffset, registers.int1); 4015 currentPresenceField |= presenceMask; 4016 continue; 4017 } 4018 break; 4019 case 5: // FIXED64 4020 case 14: // SFIXED64 4021 if (wireType == WireFormat.WIRETYPE_FIXED64) { 4022 unsafe.putLong(message, fieldOffset, decodeFixed64(data, position)); 4023 position += 8; 4024 currentPresenceField |= presenceMask; 4025 continue; 4026 } 4027 break; 4028 case 6: // FIXED32 4029 case 13: // SFIXED32 4030 if (wireType == WireFormat.WIRETYPE_FIXED32) { 4031 unsafe.putInt(message, fieldOffset, decodeFixed32(data, position)); 4032 position += 4; 4033 currentPresenceField |= presenceMask; 4034 continue; 4035 } 4036 break; 4037 case 7: // BOOL 4038 if (wireType == WireFormat.WIRETYPE_VARINT) { 4039 position = decodeVarint64(data, position, registers); 4040 UnsafeUtil.putBoolean(message, fieldOffset, registers.long1 != 0); 4041 currentPresenceField |= presenceMask; 4042 continue; 4043 } 4044 break; 4045 case 8: // STRING 4046 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 4047 if (isEnforceUtf8(typeAndOffset)) { 4048 position = decodeStringRequireUtf8(data, position, registers); 4049 } else { 4050 position = decodeString(data, position, registers); 4051 } 4052 unsafe.putObject(message, fieldOffset, registers.object1); 4053 currentPresenceField |= presenceMask; 4054 continue; 4055 } 4056 break; 4057 case 9: // MESSAGE 4058 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 4059 final Object current = mutableMessageFieldForMerge(message, pos); 4060 position = 4061 mergeMessageField( 4062 current, getMessageFieldSchema(pos), data, position, limit, registers); 4063 storeMessageField(message, pos, current); 4064 currentPresenceField |= presenceMask; 4065 continue; 4066 } 4067 break; 4068 case 10: // BYTES 4069 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 4070 position = decodeBytes(data, position, registers); 4071 unsafe.putObject(message, fieldOffset, registers.object1); 4072 currentPresenceField |= presenceMask; 4073 continue; 4074 } 4075 break; 4076 case 12: // ENUM 4077 if (wireType == WireFormat.WIRETYPE_VARINT) { 4078 position = decodeVarint32(data, position, registers); 4079 final int enumValue = registers.int1; 4080 EnumVerifier enumVerifier = getEnumFieldVerifier(pos); 4081 if (!isLegacyEnumIsClosed(typeAndOffset) 4082 || enumVerifier == null 4083 || enumVerifier.isInRange(enumValue)) { 4084 // Parse open enums and in-range closed enums into their fields directly. 4085 unsafe.putInt(message, fieldOffset, enumValue); 4086 currentPresenceField |= presenceMask; 4087 } else { 4088 // Store out-of-range closed enums in unknown fields. 4089 // UnknownFieldSetLite requires varint to be represented as Long. 4090 getMutableUnknownFields(message).storeField(tag, (long) enumValue); 4091 } 4092 continue; 4093 } 4094 break; 4095 case 15: // SINT32 4096 if (wireType == WireFormat.WIRETYPE_VARINT) { 4097 position = decodeVarint32(data, position, registers); 4098 unsafe.putInt( 4099 message, fieldOffset, CodedInputStream.decodeZigZag32(registers.int1)); 4100 currentPresenceField |= presenceMask; 4101 continue; 4102 } 4103 break; 4104 case 16: // SINT64 4105 if (wireType == WireFormat.WIRETYPE_VARINT) { 4106 position = decodeVarint64(data, position, registers); 4107 unsafe.putLong( 4108 message, fieldOffset, CodedInputStream.decodeZigZag64(registers.long1)); 4109 4110 currentPresenceField |= presenceMask; 4111 continue; 4112 } 4113 break; 4114 case 17: // GROUP 4115 if (wireType == WireFormat.WIRETYPE_START_GROUP) { 4116 final Object current = mutableMessageFieldForMerge(message, pos); 4117 final int endTag = (number << 3) | WireFormat.WIRETYPE_END_GROUP; 4118 position = 4119 mergeGroupField( 4120 current, 4121 getMessageFieldSchema(pos), 4122 data, 4123 position, 4124 limit, 4125 endTag, 4126 registers); 4127 storeMessageField(message, pos, current); 4128 currentPresenceField |= presenceMask; 4129 continue; 4130 } 4131 break; 4132 default: 4133 break; 4134 } 4135 } else if (fieldType == 27) { 4136 // Handle repeated message field. 4137 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 4138 ProtobufList<?> list = (ProtobufList<?>) unsafe.getObject(message, fieldOffset); 4139 if (!list.isModifiable()) { 4140 final int size = list.size(); 4141 list = 4142 list.mutableCopyWithCapacity( 4143 size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2); 4144 unsafe.putObject(message, fieldOffset, list); 4145 } 4146 position = 4147 decodeMessageList( 4148 getMessageFieldSchema(pos), tag, data, position, limit, list, registers); 4149 continue; 4150 } 4151 } else if (fieldType <= 49) { 4152 // Handle all other repeated fields. 4153 final int oldPosition = position; 4154 position = 4155 parseRepeatedField( 4156 message, 4157 data, 4158 position, 4159 limit, 4160 tag, 4161 number, 4162 wireType, 4163 pos, 4164 typeAndOffset, 4165 fieldType, 4166 fieldOffset, 4167 registers); 4168 if (position != oldPosition) { 4169 continue; 4170 } 4171 } else if (fieldType == 50) { 4172 if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { 4173 final int oldPosition = position; 4174 position = parseMapField(message, data, position, limit, pos, fieldOffset, registers); 4175 if (position != oldPosition) { 4176 continue; 4177 } 4178 } 4179 } else { 4180 final int oldPosition = position; 4181 position = 4182 parseOneofField( 4183 message, 4184 data, 4185 position, 4186 limit, 4187 tag, 4188 number, 4189 wireType, 4190 typeAndOffset, 4191 fieldType, 4192 fieldOffset, 4193 pos, 4194 registers); 4195 if (position != oldPosition) { 4196 continue; 4197 } 4198 } 4199 } 4200 if (tag == endDelimited && endDelimited != 0) { 4201 break; 4202 } 4203 4204 if (hasExtensions 4205 && registers.extensionRegistry != ExtensionRegistryLite.getEmptyRegistry()) { 4206 position = decodeExtensionOrUnknownField( 4207 tag, data, position, limit, message, defaultInstance, 4208 (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema, 4209 registers); 4210 } else { 4211 position = decodeUnknownField( 4212 tag, data, position, limit, getMutableUnknownFields(message), registers); 4213 } 4214 } 4215 if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { 4216 unsafe.putInt(message, (long) currentPresenceFieldOffset, currentPresenceField); 4217 } 4218 UnknownFieldSetLite unknownFields = null; 4219 for (int i = checkInitializedCount; i < repeatedFieldOffsetStart; i++) { 4220 unknownFields = 4221 filterMapUnknownEnumValues( 4222 message, 4223 intArray[i], 4224 unknownFields, 4225 (UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema, 4226 message); 4227 } 4228 if (unknownFields != null) { 4229 ((UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite>) unknownFieldSchema) 4230 .setBuilderToMessage(message, unknownFields); 4231 } 4232 if (endDelimited == 0) { 4233 if (position != limit) { 4234 throw InvalidProtocolBufferException.parseFailure(); 4235 } 4236 } else { 4237 if (position > limit || tag != endDelimited) { 4238 throw InvalidProtocolBufferException.parseFailure(); 4239 } 4240 } 4241 return position; 4242 } 4243 mutableMessageFieldForMerge(T message, int pos)4244 private Object mutableMessageFieldForMerge(T message, int pos) { 4245 final Schema fieldSchema = getMessageFieldSchema(pos); 4246 final long offset = offset(typeAndOffsetAt(pos)); 4247 4248 // Field not present, create a new one 4249 if (!isFieldPresent(message, pos)) { 4250 return fieldSchema.newInstance(); 4251 } 4252 4253 // Field present, if mutable, ready to merge 4254 final Object current = UNSAFE.getObject(message, offset); 4255 if (isMutable(current)) { 4256 return current; 4257 } 4258 4259 // Field present but immutable, make a new mutable copy 4260 final Object newMessage = fieldSchema.newInstance(); 4261 if (current != null) { 4262 fieldSchema.mergeFrom(newMessage, current); 4263 } 4264 return newMessage; 4265 } 4266 storeMessageField(T message, int pos, Object field)4267 private void storeMessageField(T message, int pos, Object field) { 4268 UNSAFE.putObject(message, offset(typeAndOffsetAt(pos)), field); 4269 setFieldPresent(message, pos); 4270 } 4271 mutableOneofMessageFieldForMerge(T message, int fieldNumber, int pos)4272 private Object mutableOneofMessageFieldForMerge(T message, int fieldNumber, int pos) { 4273 final Schema fieldSchema = getMessageFieldSchema(pos); 4274 4275 // Field not present, create it and mark it present 4276 if (!isOneofPresent(message, fieldNumber, pos)) { 4277 return fieldSchema.newInstance(); 4278 } 4279 4280 // Field present, if mutable, ready to merge 4281 final Object current = UNSAFE.getObject(message, offset(typeAndOffsetAt(pos))); 4282 if (isMutable(current)) { 4283 return current; 4284 } 4285 4286 // Field present but immutable, make a new mutable copy 4287 final Object newMessage = fieldSchema.newInstance(); 4288 if (current != null) { 4289 fieldSchema.mergeFrom(newMessage, current); 4290 } 4291 return newMessage; 4292 } 4293 storeOneofMessageField(T message, int fieldNumber, int pos, Object field)4294 private void storeOneofMessageField(T message, int fieldNumber, int pos, Object field) { 4295 UNSAFE.putObject(message, offset(typeAndOffsetAt(pos)), field); 4296 setOneofPresent(message, fieldNumber, pos); 4297 } 4298 4299 @Override mergeFrom(T message, byte[] data, int position, int limit, Registers registers)4300 public void mergeFrom(T message, byte[] data, int position, int limit, Registers registers) 4301 throws IOException { 4302 parseMessage(message, data, position, limit, 0, registers); 4303 } 4304 4305 @Override makeImmutable(T message)4306 public void makeImmutable(T message) { 4307 if (!isMutable(message)) { 4308 return; 4309 } 4310 4311 // TODO decide if we're keeping support for Full in schema classes and handle this 4312 // better. 4313 if (message instanceof GeneratedMessageLite) { 4314 GeneratedMessageLite<?, ?> generatedMessage = ((GeneratedMessageLite<?, ?>) message); 4315 generatedMessage.clearMemoizedSerializedSize(); 4316 generatedMessage.clearMemoizedHashCode(); 4317 generatedMessage.markImmutable(); 4318 } 4319 4320 final int bufferLength = buffer.length; 4321 for (int pos = 0; pos < bufferLength; pos += INTS_PER_FIELD) { 4322 final int typeAndOffset = typeAndOffsetAt(pos); 4323 final long offset = offset(typeAndOffset); 4324 switch (type(typeAndOffset)) { 4325 case 17: // GROUP 4326 case 9: // MESSAGE 4327 if (isFieldPresent(message, pos)) { 4328 getMessageFieldSchema(pos).makeImmutable(UNSAFE.getObject(message, offset)); 4329 } 4330 break; 4331 case 60: // ONEOF_MESSAGE 4332 case 68: // ONEOF_GROUP 4333 if (isOneofPresent(message, numberAt(pos), pos)) { 4334 getMessageFieldSchema(pos).makeImmutable(UNSAFE.getObject(message, offset)); 4335 } 4336 break; 4337 case 18: // DOUBLE_LIST: 4338 case 19: // FLOAT_LIST: 4339 case 20: // INT64_LIST: 4340 case 21: // UINT64_LIST: 4341 case 22: // INT32_LIST: 4342 case 23: // FIXED64_LIST: 4343 case 24: // FIXED32_LIST: 4344 case 25: // BOOL_LIST: 4345 case 26: // STRING_LIST: 4346 case 27: // MESSAGE_LIST: 4347 case 28: // BYTES_LIST: 4348 case 29: // UINT32_LIST: 4349 case 30: // ENUM_LIST: 4350 case 31: // SFIXED32_LIST: 4351 case 32: // SFIXED64_LIST: 4352 case 33: // SINT32_LIST: 4353 case 34: // SINT64_LIST: 4354 case 35: // DOUBLE_LIST_PACKED: 4355 case 36: // FLOAT_LIST_PACKED: 4356 case 37: // INT64_LIST_PACKED: 4357 case 38: // UINT64_LIST_PACKED: 4358 case 39: // INT32_LIST_PACKED: 4359 case 40: // FIXED64_LIST_PACKED: 4360 case 41: // FIXED32_LIST_PACKED: 4361 case 42: // BOOL_LIST_PACKED: 4362 case 43: // UINT32_LIST_PACKED: 4363 case 44: // ENUM_LIST_PACKED: 4364 case 45: // SFIXED32_LIST_PACKED: 4365 case 46: // SFIXED64_LIST_PACKED: 4366 case 47: // SINT32_LIST_PACKED: 4367 case 48: // SINT64_LIST_PACKED: 4368 case 49: // GROUP_LIST: 4369 listFieldSchema.makeImmutableListAt(message, offset); 4370 break; 4371 case 50: // MAP: 4372 { 4373 Object mapField = UNSAFE.getObject(message, offset); 4374 if (mapField != null) { 4375 UNSAFE.putObject(message, offset, mapFieldSchema.toImmutable(mapField)); 4376 } 4377 } 4378 break; 4379 } 4380 } 4381 unknownFieldSchema.makeImmutable(message); 4382 if (hasExtensions) { 4383 extensionSchema.makeImmutable(message); 4384 } 4385 } 4386 4387 @SuppressWarnings("unchecked") mergeMap( Object message, int pos, Object mapDefaultEntry, ExtensionRegistryLite extensionRegistry, Reader reader)4388 private final <K, V> void mergeMap( 4389 Object message, 4390 int pos, 4391 Object mapDefaultEntry, 4392 ExtensionRegistryLite extensionRegistry, 4393 Reader reader) 4394 throws IOException { 4395 long offset = offset(typeAndOffsetAt(pos)); 4396 Object mapField = UnsafeUtil.getObject(message, offset); 4397 // TODO: Consider creating separate implementations for full and lite. In lite 4398 // runtime map field will never be null but here we still need to check null because the 4399 // code is shared by both full and lite. It might be better if full/lite uses different 4400 // schema implementations. 4401 if (mapField == null) { 4402 mapField = mapFieldSchema.newMapField(mapDefaultEntry); 4403 UnsafeUtil.putObject(message, offset, mapField); 4404 } else if (mapFieldSchema.isImmutable(mapField)) { 4405 Object oldMapField = mapField; 4406 mapField = mapFieldSchema.newMapField(mapDefaultEntry); 4407 mapFieldSchema.mergeFrom(mapField, oldMapField); 4408 UnsafeUtil.putObject(message, offset, mapField); 4409 } 4410 reader.readMap( 4411 (Map<K, V>) mapFieldSchema.forMutableMapData(mapField), 4412 (Metadata<K, V>) mapFieldSchema.forMapMetadata(mapDefaultEntry), 4413 extensionRegistry); 4414 } 4415 filterMapUnknownEnumValues( Object message, int pos, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema, Object containerMessage)4416 private <UT, UB> UB filterMapUnknownEnumValues( 4417 Object message, 4418 int pos, 4419 UB unknownFields, 4420 UnknownFieldSchema<UT, UB> unknownFieldSchema, 4421 Object containerMessage) { 4422 int fieldNumber = numberAt(pos); 4423 long offset = offset(typeAndOffsetAt(pos)); 4424 Object mapField = UnsafeUtil.getObject(message, offset); 4425 if (mapField == null) { 4426 return unknownFields; 4427 } 4428 EnumVerifier enumVerifier = getEnumFieldVerifier(pos); 4429 if (enumVerifier == null) { 4430 return unknownFields; 4431 } 4432 Map<?, ?> mapData = mapFieldSchema.forMutableMapData(mapField); 4433 // Filter unknown enum values. 4434 unknownFields = 4435 filterUnknownEnumMap( 4436 pos, 4437 fieldNumber, 4438 mapData, 4439 enumVerifier, 4440 unknownFields, 4441 unknownFieldSchema, 4442 containerMessage); 4443 return unknownFields; 4444 } 4445 4446 @SuppressWarnings("unchecked") filterUnknownEnumMap( int pos, int number, Map<K, V> mapData, EnumVerifier enumVerifier, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema, Object containerMessage)4447 private <K, V, UT, UB> UB filterUnknownEnumMap( 4448 int pos, 4449 int number, 4450 Map<K, V> mapData, 4451 EnumVerifier enumVerifier, 4452 UB unknownFields, 4453 UnknownFieldSchema<UT, UB> unknownFieldSchema, 4454 Object containerMessage) { 4455 Metadata<K, V> metadata = 4456 (Metadata<K, V>) mapFieldSchema.forMapMetadata(getMapFieldDefaultEntry(pos)); 4457 for (Iterator<Map.Entry<K, V>> it = mapData.entrySet().iterator(); it.hasNext(); ) { 4458 Map.Entry<K, V> entry = it.next(); 4459 if (!enumVerifier.isInRange((Integer) entry.getValue())) { 4460 if (unknownFields == null) { 4461 unknownFields = unknownFieldSchema.getBuilderFromMessage(containerMessage); 4462 } 4463 int entrySize = 4464 MapEntryLite.computeSerializedSize(metadata, entry.getKey(), entry.getValue()); 4465 CodedBuilder codedBuilder = ByteString.newCodedBuilder(entrySize); 4466 CodedOutputStream codedOutput = codedBuilder.getCodedOutput(); 4467 try { 4468 MapEntryLite.writeTo(codedOutput, metadata, entry.getKey(), entry.getValue()); 4469 } catch (IOException e) { 4470 // Writing to ByteString CodedOutputStream should not throw IOException. 4471 throw new RuntimeException(e); 4472 } 4473 unknownFieldSchema.addLengthDelimited(unknownFields, number, codedBuilder.build()); 4474 it.remove(); 4475 } 4476 } 4477 return unknownFields; 4478 } 4479 4480 @Override isInitialized(T message)4481 public final boolean isInitialized(T message) { 4482 int currentPresenceFieldOffset = NO_PRESENCE_SENTINEL; 4483 int currentPresenceField = 0; 4484 for (int i = 0; i < checkInitializedCount; i++) { 4485 final int pos = intArray[i]; 4486 final int number = numberAt(pos); 4487 final int typeAndOffset = typeAndOffsetAt(pos); 4488 4489 int presenceMaskAndOffset = buffer[pos + 2]; 4490 final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; 4491 int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); 4492 if (presenceFieldOffset != currentPresenceFieldOffset) { 4493 currentPresenceFieldOffset = presenceFieldOffset; 4494 if (currentPresenceFieldOffset != NO_PRESENCE_SENTINEL) { 4495 currentPresenceField = UNSAFE.getInt(message, (long) presenceFieldOffset); 4496 } 4497 } 4498 4499 if (isRequired(typeAndOffset)) { 4500 if (!isFieldPresent( 4501 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask)) { 4502 return false; 4503 } 4504 // If a required message field is set but has no required fields of its own, we still 4505 // proceed and check the message is initialized. It should be fairly cheap to check these 4506 // messages but is worth documenting. 4507 } 4508 // Check nested message and groups. 4509 switch (type(typeAndOffset)) { 4510 case 9: // MESSAGE 4511 case 17: // GROUP 4512 if (isFieldPresent( 4513 message, pos, currentPresenceFieldOffset, currentPresenceField, presenceMask) 4514 && !isInitialized(message, typeAndOffset, getMessageFieldSchema(pos))) { 4515 return false; 4516 } 4517 break; 4518 case 27: // MESSAGE_LIST 4519 case 49: // GROUP_LIST 4520 if (!isListInitialized(message, typeAndOffset, pos)) { 4521 return false; 4522 } 4523 break; 4524 case 60: // ONEOF_MESSAGE 4525 case 68: // ONEOF_GROUP 4526 if (isOneofPresent(message, number, pos) 4527 && !isInitialized(message, typeAndOffset, getMessageFieldSchema(pos))) { 4528 return false; 4529 } 4530 break; 4531 case 50: // MAP 4532 if (!isMapInitialized(message, typeAndOffset, pos)) { 4533 return false; 4534 } 4535 break; 4536 default: 4537 break; 4538 } 4539 } 4540 4541 if (hasExtensions) { 4542 if (!extensionSchema.getExtensions(message).isInitialized()) { 4543 return false; 4544 } 4545 } 4546 4547 return true; 4548 } 4549 isInitialized(Object message, int typeAndOffset, Schema schema)4550 private static boolean isInitialized(Object message, int typeAndOffset, Schema schema) { 4551 Object nested = UnsafeUtil.getObject(message, offset(typeAndOffset)); 4552 return schema.isInitialized(nested); 4553 } 4554 isListInitialized(Object message, int typeAndOffset, int pos)4555 private <N> boolean isListInitialized(Object message, int typeAndOffset, int pos) { 4556 @SuppressWarnings("unchecked") 4557 List<N> list = (List<N>) UnsafeUtil.getObject(message, offset(typeAndOffset)); 4558 if (list.isEmpty()) { 4559 return true; 4560 } 4561 4562 Schema schema = getMessageFieldSchema(pos); 4563 for (int i = 0; i < list.size(); i++) { 4564 N nested = list.get(i); 4565 if (!schema.isInitialized(nested)) { 4566 return false; 4567 } 4568 } 4569 return true; 4570 } 4571 isMapInitialized(T message, int typeAndOffset, int pos)4572 private boolean isMapInitialized(T message, int typeAndOffset, int pos) { 4573 Map<?, ?> map = mapFieldSchema.forMapData(UnsafeUtil.getObject(message, offset(typeAndOffset))); 4574 if (map.isEmpty()) { 4575 return true; 4576 } 4577 Object mapDefaultEntry = getMapFieldDefaultEntry(pos); 4578 MapEntryLite.Metadata<?, ?> metadata = mapFieldSchema.forMapMetadata(mapDefaultEntry); 4579 if (metadata.valueType.getJavaType() != WireFormat.JavaType.MESSAGE) { 4580 return true; 4581 } 4582 // TODO: Use schema cache. 4583 Schema schema = null; 4584 for (Object nested : map.values()) { 4585 if (schema == null) { 4586 schema = Protobuf.getInstance().schemaFor(nested.getClass()); 4587 } 4588 if (!schema.isInitialized(nested)) { 4589 return false; 4590 } 4591 } 4592 return true; 4593 } 4594 writeString(int fieldNumber, Object value, Writer writer)4595 private void writeString(int fieldNumber, Object value, Writer writer) throws IOException { 4596 if (value instanceof String) { 4597 writer.writeString(fieldNumber, (String) value); 4598 } else { 4599 writer.writeBytes(fieldNumber, (ByteString) value); 4600 } 4601 } 4602 readString(Object message, int typeAndOffset, Reader reader)4603 private void readString(Object message, int typeAndOffset, Reader reader) throws IOException { 4604 if (isEnforceUtf8(typeAndOffset)) { 4605 // Enforce valid UTF-8 on the read. 4606 UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readStringRequireUtf8()); 4607 } else if (lite) { 4608 // Lite messages use String fields to store strings. Read a string but do not 4609 // enforce UTF-8 4610 UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readString()); 4611 } else { 4612 // Full runtime messages use Objects to store either a String or ByteString. Read 4613 // the string as a ByteString and do not enforce UTF-8. 4614 UnsafeUtil.putObject(message, offset(typeAndOffset), reader.readBytes()); 4615 } 4616 } 4617 readStringList(Object message, int typeAndOffset, Reader reader)4618 private void readStringList(Object message, int typeAndOffset, Reader reader) throws IOException { 4619 if (isEnforceUtf8(typeAndOffset)) { 4620 reader.readStringListRequireUtf8( 4621 listFieldSchema.<String>mutableListAt(message, offset(typeAndOffset))); 4622 } else { 4623 reader.readStringList(listFieldSchema.<String>mutableListAt(message, offset(typeAndOffset))); 4624 } 4625 } 4626 readMessageList( Object message, int typeAndOffset, Reader reader, Schema<E> schema, ExtensionRegistryLite extensionRegistry)4627 private <E> void readMessageList( 4628 Object message, 4629 int typeAndOffset, 4630 Reader reader, 4631 Schema<E> schema, 4632 ExtensionRegistryLite extensionRegistry) 4633 throws IOException { 4634 long offset = offset(typeAndOffset); 4635 reader.readMessageList( 4636 listFieldSchema.<E>mutableListAt(message, offset), schema, extensionRegistry); 4637 } 4638 readGroupList( Object message, long offset, Reader reader, Schema<E> schema, ExtensionRegistryLite extensionRegistry)4639 private <E> void readGroupList( 4640 Object message, 4641 long offset, 4642 Reader reader, 4643 Schema<E> schema, 4644 ExtensionRegistryLite extensionRegistry) 4645 throws IOException { 4646 reader.readGroupList( 4647 listFieldSchema.<E>mutableListAt(message, offset), schema, extensionRegistry); 4648 } 4649 numberAt(int pos)4650 private int numberAt(int pos) { 4651 return buffer[pos]; 4652 } 4653 typeAndOffsetAt(int pos)4654 private int typeAndOffsetAt(int pos) { 4655 return buffer[pos + 1]; 4656 } 4657 presenceMaskAndOffsetAt(int pos)4658 private int presenceMaskAndOffsetAt(int pos) { 4659 return buffer[pos + 2]; 4660 } 4661 type(int value)4662 private static int type(int value) { 4663 return (value & FIELD_TYPE_MASK) >>> OFFSET_BITS; 4664 } 4665 isRequired(int value)4666 private static boolean isRequired(int value) { 4667 return (value & REQUIRED_MASK) != 0; 4668 } 4669 isEnforceUtf8(int value)4670 private static boolean isEnforceUtf8(int value) { 4671 return (value & ENFORCE_UTF8_MASK) != 0; 4672 } 4673 isLegacyEnumIsClosed(int value)4674 private static boolean isLegacyEnumIsClosed(int value) { 4675 return (value & LEGACY_ENUM_IS_CLOSED_MASK) != 0; 4676 } 4677 offset(int value)4678 private static long offset(int value) { 4679 return value & OFFSET_MASK; 4680 } 4681 isMutable(Object message)4682 private static boolean isMutable(Object message) { 4683 if (message == null) { 4684 return false; 4685 } 4686 4687 // TODO decide if we're keeping support for Full in schema classes and handle this 4688 // better. 4689 if (message instanceof GeneratedMessageLite<?, ?>) { 4690 return ((GeneratedMessageLite<?, ?>) message).isMutable(); 4691 } 4692 4693 // For other types, we'll assume this is true because that's what was 4694 // happening before we started checking. 4695 return true; 4696 } 4697 checkMutable(Object message)4698 private static void checkMutable(Object message) { 4699 if (!isMutable(message)) { 4700 throw new IllegalArgumentException("Mutating immutable message: " + message); 4701 } 4702 } 4703 doubleAt(T message, long offset)4704 private static <T> double doubleAt(T message, long offset) { 4705 return UnsafeUtil.getDouble(message, offset); 4706 } 4707 floatAt(T message, long offset)4708 private static <T> float floatAt(T message, long offset) { 4709 return UnsafeUtil.getFloat(message, offset); 4710 } 4711 intAt(T message, long offset)4712 private static <T> int intAt(T message, long offset) { 4713 return UnsafeUtil.getInt(message, offset); 4714 } 4715 longAt(T message, long offset)4716 private static <T> long longAt(T message, long offset) { 4717 return UnsafeUtil.getLong(message, offset); 4718 } 4719 booleanAt(T message, long offset)4720 private static <T> boolean booleanAt(T message, long offset) { 4721 return UnsafeUtil.getBoolean(message, offset); 4722 } 4723 oneofDoubleAt(T message, long offset)4724 private static <T> double oneofDoubleAt(T message, long offset) { 4725 return ((Double) UnsafeUtil.getObject(message, offset)).doubleValue(); 4726 } 4727 oneofFloatAt(T message, long offset)4728 private static <T> float oneofFloatAt(T message, long offset) { 4729 return ((Float) UnsafeUtil.getObject(message, offset)).floatValue(); 4730 } 4731 oneofIntAt(T message, long offset)4732 private static <T> int oneofIntAt(T message, long offset) { 4733 return ((Integer) UnsafeUtil.getObject(message, offset)).intValue(); 4734 } 4735 oneofLongAt(T message, long offset)4736 private static <T> long oneofLongAt(T message, long offset) { 4737 return ((Long) UnsafeUtil.getObject(message, offset)).longValue(); 4738 } 4739 oneofBooleanAt(T message, long offset)4740 private static <T> boolean oneofBooleanAt(T message, long offset) { 4741 return ((Boolean) UnsafeUtil.getObject(message, offset)).booleanValue(); 4742 } 4743 4744 /** Returns true the field is present in both messages, or neither. */ arePresentForEquals(T message, T other, int pos)4745 private boolean arePresentForEquals(T message, T other, int pos) { 4746 return isFieldPresent(message, pos) == isFieldPresent(other, pos); 4747 } 4748 isFieldPresent( T message, int pos, int presenceFieldOffset, int presenceField, int presenceMask)4749 private boolean isFieldPresent( 4750 T message, int pos, int presenceFieldOffset, int presenceField, int presenceMask) { 4751 if (presenceFieldOffset == NO_PRESENCE_SENTINEL) { 4752 return isFieldPresent(message, pos); 4753 } else { 4754 return (presenceField & presenceMask) != 0; 4755 } 4756 } 4757 isFieldPresent(T message, int pos)4758 private boolean isFieldPresent(T message, int pos) { 4759 final int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); 4760 final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; 4761 if (presenceFieldOffset == NO_PRESENCE_SENTINEL) { 4762 final int typeAndOffset = typeAndOffsetAt(pos); 4763 final long offset = offset(typeAndOffset); 4764 switch (type(typeAndOffset)) { 4765 case 0: // DOUBLE: 4766 return Double.doubleToRawLongBits(UnsafeUtil.getDouble(message, offset)) != 0L; 4767 case 1: // FLOAT: 4768 return Float.floatToRawIntBits(UnsafeUtil.getFloat(message, offset)) != 0; 4769 case 2: // INT64: 4770 return UnsafeUtil.getLong(message, offset) != 0L; 4771 case 3: // UINT64: 4772 return UnsafeUtil.getLong(message, offset) != 0L; 4773 case 4: // INT32: 4774 return UnsafeUtil.getInt(message, offset) != 0; 4775 case 5: // FIXED64: 4776 return UnsafeUtil.getLong(message, offset) != 0L; 4777 case 6: // FIXED32: 4778 return UnsafeUtil.getInt(message, offset) != 0; 4779 case 7: // BOOL: 4780 return UnsafeUtil.getBoolean(message, offset); 4781 case 8: // STRING: 4782 Object value = UnsafeUtil.getObject(message, offset); 4783 if (value instanceof String) { 4784 return !((String) value).isEmpty(); 4785 } else if (value instanceof ByteString) { 4786 return !ByteString.EMPTY.equals(value); 4787 } else { 4788 throw new IllegalArgumentException(); 4789 } 4790 case 9: // MESSAGE: 4791 return UnsafeUtil.getObject(message, offset) != null; 4792 case 10: // BYTES: 4793 return !ByteString.EMPTY.equals(UnsafeUtil.getObject(message, offset)); 4794 case 11: // UINT32: 4795 return UnsafeUtil.getInt(message, offset) != 0; 4796 case 12: // ENUM: 4797 return UnsafeUtil.getInt(message, offset) != 0; 4798 case 13: // SFIXED32: 4799 return UnsafeUtil.getInt(message, offset) != 0; 4800 case 14: // SFIXED64: 4801 return UnsafeUtil.getLong(message, offset) != 0L; 4802 case 15: // SINT32: 4803 return UnsafeUtil.getInt(message, offset) != 0; 4804 case 16: // SINT64: 4805 return UnsafeUtil.getLong(message, offset) != 0L; 4806 case 17: // GROUP: 4807 return UnsafeUtil.getObject(message, offset) != null; 4808 default: 4809 throw new IllegalArgumentException(); 4810 } 4811 } else { 4812 final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); 4813 return (UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) & presenceMask) != 0; 4814 } 4815 } 4816 setFieldPresent(T message, int pos)4817 private void setFieldPresent(T message, int pos) { 4818 int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); 4819 final long presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; 4820 if (presenceFieldOffset == NO_PRESENCE_SENTINEL) { 4821 return; 4822 } 4823 final int presenceMask = 1 << (presenceMaskAndOffset >>> OFFSET_BITS); 4824 UnsafeUtil.putInt( 4825 message, 4826 presenceFieldOffset, 4827 UnsafeUtil.getInt(message, presenceFieldOffset) | presenceMask); 4828 } 4829 isOneofPresent(T message, int fieldNumber, int pos)4830 private boolean isOneofPresent(T message, int fieldNumber, int pos) { 4831 int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); 4832 return UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) == fieldNumber; 4833 } 4834 isOneofCaseEqual(T message, T other, int pos)4835 private boolean isOneofCaseEqual(T message, T other, int pos) { 4836 int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); 4837 return UnsafeUtil.getInt(message, presenceMaskAndOffset & OFFSET_MASK) 4838 == UnsafeUtil.getInt(other, presenceMaskAndOffset & OFFSET_MASK); 4839 } 4840 setOneofPresent(T message, int fieldNumber, int pos)4841 private void setOneofPresent(T message, int fieldNumber, int pos) { 4842 int presenceMaskAndOffset = presenceMaskAndOffsetAt(pos); 4843 UnsafeUtil.putInt(message, presenceMaskAndOffset & OFFSET_MASK, fieldNumber); 4844 } 4845 positionForFieldNumber(final int number)4846 private int positionForFieldNumber(final int number) { 4847 if (number >= minFieldNumber && number <= maxFieldNumber) { 4848 return slowPositionForFieldNumber(number, 0); 4849 } 4850 return -1; 4851 } 4852 positionForFieldNumber(final int number, final int min)4853 private int positionForFieldNumber(final int number, final int min) { 4854 if (number >= minFieldNumber && number <= maxFieldNumber) { 4855 return slowPositionForFieldNumber(number, min); 4856 } 4857 return -1; 4858 } 4859 slowPositionForFieldNumber(final int number, int min)4860 private int slowPositionForFieldNumber(final int number, int min) { 4861 int max = buffer.length / INTS_PER_FIELD - 1; 4862 while (min <= max) { 4863 // Find the midpoint address. 4864 final int mid = (max + min) >>> 1; 4865 final int pos = mid * INTS_PER_FIELD; 4866 final int midFieldNumber = numberAt(pos); 4867 if (number == midFieldNumber) { 4868 // Found the field. 4869 return pos; 4870 } 4871 if (number < midFieldNumber) { 4872 // Search the lower half. 4873 max = mid - 1; 4874 } else { 4875 // Search the upper half. 4876 min = mid + 1; 4877 } 4878 } 4879 return -1; 4880 } 4881 getSchemaSize()4882 int getSchemaSize() { 4883 return buffer.length * 3; 4884 } 4885 } 4886