• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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