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.Internal.checkNotNull; 11 import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED; 12 13 import java.io.IOException; 14 import java.util.Arrays; 15 import java.util.List; 16 import java.util.Map; 17 18 /** An adapter between the {@link Writer} interface and {@link CodedOutputStream}. */ 19 @CheckReturnValue 20 @ExperimentalApi 21 final class CodedOutputStreamWriter implements Writer { 22 private final CodedOutputStream output; 23 forCodedOutput(CodedOutputStream output)24 public static CodedOutputStreamWriter forCodedOutput(CodedOutputStream output) { 25 if (output.wrapper != null) { 26 return output.wrapper; 27 } 28 return new CodedOutputStreamWriter(output); 29 } 30 CodedOutputStreamWriter(CodedOutputStream output)31 private CodedOutputStreamWriter(CodedOutputStream output) { 32 this.output = checkNotNull(output, "output"); 33 this.output.wrapper = this; 34 } 35 36 @Override fieldOrder()37 public FieldOrder fieldOrder() { 38 return FieldOrder.ASCENDING; 39 } 40 getTotalBytesWritten()41 public int getTotalBytesWritten() { 42 return output.getTotalBytesWritten(); 43 } 44 45 @Override writeSFixed32(int fieldNumber, int value)46 public void writeSFixed32(int fieldNumber, int value) throws IOException { 47 output.writeSFixed32(fieldNumber, value); 48 } 49 50 @Override writeInt64(int fieldNumber, long value)51 public void writeInt64(int fieldNumber, long value) throws IOException { 52 output.writeInt64(fieldNumber, value); 53 } 54 55 @Override writeSFixed64(int fieldNumber, long value)56 public void writeSFixed64(int fieldNumber, long value) throws IOException { 57 output.writeSFixed64(fieldNumber, value); 58 } 59 60 @Override writeFloat(int fieldNumber, float value)61 public void writeFloat(int fieldNumber, float value) throws IOException { 62 output.writeFloat(fieldNumber, value); 63 } 64 65 @Override writeDouble(int fieldNumber, double value)66 public void writeDouble(int fieldNumber, double value) throws IOException { 67 output.writeDouble(fieldNumber, value); 68 } 69 70 @Override writeEnum(int fieldNumber, int value)71 public void writeEnum(int fieldNumber, int value) throws IOException { 72 output.writeEnum(fieldNumber, value); 73 } 74 75 @Override writeUInt64(int fieldNumber, long value)76 public void writeUInt64(int fieldNumber, long value) throws IOException { 77 output.writeUInt64(fieldNumber, value); 78 } 79 80 @Override writeInt32(int fieldNumber, int value)81 public void writeInt32(int fieldNumber, int value) throws IOException { 82 output.writeInt32(fieldNumber, value); 83 } 84 85 @Override writeFixed64(int fieldNumber, long value)86 public void writeFixed64(int fieldNumber, long value) throws IOException { 87 output.writeFixed64(fieldNumber, value); 88 } 89 90 @Override writeFixed32(int fieldNumber, int value)91 public void writeFixed32(int fieldNumber, int value) throws IOException { 92 output.writeFixed32(fieldNumber, value); 93 } 94 95 @Override writeBool(int fieldNumber, boolean value)96 public void writeBool(int fieldNumber, boolean value) throws IOException { 97 output.writeBool(fieldNumber, value); 98 } 99 100 @Override writeString(int fieldNumber, String value)101 public void writeString(int fieldNumber, String value) throws IOException { 102 output.writeString(fieldNumber, value); 103 } 104 105 @Override writeBytes(int fieldNumber, ByteString value)106 public void writeBytes(int fieldNumber, ByteString value) throws IOException { 107 output.writeBytes(fieldNumber, value); 108 } 109 110 @Override writeUInt32(int fieldNumber, int value)111 public void writeUInt32(int fieldNumber, int value) throws IOException { 112 output.writeUInt32(fieldNumber, value); 113 } 114 115 @Override writeSInt32(int fieldNumber, int value)116 public void writeSInt32(int fieldNumber, int value) throws IOException { 117 output.writeSInt32(fieldNumber, value); 118 } 119 120 @Override writeSInt64(int fieldNumber, long value)121 public void writeSInt64(int fieldNumber, long value) throws IOException { 122 output.writeSInt64(fieldNumber, value); 123 } 124 125 @Override writeMessage(int fieldNumber, Object value)126 public void writeMessage(int fieldNumber, Object value) throws IOException { 127 output.writeMessage(fieldNumber, (MessageLite) value); 128 } 129 130 @Override writeMessage(int fieldNumber, Object value, Schema schema)131 public void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException { 132 output.writeMessage(fieldNumber, (MessageLite) value, schema); 133 } 134 135 @Deprecated 136 @Override writeGroup(int fieldNumber, Object value)137 public void writeGroup(int fieldNumber, Object value) throws IOException { 138 output.writeGroup(fieldNumber, (MessageLite) value); 139 } 140 141 @Override writeGroup(int fieldNumber, Object value, Schema schema)142 public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException { 143 output.writeGroup(fieldNumber, (MessageLite) value, schema); 144 } 145 146 @Deprecated 147 @Override writeStartGroup(int fieldNumber)148 public void writeStartGroup(int fieldNumber) throws IOException { 149 output.writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP); 150 } 151 152 @Deprecated 153 @Override writeEndGroup(int fieldNumber)154 public void writeEndGroup(int fieldNumber) throws IOException { 155 output.writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP); 156 } 157 158 @Override writeMessageSetItem(int fieldNumber, Object value)159 public final void writeMessageSetItem(int fieldNumber, Object value) throws IOException { 160 if (value instanceof ByteString) { 161 output.writeRawMessageSetExtension(fieldNumber, (ByteString) value); 162 } else { 163 output.writeMessageSetExtension(fieldNumber, (MessageLite) value); 164 } 165 } 166 167 @Override writeInt32List(int fieldNumber, List<Integer> value, boolean packed)168 public void writeInt32List(int fieldNumber, List<Integer> value, boolean packed) 169 throws IOException { 170 if (value instanceof IntArrayList) { 171 writeInt32ListInternal(fieldNumber, (IntArrayList) value, packed); 172 } else { 173 writeInt32ListInternal(fieldNumber, value, packed); 174 } 175 } 176 writeInt32ListInternal(int fieldNumber, IntArrayList value, boolean packed)177 private void writeInt32ListInternal(int fieldNumber, IntArrayList value, boolean packed) 178 throws IOException { 179 if (packed) { 180 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 181 182 // Compute and write the length of the data. 183 int dataSize = 0; 184 for (int i = 0; i < value.size(); ++i) { 185 dataSize += CodedOutputStream.computeInt32SizeNoTag(value.getInt(i)); 186 } 187 output.writeUInt32NoTag(dataSize); 188 189 // Write the data itself, without any tags. 190 for (int i = 0; i < value.size(); ++i) { 191 output.writeInt32NoTag(value.getInt(i)); 192 } 193 } else { 194 for (int i = 0; i < value.size(); ++i) { 195 output.writeInt32(fieldNumber, value.getInt(i)); 196 } 197 } 198 } 199 writeInt32ListInternal(int fieldNumber, List<Integer> value, boolean packed)200 private void writeInt32ListInternal(int fieldNumber, List<Integer> value, boolean packed) 201 throws IOException { 202 if (packed) { 203 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 204 205 // Compute and write the length of the data. 206 int dataSize = 0; 207 for (int i = 0; i < value.size(); ++i) { 208 dataSize += CodedOutputStream.computeInt32SizeNoTag(value.get(i)); 209 } 210 output.writeUInt32NoTag(dataSize); 211 212 // Write the data itself, without any tags. 213 for (int i = 0; i < value.size(); ++i) { 214 output.writeInt32NoTag(value.get(i)); 215 } 216 } else { 217 for (int i = 0; i < value.size(); ++i) { 218 output.writeInt32(fieldNumber, value.get(i)); 219 } 220 } 221 } 222 223 @Override writeFixed32List(int fieldNumber, List<Integer> value, boolean packed)224 public void writeFixed32List(int fieldNumber, List<Integer> value, boolean packed) 225 throws IOException { 226 if (value instanceof IntArrayList) { 227 writeFixed32ListInternal(fieldNumber, (IntArrayList) value, packed); 228 } else { 229 writeFixed32ListInternal(fieldNumber, value, packed); 230 } 231 } 232 writeFixed32ListInternal(int fieldNumber, IntArrayList value, boolean packed)233 private void writeFixed32ListInternal(int fieldNumber, IntArrayList value, boolean packed) 234 throws IOException { 235 if (packed) { 236 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 237 238 // Compute and write the length of the data. 239 int dataSize = 0; 240 for (int i = 0; i < value.size(); ++i) { 241 dataSize += CodedOutputStream.computeFixed32SizeNoTag(value.getInt(i)); 242 } 243 output.writeUInt32NoTag(dataSize); 244 245 // Write the data itself, without any tags. 246 for (int i = 0; i < value.size(); ++i) { 247 output.writeFixed32NoTag(value.getInt(i)); 248 } 249 } else { 250 for (int i = 0; i < value.size(); ++i) { 251 output.writeFixed32(fieldNumber, value.getInt(i)); 252 } 253 } 254 } 255 writeFixed32ListInternal(int fieldNumber, List<Integer> value, boolean packed)256 private void writeFixed32ListInternal(int fieldNumber, List<Integer> value, boolean packed) 257 throws IOException { 258 if (packed) { 259 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 260 261 // Compute and write the length of the data. 262 int dataSize = 0; 263 for (int i = 0; i < value.size(); ++i) { 264 dataSize += CodedOutputStream.computeFixed32SizeNoTag(value.get(i)); 265 } 266 output.writeUInt32NoTag(dataSize); 267 268 // Write the data itself, without any tags. 269 for (int i = 0; i < value.size(); ++i) { 270 output.writeFixed32NoTag(value.get(i)); 271 } 272 } else { 273 for (int i = 0; i < value.size(); ++i) { 274 output.writeFixed32(fieldNumber, value.get(i)); 275 } 276 } 277 } 278 279 @Override writeInt64List(int fieldNumber, List<Long> value, boolean packed)280 public void writeInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException { 281 if (value instanceof LongArrayList) { 282 writeInt64ListInternal(fieldNumber, (LongArrayList) value, packed); 283 } else { 284 writeInt64ListInternal(fieldNumber, value, packed); 285 } 286 } 287 writeInt64ListInternal(int fieldNumber, LongArrayList value, boolean packed)288 private void writeInt64ListInternal(int fieldNumber, LongArrayList value, boolean packed) 289 throws IOException { 290 if (packed) { 291 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 292 293 // Compute and write the length of the data. 294 int dataSize = 0; 295 for (int i = 0; i < value.size(); ++i) { 296 dataSize += CodedOutputStream.computeInt64SizeNoTag(value.getLong(i)); 297 } 298 output.writeUInt32NoTag(dataSize); 299 300 // Write the data itself, without any tags. 301 for (int i = 0; i < value.size(); ++i) { 302 output.writeInt64NoTag(value.getLong(i)); 303 } 304 } else { 305 for (int i = 0; i < value.size(); ++i) { 306 output.writeInt64(fieldNumber, value.getLong(i)); 307 } 308 } 309 } 310 writeInt64ListInternal(int fieldNumber, List<Long> value, boolean packed)311 private void writeInt64ListInternal(int fieldNumber, List<Long> value, boolean packed) 312 throws IOException { 313 if (packed) { 314 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 315 316 // Compute and write the length of the data. 317 int dataSize = 0; 318 for (int i = 0; i < value.size(); ++i) { 319 dataSize += CodedOutputStream.computeInt64SizeNoTag(value.get(i)); 320 } 321 output.writeUInt32NoTag(dataSize); 322 323 // Write the data itself, without any tags. 324 for (int i = 0; i < value.size(); ++i) { 325 output.writeInt64NoTag(value.get(i)); 326 } 327 } else { 328 for (int i = 0; i < value.size(); ++i) { 329 output.writeInt64(fieldNumber, value.get(i)); 330 } 331 } 332 } 333 @Override writeUInt64List(int fieldNumber, List<Long> value, boolean packed)334 public void writeUInt64List(int fieldNumber, List<Long> value, boolean packed) 335 throws IOException { 336 if (value instanceof LongArrayList) { 337 writeUInt64ListInternal(fieldNumber, (LongArrayList) value, packed); 338 } else { 339 writeUInt64ListInternal(fieldNumber, value, packed); 340 } 341 } 342 writeUInt64ListInternal(int fieldNumber, LongArrayList value, boolean packed)343 private void writeUInt64ListInternal(int fieldNumber, LongArrayList value, boolean packed) 344 throws IOException { 345 if (packed) { 346 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 347 348 // Compute and write the length of the data. 349 int dataSize = 0; 350 for (int i = 0; i < value.size(); ++i) { 351 dataSize += CodedOutputStream.computeUInt64SizeNoTag(value.getLong(i)); 352 } 353 output.writeUInt32NoTag(dataSize); 354 355 // Write the data itself, without any tags. 356 for (int i = 0; i < value.size(); ++i) { 357 output.writeUInt64NoTag(value.getLong(i)); 358 } 359 } else { 360 for (int i = 0; i < value.size(); ++i) { 361 output.writeUInt64(fieldNumber, value.getLong(i)); 362 } 363 } 364 } 365 writeUInt64ListInternal(int fieldNumber, List<Long> value, boolean packed)366 private void writeUInt64ListInternal(int fieldNumber, List<Long> value, boolean packed) 367 throws IOException { 368 if (packed) { 369 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 370 371 // Compute and write the length of the data. 372 int dataSize = 0; 373 for (int i = 0; i < value.size(); ++i) { 374 dataSize += CodedOutputStream.computeUInt64SizeNoTag(value.get(i)); 375 } 376 output.writeUInt32NoTag(dataSize); 377 378 // Write the data itself, without any tags. 379 for (int i = 0; i < value.size(); ++i) { 380 output.writeUInt64NoTag(value.get(i)); 381 } 382 } else { 383 for (int i = 0; i < value.size(); ++i) { 384 output.writeUInt64(fieldNumber, value.get(i)); 385 } 386 } 387 } 388 389 @Override writeFixed64List(int fieldNumber, List<Long> value, boolean packed)390 public void writeFixed64List(int fieldNumber, List<Long> value, boolean packed) 391 throws IOException { 392 if (value instanceof LongArrayList) { 393 writeFixed64ListInternal(fieldNumber, (LongArrayList) value, packed); 394 } else { 395 writeFixed64ListInternal(fieldNumber, value, packed); 396 } 397 } 398 writeFixed64ListInternal(int fieldNumber, LongArrayList value, boolean packed)399 private void writeFixed64ListInternal(int fieldNumber, LongArrayList value, boolean packed) 400 throws IOException { 401 if (packed) { 402 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 403 404 // Compute and write the length of the data. 405 int dataSize = 0; 406 for (int i = 0; i < value.size(); ++i) { 407 dataSize += CodedOutputStream.computeFixed64SizeNoTag(value.getLong(i)); 408 } 409 output.writeUInt32NoTag(dataSize); 410 411 // Write the data itself, without any tags. 412 for (int i = 0; i < value.size(); ++i) { 413 output.writeFixed64NoTag(value.getLong(i)); 414 } 415 } else { 416 for (int i = 0; i < value.size(); ++i) { 417 output.writeFixed64(fieldNumber, value.getLong(i)); 418 } 419 } 420 } 421 writeFixed64ListInternal(int fieldNumber, List<Long> value, boolean packed)422 private void writeFixed64ListInternal(int fieldNumber, List<Long> value, boolean packed) 423 throws IOException { 424 if (packed) { 425 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 426 427 // Compute and write the length of the data. 428 int dataSize = 0; 429 for (int i = 0; i < value.size(); ++i) { 430 dataSize += CodedOutputStream.computeFixed64SizeNoTag(value.get(i)); 431 } 432 output.writeUInt32NoTag(dataSize); 433 434 // Write the data itself, without any tags. 435 for (int i = 0; i < value.size(); ++i) { 436 output.writeFixed64NoTag(value.get(i)); 437 } 438 } else { 439 for (int i = 0; i < value.size(); ++i) { 440 output.writeFixed64(fieldNumber, value.get(i)); 441 } 442 } 443 } 444 445 @Override writeFloatList(int fieldNumber, List<Float> value, boolean packed)446 public void writeFloatList(int fieldNumber, List<Float> value, boolean packed) 447 throws IOException { 448 if (value instanceof FloatArrayList) { 449 writeFloatListInternal(fieldNumber, (FloatArrayList) value, packed); 450 } else { 451 writeFloatListInternal(fieldNumber, value, packed); 452 } 453 } 454 writeFloatListInternal(int fieldNumber, FloatArrayList value, boolean packed)455 private void writeFloatListInternal(int fieldNumber, FloatArrayList value, boolean packed) 456 throws IOException { 457 if (packed) { 458 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 459 460 // Compute and write the length of the data. 461 int dataSize = 0; 462 for (int i = 0; i < value.size(); ++i) { 463 dataSize += CodedOutputStream.computeFloatSizeNoTag(value.getFloat(i)); 464 } 465 output.writeUInt32NoTag(dataSize); 466 467 // Write the data itself, without any tags. 468 for (int i = 0; i < value.size(); ++i) { 469 output.writeFloatNoTag(value.getFloat(i)); 470 } 471 } else { 472 for (int i = 0; i < value.size(); ++i) { 473 output.writeFloat(fieldNumber, value.getFloat(i)); 474 } 475 } 476 } 477 writeFloatListInternal(int fieldNumber, List<Float> value, boolean packed)478 private void writeFloatListInternal(int fieldNumber, List<Float> value, boolean packed) 479 throws IOException { 480 if (packed) { 481 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 482 483 // Compute and write the length of the data. 484 int dataSize = 0; 485 for (int i = 0; i < value.size(); ++i) { 486 dataSize += CodedOutputStream.computeFloatSizeNoTag(value.get(i)); 487 } 488 output.writeUInt32NoTag(dataSize); 489 490 // Write the data itself, without any tags. 491 for (int i = 0; i < value.size(); ++i) { 492 output.writeFloatNoTag(value.get(i)); 493 } 494 } else { 495 for (int i = 0; i < value.size(); ++i) { 496 output.writeFloat(fieldNumber, value.get(i)); 497 } 498 } 499 } 500 501 @Override writeDoubleList(int fieldNumber, List<Double> value, boolean packed)502 public void writeDoubleList(int fieldNumber, List<Double> value, boolean packed) 503 throws IOException { 504 if (value instanceof DoubleArrayList) { 505 writeDoubleListInternal(fieldNumber, (DoubleArrayList) value, packed); 506 } else { 507 writeDoubleListInternal(fieldNumber, value, packed); 508 } 509 } 510 writeDoubleListInternal(int fieldNumber, DoubleArrayList value, boolean packed)511 private void writeDoubleListInternal(int fieldNumber, DoubleArrayList value, boolean packed) 512 throws IOException { 513 if (packed) { 514 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 515 516 // Compute and write the length of the data. 517 int dataSize = 0; 518 for (int i = 0; i < value.size(); ++i) { 519 dataSize += CodedOutputStream.computeDoubleSizeNoTag(value.getDouble(i)); 520 } 521 output.writeUInt32NoTag(dataSize); 522 523 // Write the data itself, without any tags. 524 for (int i = 0; i < value.size(); ++i) { 525 output.writeDoubleNoTag(value.getDouble(i)); 526 } 527 } else { 528 for (int i = 0; i < value.size(); ++i) { 529 output.writeDouble(fieldNumber, value.getDouble(i)); 530 } 531 } 532 } 533 writeDoubleListInternal(int fieldNumber, List<Double> value, boolean packed)534 private void writeDoubleListInternal(int fieldNumber, List<Double> value, boolean packed) 535 throws IOException { 536 if (packed) { 537 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 538 539 // Compute and write the length of the data. 540 int dataSize = 0; 541 for (int i = 0; i < value.size(); ++i) { 542 dataSize += CodedOutputStream.computeDoubleSizeNoTag(value.get(i)); 543 } 544 output.writeUInt32NoTag(dataSize); 545 546 // Write the data itself, without any tags. 547 for (int i = 0; i < value.size(); ++i) { 548 output.writeDoubleNoTag(value.get(i)); 549 } 550 } else { 551 for (int i = 0; i < value.size(); ++i) { 552 output.writeDouble(fieldNumber, value.get(i)); 553 } 554 } 555 } 556 557 @Override writeEnumList(int fieldNumber, List<Integer> value, boolean packed)558 public void writeEnumList(int fieldNumber, List<Integer> value, boolean packed) 559 throws IOException { 560 if (value instanceof IntArrayList) { 561 writeEnumListInternal(fieldNumber, (IntArrayList) value, packed); 562 } else { 563 writeEnumListInternal(fieldNumber, value, packed); 564 } 565 } 566 writeEnumListInternal(int fieldNumber, IntArrayList value, boolean packed)567 private void writeEnumListInternal(int fieldNumber, IntArrayList value, boolean packed) 568 throws IOException { 569 if (packed) { 570 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 571 572 // Compute and write the length of the data. 573 int dataSize = 0; 574 for (int i = 0; i < value.size(); ++i) { 575 dataSize += CodedOutputStream.computeEnumSizeNoTag(value.getInt(i)); 576 } 577 output.writeUInt32NoTag(dataSize); 578 579 // Write the data itself, without any tags. 580 for (int i = 0; i < value.size(); ++i) { 581 output.writeEnumNoTag(value.getInt(i)); 582 } 583 } else { 584 for (int i = 0; i < value.size(); ++i) { 585 output.writeEnum(fieldNumber, value.getInt(i)); 586 } 587 } 588 } 589 writeEnumListInternal(int fieldNumber, List<Integer> value, boolean packed)590 private void writeEnumListInternal(int fieldNumber, List<Integer> value, boolean packed) 591 throws IOException { 592 if (packed) { 593 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 594 595 // Compute and write the length of the data. 596 int dataSize = 0; 597 for (int i = 0; i < value.size(); ++i) { 598 dataSize += CodedOutputStream.computeEnumSizeNoTag(value.get(i)); 599 } 600 output.writeUInt32NoTag(dataSize); 601 602 // Write the data itself, without any tags. 603 for (int i = 0; i < value.size(); ++i) { 604 output.writeEnumNoTag(value.get(i)); 605 } 606 } else { 607 for (int i = 0; i < value.size(); ++i) { 608 output.writeEnum(fieldNumber, value.get(i)); 609 } 610 } 611 } 612 613 @Override writeBoolList(int fieldNumber, List<Boolean> value, boolean packed)614 public void writeBoolList(int fieldNumber, List<Boolean> value, boolean packed) 615 throws IOException { 616 if (value instanceof BooleanArrayList) { 617 writeBoolListInternal(fieldNumber, (BooleanArrayList) value, packed); 618 } else { 619 writeBoolListInternal(fieldNumber, value, packed); 620 } 621 } 622 writeBoolListInternal(int fieldNumber, BooleanArrayList value, boolean packed)623 private void writeBoolListInternal(int fieldNumber, BooleanArrayList value, boolean packed) 624 throws IOException { 625 if (packed) { 626 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 627 628 // Compute and write the length of the data. 629 int dataSize = 0; 630 for (int i = 0; i < value.size(); ++i) { 631 dataSize += CodedOutputStream.computeBoolSizeNoTag(value.getBoolean(i)); 632 } 633 output.writeUInt32NoTag(dataSize); 634 635 // Write the data itself, without any tags. 636 for (int i = 0; i < value.size(); ++i) { 637 output.writeBoolNoTag(value.getBoolean(i)); 638 } 639 } else { 640 for (int i = 0; i < value.size(); ++i) { 641 output.writeBool(fieldNumber, value.getBoolean(i)); 642 } 643 } 644 } 645 writeBoolListInternal(int fieldNumber, List<Boolean> value, boolean packed)646 private void writeBoolListInternal(int fieldNumber, List<Boolean> value, boolean packed) 647 throws IOException { 648 if (packed) { 649 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 650 651 // Compute and write the length of the data. 652 int dataSize = 0; 653 for (int i = 0; i < value.size(); ++i) { 654 dataSize += CodedOutputStream.computeBoolSizeNoTag(value.get(i)); 655 } 656 output.writeUInt32NoTag(dataSize); 657 658 // Write the data itself, without any tags. 659 for (int i = 0; i < value.size(); ++i) { 660 output.writeBoolNoTag(value.get(i)); 661 } 662 } else { 663 for (int i = 0; i < value.size(); ++i) { 664 output.writeBool(fieldNumber, value.get(i)); 665 } 666 } 667 } 668 669 @Override writeStringList(int fieldNumber, List<String> value)670 public void writeStringList(int fieldNumber, List<String> value) throws IOException { 671 if (value instanceof LazyStringList) { 672 final LazyStringList lazyList = (LazyStringList) value; 673 for (int i = 0; i < value.size(); ++i) { 674 writeLazyString(fieldNumber, lazyList.getRaw(i)); 675 } 676 } else { 677 for (int i = 0; i < value.size(); ++i) { 678 output.writeString(fieldNumber, value.get(i)); 679 } 680 } 681 } 682 writeLazyString(int fieldNumber, Object value)683 private void writeLazyString(int fieldNumber, Object value) throws IOException { 684 if (value instanceof String) { 685 output.writeString(fieldNumber, (String) value); 686 } else { 687 output.writeBytes(fieldNumber, (ByteString) value); 688 } 689 } 690 691 @Override writeBytesList(int fieldNumber, List<ByteString> value)692 public void writeBytesList(int fieldNumber, List<ByteString> value) throws IOException { 693 for (int i = 0; i < value.size(); ++i) { 694 output.writeBytes(fieldNumber, value.get(i)); 695 } 696 } 697 698 @Override writeUInt32List(int fieldNumber, List<Integer> value, boolean packed)699 public void writeUInt32List(int fieldNumber, List<Integer> value, boolean packed) 700 throws IOException { 701 if (value instanceof IntArrayList) { 702 writeUInt32ListInternal(fieldNumber, (IntArrayList) value, packed); 703 } else { 704 writeUInt32ListInternal(fieldNumber, value, packed); 705 } 706 } 707 writeUInt32ListInternal(int fieldNumber, IntArrayList value, boolean packed)708 private void writeUInt32ListInternal(int fieldNumber, IntArrayList value, boolean packed) 709 throws IOException { 710 if (packed) { 711 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 712 713 // Compute and write the length of the data. 714 int dataSize = 0; 715 for (int i = 0; i < value.size(); ++i) { 716 dataSize += CodedOutputStream.computeUInt32SizeNoTag(value.getInt(i)); 717 } 718 output.writeUInt32NoTag(dataSize); 719 720 // Write the data itself, without any tags. 721 for (int i = 0; i < value.size(); ++i) { 722 output.writeUInt32NoTag(value.getInt(i)); 723 } 724 } else { 725 for (int i = 0; i < value.size(); ++i) { 726 output.writeUInt32(fieldNumber, value.getInt(i)); 727 } 728 } 729 } 730 writeUInt32ListInternal(int fieldNumber, List<Integer> value, boolean packed)731 public void writeUInt32ListInternal(int fieldNumber, List<Integer> value, boolean packed) 732 throws IOException { 733 if (packed) { 734 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 735 736 // Compute and write the length of the data. 737 int dataSize = 0; 738 for (int i = 0; i < value.size(); ++i) { 739 dataSize += CodedOutputStream.computeUInt32SizeNoTag(value.get(i)); 740 } 741 output.writeUInt32NoTag(dataSize); 742 743 // Write the data itself, without any tags. 744 for (int i = 0; i < value.size(); ++i) { 745 output.writeUInt32NoTag(value.get(i)); 746 } 747 } else { 748 for (int i = 0; i < value.size(); ++i) { 749 output.writeUInt32(fieldNumber, value.get(i)); 750 } 751 } 752 } 753 754 @Override writeSFixed32List(int fieldNumber, List<Integer> value, boolean packed)755 public void writeSFixed32List(int fieldNumber, List<Integer> value, boolean packed) 756 throws IOException { 757 if (value instanceof IntArrayList) { 758 writeSFixed32ListInternal(fieldNumber, (IntArrayList) value, packed); 759 } else { 760 writeSFixed32ListInternal(fieldNumber, value, packed); 761 } 762 } 763 writeSFixed32ListInternal(int fieldNumber, IntArrayList value, boolean packed)764 private void writeSFixed32ListInternal(int fieldNumber, IntArrayList value, boolean packed) 765 throws IOException { 766 if (packed) { 767 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 768 769 // Compute and write the length of the data. 770 int dataSize = 0; 771 for (int i = 0; i < value.size(); ++i) { 772 dataSize += CodedOutputStream.computeSFixed32SizeNoTag(value.getInt(i)); 773 } 774 output.writeUInt32NoTag(dataSize); 775 776 // Write the data itself, without any tags. 777 for (int i = 0; i < value.size(); ++i) { 778 output.writeSFixed32NoTag(value.getInt(i)); 779 } 780 } else { 781 for (int i = 0; i < value.size(); ++i) { 782 output.writeSFixed32(fieldNumber, value.getInt(i)); 783 } 784 } 785 } 786 writeSFixed32ListInternal(int fieldNumber, List<Integer> value, boolean packed)787 private void writeSFixed32ListInternal(int fieldNumber, List<Integer> value, boolean packed) 788 throws IOException { 789 if (packed) { 790 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 791 792 // Compute and write the length of the data. 793 int dataSize = 0; 794 for (int i = 0; i < value.size(); ++i) { 795 dataSize += CodedOutputStream.computeSFixed32SizeNoTag(value.get(i)); 796 } 797 output.writeUInt32NoTag(dataSize); 798 799 // Write the data itself, without any tags. 800 for (int i = 0; i < value.size(); ++i) { 801 output.writeSFixed32NoTag(value.get(i)); 802 } 803 } else { 804 for (int i = 0; i < value.size(); ++i) { 805 output.writeSFixed32(fieldNumber, value.get(i)); 806 } 807 } 808 } 809 810 @Override writeSFixed64List(int fieldNumber, List<Long> value, boolean packed)811 public void writeSFixed64List(int fieldNumber, List<Long> value, boolean packed) 812 throws IOException { 813 if (value instanceof LongArrayList) { 814 writeSFixed64ListInternal(fieldNumber, (LongArrayList) value, packed); 815 } else { 816 writeSFixed64ListInternal(fieldNumber, value, packed); 817 } 818 } 819 writeSFixed64ListInternal(int fieldNumber, LongArrayList value, boolean packed)820 private void writeSFixed64ListInternal(int fieldNumber, LongArrayList value, boolean packed) 821 throws IOException { 822 if (packed) { 823 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 824 825 // Compute and write the length of the data. 826 int dataSize = 0; 827 for (int i = 0; i < value.size(); ++i) { 828 dataSize += CodedOutputStream.computeSFixed64SizeNoTag(value.getLong(i)); 829 } 830 output.writeUInt32NoTag(dataSize); 831 832 // Write the data itself, without any tags. 833 for (int i = 0; i < value.size(); ++i) { 834 output.writeSFixed64NoTag(value.getLong(i)); 835 } 836 } else { 837 for (int i = 0; i < value.size(); ++i) { 838 output.writeSFixed64(fieldNumber, value.getLong(i)); 839 } 840 } 841 } 842 writeSFixed64ListInternal(int fieldNumber, List<Long> value, boolean packed)843 private void writeSFixed64ListInternal(int fieldNumber, List<Long> value, boolean packed) 844 throws IOException { 845 if (packed) { 846 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 847 848 // Compute and write the length of the data. 849 int dataSize = 0; 850 for (int i = 0; i < value.size(); ++i) { 851 dataSize += CodedOutputStream.computeSFixed64SizeNoTag(value.get(i)); 852 } 853 output.writeUInt32NoTag(dataSize); 854 855 // Write the data itself, without any tags. 856 for (int i = 0; i < value.size(); ++i) { 857 output.writeSFixed64NoTag(value.get(i)); 858 } 859 } else { 860 for (int i = 0; i < value.size(); ++i) { 861 output.writeSFixed64(fieldNumber, value.get(i)); 862 } 863 } 864 } 865 866 @Override writeSInt32List(int fieldNumber, List<Integer> value, boolean packed)867 public void writeSInt32List(int fieldNumber, List<Integer> value, boolean packed) 868 throws IOException { 869 if (value instanceof IntArrayList) { 870 writeSInt32ListInternal(fieldNumber, (IntArrayList) value, packed); 871 } else { 872 writeSInt32ListInternal(fieldNumber, value, packed); 873 } 874 } 875 writeSInt32ListInternal(int fieldNumber, IntArrayList value, boolean packed)876 private void writeSInt32ListInternal(int fieldNumber, IntArrayList value, boolean packed) 877 throws IOException { 878 if (packed) { 879 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 880 881 // Compute and write the length of the data. 882 int dataSize = 0; 883 for (int i = 0; i < value.size(); ++i) { 884 dataSize += CodedOutputStream.computeSInt32SizeNoTag(value.getInt(i)); 885 } 886 output.writeUInt32NoTag(dataSize); 887 888 // Write the data itself, without any tags. 889 for (int i = 0; i < value.size(); ++i) { 890 output.writeSInt32NoTag(value.getInt(i)); 891 } 892 } else { 893 for (int i = 0; i < value.size(); ++i) { 894 output.writeSInt32(fieldNumber, value.getInt(i)); 895 } 896 } 897 } 898 writeSInt32ListInternal(int fieldNumber, List<Integer> value, boolean packed)899 public void writeSInt32ListInternal(int fieldNumber, List<Integer> value, boolean packed) 900 throws IOException { 901 if (packed) { 902 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 903 904 // Compute and write the length of the data. 905 int dataSize = 0; 906 for (int i = 0; i < value.size(); ++i) { 907 dataSize += CodedOutputStream.computeSInt32SizeNoTag(value.get(i)); 908 } 909 output.writeUInt32NoTag(dataSize); 910 911 // Write the data itself, without any tags. 912 for (int i = 0; i < value.size(); ++i) { 913 output.writeSInt32NoTag(value.get(i)); 914 } 915 } else { 916 for (int i = 0; i < value.size(); ++i) { 917 output.writeSInt32(fieldNumber, value.get(i)); 918 } 919 } 920 } 921 922 @Override writeSInt64List(int fieldNumber, List<Long> value, boolean packed)923 public void writeSInt64List(int fieldNumber, List<Long> value, boolean packed) 924 throws IOException { 925 if (value instanceof LongArrayList) { 926 writeSInt64ListInternal(fieldNumber, (LongArrayList) value, packed); 927 } else { 928 writeSInt64ListInternal(fieldNumber, value, packed); 929 } 930 } 931 writeSInt64ListInternal(int fieldNumber, LongArrayList value, boolean packed)932 private void writeSInt64ListInternal(int fieldNumber, LongArrayList value, boolean packed) 933 throws IOException { 934 if (packed) { 935 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 936 937 // Compute and write the length of the data. 938 int dataSize = 0; 939 for (int i = 0; i < value.size(); ++i) { 940 dataSize += CodedOutputStream.computeSInt64SizeNoTag(value.getLong(i)); 941 } 942 output.writeUInt32NoTag(dataSize); 943 944 // Write the data itself, without any tags. 945 for (int i = 0; i < value.size(); ++i) { 946 output.writeSInt64NoTag(value.getLong(i)); 947 } 948 } else { 949 for (int i = 0; i < value.size(); ++i) { 950 output.writeSInt64(fieldNumber, value.getLong(i)); 951 } 952 } 953 } 954 writeSInt64ListInternal(int fieldNumber, List<Long> value, boolean packed)955 private void writeSInt64ListInternal(int fieldNumber, List<Long> value, boolean packed) 956 throws IOException { 957 if (packed) { 958 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 959 960 // Compute and write the length of the data. 961 int dataSize = 0; 962 for (int i = 0; i < value.size(); ++i) { 963 dataSize += CodedOutputStream.computeSInt64SizeNoTag(value.get(i)); 964 } 965 output.writeUInt32NoTag(dataSize); 966 967 // Write the data itself, without any tags. 968 for (int i = 0; i < value.size(); ++i) { 969 output.writeSInt64NoTag(value.get(i)); 970 } 971 } else { 972 for (int i = 0; i < value.size(); ++i) { 973 output.writeSInt64(fieldNumber, value.get(i)); 974 } 975 } 976 } 977 978 @Override writeMessageList(int fieldNumber, List<?> value)979 public void writeMessageList(int fieldNumber, List<?> value) throws IOException { 980 for (int i = 0; i < value.size(); ++i) { 981 writeMessage(fieldNumber, value.get(i)); 982 } 983 } 984 985 @Override writeMessageList(int fieldNumber, List<?> value, Schema schema)986 public void writeMessageList(int fieldNumber, List<?> value, Schema schema) throws IOException { 987 for (int i = 0; i < value.size(); ++i) { 988 writeMessage(fieldNumber, value.get(i), schema); 989 } 990 } 991 992 @Deprecated 993 @Override writeGroupList(int fieldNumber, List<?> value)994 public void writeGroupList(int fieldNumber, List<?> value) throws IOException { 995 for (int i = 0; i < value.size(); ++i) { 996 writeGroup(fieldNumber, value.get(i)); 997 } 998 } 999 1000 @Override writeGroupList(int fieldNumber, List<?> value, Schema schema)1001 public void writeGroupList(int fieldNumber, List<?> value, Schema schema) throws IOException { 1002 for (int i = 0; i < value.size(); ++i) { 1003 writeGroup(fieldNumber, value.get(i), schema); 1004 } 1005 } 1006 1007 @Override writeMap(int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map)1008 public <K, V> void writeMap(int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map) 1009 throws IOException { 1010 if (output.isSerializationDeterministic()) { 1011 writeDeterministicMap(fieldNumber, metadata, map); 1012 return; 1013 } 1014 for (Map.Entry<K, V> entry : map.entrySet()) { 1015 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 1016 output.writeUInt32NoTag( 1017 MapEntryLite.computeSerializedSize(metadata, entry.getKey(), entry.getValue())); 1018 MapEntryLite.writeTo(output, metadata, entry.getKey(), entry.getValue()); 1019 } 1020 } 1021 1022 @SuppressWarnings("unchecked") writeDeterministicMap( int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map)1023 private <K, V> void writeDeterministicMap( 1024 int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map) throws IOException { 1025 switch (metadata.keyType) { 1026 case BOOL: 1027 V value; 1028 if ((value = map.get(Boolean.FALSE)) != null) { 1029 writeDeterministicBooleanMapEntry( 1030 fieldNumber, /* key= */ false, value, (MapEntryLite.Metadata<Boolean, V>) metadata); 1031 } 1032 if ((value = map.get(Boolean.TRUE)) != null) { 1033 writeDeterministicBooleanMapEntry( 1034 fieldNumber, /* key= */ true, value, (MapEntryLite.Metadata<Boolean, V>) metadata); 1035 } 1036 break; 1037 case FIXED32: 1038 case INT32: 1039 case SFIXED32: 1040 case SINT32: 1041 case UINT32: 1042 writeDeterministicIntegerMap( 1043 fieldNumber, (MapEntryLite.Metadata<Integer, V>) metadata, (Map<Integer, V>) map); 1044 break; 1045 case FIXED64: 1046 case INT64: 1047 case SFIXED64: 1048 case SINT64: 1049 case UINT64: 1050 writeDeterministicLongMap( 1051 fieldNumber, (MapEntryLite.Metadata<Long, V>) metadata, (Map<Long, V>) map); 1052 break; 1053 case STRING: 1054 writeDeterministicStringMap( 1055 fieldNumber, (MapEntryLite.Metadata<String, V>) metadata, (Map<String, V>) map); 1056 break; 1057 default: 1058 throw new IllegalArgumentException("does not support key type: " + metadata.keyType); 1059 } 1060 } 1061 writeDeterministicBooleanMapEntry( int fieldNumber, boolean key, V value, MapEntryLite.Metadata<Boolean, V> metadata)1062 private <V> void writeDeterministicBooleanMapEntry( 1063 int fieldNumber, boolean key, V value, MapEntryLite.Metadata<Boolean, V> metadata) 1064 throws IOException { 1065 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 1066 output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value)); 1067 MapEntryLite.writeTo(output, metadata, key, value); 1068 } 1069 writeDeterministicIntegerMap( int fieldNumber, MapEntryLite.Metadata<Integer, V> metadata, Map<Integer, V> map)1070 private <V> void writeDeterministicIntegerMap( 1071 int fieldNumber, MapEntryLite.Metadata<Integer, V> metadata, Map<Integer, V> map) 1072 throws IOException { 1073 int[] keys = new int[map.size()]; 1074 int index = 0; 1075 for (int k : map.keySet()) { 1076 keys[index++] = k; 1077 } 1078 Arrays.sort(keys); 1079 for (int key : keys) { 1080 V value = map.get(key); 1081 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 1082 output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value)); 1083 MapEntryLite.writeTo(output, metadata, key, value); 1084 } 1085 } 1086 writeDeterministicLongMap( int fieldNumber, MapEntryLite.Metadata<Long, V> metadata, Map<Long, V> map)1087 private <V> void writeDeterministicLongMap( 1088 int fieldNumber, MapEntryLite.Metadata<Long, V> metadata, Map<Long, V> map) 1089 throws IOException { 1090 long[] keys = new long[map.size()]; 1091 int index = 0; 1092 for (long k : map.keySet()) { 1093 keys[index++] = k; 1094 } 1095 Arrays.sort(keys); 1096 for (long key : keys) { 1097 V value = map.get(key); 1098 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 1099 output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value)); 1100 MapEntryLite.writeTo(output, metadata, key, value); 1101 } 1102 } 1103 writeDeterministicStringMap( int fieldNumber, MapEntryLite.Metadata<String, V> metadata, Map<String, V> map)1104 private <V> void writeDeterministicStringMap( 1105 int fieldNumber, MapEntryLite.Metadata<String, V> metadata, Map<String, V> map) 1106 throws IOException { 1107 String[] keys = new String[map.size()]; 1108 int index = 0; 1109 for (String k : map.keySet()) { 1110 keys[index++] = k; 1111 } 1112 Arrays.sort(keys); 1113 for (String key : keys) { 1114 V value = map.get(key); 1115 output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED); 1116 output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value)); 1117 MapEntryLite.writeTo(output, metadata, key, value); 1118 } 1119 } 1120 } 1121