1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 package com.google.protobuf; 32 33 import static com.google.protobuf.MessageSchema.getMutableUnknownFields; 34 35 import com.google.protobuf.Internal.ProtobufList; 36 import java.io.IOException; 37 38 /** 39 * Helper functions to decode protobuf wire format from a byte array. 40 * 41 * <p>Note that these functions don't do boundary check on the byte array but instead rely on Java 42 * VM to check it. That means parsing rountines utilizing these functions must catch 43 * IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when 44 * crossing protobuf public API boundaries. 45 */ 46 final class ArrayDecoders { 47 /** 48 * A helper used to return multiple values in a Java function. Java doesn't natively support 49 * returning multiple values in a function. Creating a new Object to hold the return values will 50 * be too expensive. Instead, we pass a Registers instance to functions that want to return 51 * multiple values and let the function set the return value in this Registers instance instead. 52 * 53 * <p>TODO(xiaofeng): This could be merged into CodedInputStream or CodedInputStreamReader which 54 * is already being passed through all the parsing rountines. 55 */ 56 static final class Registers { 57 public int int1; 58 public long long1; 59 public Object object1; 60 public final ExtensionRegistryLite extensionRegistry; 61 Registers()62 Registers() { 63 this.extensionRegistry = ExtensionRegistryLite.getEmptyRegistry(); 64 } 65 Registers(ExtensionRegistryLite extensionRegistry)66 Registers(ExtensionRegistryLite extensionRegistry) { 67 if (extensionRegistry == null) { 68 throw new NullPointerException(); 69 } 70 this.extensionRegistry = extensionRegistry; 71 } 72 } 73 74 /** 75 * Decodes a varint. Returns the position after the varint. The decoded varint is stored in 76 * registers.int1. 77 */ decodeVarint32(byte[] data, int position, Registers registers)78 static int decodeVarint32(byte[] data, int position, Registers registers) { 79 int value = data[position++]; 80 if (value >= 0) { 81 registers.int1 = value; 82 return position; 83 } 84 return decodeVarint32(value, data, position, registers); 85 } 86 87 /** Like decodeVarint32 except that the first byte is already read. */ decodeVarint32(int firstByte, byte[] data, int position, Registers registers)88 static int decodeVarint32(int firstByte, byte[] data, int position, Registers registers) { 89 int value = firstByte & 0x7F; 90 final byte b2 = data[position++]; 91 if (b2 >= 0) { 92 registers.int1 = value | ((int) b2 << 7); 93 return position; 94 } 95 value |= (b2 & 0x7F) << 7; 96 97 final byte b3 = data[position++]; 98 if (b3 >= 0) { 99 registers.int1 = value | ((int) b3 << 14); 100 return position; 101 } 102 value |= (b3 & 0x7F) << 14; 103 104 final byte b4 = data[position++]; 105 if (b4 >= 0) { 106 registers.int1 = value | ((int) b4 << 21); 107 return position; 108 } 109 value |= (b4 & 0x7F) << 21; 110 111 final byte b5 = data[position++]; 112 if (b5 >= 0) { 113 registers.int1 = value | ((int) b5 << 28); 114 return position; 115 } 116 value |= (b5 & 0x7F) << 28; 117 118 while (data[position++] < 0) {} 119 120 registers.int1 = value; 121 return position; 122 } 123 124 /** 125 * Decodes a varint. Returns the position after the varint. The decoded varint is stored in 126 * registers.long1. 127 */ decodeVarint64(byte[] data, int position, Registers registers)128 static int decodeVarint64(byte[] data, int position, Registers registers) { 129 long value = data[position++]; 130 if (value >= 0) { 131 registers.long1 = value; 132 return position; 133 } else { 134 return decodeVarint64(value, data, position, registers); 135 } 136 } 137 138 /** Like decodeVarint64 except that the first byte is already read. */ decodeVarint64(long firstByte, byte[] data, int position, Registers registers)139 static int decodeVarint64(long firstByte, byte[] data, int position, Registers registers) { 140 long value = firstByte & 0x7F; 141 byte next = data[position++]; 142 int shift = 7; 143 value |= (long) (next & 0x7F) << 7; 144 while (next < 0) { 145 next = data[position++]; 146 shift += 7; 147 value |= (long) (next & 0x7F) << shift; 148 } 149 registers.long1 = value; 150 return position; 151 } 152 153 /** Decodes and returns a fixed32 value. */ decodeFixed32(byte[] data, int position)154 static int decodeFixed32(byte[] data, int position) { 155 return (data[position] & 0xff) 156 | ((data[position + 1] & 0xff) << 8) 157 | ((data[position + 2] & 0xff) << 16) 158 | ((data[position + 3] & 0xff) << 24); 159 } 160 161 /** Decodes and returns a fixed64 value. */ decodeFixed64(byte[] data, int position)162 static long decodeFixed64(byte[] data, int position) { 163 return (data[position] & 0xffL) 164 | ((data[position + 1] & 0xffL) << 8) 165 | ((data[position + 2] & 0xffL) << 16) 166 | ((data[position + 3] & 0xffL) << 24) 167 | ((data[position + 4] & 0xffL) << 32) 168 | ((data[position + 5] & 0xffL) << 40) 169 | ((data[position + 6] & 0xffL) << 48) 170 | ((data[position + 7] & 0xffL) << 56); 171 } 172 173 /** Decodes and returns a double value. */ decodeDouble(byte[] data, int position)174 static double decodeDouble(byte[] data, int position) { 175 return Double.longBitsToDouble(decodeFixed64(data, position)); 176 } 177 178 /** Decodes and returns a float value. */ decodeFloat(byte[] data, int position)179 static float decodeFloat(byte[] data, int position) { 180 return Float.intBitsToFloat(decodeFixed32(data, position)); 181 } 182 183 /** Decodes a string value. */ decodeString(byte[] data, int position, Registers registers)184 static int decodeString(byte[] data, int position, Registers registers) 185 throws InvalidProtocolBufferException { 186 position = decodeVarint32(data, position, registers); 187 final int length = registers.int1; 188 if (length < 0) { 189 throw InvalidProtocolBufferException.negativeSize(); 190 } else if (length == 0) { 191 registers.object1 = ""; 192 return position; 193 } else { 194 registers.object1 = new String(data, position, length, Internal.UTF_8); 195 return position + length; 196 } 197 } 198 199 /** Decodes a string value with utf8 check. */ decodeStringRequireUtf8(byte[] data, int position, Registers registers)200 static int decodeStringRequireUtf8(byte[] data, int position, Registers registers) 201 throws InvalidProtocolBufferException { 202 position = decodeVarint32(data, position, registers); 203 final int length = registers.int1; 204 if (length < 0) { 205 throw InvalidProtocolBufferException.negativeSize(); 206 } else if (length == 0) { 207 registers.object1 = ""; 208 return position; 209 } else { 210 registers.object1 = Utf8.decodeUtf8(data, position, length); 211 return position + length; 212 } 213 } 214 215 /** Decodes a bytes value. */ decodeBytes(byte[] data, int position, Registers registers)216 static int decodeBytes(byte[] data, int position, Registers registers) 217 throws InvalidProtocolBufferException { 218 position = decodeVarint32(data, position, registers); 219 final int length = registers.int1; 220 if (length < 0) { 221 throw InvalidProtocolBufferException.negativeSize(); 222 } else if (length > data.length - position) { 223 throw InvalidProtocolBufferException.truncatedMessage(); 224 } else if (length == 0) { 225 registers.object1 = ByteString.EMPTY; 226 return position; 227 } else { 228 registers.object1 = ByteString.copyFrom(data, position, length); 229 return position + length; 230 } 231 } 232 233 /** Decodes a message value. */ 234 @SuppressWarnings({"unchecked", "rawtypes"}) decodeMessageField( Schema schema, byte[] data, int position, int limit, Registers registers)235 static int decodeMessageField( 236 Schema schema, byte[] data, int position, int limit, Registers registers) throws IOException { 237 int length = data[position++]; 238 if (length < 0) { 239 position = decodeVarint32(length, data, position, registers); 240 length = registers.int1; 241 } 242 if (length < 0 || length > limit - position) { 243 throw InvalidProtocolBufferException.truncatedMessage(); 244 } 245 Object result = schema.newInstance(); 246 schema.mergeFrom(result, data, position, position + length, registers); 247 schema.makeImmutable(result); 248 registers.object1 = result; 249 return position + length; 250 } 251 252 /** Decodes a group value. */ 253 @SuppressWarnings({"unchecked", "rawtypes"}) decodeGroupField( Schema schema, byte[] data, int position, int limit, int endGroup, Registers registers)254 static int decodeGroupField( 255 Schema schema, byte[] data, int position, int limit, int endGroup, Registers registers) 256 throws IOException { 257 // A group field must has a MessageSchema (the only other subclass of Schema is MessageSetSchema 258 // and it can't be used in group fields). 259 final MessageSchema messageSchema = (MessageSchema) schema; 260 Object result = messageSchema.newInstance(); 261 // It's OK to directly use parseProto2Message since proto3 doesn't have group. 262 final int endPosition = 263 messageSchema.parseProto2Message(result, data, position, limit, endGroup, registers); 264 messageSchema.makeImmutable(result); 265 registers.object1 = result; 266 return endPosition; 267 } 268 269 /** Decodes a repeated 32-bit varint field. Returns the position after all read values. */ decodeVarint32List( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)270 static int decodeVarint32List( 271 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 272 final IntArrayList output = (IntArrayList) list; 273 position = decodeVarint32(data, position, registers); 274 output.addInt(registers.int1); 275 while (position < limit) { 276 int nextPosition = decodeVarint32(data, position, registers); 277 if (tag != registers.int1) { 278 break; 279 } 280 position = decodeVarint32(data, nextPosition, registers); 281 output.addInt(registers.int1); 282 } 283 return position; 284 } 285 286 /** Decodes a repeated 64-bit varint field. Returns the position after all read values. */ decodeVarint64List( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)287 static int decodeVarint64List( 288 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 289 final LongArrayList output = (LongArrayList) list; 290 position = decodeVarint64(data, position, registers); 291 output.addLong(registers.long1); 292 while (position < limit) { 293 int nextPosition = decodeVarint32(data, position, registers); 294 if (tag != registers.int1) { 295 break; 296 } 297 position = decodeVarint64(data, nextPosition, registers); 298 output.addLong(registers.long1); 299 } 300 return position; 301 } 302 303 /** Decodes a repeated fixed32 field. Returns the position after all read values. */ decodeFixed32List( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)304 static int decodeFixed32List( 305 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 306 final IntArrayList output = (IntArrayList) list; 307 output.addInt(decodeFixed32(data, position)); 308 position += 4; 309 while (position < limit) { 310 int nextPosition = decodeVarint32(data, position, registers); 311 if (tag != registers.int1) { 312 break; 313 } 314 output.addInt(decodeFixed32(data, nextPosition)); 315 position = nextPosition + 4; 316 } 317 return position; 318 } 319 320 /** Decodes a repeated fixed64 field. Returns the position after all read values. */ decodeFixed64List( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)321 static int decodeFixed64List( 322 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 323 final LongArrayList output = (LongArrayList) list; 324 output.addLong(decodeFixed64(data, position)); 325 position += 8; 326 while (position < limit) { 327 int nextPosition = decodeVarint32(data, position, registers); 328 if (tag != registers.int1) { 329 break; 330 } 331 output.addLong(decodeFixed64(data, nextPosition)); 332 position = nextPosition + 8; 333 } 334 return position; 335 } 336 337 /** Decodes a repeated float field. Returns the position after all read values. */ decodeFloatList( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)338 static int decodeFloatList( 339 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 340 final FloatArrayList output = (FloatArrayList) list; 341 output.addFloat(decodeFloat(data, position)); 342 position += 4; 343 while (position < limit) { 344 int nextPosition = decodeVarint32(data, position, registers); 345 if (tag != registers.int1) { 346 break; 347 } 348 output.addFloat(decodeFloat(data, nextPosition)); 349 position = nextPosition + 4; 350 } 351 return position; 352 } 353 354 /** Decodes a repeated double field. Returns the position after all read values. */ decodeDoubleList( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)355 static int decodeDoubleList( 356 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 357 final DoubleArrayList output = (DoubleArrayList) list; 358 output.addDouble(decodeDouble(data, position)); 359 position += 8; 360 while (position < limit) { 361 int nextPosition = decodeVarint32(data, position, registers); 362 if (tag != registers.int1) { 363 break; 364 } 365 output.addDouble(decodeDouble(data, nextPosition)); 366 position = nextPosition + 8; 367 } 368 return position; 369 } 370 371 /** Decodes a repeated boolean field. Returns the position after all read values. */ decodeBoolList( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)372 static int decodeBoolList( 373 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 374 final BooleanArrayList output = (BooleanArrayList) list; 375 position = decodeVarint64(data, position, registers); 376 output.addBoolean(registers.long1 != 0); 377 while (position < limit) { 378 int nextPosition = decodeVarint32(data, position, registers); 379 if (tag != registers.int1) { 380 break; 381 } 382 position = decodeVarint64(data, nextPosition, registers); 383 output.addBoolean(registers.long1 != 0); 384 } 385 return position; 386 } 387 388 /** Decodes a repeated sint32 field. Returns the position after all read values. */ decodeSInt32List( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)389 static int decodeSInt32List( 390 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 391 final IntArrayList output = (IntArrayList) list; 392 position = decodeVarint32(data, position, registers); 393 output.addInt(CodedInputStream.decodeZigZag32(registers.int1)); 394 while (position < limit) { 395 int nextPosition = decodeVarint32(data, position, registers); 396 if (tag != registers.int1) { 397 break; 398 } 399 position = decodeVarint32(data, nextPosition, registers); 400 output.addInt(CodedInputStream.decodeZigZag32(registers.int1)); 401 } 402 return position; 403 } 404 405 /** Decodes a repeated sint64 field. Returns the position after all read values. */ decodeSInt64List( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)406 static int decodeSInt64List( 407 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) { 408 final LongArrayList output = (LongArrayList) list; 409 position = decodeVarint64(data, position, registers); 410 output.addLong(CodedInputStream.decodeZigZag64(registers.long1)); 411 while (position < limit) { 412 int nextPosition = decodeVarint32(data, position, registers); 413 if (tag != registers.int1) { 414 break; 415 } 416 position = decodeVarint64(data, nextPosition, registers); 417 output.addLong(CodedInputStream.decodeZigZag64(registers.long1)); 418 } 419 return position; 420 } 421 422 /** Decodes a packed 32-bit varint field. Returns the position after all read values. */ decodePackedVarint32List( byte[] data, int position, ProtobufList<?> list, Registers registers)423 static int decodePackedVarint32List( 424 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 425 final IntArrayList output = (IntArrayList) list; 426 position = decodeVarint32(data, position, registers); 427 final int fieldLimit = position + registers.int1; 428 while (position < fieldLimit) { 429 position = decodeVarint32(data, position, registers); 430 output.addInt(registers.int1); 431 } 432 if (position != fieldLimit) { 433 throw InvalidProtocolBufferException.truncatedMessage(); 434 } 435 return position; 436 } 437 438 /** Decodes a packed 64-bit varint field. Returns the position after all read values. */ decodePackedVarint64List( byte[] data, int position, ProtobufList<?> list, Registers registers)439 static int decodePackedVarint64List( 440 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 441 final LongArrayList output = (LongArrayList) list; 442 position = decodeVarint32(data, position, registers); 443 final int fieldLimit = position + registers.int1; 444 while (position < fieldLimit) { 445 position = decodeVarint64(data, position, registers); 446 output.addLong(registers.long1); 447 } 448 if (position != fieldLimit) { 449 throw InvalidProtocolBufferException.truncatedMessage(); 450 } 451 return position; 452 } 453 454 /** Decodes a packed fixed32 field. Returns the position after all read values. */ decodePackedFixed32List( byte[] data, int position, ProtobufList<?> list, Registers registers)455 static int decodePackedFixed32List( 456 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 457 final IntArrayList output = (IntArrayList) list; 458 position = decodeVarint32(data, position, registers); 459 final int fieldLimit = position + registers.int1; 460 while (position < fieldLimit) { 461 output.addInt(decodeFixed32(data, position)); 462 position += 4; 463 } 464 if (position != fieldLimit) { 465 throw InvalidProtocolBufferException.truncatedMessage(); 466 } 467 return position; 468 } 469 470 /** Decodes a packed fixed64 field. Returns the position after all read values. */ decodePackedFixed64List( byte[] data, int position, ProtobufList<?> list, Registers registers)471 static int decodePackedFixed64List( 472 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 473 final LongArrayList output = (LongArrayList) list; 474 position = decodeVarint32(data, position, registers); 475 final int fieldLimit = position + registers.int1; 476 while (position < fieldLimit) { 477 output.addLong(decodeFixed64(data, position)); 478 position += 8; 479 } 480 if (position != fieldLimit) { 481 throw InvalidProtocolBufferException.truncatedMessage(); 482 } 483 return position; 484 } 485 486 /** Decodes a packed float field. Returns the position after all read values. */ decodePackedFloatList( byte[] data, int position, ProtobufList<?> list, Registers registers)487 static int decodePackedFloatList( 488 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 489 final FloatArrayList output = (FloatArrayList) list; 490 position = decodeVarint32(data, position, registers); 491 final int fieldLimit = position + registers.int1; 492 while (position < fieldLimit) { 493 output.addFloat(decodeFloat(data, position)); 494 position += 4; 495 } 496 if (position != fieldLimit) { 497 throw InvalidProtocolBufferException.truncatedMessage(); 498 } 499 return position; 500 } 501 502 /** Decodes a packed double field. Returns the position after all read values. */ decodePackedDoubleList( byte[] data, int position, ProtobufList<?> list, Registers registers)503 static int decodePackedDoubleList( 504 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 505 final DoubleArrayList output = (DoubleArrayList) list; 506 position = decodeVarint32(data, position, registers); 507 final int fieldLimit = position + registers.int1; 508 while (position < fieldLimit) { 509 output.addDouble(decodeDouble(data, position)); 510 position += 8; 511 } 512 if (position != fieldLimit) { 513 throw InvalidProtocolBufferException.truncatedMessage(); 514 } 515 return position; 516 } 517 518 /** Decodes a packed boolean field. Returns the position after all read values. */ decodePackedBoolList( byte[] data, int position, ProtobufList<?> list, Registers registers)519 static int decodePackedBoolList( 520 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 521 final BooleanArrayList output = (BooleanArrayList) list; 522 position = decodeVarint32(data, position, registers); 523 final int fieldLimit = position + registers.int1; 524 while (position < fieldLimit) { 525 position = decodeVarint64(data, position, registers); 526 output.addBoolean(registers.long1 != 0); 527 } 528 if (position != fieldLimit) { 529 throw InvalidProtocolBufferException.truncatedMessage(); 530 } 531 return position; 532 } 533 534 /** Decodes a packed sint32 field. Returns the position after all read values. */ decodePackedSInt32List( byte[] data, int position, ProtobufList<?> list, Registers registers)535 static int decodePackedSInt32List( 536 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 537 final IntArrayList output = (IntArrayList) list; 538 position = decodeVarint32(data, position, registers); 539 final int fieldLimit = position + registers.int1; 540 while (position < fieldLimit) { 541 position = decodeVarint32(data, position, registers); 542 output.addInt(CodedInputStream.decodeZigZag32(registers.int1)); 543 } 544 if (position != fieldLimit) { 545 throw InvalidProtocolBufferException.truncatedMessage(); 546 } 547 return position; 548 } 549 550 /** Decodes a packed sint64 field. Returns the position after all read values. */ 551 @SuppressWarnings("unchecked") decodePackedSInt64List( byte[] data, int position, ProtobufList<?> list, Registers registers)552 static int decodePackedSInt64List( 553 byte[] data, int position, ProtobufList<?> list, Registers registers) throws IOException { 554 final LongArrayList output = (LongArrayList) list; 555 position = decodeVarint32(data, position, registers); 556 final int fieldLimit = position + registers.int1; 557 while (position < fieldLimit) { 558 position = decodeVarint64(data, position, registers); 559 output.addLong(CodedInputStream.decodeZigZag64(registers.long1)); 560 } 561 if (position != fieldLimit) { 562 throw InvalidProtocolBufferException.truncatedMessage(); 563 } 564 return position; 565 } 566 567 /** Decodes a repeated string field. Returns the position after all read values. */ 568 @SuppressWarnings("unchecked") decodeStringList( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)569 static int decodeStringList( 570 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) 571 throws InvalidProtocolBufferException { 572 final ProtobufList<String> output = (ProtobufList<String>) list; 573 position = decodeVarint32(data, position, registers); 574 final int length = registers.int1; 575 if (length < 0) { 576 throw InvalidProtocolBufferException.negativeSize(); 577 } else if (length == 0) { 578 output.add(""); 579 } else { 580 String value = new String(data, position, length, Internal.UTF_8); 581 output.add(value); 582 position += length; 583 } 584 while (position < limit) { 585 int nextPosition = decodeVarint32(data, position, registers); 586 if (tag != registers.int1) { 587 break; 588 } 589 position = decodeVarint32(data, nextPosition, registers); 590 final int nextLength = registers.int1; 591 if (nextLength < 0) { 592 throw InvalidProtocolBufferException.negativeSize(); 593 } else if (nextLength == 0) { 594 output.add(""); 595 } else { 596 String value = new String(data, position, nextLength, Internal.UTF_8); 597 output.add(value); 598 position += nextLength; 599 } 600 } 601 return position; 602 } 603 604 /** 605 * Decodes a repeated string field with utf8 check. Returns the position after all read values. 606 */ 607 @SuppressWarnings("unchecked") decodeStringListRequireUtf8( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)608 static int decodeStringListRequireUtf8( 609 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) 610 throws InvalidProtocolBufferException { 611 final ProtobufList<String> output = (ProtobufList<String>) list; 612 position = decodeVarint32(data, position, registers); 613 final int length = registers.int1; 614 if (length < 0) { 615 throw InvalidProtocolBufferException.negativeSize(); 616 } else if (length == 0) { 617 output.add(""); 618 } else { 619 if (!Utf8.isValidUtf8(data, position, position + length)) { 620 throw InvalidProtocolBufferException.invalidUtf8(); 621 } 622 String value = new String(data, position, length, Internal.UTF_8); 623 output.add(value); 624 position += length; 625 } 626 while (position < limit) { 627 int nextPosition = decodeVarint32(data, position, registers); 628 if (tag != registers.int1) { 629 break; 630 } 631 position = decodeVarint32(data, nextPosition, registers); 632 final int nextLength = registers.int1; 633 if (nextLength < 0) { 634 throw InvalidProtocolBufferException.negativeSize(); 635 } else if (nextLength == 0) { 636 output.add(""); 637 } else { 638 if (!Utf8.isValidUtf8(data, position, position + nextLength)) { 639 throw InvalidProtocolBufferException.invalidUtf8(); 640 } 641 String value = new String(data, position, nextLength, Internal.UTF_8); 642 output.add(value); 643 position += nextLength; 644 } 645 } 646 return position; 647 } 648 649 /** Decodes a repeated bytes field. Returns the position after all read values. */ 650 @SuppressWarnings("unchecked") decodeBytesList( int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)651 static int decodeBytesList( 652 int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers) 653 throws InvalidProtocolBufferException { 654 final ProtobufList<ByteString> output = (ProtobufList<ByteString>) list; 655 position = decodeVarint32(data, position, registers); 656 final int length = registers.int1; 657 if (length < 0) { 658 throw InvalidProtocolBufferException.negativeSize(); 659 } else if (length > data.length - position) { 660 throw InvalidProtocolBufferException.truncatedMessage(); 661 } else if (length == 0) { 662 output.add(ByteString.EMPTY); 663 } else { 664 output.add(ByteString.copyFrom(data, position, length)); 665 position += length; 666 } 667 while (position < limit) { 668 int nextPosition = decodeVarint32(data, position, registers); 669 if (tag != registers.int1) { 670 break; 671 } 672 position = decodeVarint32(data, nextPosition, registers); 673 final int nextLength = registers.int1; 674 if (nextLength < 0) { 675 throw InvalidProtocolBufferException.negativeSize(); 676 } else if (nextLength > data.length - position) { 677 throw InvalidProtocolBufferException.truncatedMessage(); 678 } else if (nextLength == 0) { 679 output.add(ByteString.EMPTY); 680 } else { 681 output.add(ByteString.copyFrom(data, position, nextLength)); 682 position += nextLength; 683 } 684 } 685 return position; 686 } 687 688 /** 689 * Decodes a repeated message field 690 * 691 * @return The position of after read all messages 692 */ 693 @SuppressWarnings({"unchecked"}) decodeMessageList( Schema<?> schema, int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)694 static int decodeMessageList( 695 Schema<?> schema, 696 int tag, 697 byte[] data, 698 int position, 699 int limit, 700 ProtobufList<?> list, 701 Registers registers) 702 throws IOException { 703 final ProtobufList<Object> output = (ProtobufList<Object>) list; 704 position = decodeMessageField(schema, data, position, limit, registers); 705 output.add(registers.object1); 706 while (position < limit) { 707 int nextPosition = decodeVarint32(data, position, registers); 708 if (tag != registers.int1) { 709 break; 710 } 711 position = decodeMessageField(schema, data, nextPosition, limit, registers); 712 output.add(registers.object1); 713 } 714 return position; 715 } 716 717 /** 718 * Decodes a repeated group field 719 * 720 * @return The position of after read all groups 721 */ 722 @SuppressWarnings({"unchecked", "rawtypes"}) decodeGroupList( Schema schema, int tag, byte[] data, int position, int limit, ProtobufList<?> list, Registers registers)723 static int decodeGroupList( 724 Schema schema, 725 int tag, 726 byte[] data, 727 int position, 728 int limit, 729 ProtobufList<?> list, 730 Registers registers) 731 throws IOException { 732 final ProtobufList<Object> output = (ProtobufList<Object>) list; 733 final int endgroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP; 734 position = decodeGroupField(schema, data, position, limit, endgroup, registers); 735 output.add(registers.object1); 736 while (position < limit) { 737 int nextPosition = decodeVarint32(data, position, registers); 738 if (tag != registers.int1) { 739 break; 740 } 741 position = decodeGroupField(schema, data, nextPosition, limit, endgroup, registers); 742 output.add(registers.object1); 743 } 744 return position; 745 } 746 decodeExtensionOrUnknownField( int tag, byte[] data, int position, int limit, Object message, MessageLite defaultInstance, UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> unknownFieldSchema, Registers registers)747 static int decodeExtensionOrUnknownField( 748 int tag, byte[] data, int position, int limit, 749 Object message, 750 MessageLite defaultInstance, 751 UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> unknownFieldSchema, 752 Registers registers) 753 throws IOException { 754 final int number = tag >>> 3; 755 GeneratedMessageLite.GeneratedExtension extension = 756 registers.extensionRegistry.findLiteExtensionByNumber(defaultInstance, number); 757 if (extension == null) { 758 return decodeUnknownField( 759 tag, data, position, limit, getMutableUnknownFields(message), registers); 760 } else { 761 ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable(); 762 return decodeExtension( 763 tag, data, position, limit, (GeneratedMessageLite.ExtendableMessage) message, 764 extension, unknownFieldSchema, registers); 765 } 766 } 767 decodeExtension( int tag, byte[] data, int position, int limit, GeneratedMessageLite.ExtendableMessage<?, ?> message, GeneratedMessageLite.GeneratedExtension<?, ?> extension, UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> unknownFieldSchema, Registers registers)768 static int decodeExtension( 769 int tag, 770 byte[] data, 771 int position, 772 int limit, 773 GeneratedMessageLite.ExtendableMessage<?, ?> message, 774 GeneratedMessageLite.GeneratedExtension<?, ?> extension, 775 UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> unknownFieldSchema, 776 Registers registers) 777 throws IOException { 778 final FieldSet<GeneratedMessageLite.ExtensionDescriptor> extensions = message.extensions; 779 final int fieldNumber = tag >>> 3; 780 if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) { 781 switch (extension.getLiteType()) { 782 case DOUBLE: 783 { 784 DoubleArrayList list = new DoubleArrayList(); 785 position = decodePackedDoubleList(data, position, list, registers); 786 extensions.setField(extension.descriptor, list); 787 break; 788 } 789 case FLOAT: 790 { 791 FloatArrayList list = new FloatArrayList(); 792 position = decodePackedFloatList(data, position, list, registers); 793 extensions.setField(extension.descriptor, list); 794 break; 795 } 796 case INT64: 797 case UINT64: 798 { 799 LongArrayList list = new LongArrayList(); 800 position = decodePackedVarint64List(data, position, list, registers); 801 extensions.setField(extension.descriptor, list); 802 break; 803 } 804 case INT32: 805 case UINT32: 806 { 807 IntArrayList list = new IntArrayList(); 808 position = decodePackedVarint32List(data, position, list, registers); 809 extensions.setField(extension.descriptor, list); 810 break; 811 } 812 case FIXED64: 813 case SFIXED64: 814 { 815 LongArrayList list = new LongArrayList(); 816 position = decodePackedFixed64List(data, position, list, registers); 817 extensions.setField(extension.descriptor, list); 818 break; 819 } 820 case FIXED32: 821 case SFIXED32: 822 { 823 IntArrayList list = new IntArrayList(); 824 position = decodePackedFixed32List(data, position, list, registers); 825 extensions.setField(extension.descriptor, list); 826 break; 827 } 828 case BOOL: 829 { 830 BooleanArrayList list = new BooleanArrayList(); 831 position = decodePackedBoolList(data, position, list, registers); 832 extensions.setField(extension.descriptor, list); 833 break; 834 } 835 case SINT32: 836 { 837 IntArrayList list = new IntArrayList(); 838 position = decodePackedSInt32List(data, position, list, registers); 839 extensions.setField(extension.descriptor, list); 840 break; 841 } 842 case SINT64: 843 { 844 LongArrayList list = new LongArrayList(); 845 position = decodePackedSInt64List(data, position, list, registers); 846 extensions.setField(extension.descriptor, list); 847 break; 848 } 849 case ENUM: 850 { 851 IntArrayList list = new IntArrayList(); 852 position = decodePackedVarint32List(data, position, list, registers); 853 UnknownFieldSetLite unknownFields = message.unknownFields; 854 if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) { 855 unknownFields = null; 856 } 857 unknownFields = 858 SchemaUtil.filterUnknownEnumList( 859 fieldNumber, 860 list, 861 extension.descriptor.getEnumType(), 862 unknownFields, 863 unknownFieldSchema); 864 if (unknownFields != null) { 865 message.unknownFields = unknownFields; 866 } 867 extensions.setField(extension.descriptor, list); 868 break; 869 } 870 default: 871 throw new IllegalStateException( 872 "Type cannot be packed: " + extension.descriptor.getLiteType()); 873 } 874 } else { 875 Object value = null; 876 // Enum is a special case because unknown enum values will be put into UnknownFieldSetLite. 877 if (extension.getLiteType() == WireFormat.FieldType.ENUM) { 878 position = decodeVarint32(data, position, registers); 879 Object enumValue = extension.descriptor.getEnumType().findValueByNumber(registers.int1); 880 if (enumValue == null) { 881 UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields; 882 if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) { 883 unknownFields = UnknownFieldSetLite.newInstance(); 884 ((GeneratedMessageLite) message).unknownFields = unknownFields; 885 } 886 SchemaUtil.storeUnknownEnum( 887 fieldNumber, registers.int1, unknownFields, unknownFieldSchema); 888 return position; 889 } 890 // Note, we store the integer value instead of the actual enum object in FieldSet. 891 // This is also different from full-runtime where we store EnumValueDescriptor. 892 value = registers.int1; 893 } else { 894 switch (extension.getLiteType()) { 895 case DOUBLE: 896 value = decodeDouble(data, position); 897 position += 8; 898 break; 899 case FLOAT: 900 value = decodeFloat(data, position); 901 position += 4; 902 break; 903 case INT64: 904 case UINT64: 905 position = decodeVarint64(data, position, registers); 906 value = registers.long1; 907 break; 908 case INT32: 909 case UINT32: 910 position = decodeVarint32(data, position, registers); 911 value = registers.int1; 912 break; 913 case FIXED64: 914 case SFIXED64: 915 value = decodeFixed64(data, position); 916 position += 8; 917 break; 918 case FIXED32: 919 case SFIXED32: 920 value = decodeFixed32(data, position); 921 position += 4; 922 break; 923 case BOOL: 924 position = decodeVarint64(data, position, registers); 925 value = (registers.long1 != 0); 926 break; 927 case BYTES: 928 position = decodeBytes(data, position, registers); 929 value = registers.object1; 930 break; 931 case SINT32: 932 position = decodeVarint32(data, position, registers); 933 value = CodedInputStream.decodeZigZag32(registers.int1); 934 break; 935 case SINT64: 936 position = decodeVarint64(data, position, registers); 937 value = CodedInputStream.decodeZigZag64(registers.long1); 938 break; 939 case STRING: 940 position = decodeString(data, position, registers); 941 value = registers.object1; 942 break; 943 case GROUP: 944 final int endTag = (fieldNumber << 3) | WireFormat.WIRETYPE_END_GROUP; 945 position = decodeGroupField( 946 Protobuf.getInstance().schemaFor(extension.getMessageDefaultInstance().getClass()), 947 data, position, limit, endTag, registers); 948 value = registers.object1; 949 break; 950 951 case MESSAGE: 952 position = decodeMessageField( 953 Protobuf.getInstance().schemaFor(extension.getMessageDefaultInstance().getClass()), 954 data, position, limit, registers); 955 value = registers.object1; 956 break; 957 958 case ENUM: 959 throw new IllegalStateException("Shouldn't reach here."); 960 } 961 } 962 if (extension.isRepeated()) { 963 extensions.addRepeatedField(extension.descriptor, value); 964 } else { 965 switch (extension.getLiteType()) { 966 case MESSAGE: 967 case GROUP: 968 Object oldValue = extensions.getField(extension.descriptor); 969 if (oldValue != null) { 970 value = Internal.mergeMessage(oldValue, value); 971 } 972 break; 973 default: 974 break; 975 } 976 extensions.setField(extension.descriptor, value); 977 } 978 } 979 return position; 980 } 981 982 /** Decodes an unknown field. */ decodeUnknownField( int tag, byte[] data, int position, int limit, UnknownFieldSetLite unknownFields, Registers registers)983 static int decodeUnknownField( 984 int tag, 985 byte[] data, 986 int position, 987 int limit, 988 UnknownFieldSetLite unknownFields, 989 Registers registers) 990 throws InvalidProtocolBufferException { 991 if (WireFormat.getTagFieldNumber(tag) == 0) { 992 throw InvalidProtocolBufferException.invalidTag(); 993 } 994 switch (WireFormat.getTagWireType(tag)) { 995 case WireFormat.WIRETYPE_VARINT: 996 position = decodeVarint64(data, position, registers); 997 unknownFields.storeField(tag, registers.long1); 998 return position; 999 case WireFormat.WIRETYPE_FIXED32: 1000 unknownFields.storeField(tag, decodeFixed32(data, position)); 1001 return position + 4; 1002 case WireFormat.WIRETYPE_FIXED64: 1003 unknownFields.storeField(tag, decodeFixed64(data, position)); 1004 return position + 8; 1005 case WireFormat.WIRETYPE_LENGTH_DELIMITED: 1006 position = decodeVarint32(data, position, registers); 1007 final int length = registers.int1; 1008 if (length < 0) { 1009 throw InvalidProtocolBufferException.negativeSize(); 1010 } else if (length > data.length - position) { 1011 throw InvalidProtocolBufferException.truncatedMessage(); 1012 } else if (length == 0) { 1013 unknownFields.storeField(tag, ByteString.EMPTY); 1014 } else { 1015 unknownFields.storeField(tag, ByteString.copyFrom(data, position, length)); 1016 } 1017 return position + length; 1018 case WireFormat.WIRETYPE_START_GROUP: 1019 final UnknownFieldSetLite child = UnknownFieldSetLite.newInstance(); 1020 final int endGroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP; 1021 int lastTag = 0; 1022 while (position < limit) { 1023 position = decodeVarint32(data, position, registers); 1024 lastTag = registers.int1; 1025 if (lastTag == endGroup) { 1026 break; 1027 } 1028 position = decodeUnknownField(lastTag, data, position, limit, child, registers); 1029 } 1030 if (position > limit || lastTag != endGroup) { 1031 throw InvalidProtocolBufferException.parseFailure(); 1032 } 1033 unknownFields.storeField(tag, child); 1034 return position; 1035 default: 1036 throw InvalidProtocolBufferException.invalidTag(); 1037 } 1038 } 1039 1040 /** Skips an unknown field. */ skipField(int tag, byte[] data, int position, int limit, Registers registers)1041 static int skipField(int tag, byte[] data, int position, int limit, Registers registers) 1042 throws InvalidProtocolBufferException { 1043 if (WireFormat.getTagFieldNumber(tag) == 0) { 1044 throw InvalidProtocolBufferException.invalidTag(); 1045 } 1046 switch (WireFormat.getTagWireType(tag)) { 1047 case WireFormat.WIRETYPE_VARINT: 1048 position = decodeVarint64(data, position, registers); 1049 return position; 1050 case WireFormat.WIRETYPE_FIXED32: 1051 return position + 4; 1052 case WireFormat.WIRETYPE_FIXED64: 1053 return position + 8; 1054 case WireFormat.WIRETYPE_LENGTH_DELIMITED: 1055 position = decodeVarint32(data, position, registers); 1056 return position + registers.int1; 1057 case WireFormat.WIRETYPE_START_GROUP: 1058 final int endGroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP; 1059 int lastTag = 0; 1060 while (position < limit) { 1061 position = decodeVarint32(data, position, registers); 1062 lastTag = registers.int1; 1063 if (lastTag == endGroup) { 1064 break; 1065 } 1066 position = skipField(lastTag, data, position, limit, registers); 1067 } 1068 if (position > limit || lastTag != endGroup) { 1069 throw InvalidProtocolBufferException.parseFailure(); 1070 } 1071 return position; 1072 default: 1073 throw InvalidProtocolBufferException.invalidTag(); 1074 } 1075 } 1076 } 1077