xref: /aosp_15_r20/external/protobuf/javanano/src/test/java/com/google/protobuf/nano/NanoTest.java (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2013 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.nano;
32 
33 import com.google.protobuf.nano.CodedOutputByteBufferNano;
34 import com.google.protobuf.nano.EnumClassNanos.EnumClassNano;
35 import com.google.protobuf.nano.EnumClassNanos.EnumClassNano.MessageScopeEnum;
36 import com.google.protobuf.nano.EnumClassNanos.FileScopeEnum;
37 import com.google.protobuf.nano.MapTestProto.TestMap;
38 import com.google.protobuf.nano.MapTestProto.TestMap.MessageValue;
39 import com.google.protobuf.nano.NanoAccessorsOuterClass.TestNanoAccessors;
40 import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas;
41 import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
42 import com.google.protobuf.nano.UnittestRecursiveNano.RecursiveMessageNano;
43 import com.google.protobuf.nano.NanoReferenceTypesCompat;
44 import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano;
45 import com.google.protobuf.nano.UnittestSingleNano.SingleMessageNano;
46 import com.google.protobuf.nano.testext.nano.Extensions;
47 import com.google.protobuf.nano.testext.nano.Extensions.AnotherMessage;
48 import com.google.protobuf.nano.testext.nano.Extensions.MessageWithGroup;
49 import com.google.protobuf.nano.testimport.nano.UnittestImportNano;
50 
51 import junit.framework.TestCase;
52 
53 import java.util.Arrays;
54 import java.util.HashMap;
55 import java.util.Map;
56 import java.util.TreeMap;
57 
58 /**
59  * Test nano runtime.
60  *
61  * @author [email protected] Ulas Kirazci
62  */
63 public class NanoTest extends TestCase {
64   @Override
setUp()65   public void setUp() throws Exception {
66   }
67 
testSimpleMessageNano()68   public void testSimpleMessageNano() throws Exception {
69     SimpleMessageNano msg = new SimpleMessageNano();
70     assertEquals(123, msg.d);
71     assertEquals(null, msg.nestedMsg);
72     assertEquals(SimpleMessageNano.BAZ, msg.defaultNestedEnum);
73 
74     msg.d = 456;
75     assertEquals(456, msg.d);
76 
77     SimpleMessageNano.NestedMessage nestedMsg = new SimpleMessageNano.NestedMessage();
78     nestedMsg.bb = 2;
79     assertEquals(2, nestedMsg.bb);
80     msg.nestedMsg = nestedMsg;
81     assertEquals(2, msg.nestedMsg.bb);
82 
83     msg.defaultNestedEnum = SimpleMessageNano.BAR;
84     assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
85 
86     byte [] result = MessageNano.toByteArray(msg);
87     int msgSerializedSize = msg.getSerializedSize();
88     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
89     assertTrue(msgSerializedSize == 9);
90     assertEquals(result.length, msgSerializedSize);
91 
92     SimpleMessageNano newMsg = SimpleMessageNano.parseFrom(result);
93     assertEquals(456, newMsg.d);
94     assertEquals(2, msg.nestedMsg.bb);
95     assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
96 
97     msg.nestedMsg = null;
98     assertTrue(msgSerializedSize != msg.getSerializedSize());
99 
100     msg.clear();
101     assertEquals(0, msg.getSerializedSize());
102   }
103 
testRecursiveMessageNano()104   public void testRecursiveMessageNano() throws Exception {
105     RecursiveMessageNano msg = new RecursiveMessageNano();
106     assertTrue(msg.repeatedRecursiveMessageNano.length == 0);
107 
108     RecursiveMessageNano msg1 = new RecursiveMessageNano();
109     msg1.id = 1;
110     assertEquals(1, msg1.id);
111     RecursiveMessageNano msg2 = new RecursiveMessageNano();
112     msg2.id = 2;
113     RecursiveMessageNano msg3 = new RecursiveMessageNano();
114     msg3.id = 3;
115 
116     RecursiveMessageNano.NestedMessage nestedMsg = new RecursiveMessageNano.NestedMessage();
117     nestedMsg.a = msg1;
118     assertEquals(1, nestedMsg.a.id);
119 
120     msg.id = 0;
121     msg.nestedMessage = nestedMsg;
122     msg.optionalRecursiveMessageNano = msg2;
123     msg.repeatedRecursiveMessageNano = new RecursiveMessageNano[] { msg3 };
124 
125     byte [] result = MessageNano.toByteArray(msg);
126     int msgSerializedSize = msg.getSerializedSize();
127     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
128     assertTrue(msgSerializedSize == 16);
129     assertEquals(result.length, msgSerializedSize);
130 
131     RecursiveMessageNano newMsg = RecursiveMessageNano.parseFrom(result);
132     assertEquals(1, newMsg.repeatedRecursiveMessageNano.length);
133 
134     assertEquals(0, newMsg.id);
135     assertEquals(1, newMsg.nestedMessage.a.id);
136     assertEquals(2, newMsg.optionalRecursiveMessageNano.id);
137     assertEquals(3, newMsg.repeatedRecursiveMessageNano[0].id);
138   }
139 
testMessageNoFields()140   public void testMessageNoFields() {
141     SingleMessageNano msg = new SingleMessageNano();
142     assertEquals(0, msg.getSerializedSize());
143     assertEquals(0, MessageNano.toByteArray(msg).length);
144   }
145 
testNanoRequiredInt32()146   public void testNanoRequiredInt32() throws Exception {
147     TestAllTypesNano msg = new TestAllTypesNano();
148     msg.id = 123;
149     assertEquals(123, msg.id);
150     msg.clear().id = 456;
151     assertEquals(456, msg.id);
152     msg.clear();
153 
154     msg.id = 123;
155     byte [] result = MessageNano.toByteArray(msg);
156     int msgSerializedSize = msg.getSerializedSize();
157     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
158     assertTrue(msgSerializedSize == 3);
159     assertEquals(result.length, msgSerializedSize);
160 
161     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
162     assertEquals(123, newMsg.id);
163   }
164 
testNanoOptionalInt32()165   public void testNanoOptionalInt32() throws Exception {
166     TestAllTypesNano msg = new TestAllTypesNano();
167     msg.optionalInt32 = 123;
168     assertEquals(123, msg.optionalInt32);
169     msg.clear()
170        .optionalInt32 = 456;
171     assertEquals(456, msg.optionalInt32);
172     msg.clear();
173 
174     msg.optionalInt32 = 123;
175     byte [] result = MessageNano.toByteArray(msg);
176     int msgSerializedSize = msg.getSerializedSize();
177     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
178     assertTrue(msgSerializedSize == 5);
179     assertEquals(result.length, msgSerializedSize);
180 
181     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
182     assertEquals(123, newMsg.optionalInt32);
183   }
184 
testNanoOptionalInt64()185   public void testNanoOptionalInt64() throws Exception {
186     TestAllTypesNano msg = new TestAllTypesNano();
187     msg.optionalInt64 = 123;
188     assertEquals(123, msg.optionalInt64);
189     msg.clear()
190        .optionalInt64 = 456;
191     assertEquals(456, msg.optionalInt64);
192     msg.clear();
193     assertEquals(0, msg.optionalInt64);
194 
195     msg.optionalInt64 = 123;
196     byte [] result = MessageNano.toByteArray(msg);
197     int msgSerializedSize = msg.getSerializedSize();
198     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
199     assertTrue(msgSerializedSize == 5);
200     assertEquals(result.length, msgSerializedSize);
201 
202     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
203     assertEquals(123, newMsg.optionalInt64);
204   }
205 
testNanoOptionalUint32()206   public void testNanoOptionalUint32() throws Exception {
207     TestAllTypesNano msg = new TestAllTypesNano();
208     msg.optionalUint32 = 123;
209     assertEquals(123, msg.optionalUint32);
210     msg.clear()
211        .optionalUint32 = 456;
212     assertEquals(456, msg.optionalUint32);
213     msg.clear();
214     assertEquals(0, msg.optionalUint32);
215 
216     msg.optionalUint32 = 123;
217     byte [] result = MessageNano.toByteArray(msg);
218     int msgSerializedSize = msg.getSerializedSize();
219     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
220     assertTrue(msgSerializedSize == 5);
221     assertEquals(result.length, msgSerializedSize);
222 
223     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
224     assertEquals(123, newMsg.optionalUint32);
225   }
226 
testNanoOptionalUint64()227   public void testNanoOptionalUint64() throws Exception {
228     TestAllTypesNano msg = new TestAllTypesNano();
229     msg.optionalUint64 = 123;
230     assertEquals(123, msg.optionalUint64);
231     msg.clear()
232        .optionalUint64 = 456;
233     assertEquals(456, msg.optionalUint64);
234     msg.clear();
235     assertEquals(0, msg.optionalUint64);
236 
237     msg.optionalUint64 = 123;
238     byte [] result = MessageNano.toByteArray(msg);
239     int msgSerializedSize = msg.getSerializedSize();
240     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
241     assertTrue(msgSerializedSize == 5);
242     assertEquals(result.length, msgSerializedSize);
243 
244     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
245     assertEquals(123, newMsg.optionalUint64);
246   }
247 
testNanoOptionalSint32()248   public void testNanoOptionalSint32() throws Exception {
249     TestAllTypesNano msg = new TestAllTypesNano();
250     msg.optionalSint32 = 123;
251     assertEquals(123, msg.optionalSint32);
252     msg.clear()
253        .optionalSint32 = 456;
254     assertEquals(456, msg.optionalSint32);
255     msg.clear();
256     assertEquals(0, msg.optionalSint32);
257 
258     msg.optionalSint32 = -123;
259     byte [] result = MessageNano.toByteArray(msg);
260     int msgSerializedSize = msg.getSerializedSize();
261     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
262     assertTrue(msgSerializedSize == 6);
263     assertEquals(result.length, msgSerializedSize);
264 
265     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
266     assertEquals(-123, newMsg.optionalSint32);
267   }
268 
testNanoOptionalSint64()269   public void testNanoOptionalSint64() throws Exception {
270     TestAllTypesNano msg = new TestAllTypesNano();
271     msg.optionalSint64 = 123;
272     assertEquals(123, msg.optionalSint64);
273     msg.clear()
274        .optionalSint64 = 456;
275     assertEquals(456, msg.optionalSint64);
276     msg.clear();
277     assertEquals(0, msg.optionalSint64);
278 
279     msg.optionalSint64 = -123;
280     byte [] result = MessageNano.toByteArray(msg);
281     int msgSerializedSize = msg.getSerializedSize();
282     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
283     assertTrue(msgSerializedSize == 6);
284     assertEquals(result.length, msgSerializedSize);
285 
286     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
287     assertEquals(-123, newMsg.optionalSint64);
288   }
289 
testNanoOptionalFixed32()290   public void testNanoOptionalFixed32() throws Exception {
291     TestAllTypesNano msg = new TestAllTypesNano();
292     msg.optionalFixed32 = 123;
293     assertEquals(123, msg.optionalFixed32);
294     msg.clear()
295        .optionalFixed32 = 456;
296     assertEquals(456, msg.optionalFixed32);
297     msg.clear();
298     assertEquals(0, msg.optionalFixed32);
299 
300     msg.optionalFixed32 = 123;
301     byte [] result = MessageNano.toByteArray(msg);
302     int msgSerializedSize = msg.getSerializedSize();
303     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
304     assertTrue(msgSerializedSize == 8);
305     assertEquals(result.length, msgSerializedSize);
306 
307     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
308     assertEquals(123, newMsg.optionalFixed32);
309   }
310 
testNanoOptionalFixed64()311   public void testNanoOptionalFixed64() throws Exception {
312     TestAllTypesNano msg = new TestAllTypesNano();
313     msg.optionalFixed64 = 123;
314     assertEquals(123, msg.optionalFixed64);
315     msg.clear()
316        .optionalFixed64 = 456;
317     assertEquals(456, msg.optionalFixed64);
318     msg.clear();
319     assertEquals(0, msg.optionalFixed64);
320 
321     msg.optionalFixed64 = 123;
322     byte [] result = MessageNano.toByteArray(msg);
323     int msgSerializedSize = msg.getSerializedSize();
324     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
325     assertTrue(msgSerializedSize == 12);
326     assertEquals(result.length, msgSerializedSize);
327 
328     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
329     assertEquals(123, newMsg.optionalFixed64);
330   }
331 
testNanoOptionalSfixed32()332   public void testNanoOptionalSfixed32() throws Exception {
333     TestAllTypesNano msg = new TestAllTypesNano();
334     msg.optionalSfixed32 = 123;
335     assertEquals(123, msg.optionalSfixed32);
336     msg.clear()
337        .optionalSfixed32 = 456;
338     assertEquals(456, msg.optionalSfixed32);
339     msg.clear();
340     assertEquals(0, msg.optionalSfixed32);
341 
342     msg.optionalSfixed32 = 123;
343     byte [] result = MessageNano.toByteArray(msg);
344     int msgSerializedSize = msg.getSerializedSize();
345     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
346     assertTrue(msgSerializedSize == 8);
347     assertEquals(result.length, msgSerializedSize);
348 
349     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
350     assertEquals(123, newMsg.optionalSfixed32);
351   }
352 
testNanoOptionalSfixed64()353   public void testNanoOptionalSfixed64() throws Exception {
354     TestAllTypesNano msg = new TestAllTypesNano();
355     msg.optionalSfixed64 = 123;
356     assertEquals(123, msg.optionalSfixed64);
357     msg.clear()
358        .optionalSfixed64 = 456;
359     assertEquals(456, msg.optionalSfixed64);
360     msg.clear();
361     assertEquals(0, msg.optionalSfixed64);
362 
363     msg.optionalSfixed64 = -123;
364     byte [] result = MessageNano.toByteArray(msg);
365     int msgSerializedSize = msg.getSerializedSize();
366     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
367     assertTrue(msgSerializedSize == 12);
368     assertEquals(result.length, msgSerializedSize);
369 
370     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
371     assertEquals(-123, newMsg.optionalSfixed64);
372   }
373 
testNanoOptionalFloat()374   public void testNanoOptionalFloat() throws Exception {
375     TestAllTypesNano msg = new TestAllTypesNano();
376     msg.optionalFloat = 123f;
377     assertTrue(123.0f == msg.optionalFloat);
378     msg.clear()
379        .optionalFloat = 456.0f;
380     assertTrue(456.0f == msg.optionalFloat);
381     msg.clear();
382     assertTrue(0.0f == msg.optionalFloat);
383 
384     msg.optionalFloat = -123.456f;
385     byte [] result = MessageNano.toByteArray(msg);
386     int msgSerializedSize = msg.getSerializedSize();
387     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
388     assertTrue(msgSerializedSize == 8);
389     assertEquals(result.length, msgSerializedSize);
390 
391     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
392     assertTrue(-123.456f == newMsg.optionalFloat);
393   }
394 
testNanoOptionalDouble()395   public void testNanoOptionalDouble() throws Exception {
396     TestAllTypesNano msg = new TestAllTypesNano();
397     msg.optionalDouble = 123;
398     assertTrue(123.0 == msg.optionalDouble);
399     msg.clear()
400        .optionalDouble = 456.0;
401     assertTrue(456.0 == msg.optionalDouble);
402     msg.clear();
403     assertTrue(0.0 == msg.optionalDouble);
404 
405     msg.optionalDouble = -123.456;
406     byte [] result = MessageNano.toByteArray(msg);
407     int msgSerializedSize = msg.getSerializedSize();
408     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
409     assertTrue(msgSerializedSize == 12);
410     assertEquals(result.length, msgSerializedSize);
411 
412     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
413     assertTrue(-123.456 == newMsg.optionalDouble);
414   }
415 
testNanoOptionalBool()416   public void testNanoOptionalBool() throws Exception {
417     TestAllTypesNano msg = new TestAllTypesNano();
418     msg.optionalBool = true;
419     assertTrue(msg.optionalBool);
420     msg.clear()
421        .optionalBool = true;
422     assertTrue(msg.optionalBool);
423     msg.clear();
424     assertFalse(msg.optionalBool);
425 
426     msg.optionalBool = true;
427     byte [] result = MessageNano.toByteArray(msg);
428     int msgSerializedSize = msg.getSerializedSize();
429     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
430     assertTrue(msgSerializedSize == 5);
431     assertEquals(result.length, msgSerializedSize);
432 
433     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
434     assertTrue(newMsg.optionalBool);
435   }
436 
testNanoOptionalString()437   public void testNanoOptionalString() throws Exception {
438     TestAllTypesNano msg = new TestAllTypesNano();
439     msg.optionalString = "hello";
440     assertEquals("hello", msg.optionalString);
441     msg.clear();
442     assertTrue(msg.optionalString.isEmpty());
443     msg.clear()
444        .optionalString = "hello2";
445     assertEquals("hello2", msg.optionalString);
446     msg.clear();
447     assertTrue(msg.optionalString.isEmpty());
448 
449     msg.optionalString = "bye";
450     byte [] result = MessageNano.toByteArray(msg);
451     int msgSerializedSize = msg.getSerializedSize();
452     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
453     assertTrue(msgSerializedSize == 8);
454     assertEquals(result.length, msgSerializedSize);
455 
456     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
457     assertTrue(newMsg.optionalString != null);
458     assertEquals("bye", newMsg.optionalString);
459   }
460 
testNanoOptionalBytes()461   public void testNanoOptionalBytes() throws Exception {
462     TestAllTypesNano msg = new TestAllTypesNano();
463     assertFalse(msg.optionalBytes.length > 0);
464     msg.optionalBytes = InternalNano.copyFromUtf8("hello");
465     assertTrue(msg.optionalBytes.length > 0);
466     assertEquals("hello", new String(msg.optionalBytes, InternalNano.UTF_8));
467     msg.clear();
468     assertFalse(msg.optionalBytes.length > 0);
469     msg.clear()
470        .optionalBytes = InternalNano.copyFromUtf8("hello");
471     assertTrue(msg.optionalBytes.length > 0);
472     msg.clear();
473     assertFalse(msg.optionalBytes.length > 0);
474 
475     msg.optionalBytes = InternalNano.copyFromUtf8("bye");
476     byte [] result = MessageNano.toByteArray(msg);
477     int msgSerializedSize = msg.getSerializedSize();
478     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
479     assertTrue(msgSerializedSize == 8);
480     assertEquals(result.length, msgSerializedSize);
481 
482     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
483     assertTrue(newMsg.optionalBytes.length > 0);
484     assertEquals("bye", new String(newMsg.optionalBytes, InternalNano.UTF_8));
485   }
486 
testNanoOptionalGroup()487   public void testNanoOptionalGroup() throws Exception {
488     TestAllTypesNano msg = new TestAllTypesNano();
489     TestAllTypesNano.OptionalGroup grp = new TestAllTypesNano.OptionalGroup();
490     grp.a = 1;
491     assertFalse(msg.optionalGroup != null);
492     msg.optionalGroup = grp;
493     assertTrue(msg.optionalGroup != null);
494     assertEquals(1, msg.optionalGroup.a);
495     msg.clear();
496     assertFalse(msg.optionalGroup != null);
497     msg.clear()
498        .optionalGroup = new TestAllTypesNano.OptionalGroup();
499     msg.optionalGroup.a = 2;
500     assertTrue(msg.optionalGroup != null);
501     msg.clear();
502     assertFalse(msg.optionalGroup != null);
503 
504     msg.optionalGroup = grp;
505     byte [] result = MessageNano.toByteArray(msg);
506     int msgSerializedSize = msg.getSerializedSize();
507     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
508     assertTrue(msgSerializedSize == 10);
509     assertEquals(result.length, msgSerializedSize);
510 
511     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
512     assertTrue(newMsg.optionalGroup != null);
513     assertEquals(1, newMsg.optionalGroup.a);
514   }
515 
testNanoOptionalGroupWithUnknownFieldsEnabled()516   public void testNanoOptionalGroupWithUnknownFieldsEnabled() throws Exception {
517     MessageWithGroup msg = new MessageWithGroup();
518     MessageWithGroup.Group grp = new MessageWithGroup.Group();
519     grp.a = 1;
520     msg.group = grp;
521     byte [] serialized = MessageNano.toByteArray(msg);
522 
523     MessageWithGroup parsed = MessageWithGroup.parseFrom(serialized);
524     assertEquals(1, parsed.group.a);
525 
526     byte [] serialized2 = MessageNano.toByteArray(parsed);
527     assertEquals(serialized.length, serialized2.length);
528     MessageWithGroup parsed2 = MessageWithGroup.parseFrom(serialized2);
529     assertEquals(1, parsed2.group.a);
530   }
531 
testNanoOptionalNestedMessage()532   public void testNanoOptionalNestedMessage() throws Exception {
533     TestAllTypesNano msg = new TestAllTypesNano();
534     TestAllTypesNano.NestedMessage nestedMsg = new TestAllTypesNano.NestedMessage();
535     nestedMsg.bb = 1;
536     assertFalse(msg.optionalNestedMessage != null);
537     msg.optionalNestedMessage = nestedMsg;
538     assertTrue(msg.optionalNestedMessage != null);
539     assertEquals(1, msg.optionalNestedMessage.bb);
540     msg.clear();
541     assertFalse(msg.optionalNestedMessage != null);
542     msg.clear()
543        .optionalNestedMessage = new TestAllTypesNano.NestedMessage();
544     msg.optionalNestedMessage.bb = 2;
545     assertTrue(msg.optionalNestedMessage != null);
546     msg.clear();
547     assertFalse(msg.optionalNestedMessage != null);
548 
549     msg.optionalNestedMessage = nestedMsg;
550     byte [] result = MessageNano.toByteArray(msg);
551     int msgSerializedSize = msg.getSerializedSize();
552     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
553     assertTrue(msgSerializedSize == 8);
554     assertEquals(result.length, msgSerializedSize);
555 
556     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
557     assertTrue(newMsg.optionalNestedMessage != null);
558     assertEquals(1, newMsg.optionalNestedMessage.bb);
559   }
560 
testNanoOptionalForeignMessage()561   public void testNanoOptionalForeignMessage() throws Exception {
562     TestAllTypesNano msg = new TestAllTypesNano();
563     NanoOuterClass.ForeignMessageNano nestedMsg = new NanoOuterClass.ForeignMessageNano();
564     nestedMsg.c = 1;
565     assertFalse(msg.optionalForeignMessage != null);
566     msg.optionalForeignMessage = nestedMsg;
567     assertTrue(msg.optionalForeignMessage != null);
568     assertEquals(1, msg.optionalForeignMessage.c);
569     msg.clear();
570     assertFalse(msg.optionalForeignMessage != null);
571     msg.clear()
572        .optionalForeignMessage = new NanoOuterClass.ForeignMessageNano();
573     msg.optionalForeignMessage.c = 2;
574     assertTrue(msg.optionalForeignMessage != null);
575     msg.clear();
576     assertFalse(msg.optionalForeignMessage != null);
577 
578     msg.optionalForeignMessage = nestedMsg;
579     byte [] result = MessageNano.toByteArray(msg);
580     int msgSerializedSize = msg.getSerializedSize();
581     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
582     assertTrue(msgSerializedSize == 8);
583     assertEquals(result.length, msgSerializedSize);
584 
585     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
586     assertTrue(newMsg.optionalForeignMessage != null);
587     assertEquals(1, newMsg.optionalForeignMessage.c);
588   }
589 
testNanoOptionalImportMessage()590   public void testNanoOptionalImportMessage() throws Exception {
591     TestAllTypesNano msg = new TestAllTypesNano();
592     UnittestImportNano.ImportMessageNano nestedMsg = new UnittestImportNano.ImportMessageNano();
593     nestedMsg.d = 1;
594     assertFalse(msg.optionalImportMessage != null);
595     msg.optionalImportMessage = nestedMsg;
596     assertTrue(msg.optionalImportMessage != null);
597     assertEquals(1, msg.optionalImportMessage.d);
598     msg.clear();
599     assertFalse(msg.optionalImportMessage != null);
600     msg.clear()
601        .optionalImportMessage = new UnittestImportNano.ImportMessageNano();
602     msg.optionalImportMessage.d = 2;
603     assertTrue(msg.optionalImportMessage != null);
604     msg.clear();
605     assertFalse(msg.optionalImportMessage != null);
606 
607     msg.optionalImportMessage = nestedMsg;
608     byte [] result = MessageNano.toByteArray(msg);
609     int msgSerializedSize = msg.getSerializedSize();
610     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
611     assertTrue(msgSerializedSize == 8);
612     assertEquals(result.length, msgSerializedSize);
613 
614     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
615     assertTrue(newMsg.optionalImportMessage != null);
616     assertEquals(1, newMsg.optionalImportMessage.d);
617   }
618 
testNanoOptionalNestedEnum()619   public void testNanoOptionalNestedEnum() throws Exception {
620     TestAllTypesNano msg = new TestAllTypesNano();
621     msg.optionalNestedEnum = TestAllTypesNano.BAR;
622     assertEquals(TestAllTypesNano.BAR, msg.optionalNestedEnum);
623     msg.clear()
624        .optionalNestedEnum = TestAllTypesNano.BAZ;
625     assertEquals(TestAllTypesNano.BAZ, msg.optionalNestedEnum);
626     msg.clear();
627     assertEquals(TestAllTypesNano.FOO, msg.optionalNestedEnum);
628 
629     msg.optionalNestedEnum = TestAllTypesNano.BAR;
630     byte [] result = MessageNano.toByteArray(msg);
631     int msgSerializedSize = msg.getSerializedSize();
632     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
633     assertTrue(msgSerializedSize == 6);
634     assertEquals(result.length, msgSerializedSize);
635 
636     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
637     assertEquals(TestAllTypesNano.BAR, newMsg.optionalNestedEnum);
638   }
639 
testNanoOptionalForeignEnum()640   public void testNanoOptionalForeignEnum() throws Exception {
641     TestAllTypesNano msg = new TestAllTypesNano();
642     msg.optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAR;
643     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.optionalForeignEnum);
644     msg.clear()
645        .optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAZ;
646     assertEquals(NanoOuterClass.FOREIGN_NANO_BAZ, msg.optionalForeignEnum);
647     msg.clear();
648     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.optionalForeignEnum);
649 
650     msg.optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAR;
651     byte [] result = MessageNano.toByteArray(msg);
652     int msgSerializedSize = msg.getSerializedSize();
653     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
654     assertTrue(msgSerializedSize == 6);
655     assertEquals(result.length, msgSerializedSize);
656 
657     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
658     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, newMsg.optionalForeignEnum);
659   }
660 
testNanoOptionalImportEnum()661   public void testNanoOptionalImportEnum() throws Exception {
662     TestAllTypesNano msg = new TestAllTypesNano();
663     msg.optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAR;
664     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.optionalImportEnum);
665     msg.clear()
666        .optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAZ;
667     assertEquals(UnittestImportNano.IMPORT_NANO_BAZ, msg.optionalImportEnum);
668     msg.clear();
669     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.optionalImportEnum);
670 
671     msg.optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAR;
672     byte [] result = MessageNano.toByteArray(msg);
673     int msgSerializedSize = msg.getSerializedSize();
674     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
675     assertTrue(msgSerializedSize == 6);
676     assertEquals(result.length, msgSerializedSize);
677 
678     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
679     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, newMsg.optionalImportEnum);
680   }
681 
testNanoOptionalStringPiece()682   public void testNanoOptionalStringPiece() throws Exception {
683     TestAllTypesNano msg = new TestAllTypesNano();
684     msg.optionalStringPiece = "hello";
685     assertEquals("hello", msg.optionalStringPiece);
686     msg.clear();
687     assertTrue(msg.optionalStringPiece.isEmpty());
688     msg.clear()
689        .optionalStringPiece = "hello2";
690     assertEquals("hello2", msg.optionalStringPiece);
691     msg.clear();
692     assertTrue(msg.optionalStringPiece.isEmpty());
693 
694     msg.optionalStringPiece = "bye";
695     byte [] result = MessageNano.toByteArray(msg);
696     int msgSerializedSize = msg.getSerializedSize();
697     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
698     assertTrue(msgSerializedSize == 9);
699     assertEquals(result.length, msgSerializedSize);
700 
701     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
702     assertTrue(newMsg.optionalStringPiece != null);
703     assertEquals("bye", newMsg.optionalStringPiece);
704   }
705 
testNanoOptionalCord()706   public void testNanoOptionalCord() throws Exception {
707     TestAllTypesNano msg = new TestAllTypesNano();
708     msg.optionalCord = "hello";
709     assertEquals("hello", msg.optionalCord);
710     msg.clear();
711     assertTrue(msg.optionalCord.isEmpty());
712     msg.clear()
713        .optionalCord = "hello2";
714     assertEquals("hello2", msg.optionalCord);
715     msg.clear();
716     assertTrue(msg.optionalCord.isEmpty());
717 
718     msg.optionalCord = "bye";
719     byte [] result = MessageNano.toByteArray(msg);
720     int msgSerializedSize = msg.getSerializedSize();
721     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
722     assertTrue(msgSerializedSize == 9);
723     assertEquals(result.length, msgSerializedSize);
724 
725     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
726     assertTrue(newMsg.optionalCord != null);
727     assertEquals("bye", newMsg.optionalCord);
728   }
729 
testNanoRepeatedInt32()730   public void testNanoRepeatedInt32() throws Exception {
731     TestAllTypesNano msg = new TestAllTypesNano();
732     assertEquals(0, msg.repeatedInt32.length);
733     msg.repeatedInt32 = new int[] { 123, 789, 456 };
734     assertEquals(789, msg.repeatedInt32[1]);
735     assertEquals(456, msg.repeatedInt32[2]);
736     msg.clear();
737     assertEquals(0, msg.repeatedInt32.length);
738     msg.clear()
739        .repeatedInt32 = new int[] { 456 };
740     assertEquals(1, msg.repeatedInt32.length);
741     assertEquals(456, msg.repeatedInt32[0]);
742     msg.clear();
743     assertEquals(0, msg.repeatedInt32.length);
744 
745     // Test 1 entry
746     msg.clear()
747        .repeatedInt32 = new int[] { 123 };
748     assertEquals(1, msg.repeatedInt32.length);
749     byte [] result = MessageNano.toByteArray(msg);
750     int msgSerializedSize = msg.getSerializedSize();
751     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
752     assertTrue(msgSerializedSize == 6);
753     assertEquals(result.length, msgSerializedSize);
754     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
755     assertEquals(1, newMsg.repeatedInt32.length);
756     assertEquals(123, newMsg.repeatedInt32[0]);
757 
758     // Test 2 entries
759     msg.clear()
760        .repeatedInt32 = new int[] { 123, 456 };
761     assertEquals(2, msg.repeatedInt32.length);
762     result = MessageNano.toByteArray(msg);
763     msgSerializedSize = msg.getSerializedSize();
764     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
765     assertTrue(msgSerializedSize == 10);
766     assertEquals(result.length, msgSerializedSize);
767 
768     newMsg = TestAllTypesNano.parseFrom(result);
769     assertEquals(2, newMsg.repeatedInt32.length);
770     assertEquals(123, newMsg.repeatedInt32[0]);
771     assertEquals(456, newMsg.repeatedInt32[1]);
772   }
773 
testNanoRepeatedInt64()774   public void testNanoRepeatedInt64() throws Exception {
775     TestAllTypesNano msg = new TestAllTypesNano();
776     assertEquals(0, msg.repeatedInt64.length);
777     msg.repeatedInt64 = new long[] { 123, 789, 456 };
778     assertEquals(789, msg.repeatedInt64[1]);
779     assertEquals(456, msg.repeatedInt64[2]);
780     msg.clear();
781     assertEquals(0, msg.repeatedInt64.length);
782     msg.clear()
783        .repeatedInt64 = new long[] { 456 };
784     assertEquals(1, msg.repeatedInt64.length);
785     assertEquals(456, msg.repeatedInt64[0]);
786     msg.clear();
787     assertEquals(0, msg.repeatedInt64.length);
788 
789     // Test 1 entry
790     msg.clear()
791        .repeatedInt64 = new long[] { 123 };
792     assertEquals(1, msg.repeatedInt64.length);
793     byte [] result = MessageNano.toByteArray(msg);
794     int msgSerializedSize = msg.getSerializedSize();
795     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
796     assertTrue(msgSerializedSize == 6);
797     assertEquals(result.length, msgSerializedSize);
798     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
799     assertEquals(1, newMsg.repeatedInt64.length);
800     assertEquals(123, newMsg.repeatedInt64[0]);
801 
802     // Test 2 entries
803     msg.clear()
804        .repeatedInt64 = new long[] { 123, 456 };
805     assertEquals(2, msg.repeatedInt64.length);
806     result = MessageNano.toByteArray(msg);
807     msgSerializedSize = msg.getSerializedSize();
808     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
809     assertTrue(msgSerializedSize == 10);
810     assertEquals(result.length, msgSerializedSize);
811 
812     newMsg = TestAllTypesNano.parseFrom(result);
813     assertEquals(2, newMsg.repeatedInt64.length);
814     assertEquals(123, newMsg.repeatedInt64[0]);
815     assertEquals(456, newMsg.repeatedInt64[1]);
816   }
817 
testNanoRepeatedUint32()818   public void testNanoRepeatedUint32() throws Exception {
819     TestAllTypesNano msg = new TestAllTypesNano();
820     assertEquals(0, msg.repeatedUint32.length);
821     msg.repeatedUint32 = new int[] { 123, 789, 456 };
822     assertEquals(789, msg.repeatedUint32[1]);
823     assertEquals(456, msg.repeatedUint32[2]);
824     msg.clear();
825     assertEquals(0, msg.repeatedUint32.length);
826     msg.clear()
827        .repeatedUint32 = new int[] { 456 };
828     assertEquals(1, msg.repeatedUint32.length);
829     assertEquals(456, msg.repeatedUint32[0]);
830     msg.clear();
831     assertEquals(0, msg.repeatedUint32.length);
832 
833     // Test 1 entry
834     msg.clear()
835        .repeatedUint32 = new int[] { 123 };
836     assertEquals(1, msg.repeatedUint32.length);
837     byte [] result = MessageNano.toByteArray(msg);
838     int msgSerializedSize = msg.getSerializedSize();
839     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
840     assertTrue(msgSerializedSize == 6);
841     assertEquals(result.length, msgSerializedSize);
842     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
843     assertEquals(1, newMsg.repeatedUint32.length);
844     assertEquals(123, newMsg.repeatedUint32[0]);
845 
846     // Test 2 entries
847     msg.clear()
848        .repeatedUint32 = new int[] { 123, 456 };
849     assertEquals(2, msg.repeatedUint32.length);
850     result = MessageNano.toByteArray(msg);
851     msgSerializedSize = msg.getSerializedSize();
852     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
853     assertTrue(msgSerializedSize == 10);
854     assertEquals(result.length, msgSerializedSize);
855 
856     newMsg = TestAllTypesNano.parseFrom(result);
857     assertEquals(2, newMsg.repeatedUint32.length);
858     assertEquals(123, newMsg.repeatedUint32[0]);
859     assertEquals(456, newMsg.repeatedUint32[1]);
860   }
861 
testNanoRepeatedUint64()862   public void testNanoRepeatedUint64() throws Exception {
863     TestAllTypesNano msg = new TestAllTypesNano();
864     assertEquals(0, msg.repeatedUint64.length);
865     msg.repeatedUint64 = new long[] { 123, 789, 456 };
866     assertEquals(789, msg.repeatedUint64[1]);
867     assertEquals(456, msg.repeatedUint64[2]);
868     msg.clear();
869     assertEquals(0, msg.repeatedUint64.length);
870     msg.clear()
871        .repeatedUint64 = new long[] { 456 };
872     assertEquals(1, msg.repeatedUint64.length);
873     assertEquals(456, msg.repeatedUint64[0]);
874     msg.clear();
875     assertEquals(0, msg.repeatedUint64.length);
876 
877     // Test 1 entry
878     msg.clear()
879        .repeatedUint64 = new long[] { 123 };
880     assertEquals(1, msg.repeatedUint64.length);
881     byte [] result = MessageNano.toByteArray(msg);
882     int msgSerializedSize = msg.getSerializedSize();
883     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
884     assertTrue(msgSerializedSize == 6);
885     assertEquals(result.length, msgSerializedSize);
886     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
887     assertEquals(1, newMsg.repeatedUint64.length);
888     assertEquals(123, newMsg.repeatedUint64[0]);
889 
890     // Test 2 entries
891     msg.clear()
892        .repeatedUint64 = new long[] { 123, 456 };
893     assertEquals(2, msg.repeatedUint64.length);
894     result = MessageNano.toByteArray(msg);
895     msgSerializedSize = msg.getSerializedSize();
896     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
897     assertTrue(msgSerializedSize == 10);
898     assertEquals(result.length, msgSerializedSize);
899 
900     newMsg = TestAllTypesNano.parseFrom(result);
901     assertEquals(2, newMsg.repeatedUint64.length);
902     assertEquals(123, newMsg.repeatedUint64[0]);
903     assertEquals(456, newMsg.repeatedUint64[1]);
904   }
905 
testNanoRepeatedSint32()906   public void testNanoRepeatedSint32() throws Exception {
907     TestAllTypesNano msg = new TestAllTypesNano();
908     assertEquals(0, msg.repeatedSint32.length);
909     msg.repeatedSint32 = new int[] { 123, 789, 456 };
910     assertEquals(789, msg.repeatedSint32[1]);
911     assertEquals(456, msg.repeatedSint32[2]);
912     msg.clear();
913     assertEquals(0, msg.repeatedSint32.length);
914     msg.clear()
915        .repeatedSint32 = new int[] { 456 };
916     assertEquals(1, msg.repeatedSint32.length);
917     assertEquals(456, msg.repeatedSint32[0]);
918     msg.clear();
919     assertEquals(0, msg.repeatedSint32.length);
920 
921     // Test 1 entry
922     msg.clear()
923        .repeatedSint32 = new int[] { 123 };
924     assertEquals(1, msg.repeatedSint32.length);
925     byte [] result = MessageNano.toByteArray(msg);
926     int msgSerializedSize = msg.getSerializedSize();
927     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
928     assertTrue(msgSerializedSize == 7);
929     assertEquals(result.length, msgSerializedSize);
930     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
931     assertEquals(1, newMsg.repeatedSint32.length);
932     assertEquals(123, newMsg.repeatedSint32[0]);
933 
934     // Test 2 entries
935     msg.clear()
936        .repeatedSint32 = new int[] { 123, 456 };
937     assertEquals(2, msg.repeatedSint32.length);
938     result = MessageNano.toByteArray(msg);
939     msgSerializedSize = msg.getSerializedSize();
940     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
941     assertTrue(msgSerializedSize == 11);
942     assertEquals(result.length, msgSerializedSize);
943 
944     newMsg = TestAllTypesNano.parseFrom(result);
945     assertEquals(2, newMsg.repeatedSint32.length);
946     assertEquals(123, newMsg.repeatedSint32[0]);
947     assertEquals(456, newMsg.repeatedSint32[1]);
948   }
949 
testNanoRepeatedSint64()950   public void testNanoRepeatedSint64() throws Exception {
951     TestAllTypesNano msg = new TestAllTypesNano();
952     assertEquals(0, msg.repeatedSint64.length);
953     msg.repeatedSint64 = new long[] { 123, 789, 456 };
954     assertEquals(789, msg.repeatedSint64[1]);
955     assertEquals(456, msg.repeatedSint64[2]);
956     msg.clear();
957     assertEquals(0, msg.repeatedSint64.length);
958     msg.clear()
959        .repeatedSint64 = new long[] { 456 };
960     assertEquals(1, msg.repeatedSint64.length);
961     assertEquals(456, msg.repeatedSint64[0]);
962     msg.clear();
963     assertEquals(0, msg.repeatedSint64.length);
964 
965     // Test 1 entry
966     msg.clear()
967        .repeatedSint64 = new long[] { 123 };
968     assertEquals(1, msg.repeatedSint64.length);
969     byte [] result = MessageNano.toByteArray(msg);
970     int msgSerializedSize = msg.getSerializedSize();
971     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
972     assertTrue(msgSerializedSize == 7);
973     assertEquals(result.length, msgSerializedSize);
974     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
975     assertEquals(1, newMsg.repeatedSint64.length);
976     assertEquals(123, newMsg.repeatedSint64[0]);
977 
978     // Test 2 entries
979     msg.clear()
980        .repeatedSint64 = new long[] { 123, 456 };
981     assertEquals(2, msg.repeatedSint64.length);
982     result = MessageNano.toByteArray(msg);
983     msgSerializedSize = msg.getSerializedSize();
984     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
985     assertTrue(msgSerializedSize == 11);
986     assertEquals(result.length, msgSerializedSize);
987 
988     newMsg = TestAllTypesNano.parseFrom(result);
989     assertEquals(2, newMsg.repeatedSint64.length);
990     assertEquals(123, newMsg.repeatedSint64[0]);
991     assertEquals(456, newMsg.repeatedSint64[1]);
992   }
993 
testNanoRepeatedFixed32()994   public void testNanoRepeatedFixed32() throws Exception {
995     TestAllTypesNano msg = new TestAllTypesNano();
996     assertEquals(0, msg.repeatedFixed32.length);
997     msg.repeatedFixed32 = new int[] { 123, 789, 456 };
998     assertEquals(789, msg.repeatedFixed32[1]);
999     assertEquals(456, msg.repeatedFixed32[2]);
1000     msg.clear();
1001     assertEquals(0, msg.repeatedFixed32.length);
1002     msg.clear()
1003        .repeatedFixed32 = new int[] { 456 };
1004     assertEquals(1, msg.repeatedFixed32.length);
1005     assertEquals(456, msg.repeatedFixed32[0]);
1006     msg.clear();
1007     assertEquals(0, msg.repeatedFixed32.length);
1008 
1009     // Test 1 entry
1010     msg.clear()
1011        .repeatedFixed32 = new int[] { 123 };
1012     assertEquals(1, msg.repeatedFixed32.length);
1013     byte [] result = MessageNano.toByteArray(msg);
1014     int msgSerializedSize = msg.getSerializedSize();
1015     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1016     assertTrue(msgSerializedSize == 9);
1017     assertEquals(result.length, msgSerializedSize);
1018     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1019     assertEquals(1, newMsg.repeatedFixed32.length);
1020     assertEquals(123, newMsg.repeatedFixed32[0]);
1021 
1022     // Test 2 entries
1023     msg.clear()
1024        .repeatedFixed32 = new int[] { 123, 456 };
1025     assertEquals(2, msg.repeatedFixed32.length);
1026     result = MessageNano.toByteArray(msg);
1027     msgSerializedSize = msg.getSerializedSize();
1028     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1029     assertTrue(msgSerializedSize == 15);
1030     assertEquals(result.length, msgSerializedSize);
1031 
1032     newMsg = TestAllTypesNano.parseFrom(result);
1033     assertEquals(2, newMsg.repeatedFixed32.length);
1034     assertEquals(123, newMsg.repeatedFixed32[0]);
1035     assertEquals(456, newMsg.repeatedFixed32[1]);
1036   }
1037 
testNanoRepeatedFixed64()1038   public void testNanoRepeatedFixed64() throws Exception {
1039     TestAllTypesNano msg = new TestAllTypesNano();
1040     assertEquals(0, msg.repeatedFixed64.length);
1041     msg.repeatedFixed64 = new long[] { 123, 789, 456 };
1042     assertEquals(789, msg.repeatedFixed64[1]);
1043     assertEquals(456, msg.repeatedFixed64[2]);
1044     msg.clear();
1045     assertEquals(0, msg.repeatedFixed64.length);
1046     msg.clear()
1047        .repeatedFixed64 = new long[] { 456 };
1048     assertEquals(1, msg.repeatedFixed64.length);
1049     assertEquals(456, msg.repeatedFixed64[0]);
1050     msg.clear();
1051     assertEquals(0, msg.repeatedFixed64.length);
1052 
1053     // Test 1 entry
1054     msg.clear()
1055        .repeatedFixed64 = new long[] { 123 };
1056     assertEquals(1, msg.repeatedFixed64.length);
1057     byte [] result = MessageNano.toByteArray(msg);
1058     int msgSerializedSize = msg.getSerializedSize();
1059     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1060     assertTrue(msgSerializedSize == 13);
1061     assertEquals(result.length, msgSerializedSize);
1062     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1063     assertEquals(1, newMsg.repeatedFixed64.length);
1064     assertEquals(123, newMsg.repeatedFixed64[0]);
1065 
1066     // Test 2 entries
1067     msg.clear()
1068        .repeatedFixed64 = new long[] { 123, 456 };
1069     assertEquals(2, msg.repeatedFixed64.length);
1070     result = MessageNano.toByteArray(msg);
1071     msgSerializedSize = msg.getSerializedSize();
1072     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1073     assertTrue(msgSerializedSize == 23);
1074     assertEquals(result.length, msgSerializedSize);
1075 
1076     newMsg = TestAllTypesNano.parseFrom(result);
1077     assertEquals(2, newMsg.repeatedFixed64.length);
1078     assertEquals(123, newMsg.repeatedFixed64[0]);
1079     assertEquals(456, newMsg.repeatedFixed64[1]);
1080   }
1081 
testNanoRepeatedSfixed32()1082   public void testNanoRepeatedSfixed32() throws Exception {
1083     TestAllTypesNano msg = new TestAllTypesNano();
1084     assertEquals(0, msg.repeatedSfixed32.length);
1085     msg.repeatedSfixed32 = new int[] { 123, 789, 456 };
1086     assertEquals(789, msg.repeatedSfixed32[1]);
1087     assertEquals(456, msg.repeatedSfixed32[2]);
1088     msg.clear();
1089     assertEquals(0, msg.repeatedSfixed32.length);
1090     msg.clear()
1091        .repeatedSfixed32 = new int[] { 456 };
1092     assertEquals(1, msg.repeatedSfixed32.length);
1093     assertEquals(456, msg.repeatedSfixed32[0]);
1094     msg.clear();
1095     assertEquals(0, msg.repeatedSfixed32.length);
1096 
1097     // Test 1 entry
1098     msg.clear()
1099        .repeatedSfixed32 = new int[] { 123 };
1100     assertEquals(1, msg.repeatedSfixed32.length);
1101     byte [] result = MessageNano.toByteArray(msg);
1102     int msgSerializedSize = msg.getSerializedSize();
1103     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1104     assertTrue(msgSerializedSize == 9);
1105     assertEquals(result.length, msgSerializedSize);
1106     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1107     assertEquals(1, newMsg.repeatedSfixed32.length);
1108     assertEquals(123, newMsg.repeatedSfixed32[0]);
1109 
1110     // Test 2 entries
1111     msg.clear()
1112        .repeatedSfixed32 = new int[] { 123, 456 };
1113     assertEquals(2, msg.repeatedSfixed32.length);
1114     result = MessageNano.toByteArray(msg);
1115     msgSerializedSize = msg.getSerializedSize();
1116     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1117     assertTrue(msgSerializedSize == 15);
1118     assertEquals(result.length, msgSerializedSize);
1119 
1120     newMsg = TestAllTypesNano.parseFrom(result);
1121     assertEquals(2, newMsg.repeatedSfixed32.length);
1122     assertEquals(123, newMsg.repeatedSfixed32[0]);
1123     assertEquals(456, newMsg.repeatedSfixed32[1]);
1124   }
1125 
testNanoRepeatedSfixed64()1126   public void testNanoRepeatedSfixed64() throws Exception {
1127     TestAllTypesNano msg = new TestAllTypesNano();
1128     assertEquals(0, msg.repeatedSfixed64.length);
1129     msg.repeatedSfixed64 = new long[] { 123, 789, 456 };
1130     assertEquals(789, msg.repeatedSfixed64[1]);
1131     assertEquals(456, msg.repeatedSfixed64[2]);
1132     msg.clear();
1133     assertEquals(0, msg.repeatedSfixed64.length);
1134     msg.clear()
1135        .repeatedSfixed64 = new long[] { 456 };
1136     assertEquals(1, msg.repeatedSfixed64.length);
1137     assertEquals(456, msg.repeatedSfixed64[0]);
1138     msg.clear();
1139     assertEquals(0, msg.repeatedSfixed64.length);
1140 
1141     // Test 1 entry
1142     msg.clear()
1143        .repeatedSfixed64 = new long[] { 123 };
1144     assertEquals(1, msg.repeatedSfixed64.length);
1145     byte [] result = MessageNano.toByteArray(msg);
1146     int msgSerializedSize = msg.getSerializedSize();
1147     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1148     assertTrue(msgSerializedSize == 13);
1149     assertEquals(result.length, msgSerializedSize);
1150     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1151     assertEquals(1, newMsg.repeatedSfixed64.length);
1152     assertEquals(123, newMsg.repeatedSfixed64[0]);
1153 
1154     // Test 2 entries
1155     msg.clear()
1156        .repeatedSfixed64 = new long[] { 123, 456 };
1157     assertEquals(2, msg.repeatedSfixed64.length);
1158     result = MessageNano.toByteArray(msg);
1159     msgSerializedSize = msg.getSerializedSize();
1160     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1161     assertTrue(msgSerializedSize == 23);
1162     assertEquals(result.length, msgSerializedSize);
1163 
1164     newMsg = TestAllTypesNano.parseFrom(result);
1165     assertEquals(2, newMsg.repeatedSfixed64.length);
1166     assertEquals(123, newMsg.repeatedSfixed64[0]);
1167     assertEquals(456, newMsg.repeatedSfixed64[1]);
1168   }
1169 
testNanoRepeatedFloat()1170   public void testNanoRepeatedFloat() throws Exception {
1171     TestAllTypesNano msg = new TestAllTypesNano();
1172     assertEquals(0, msg.repeatedFloat.length);
1173     msg.repeatedFloat = new float[] { 123f, 789f, 456f };
1174     assertEquals(789f, msg.repeatedFloat[1]);
1175     assertEquals(456f, msg.repeatedFloat[2]);
1176     msg.clear();
1177     assertEquals(0, msg.repeatedFloat.length);
1178     msg.clear()
1179        .repeatedFloat = new float[] { 456f };
1180     assertEquals(1, msg.repeatedFloat.length);
1181     assertEquals(456f, msg.repeatedFloat[0]);
1182     msg.clear();
1183     assertEquals(0, msg.repeatedFloat.length);
1184 
1185     // Test 1 entry
1186     msg.clear()
1187        .repeatedFloat = new float[] { 123f };
1188     assertEquals(1, msg.repeatedFloat.length);
1189     byte [] result = MessageNano.toByteArray(msg);
1190     int msgSerializedSize = msg.getSerializedSize();
1191     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1192     assertTrue(msgSerializedSize == 9);
1193     assertEquals(result.length, msgSerializedSize);
1194     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1195     assertEquals(1, newMsg.repeatedFloat.length);
1196     assertEquals(123f, newMsg.repeatedFloat[0]);
1197 
1198     // Test 2 entries
1199     msg.clear()
1200        .repeatedFloat = new float[] { 123f, 456f };
1201     assertEquals(2, msg.repeatedFloat.length);
1202     result = MessageNano.toByteArray(msg);
1203     msgSerializedSize = msg.getSerializedSize();
1204     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1205     assertTrue(msgSerializedSize == 15);
1206     assertEquals(result.length, msgSerializedSize);
1207 
1208     newMsg = TestAllTypesNano.parseFrom(result);
1209     assertEquals(2, newMsg.repeatedFloat.length);
1210     assertEquals(123f, newMsg.repeatedFloat[0]);
1211     assertEquals(456f, newMsg.repeatedFloat[1]);
1212   }
1213 
testNanoRepeatedDouble()1214   public void testNanoRepeatedDouble() throws Exception {
1215     TestAllTypesNano msg = new TestAllTypesNano();
1216     assertEquals(0, msg.repeatedDouble.length);
1217     msg.repeatedDouble = new double[] { 123.0, 789.0, 456.0 };
1218     assertEquals(789.0, msg.repeatedDouble[1]);
1219     assertEquals(456.0, msg.repeatedDouble[2]);
1220     msg.clear();
1221     assertEquals(0, msg.repeatedDouble.length);
1222     msg.clear()
1223        .repeatedDouble = new double[] { 456.0 };
1224     assertEquals(1, msg.repeatedDouble.length);
1225     assertEquals(456.0, msg.repeatedDouble[0]);
1226     msg.clear();
1227     assertEquals(0, msg.repeatedDouble.length);
1228 
1229     // Test 1 entry
1230     msg.clear()
1231        .repeatedDouble = new double[] { 123.0 };
1232     assertEquals(1, msg.repeatedDouble.length);
1233     byte [] result = MessageNano.toByteArray(msg);
1234     int msgSerializedSize = msg.getSerializedSize();
1235     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1236     assertTrue(msgSerializedSize == 13);
1237     assertEquals(result.length, msgSerializedSize);
1238     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1239     assertEquals(1, newMsg.repeatedDouble.length);
1240     assertEquals(123.0, newMsg.repeatedDouble[0]);
1241 
1242     // Test 2 entries
1243     msg.clear()
1244        .repeatedDouble = new double[] { 123.0, 456.0 };
1245     assertEquals(2, msg.repeatedDouble.length);
1246     result = MessageNano.toByteArray(msg);
1247     msgSerializedSize = msg.getSerializedSize();
1248     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1249     assertTrue(msgSerializedSize == 23);
1250     assertEquals(result.length, msgSerializedSize);
1251 
1252     newMsg = TestAllTypesNano.parseFrom(result);
1253     assertEquals(2, newMsg.repeatedDouble.length);
1254     assertEquals(123.0, newMsg.repeatedDouble[0]);
1255     assertEquals(456.0, newMsg.repeatedDouble[1]);
1256   }
1257 
testNanoRepeatedBool()1258   public void testNanoRepeatedBool() throws Exception {
1259     TestAllTypesNano msg = new TestAllTypesNano();
1260     assertEquals(0, msg.repeatedBool.length);
1261     msg.repeatedBool = new boolean[] { false, true, false };
1262     assertTrue(msg.repeatedBool[1]);
1263     assertFalse(msg.repeatedBool[2]);
1264     msg.clear();
1265     assertEquals(0, msg.repeatedBool.length);
1266     msg.clear()
1267        .repeatedBool = new boolean[] { true };
1268     assertEquals(1, msg.repeatedBool.length);
1269     assertTrue(msg.repeatedBool[0]);
1270     msg.clear();
1271     assertEquals(0, msg.repeatedBool.length);
1272 
1273     // Test 1 entry
1274     msg.clear()
1275        .repeatedBool = new boolean[] { false };
1276     assertEquals(1, msg.repeatedBool.length);
1277     byte [] result = MessageNano.toByteArray(msg);
1278     int msgSerializedSize = msg.getSerializedSize();
1279     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1280     assertTrue(msgSerializedSize == 6);
1281     assertEquals(result.length, msgSerializedSize);
1282     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1283     assertEquals(1, newMsg.repeatedBool.length);
1284     assertFalse(newMsg.repeatedBool[0]);
1285 
1286     // Test 2 entries
1287     msg.clear()
1288        .repeatedBool = new boolean[] { true, false };
1289     assertEquals(2, msg.repeatedBool.length);
1290     result = MessageNano.toByteArray(msg);
1291     msgSerializedSize = msg.getSerializedSize();
1292     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1293     assertTrue(msgSerializedSize == 9);
1294     assertEquals(result.length, msgSerializedSize);
1295 
1296     newMsg = TestAllTypesNano.parseFrom(result);
1297     assertEquals(2, newMsg.repeatedBool.length);
1298     assertTrue(newMsg.repeatedBool[0]);
1299     assertFalse(newMsg.repeatedBool[1]);
1300   }
1301 
testNanoRepeatedString()1302   public void testNanoRepeatedString() throws Exception {
1303     TestAllTypesNano msg = new TestAllTypesNano();
1304     assertEquals(0, msg.repeatedString.length);
1305     msg.repeatedString = new String[] { "hello", "bye", "boo" };
1306     assertEquals("bye", msg.repeatedString[1]);
1307     assertEquals("boo", msg.repeatedString[2]);
1308     msg.clear();
1309     assertEquals(0, msg.repeatedString.length);
1310     msg.clear()
1311        .repeatedString = new String[] { "boo" };
1312     assertEquals(1, msg.repeatedString.length);
1313     assertEquals("boo", msg.repeatedString[0]);
1314     msg.clear();
1315     assertEquals(0, msg.repeatedString.length);
1316 
1317     // Test 1 entry
1318     msg.clear()
1319        .repeatedString = new String[] { "" };
1320     assertEquals(1, msg.repeatedString.length);
1321     byte [] result = MessageNano.toByteArray(msg);
1322     int msgSerializedSize = msg.getSerializedSize();
1323     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1324     assertTrue(msgSerializedSize == 6);
1325     assertEquals(result.length, msgSerializedSize);
1326     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1327     assertEquals(1, newMsg.repeatedString.length);
1328     assertTrue(newMsg.repeatedString[0].isEmpty());
1329 
1330     // Test 2 entries
1331     msg.clear()
1332        .repeatedString = new String[] { "hello", "world" };
1333     assertEquals(2, msg.repeatedString.length);
1334     result = MessageNano.toByteArray(msg);
1335     msgSerializedSize = msg.getSerializedSize();
1336     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1337     assertTrue(msgSerializedSize == 19);
1338     assertEquals(result.length, msgSerializedSize);
1339 
1340     newMsg = TestAllTypesNano.parseFrom(result);
1341     assertEquals(2, newMsg.repeatedString.length);
1342     assertEquals("hello", newMsg.repeatedString[0]);
1343     assertEquals("world", newMsg.repeatedString[1]);
1344   }
1345 
testNanoRepeatedBytes()1346   public void testNanoRepeatedBytes() throws Exception {
1347     TestAllTypesNano msg = new TestAllTypesNano();
1348     assertEquals(0, msg.repeatedBytes.length);
1349     msg.repeatedBytes = new byte[][] {
1350         InternalNano.copyFromUtf8("hello"),
1351         InternalNano.copyFromUtf8("bye"),
1352         InternalNano.copyFromUtf8("boo")
1353     };
1354     assertEquals("bye", new String(msg.repeatedBytes[1], InternalNano.UTF_8));
1355     assertEquals("boo", new String(msg.repeatedBytes[2], InternalNano.UTF_8));
1356     msg.clear();
1357     assertEquals(0, msg.repeatedBytes.length);
1358     msg.clear()
1359        .repeatedBytes = new byte[][] { InternalNano.copyFromUtf8("boo") };
1360     assertEquals(1, msg.repeatedBytes.length);
1361     assertEquals("boo", new String(msg.repeatedBytes[0], InternalNano.UTF_8));
1362     msg.clear();
1363     assertEquals(0, msg.repeatedBytes.length);
1364 
1365     // Test 1 entry
1366     msg.clear()
1367        .repeatedBytes = new byte[][] { InternalNano.copyFromUtf8("") };
1368     assertEquals(1, msg.repeatedBytes.length);
1369     byte [] result = MessageNano.toByteArray(msg);
1370     int msgSerializedSize = msg.getSerializedSize();
1371     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1372     assertTrue(msgSerializedSize == 6);
1373     assertEquals(result.length, msgSerializedSize);
1374     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1375     assertEquals(1, newMsg.repeatedBytes.length);
1376     assertTrue(newMsg.repeatedBytes[0].length == 0);
1377 
1378     // Test 2 entries
1379     msg.clear()
1380        .repeatedBytes = new byte[][] {
1381       InternalNano.copyFromUtf8("hello"),
1382       InternalNano.copyFromUtf8("world")
1383     };
1384     assertEquals(2, msg.repeatedBytes.length);
1385     result = MessageNano.toByteArray(msg);
1386     msgSerializedSize = msg.getSerializedSize();
1387     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1388     assertTrue(msgSerializedSize == 19);
1389     assertEquals(result.length, msgSerializedSize);
1390 
1391     newMsg = TestAllTypesNano.parseFrom(result);
1392     assertEquals(2, newMsg.repeatedBytes.length);
1393     assertEquals("hello", new String(newMsg.repeatedBytes[0], InternalNano.UTF_8));
1394     assertEquals("world", new String(newMsg.repeatedBytes[1], InternalNano.UTF_8));
1395   }
1396 
testNanoRepeatedGroup()1397   public void testNanoRepeatedGroup() throws Exception {
1398     TestAllTypesNano msg = new TestAllTypesNano();
1399     TestAllTypesNano.RepeatedGroup group0 =
1400       new TestAllTypesNano.RepeatedGroup();
1401     group0.a = 0;
1402     TestAllTypesNano.RepeatedGroup group1 =
1403       new TestAllTypesNano.RepeatedGroup();
1404     group1.a = 1;
1405     TestAllTypesNano.RepeatedGroup group2 =
1406       new TestAllTypesNano.RepeatedGroup();
1407     group2.a = 2;
1408 
1409     msg.repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0, group1, group2 };
1410     assertEquals(3, msg.repeatedGroup.length);
1411     assertEquals(0, msg.repeatedGroup[0].a);
1412     assertEquals(1, msg.repeatedGroup[1].a);
1413     assertEquals(2, msg.repeatedGroup[2].a);
1414     msg.clear();
1415     assertEquals(0, msg.repeatedGroup.length);
1416     msg.clear()
1417        .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group1 };
1418     assertEquals(1, msg.repeatedGroup.length);
1419     assertEquals(1, msg.repeatedGroup[0].a);
1420     msg.clear();
1421     assertEquals(0, msg.repeatedGroup.length);
1422 
1423     // Test 1 entry
1424     msg.clear()
1425        .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0 };
1426     assertEquals(1, msg.repeatedGroup.length);
1427     byte [] result = MessageNano.toByteArray(msg);
1428     int msgSerializedSize = msg.getSerializedSize();
1429     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1430     assertTrue(msgSerializedSize == 7);
1431     assertEquals(result.length, msgSerializedSize);
1432     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1433     assertEquals(1, newMsg.repeatedGroup.length);
1434     assertEquals(0, newMsg.repeatedGroup[0].a);
1435 
1436     // Test 2 entries
1437     msg.clear()
1438        .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0, group1 };
1439     assertEquals(2, msg.repeatedGroup.length);
1440     result = MessageNano.toByteArray(msg);
1441     msgSerializedSize = msg.getSerializedSize();
1442     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1443     assertTrue(msgSerializedSize == 14);
1444     assertEquals(result.length, msgSerializedSize);
1445 
1446     newMsg = TestAllTypesNano.parseFrom(result);
1447     assertEquals(2, newMsg.repeatedGroup.length);
1448     assertEquals(0, newMsg.repeatedGroup[0].a);
1449     assertEquals(1, newMsg.repeatedGroup[1].a);
1450   }
1451 
testNanoRepeatedNestedMessage()1452   public void testNanoRepeatedNestedMessage() throws Exception {
1453     TestAllTypesNano msg = new TestAllTypesNano();
1454     TestAllTypesNano.NestedMessage nestedMsg0 =
1455       new TestAllTypesNano.NestedMessage();
1456     nestedMsg0.bb = 0;
1457     TestAllTypesNano.NestedMessage nestedMsg1 =
1458       new TestAllTypesNano.NestedMessage();
1459     nestedMsg1.bb = 1;
1460     TestAllTypesNano.NestedMessage nestedMsg2 =
1461       new TestAllTypesNano.NestedMessage();
1462     nestedMsg2.bb = 2;
1463 
1464     msg.repeatedNestedMessage =
1465         new TestAllTypesNano.NestedMessage[] { nestedMsg0, nestedMsg1, nestedMsg2 };
1466     assertEquals(3, msg.repeatedNestedMessage.length);
1467     assertEquals(0, msg.repeatedNestedMessage[0].bb);
1468     assertEquals(1, msg.repeatedNestedMessage[1].bb);
1469     assertEquals(2, msg.repeatedNestedMessage[2].bb);
1470     msg.clear();
1471     assertEquals(0, msg.repeatedNestedMessage.length);
1472     msg.clear()
1473        .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg1 };
1474     assertEquals(1, msg.repeatedNestedMessage.length);
1475     assertEquals(1, msg.repeatedNestedMessage[0].bb);
1476     msg.clear();
1477     assertEquals(0, msg.repeatedNestedMessage.length);
1478 
1479     // Test 1 entry
1480     msg.clear()
1481        .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0 };
1482     assertEquals(1, msg.repeatedNestedMessage.length);
1483     byte [] result = MessageNano.toByteArray(msg);
1484     int msgSerializedSize = msg.getSerializedSize();
1485     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1486     assertTrue(msgSerializedSize == 6);
1487     assertEquals(result.length, msgSerializedSize);
1488     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1489     assertEquals(1, newMsg.repeatedNestedMessage.length);
1490     assertEquals(0, newMsg.repeatedNestedMessage[0].bb);
1491 
1492     // Test 2 entries
1493     msg.clear()
1494        .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0, nestedMsg1 };
1495     assertEquals(2, msg.repeatedNestedMessage.length);
1496     result = MessageNano.toByteArray(msg);
1497     msgSerializedSize = msg.getSerializedSize();
1498     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1499     assertTrue(msgSerializedSize == 11);
1500     assertEquals(result.length, msgSerializedSize);
1501 
1502     newMsg = TestAllTypesNano.parseFrom(result);
1503     assertEquals(2, newMsg.repeatedNestedMessage.length);
1504     assertEquals(0, newMsg.repeatedNestedMessage[0].bb);
1505     assertEquals(1, newMsg.repeatedNestedMessage[1].bb);
1506   }
1507 
testNanoRepeatedForeignMessage()1508   public void testNanoRepeatedForeignMessage() throws Exception {
1509     TestAllTypesNano msg = new TestAllTypesNano();
1510     NanoOuterClass.ForeignMessageNano foreignMsg0 =
1511       new NanoOuterClass.ForeignMessageNano();
1512     foreignMsg0.c = 0;
1513     NanoOuterClass.ForeignMessageNano foreignMsg1 =
1514       new NanoOuterClass.ForeignMessageNano();
1515     foreignMsg1.c = 1;
1516     NanoOuterClass.ForeignMessageNano foreignMsg2 =
1517       new NanoOuterClass.ForeignMessageNano();
1518     foreignMsg2.c = 2;
1519 
1520     msg.repeatedForeignMessage =
1521         new NanoOuterClass.ForeignMessageNano[] { foreignMsg0, foreignMsg1, foreignMsg2 };
1522     assertEquals(3, msg.repeatedForeignMessage.length);
1523     assertEquals(0, msg.repeatedForeignMessage[0].c);
1524     assertEquals(1, msg.repeatedForeignMessage[1].c);
1525     assertEquals(2, msg.repeatedForeignMessage[2].c);
1526     msg.clear();
1527     assertEquals(0, msg.repeatedForeignMessage.length);
1528     msg.clear()
1529        .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg1 };
1530     assertEquals(1, msg.repeatedForeignMessage.length);
1531     assertEquals(1, msg.repeatedForeignMessage[0].c);
1532     msg.clear();
1533     assertEquals(0, msg.repeatedForeignMessage.length);
1534 
1535     // Test 1 entry
1536     msg.clear()
1537        .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg0 };
1538     assertEquals(1, msg.repeatedForeignMessage.length);
1539     byte [] result = MessageNano.toByteArray(msg);
1540     int msgSerializedSize = msg.getSerializedSize();
1541     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1542     assertTrue(msgSerializedSize == 6);
1543     assertEquals(result.length, msgSerializedSize);
1544     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1545     assertEquals(1, newMsg.repeatedForeignMessage.length);
1546     assertEquals(0, newMsg.repeatedForeignMessage[0].c);
1547 
1548     // Test 2 entries
1549     msg.clear()
1550        .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg0, foreignMsg1 };
1551     assertEquals(2, msg.repeatedForeignMessage.length);
1552     result = MessageNano.toByteArray(msg);
1553     msgSerializedSize = msg.getSerializedSize();
1554     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1555     assertTrue(msgSerializedSize == 11);
1556     assertEquals(result.length, msgSerializedSize);
1557 
1558     newMsg = TestAllTypesNano.parseFrom(result);
1559     assertEquals(2, newMsg.repeatedForeignMessage.length);
1560     assertEquals(0, newMsg.repeatedForeignMessage[0].c);
1561     assertEquals(1, newMsg.repeatedForeignMessage[1].c);
1562   }
1563 
testNanoRepeatedImportMessage()1564   public void testNanoRepeatedImportMessage() throws Exception {
1565     TestAllTypesNano msg = new TestAllTypesNano();
1566     UnittestImportNano.ImportMessageNano foreignMsg0 =
1567       new UnittestImportNano.ImportMessageNano();
1568     foreignMsg0.d = 0;
1569     UnittestImportNano.ImportMessageNano foreignMsg1 =
1570       new UnittestImportNano.ImportMessageNano();
1571     foreignMsg1.d = 1;
1572     UnittestImportNano.ImportMessageNano foreignMsg2 =
1573       new UnittestImportNano.ImportMessageNano();
1574     foreignMsg2.d = 2;
1575 
1576     msg.repeatedImportMessage =
1577         new UnittestImportNano.ImportMessageNano[] { foreignMsg0, foreignMsg1, foreignMsg2 };
1578     assertEquals(3, msg.repeatedImportMessage.length);
1579     assertEquals(0, msg.repeatedImportMessage[0].d);
1580     assertEquals(1, msg.repeatedImportMessage[1].d);
1581     assertEquals(2, msg.repeatedImportMessage[2].d);
1582     msg.clear();
1583     assertEquals(0, msg.repeatedImportMessage.length);
1584     msg.clear()
1585        .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg1 };
1586     assertEquals(1, msg.repeatedImportMessage.length);
1587     assertEquals(1, msg.repeatedImportMessage[0].d);
1588     msg.clear();
1589     assertEquals(0, msg.repeatedImportMessage.length);
1590 
1591     // Test 1 entry
1592     msg.clear()
1593        .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg0 };
1594     assertEquals(1, msg.repeatedImportMessage.length);
1595     byte [] result = MessageNano.toByteArray(msg);
1596     int msgSerializedSize = msg.getSerializedSize();
1597     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1598     assertTrue(msgSerializedSize == 6);
1599     assertEquals(result.length, msgSerializedSize);
1600     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1601     assertEquals(1, newMsg.repeatedImportMessage.length);
1602     assertEquals(0, newMsg.repeatedImportMessage[0].d);
1603 
1604     // Test 2 entries
1605     msg.clear()
1606        .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg0, foreignMsg1 };
1607     assertEquals(2, msg.repeatedImportMessage.length);
1608     result = MessageNano.toByteArray(msg);
1609     msgSerializedSize = msg.getSerializedSize();
1610     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1611     assertTrue(msgSerializedSize == 11);
1612     assertEquals(result.length, msgSerializedSize);
1613 
1614     newMsg = TestAllTypesNano.parseFrom(result);
1615     assertEquals(2, newMsg.repeatedImportMessage.length);
1616     assertEquals(0, newMsg.repeatedImportMessage[0].d);
1617     assertEquals(1, newMsg.repeatedImportMessage[1].d);
1618   }
1619 
testNanoRepeatedNestedEnum()1620   public void testNanoRepeatedNestedEnum() throws Exception {
1621     TestAllTypesNano msg = new TestAllTypesNano();
1622     msg.repeatedNestedEnum = new int[] {
1623         TestAllTypesNano.FOO,
1624         TestAllTypesNano.BAR,
1625         TestAllTypesNano.BAZ
1626     };
1627     assertEquals(3, msg.repeatedNestedEnum.length);
1628     assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
1629     assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[1]);
1630     assertEquals(TestAllTypesNano.BAZ, msg.repeatedNestedEnum[2]);
1631     msg.clear();
1632     assertEquals(0, msg.repeatedNestedEnum.length);
1633     msg.clear()
1634        .repeatedNestedEnum = new int[] { TestAllTypesNano.BAR };
1635     assertEquals(1, msg.repeatedNestedEnum.length);
1636     assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[0]);
1637     msg.clear();
1638     assertEquals(0, msg.repeatedNestedEnum.length);
1639 
1640     // Test 1 entry
1641     msg.clear()
1642        .repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
1643     byte [] result = MessageNano.toByteArray(msg);
1644     int msgSerializedSize = msg.getSerializedSize();
1645     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1646     assertTrue(msgSerializedSize == 6);
1647     assertEquals(result.length, msgSerializedSize);
1648     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1649     assertEquals(1, newMsg.repeatedNestedEnum.length);
1650     assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
1651 
1652     // Test 2 entries
1653     msg.clear()
1654        .repeatedNestedEnum = new int[] { TestAllTypesNano.FOO, TestAllTypesNano.BAR };
1655     assertEquals(2, msg.repeatedNestedEnum.length);
1656     result = MessageNano.toByteArray(msg);
1657     msgSerializedSize = msg.getSerializedSize();
1658     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1659     assertTrue(msgSerializedSize == 9);
1660     assertEquals(result.length, msgSerializedSize);
1661 
1662     newMsg = TestAllTypesNano.parseFrom(result);
1663     assertEquals(2, newMsg.repeatedNestedEnum.length);
1664     assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
1665     assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[1]);
1666   }
1667 
testNanoRepeatedForeignEnum()1668   public void testNanoRepeatedForeignEnum() throws Exception {
1669     TestAllTypesNano msg = new TestAllTypesNano();
1670     msg.repeatedForeignEnum = new int[] {
1671         NanoOuterClass.FOREIGN_NANO_FOO,
1672         NanoOuterClass.FOREIGN_NANO_BAR,
1673         NanoOuterClass.FOREIGN_NANO_BAZ
1674     };
1675     assertEquals(3, msg.repeatedForeignEnum.length);
1676     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
1677     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[1]);
1678     assertEquals(NanoOuterClass.FOREIGN_NANO_BAZ, msg.repeatedForeignEnum[2]);
1679     msg.clear();
1680     assertEquals(0, msg.repeatedForeignEnum.length);
1681     msg.clear()
1682        .repeatedForeignEnum = new int[] { NanoOuterClass.FOREIGN_NANO_BAR };
1683     assertEquals(1, msg.repeatedForeignEnum.length);
1684     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[0]);
1685     msg.clear();
1686     assertEquals(0, msg.repeatedForeignEnum.length);
1687 
1688     // Test 1 entry
1689     msg.clear()
1690        .repeatedForeignEnum = new int[] { NanoOuterClass.FOREIGN_NANO_FOO };
1691     byte [] result = MessageNano.toByteArray(msg);
1692     int msgSerializedSize = msg.getSerializedSize();
1693     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1694     assertTrue(msgSerializedSize == 6);
1695     assertEquals(result.length, msgSerializedSize);
1696     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1697     assertEquals(1, newMsg.repeatedForeignEnum.length);
1698     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
1699 
1700     // Test 2 entries
1701     msg.clear()
1702        .repeatedForeignEnum = new int[] {
1703       NanoOuterClass.FOREIGN_NANO_FOO,
1704       NanoOuterClass.FOREIGN_NANO_BAR
1705     };
1706     assertEquals(2, msg.repeatedForeignEnum.length);
1707     result = MessageNano.toByteArray(msg);
1708     msgSerializedSize = msg.getSerializedSize();
1709     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1710     assertTrue(msgSerializedSize == 9);
1711     assertEquals(result.length, msgSerializedSize);
1712 
1713     newMsg = TestAllTypesNano.parseFrom(result);
1714     assertEquals(2, newMsg.repeatedForeignEnum.length);
1715     assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
1716     assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[1]);
1717   }
1718 
testNanoRepeatedImportEnum()1719   public void testNanoRepeatedImportEnum() throws Exception {
1720     TestAllTypesNano msg = new TestAllTypesNano();
1721     msg.repeatedImportEnum = new int[] {
1722         UnittestImportNano.IMPORT_NANO_FOO,
1723         UnittestImportNano.IMPORT_NANO_BAR,
1724         UnittestImportNano.IMPORT_NANO_BAZ
1725     };
1726     assertEquals(3, msg.repeatedImportEnum.length);
1727     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
1728     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[1]);
1729     assertEquals(UnittestImportNano.IMPORT_NANO_BAZ, msg.repeatedImportEnum[2]);
1730     msg.clear();
1731     assertEquals(0, msg.repeatedImportEnum.length);
1732     msg.clear()
1733        .repeatedImportEnum = new int[] { UnittestImportNano.IMPORT_NANO_BAR };
1734     assertEquals(1, msg.repeatedImportEnum.length);
1735     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[0]);
1736     msg.clear();
1737     assertEquals(0, msg.repeatedImportEnum.length);
1738 
1739     // Test 1 entry
1740     msg.clear()
1741        .repeatedImportEnum = new int[] { UnittestImportNano.IMPORT_NANO_FOO };
1742     byte [] result = MessageNano.toByteArray(msg);
1743     int msgSerializedSize = msg.getSerializedSize();
1744     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1745     assertTrue(msgSerializedSize == 6);
1746     assertEquals(result.length, msgSerializedSize);
1747     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1748     assertEquals(1, newMsg.repeatedImportEnum.length);
1749     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
1750 
1751     // Test 2 entries
1752     msg.clear()
1753        .repeatedImportEnum = new int[] {
1754       UnittestImportNano.IMPORT_NANO_FOO,
1755       UnittestImportNano.IMPORT_NANO_BAR
1756     };
1757     assertEquals(2, msg.repeatedImportEnum.length);
1758     result = MessageNano.toByteArray(msg);
1759     msgSerializedSize = msg.getSerializedSize();
1760     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1761     assertTrue(msgSerializedSize == 9);
1762     assertEquals(result.length, msgSerializedSize);
1763 
1764     newMsg = TestAllTypesNano.parseFrom(result);
1765     assertEquals(2, newMsg.repeatedImportEnum.length);
1766     assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
1767     assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[1]);
1768   }
1769 
testNanoRepeatedStringPiece()1770   public void testNanoRepeatedStringPiece() throws Exception {
1771     TestAllTypesNano msg = new TestAllTypesNano();
1772     assertEquals(0, msg.repeatedStringPiece.length);
1773     msg.repeatedStringPiece = new String[] { "hello", "bye", "boo" };
1774     assertEquals("bye", msg.repeatedStringPiece[1]);
1775     assertEquals("boo", msg.repeatedStringPiece[2]);
1776     msg.clear();
1777     assertEquals(0, msg.repeatedStringPiece.length);
1778     msg.clear()
1779        .repeatedStringPiece = new String[] { "boo" };
1780     assertEquals(1, msg.repeatedStringPiece.length);
1781     assertEquals("boo", msg.repeatedStringPiece[0]);
1782     msg.clear();
1783     assertEquals(0, msg.repeatedStringPiece.length);
1784 
1785     // Test 1 entry
1786     msg.clear()
1787        .repeatedStringPiece = new String[] { "" };
1788     assertEquals(1, msg.repeatedStringPiece.length);
1789     byte [] result = MessageNano.toByteArray(msg);
1790     int msgSerializedSize = msg.getSerializedSize();
1791     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1792     assertTrue(msgSerializedSize == 6);
1793     assertEquals(result.length, msgSerializedSize);
1794     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1795     assertEquals(1, newMsg.repeatedStringPiece.length);
1796     assertTrue(newMsg.repeatedStringPiece[0].isEmpty());
1797 
1798     // Test 2 entries
1799     msg.clear()
1800        .repeatedStringPiece = new String[] { "hello", "world" };
1801     assertEquals(2, msg.repeatedStringPiece.length);
1802     result = MessageNano.toByteArray(msg);
1803     msgSerializedSize = msg.getSerializedSize();
1804     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1805     assertTrue(msgSerializedSize == 19);
1806     assertEquals(result.length, msgSerializedSize);
1807 
1808     newMsg = TestAllTypesNano.parseFrom(result);
1809     assertEquals(2, newMsg.repeatedStringPiece.length);
1810     assertEquals("hello", newMsg.repeatedStringPiece[0]);
1811     assertEquals("world", newMsg.repeatedStringPiece[1]);
1812   }
1813 
testNanoRepeatedCord()1814   public void testNanoRepeatedCord() throws Exception {
1815     TestAllTypesNano msg = new TestAllTypesNano();
1816     assertEquals(0, msg.repeatedCord.length);
1817     msg.repeatedCord = new String[] { "hello", "bye", "boo" };
1818     assertEquals("bye", msg.repeatedCord[1]);
1819     assertEquals("boo", msg.repeatedCord[2]);
1820     msg.clear();
1821     assertEquals(0, msg.repeatedCord.length);
1822     msg.clear()
1823        .repeatedCord = new String[] { "boo" };
1824     assertEquals(1, msg.repeatedCord.length);
1825     assertEquals("boo", msg.repeatedCord[0]);
1826     msg.clear();
1827     assertEquals(0, msg.repeatedCord.length);
1828 
1829     // Test 1 entry
1830     msg.clear()
1831        .repeatedCord = new String[] { "" };
1832     assertEquals(1, msg.repeatedCord.length);
1833     byte [] result = MessageNano.toByteArray(msg);
1834     int msgSerializedSize = msg.getSerializedSize();
1835     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1836     assertTrue(msgSerializedSize == 6);
1837     assertEquals(result.length, msgSerializedSize);
1838     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1839     assertEquals(1, newMsg.repeatedCord.length);
1840     assertTrue(newMsg.repeatedCord[0].isEmpty());
1841 
1842     // Test 2 entries
1843     msg.clear()
1844        .repeatedCord = new String[] { "hello", "world" };
1845     assertEquals(2, msg.repeatedCord.length);
1846     result = MessageNano.toByteArray(msg);
1847     msgSerializedSize = msg.getSerializedSize();
1848     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1849     assertTrue(msgSerializedSize == 19);
1850     assertEquals(result.length, msgSerializedSize);
1851 
1852     newMsg = TestAllTypesNano.parseFrom(result);
1853     assertEquals(2, newMsg.repeatedCord.length);
1854     assertEquals("hello", newMsg.repeatedCord[0]);
1855     assertEquals("world", newMsg.repeatedCord[1]);
1856   }
1857 
testNanoRepeatedPackedInt32()1858   public void testNanoRepeatedPackedInt32() throws Exception {
1859     TestAllTypesNano msg = new TestAllTypesNano();
1860     assertEquals(0, msg.repeatedPackedInt32.length);
1861     msg.repeatedPackedInt32 = new int[] { 123, 789, 456 };
1862     assertEquals(789, msg.repeatedPackedInt32[1]);
1863     assertEquals(456, msg.repeatedPackedInt32[2]);
1864     msg.clear();
1865     assertEquals(0, msg.repeatedPackedInt32.length);
1866     msg.clear()
1867        .repeatedPackedInt32 = new int[] { 456 };
1868     assertEquals(1, msg.repeatedPackedInt32.length);
1869     assertEquals(456, msg.repeatedPackedInt32[0]);
1870     msg.clear();
1871     assertEquals(0, msg.repeatedPackedInt32.length);
1872 
1873     // Test 1 entry
1874     msg.clear()
1875        .repeatedPackedInt32 = new int[] { 123 };
1876     assertEquals(1, msg.repeatedPackedInt32.length);
1877     byte [] result = MessageNano.toByteArray(msg);
1878     int msgSerializedSize = msg.getSerializedSize();
1879     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1880     assertTrue(msgSerializedSize == 7);
1881     assertEquals(result.length, msgSerializedSize);
1882     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1883     assertEquals(1, newMsg.repeatedPackedInt32.length);
1884     assertEquals(123, newMsg.repeatedPackedInt32[0]);
1885 
1886     // Test 2 entries
1887     msg.clear()
1888        .repeatedPackedInt32 = new int[] { 123, 456 };
1889     assertEquals(2, msg.repeatedPackedInt32.length);
1890     result = MessageNano.toByteArray(msg);
1891     msgSerializedSize = msg.getSerializedSize();
1892     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1893     assertTrue(msgSerializedSize == 9);
1894     assertEquals(result.length, msgSerializedSize);
1895 
1896     newMsg = TestAllTypesNano.parseFrom(result);
1897     assertEquals(2, newMsg.repeatedPackedInt32.length);
1898     assertEquals(123, newMsg.repeatedPackedInt32[0]);
1899     assertEquals(456, newMsg.repeatedPackedInt32[1]);
1900   }
1901 
testNanoRepeatedPackedSfixed64()1902   public void testNanoRepeatedPackedSfixed64() throws Exception {
1903     TestAllTypesNano msg = new TestAllTypesNano();
1904     assertEquals(0, msg.repeatedPackedSfixed64.length);
1905     msg.repeatedPackedSfixed64 = new long[] { 123, 789, 456 };
1906     assertEquals(789, msg.repeatedPackedSfixed64[1]);
1907     assertEquals(456, msg.repeatedPackedSfixed64[2]);
1908     msg.clear();
1909     assertEquals(0, msg.repeatedPackedSfixed64.length);
1910     msg.clear()
1911        .repeatedPackedSfixed64 = new long[] { 456 };
1912     assertEquals(1, msg.repeatedPackedSfixed64.length);
1913     assertEquals(456, msg.repeatedPackedSfixed64[0]);
1914     msg.clear();
1915     assertEquals(0, msg.repeatedPackedSfixed64.length);
1916 
1917     // Test 1 entry
1918     msg.clear()
1919        .repeatedPackedSfixed64 = new long[] { 123 };
1920     assertEquals(1, msg.repeatedPackedSfixed64.length);
1921     byte [] result = MessageNano.toByteArray(msg);
1922     int msgSerializedSize = msg.getSerializedSize();
1923     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1924     assertTrue(msgSerializedSize == 14);
1925     assertEquals(result.length, msgSerializedSize);
1926     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1927     assertEquals(1, newMsg.repeatedPackedSfixed64.length);
1928     assertEquals(123, newMsg.repeatedPackedSfixed64[0]);
1929 
1930     // Test 2 entries
1931     msg.clear()
1932        .repeatedPackedSfixed64 = new long[] { 123, 456 };
1933     assertEquals(2, msg.repeatedPackedSfixed64.length);
1934     result = MessageNano.toByteArray(msg);
1935     msgSerializedSize = msg.getSerializedSize();
1936     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1937     assertTrue(msgSerializedSize == 22);
1938     assertEquals(result.length, msgSerializedSize);
1939 
1940     newMsg = TestAllTypesNano.parseFrom(result);
1941     assertEquals(2, newMsg.repeatedPackedSfixed64.length);
1942     assertEquals(123, newMsg.repeatedPackedSfixed64[0]);
1943     assertEquals(456, newMsg.repeatedPackedSfixed64[1]);
1944   }
1945 
testNanoRepeatedPackedNestedEnum()1946   public void testNanoRepeatedPackedNestedEnum() throws Exception {
1947     TestAllTypesNano msg = new TestAllTypesNano();
1948     msg.repeatedPackedNestedEnum = new int[] {
1949         TestAllTypesNano.FOO,
1950         TestAllTypesNano.BAR,
1951         TestAllTypesNano.BAZ
1952     };
1953     assertEquals(3, msg.repeatedPackedNestedEnum.length);
1954     assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
1955     assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[1]);
1956     assertEquals(TestAllTypesNano.BAZ, msg.repeatedPackedNestedEnum[2]);
1957     msg.clear();
1958     assertEquals(0, msg.repeatedPackedNestedEnum.length);
1959     msg.clear()
1960        .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.BAR };
1961     assertEquals(1, msg.repeatedPackedNestedEnum.length);
1962     assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[0]);
1963     msg.clear();
1964     assertEquals(0, msg.repeatedPackedNestedEnum.length);
1965 
1966     // Test 1 entry
1967     msg.clear()
1968        .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.FOO };
1969     byte [] result = MessageNano.toByteArray(msg);
1970     int msgSerializedSize = msg.getSerializedSize();
1971     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1972     assertTrue(msgSerializedSize == 7);
1973     assertEquals(result.length, msgSerializedSize);
1974     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
1975     assertEquals(1, newMsg.repeatedPackedNestedEnum.length);
1976     assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
1977 
1978     // Test 2 entries
1979     msg.clear()
1980        .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.FOO, TestAllTypesNano.BAR };
1981     assertEquals(2, msg.repeatedPackedNestedEnum.length);
1982     result = MessageNano.toByteArray(msg);
1983     msgSerializedSize = msg.getSerializedSize();
1984     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
1985     assertTrue(msgSerializedSize == 8);
1986     assertEquals(result.length, msgSerializedSize);
1987 
1988     newMsg = TestAllTypesNano.parseFrom(result);
1989     assertEquals(2, newMsg.repeatedPackedNestedEnum.length);
1990     assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
1991     assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[1]);
1992   }
1993 
testNanoRepeatedPackedSerializedSize()1994   public void testNanoRepeatedPackedSerializedSize() throws Exception {
1995     TestAllTypesNano msg = new TestAllTypesNano();
1996     msg.repeatedPackedInt32 = new int[] { 123, 789, 456 };
1997     int msgSerializedSize = msg.getSerializedSize();
1998     byte [] result = MessageNano.toByteArray(msg);
1999     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
2000     assertTrue(msgSerializedSize == 11);
2001     assertEquals(result.length, msgSerializedSize);
2002     TestAllTypesNano msg2 = new TestAllTypesNano();
2003     msg2.repeatedPackedInt32 = new int[] { 123, 789, 456 };
2004     byte [] result2 = new byte[msgSerializedSize];
2005     MessageNano.toByteArray(msg2, result2, 0, msgSerializedSize);
2006 
2007     // Check equal size and content.
2008     assertEquals(msgSerializedSize, msg2.getSerializedSize());
2009     assertTrue(Arrays.equals(result, result2));
2010   }
2011 
testNanoRepeatedInt32ReMerge()2012   public void testNanoRepeatedInt32ReMerge() throws Exception {
2013     TestAllTypesNano msg = new TestAllTypesNano();
2014     msg.repeatedInt32 = new int[] { 234 };
2015     byte [] result1 = MessageNano.toByteArray(msg);
2016 
2017     msg.clear().optionalInt32 = 789;
2018     byte [] result2 = MessageNano.toByteArray(msg);
2019 
2020     msg.clear().repeatedInt32 = new int[] { 123, 456 };
2021     byte [] result3 = MessageNano.toByteArray(msg);
2022 
2023     // Concatenate the three serializations and read as one message.
2024     byte [] result = new byte[result1.length + result2.length + result3.length];
2025     System.arraycopy(result1, 0, result, 0, result1.length);
2026     System.arraycopy(result2, 0, result, result1.length, result2.length);
2027     System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
2028 
2029     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
2030     assertEquals(789, newMsg.optionalInt32);
2031     assertEquals(3, newMsg.repeatedInt32.length);
2032     assertEquals(234, newMsg.repeatedInt32[0]);
2033     assertEquals(123, newMsg.repeatedInt32[1]);
2034     assertEquals(456, newMsg.repeatedInt32[2]);
2035   }
2036 
testNanoRepeatedNestedEnumReMerge()2037   public void testNanoRepeatedNestedEnumReMerge() throws Exception {
2038     TestAllTypesNano msg = new TestAllTypesNano();
2039     msg.repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
2040     byte [] result1 = MessageNano.toByteArray(msg);
2041 
2042     msg.clear().optionalInt32 = 789;
2043     byte [] result2 = MessageNano.toByteArray(msg);
2044 
2045     msg.clear().repeatedNestedEnum = new int[] { TestAllTypesNano.BAR, TestAllTypesNano.FOO };
2046     byte [] result3 = MessageNano.toByteArray(msg);
2047 
2048     // Concatenate the three serializations and read as one message.
2049     byte [] result = new byte[result1.length + result2.length + result3.length];
2050     System.arraycopy(result1, 0, result, 0, result1.length);
2051     System.arraycopy(result2, 0, result, result1.length, result2.length);
2052     System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
2053 
2054     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
2055     assertEquals(789, newMsg.optionalInt32);
2056     assertEquals(3, newMsg.repeatedNestedEnum.length);
2057     assertEquals(TestAllTypesNano.FOO, newMsg.repeatedNestedEnum[0]);
2058     assertEquals(TestAllTypesNano.BAR, newMsg.repeatedNestedEnum[1]);
2059     assertEquals(TestAllTypesNano.FOO, newMsg.repeatedNestedEnum[2]);
2060   }
2061 
testNanoRepeatedNestedMessageReMerge()2062   public void testNanoRepeatedNestedMessageReMerge() throws Exception {
2063     TestAllTypesNano msg = new TestAllTypesNano();
2064     TestAllTypesNano.NestedMessage nestedMsg0 =
2065       new TestAllTypesNano.NestedMessage();
2066     nestedMsg0.bb = 0;
2067     TestAllTypesNano.NestedMessage nestedMsg1 =
2068       new TestAllTypesNano.NestedMessage();
2069     nestedMsg1.bb = 1;
2070     TestAllTypesNano.NestedMessage nestedMsg2 =
2071       new TestAllTypesNano.NestedMessage();
2072     nestedMsg2.bb = 2;
2073 
2074     msg.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0 };
2075     byte [] result1 = MessageNano.toByteArray(msg);
2076 
2077     msg.clear().optionalInt32 = 789;
2078     byte [] result2 = MessageNano.toByteArray(msg);
2079 
2080     msg.clear().repeatedNestedMessage =
2081         new TestAllTypesNano.NestedMessage[] { nestedMsg1, nestedMsg2 };
2082     byte [] result3 = MessageNano.toByteArray(msg);
2083 
2084     // Concatenate the three serializations and read as one message.
2085     byte [] result = new byte[result1.length + result2.length + result3.length];
2086     System.arraycopy(result1, 0, result, 0, result1.length);
2087     System.arraycopy(result2, 0, result, result1.length, result2.length);
2088     System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
2089 
2090     TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
2091     assertEquals(789, newMsg.optionalInt32);
2092     assertEquals(3, newMsg.repeatedNestedMessage.length);
2093     assertEquals(nestedMsg0.bb, newMsg.repeatedNestedMessage[0].bb);
2094     assertEquals(nestedMsg1.bb, newMsg.repeatedNestedMessage[1].bb);
2095     assertEquals(nestedMsg2.bb, newMsg.repeatedNestedMessage[2].bb);
2096   }
2097 
2098   /**
2099    * Tests that invalid enum values from the wire are not accepted.
2100    */
testNanoEnumValidity()2101   public void testNanoEnumValidity() throws Exception {
2102     final int invalid = 120;
2103     final int alsoInvalid = 121;
2104 
2105     EnumValidity.M m = new EnumValidity.M();
2106     // Sanity check & baseline of the assertions for the first case below.
2107     assertEquals(EnumValidity.E.default_, m.optionalE);
2108     assertEquals(EnumValidity.E.BAZ, m.defaultE);
2109 
2110     m.optionalE = invalid;
2111     m.defaultE = invalid;
2112     // E contains all valid values
2113     m.repeatedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR};
2114     m.packedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ};
2115     // E2 contains some invalid values
2116     m.repeatedE2 = new int[] {invalid, EnumValidity.E.BAR, alsoInvalid};
2117     m.packedE2 = new int[] {EnumValidity.E.FOO, invalid, alsoInvalid};
2118     // E3 contains all invalid values
2119     m.repeatedE3 = new int[] {invalid, invalid};
2120     m.packedE3 = new int[] {alsoInvalid, alsoInvalid};
2121     byte[] serialized = MessageNano.toByteArray(m);
2122     // Sanity check that we do have all data in the byte array.
2123     assertEquals(31, serialized.length);
2124 
2125     // Test 1: tests that invalid values aren't included in the deserialized message.
2126     EnumValidity.M deserialized = MessageNano.mergeFrom(new EnumValidity.M(), serialized);
2127     assertEquals(EnumValidity.E.default_, deserialized.optionalE);
2128     assertEquals(EnumValidity.E.BAZ, deserialized.defaultE);
2129     assertTrue(Arrays.equals(
2130         new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR}, deserialized.repeatedE));
2131     assertTrue(Arrays.equals(
2132         new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ}, deserialized.packedE));
2133     assertTrue(Arrays.equals(
2134         new int[] {EnumValidity.E.BAR}, deserialized.repeatedE2));
2135     assertTrue(Arrays.equals(
2136         new int[] {EnumValidity.E.FOO}, deserialized.packedE2));
2137     assertEquals(0, deserialized.repeatedE3.length);
2138     assertEquals(0, deserialized.packedE3.length);
2139 
2140     // Test 2: tests that invalid values do not override previous values in the field, including
2141     // arrays, including pre-existing invalid values.
2142     deserialized.optionalE = EnumValidity.E.BAR;
2143     deserialized.defaultE = alsoInvalid;
2144     deserialized.repeatedE = new int[] {EnumValidity.E.BAZ};
2145     deserialized.packedE = new int[] {EnumValidity.E.BAZ, alsoInvalid};
2146     deserialized.repeatedE2 = new int[] {invalid, alsoInvalid};
2147     deserialized.packedE2 = null;
2148     deserialized.repeatedE3 = null;
2149     deserialized.packedE3 = new int[0];
2150     MessageNano.mergeFrom(deserialized, serialized);
2151     assertEquals(EnumValidity.E.BAR, deserialized.optionalE);
2152     assertEquals(alsoInvalid, deserialized.defaultE);
2153     assertTrue(Arrays.equals(
2154         new int[] {EnumValidity.E.BAZ, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAR},
2155         deserialized.repeatedE));
2156     assertTrue(Arrays.equals(
2157         new int[] {EnumValidity.E.BAZ, alsoInvalid, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAZ},
2158         deserialized.packedE));
2159     assertTrue(Arrays.equals(
2160         new int[] {invalid, alsoInvalid, /* + */ EnumValidity.E.BAR},
2161         deserialized.repeatedE2));
2162     assertTrue(Arrays.equals(
2163         new int[] {/* <null> + */ EnumValidity.E.FOO},
2164         deserialized.packedE2));
2165     assertNull(deserialized.repeatedE3); // null + all invalid == null
2166     assertEquals(0, deserialized.packedE3.length); // empty + all invalid == empty
2167 
2168     // Test 3: reading by alternative forms
2169     EnumValidity.Alt alt = MessageNano.mergeFrom(new EnumValidity.Alt(), serialized);
2170     assertEquals(EnumValidity.E.BAR, // last valid value in m.repeatedE2
2171         alt.repeatedE2AsOptional);
2172     assertTrue(Arrays.equals(new int[] {EnumValidity.E.FOO}, alt.packedE2AsNonPacked));
2173     assertEquals(0, alt.nonPackedE3AsPacked.length);
2174   }
2175 
2176   /**
2177    * Tests the same as {@link #testNanoEnumValidity()} with accessor style. Repeated fields are
2178    * not re-tested here because they are not affected by the accessor style.
2179    */
testNanoEnumValidityAccessors()2180   public void testNanoEnumValidityAccessors() throws Exception {
2181     final int invalid = 120;
2182     final int alsoInvalid = 121;
2183 
2184     EnumValidityAccessors.M m = new EnumValidityAccessors.M();
2185     // Sanity check & baseline of the assertions for the first case below.
2186     assertEquals(EnumValidityAccessors.default_, m.getOptionalE());
2187     assertEquals(EnumValidityAccessors.BAZ, m.getDefaultE());
2188 
2189     m.setOptionalE(invalid);
2190     m.setDefaultE(invalid);
2191     // Set repeatedE2 for Alt.repeatedE2AsOptional
2192     m.repeatedE2 = new int[] {invalid, EnumValidityAccessors.BAR, alsoInvalid};
2193     byte[] serialized = MessageNano.toByteArray(m);
2194     // Sanity check that we do have all data in the byte array.
2195     assertEquals(10, serialized.length);
2196 
2197     // Test 1: tests that invalid values aren't included in the deserialized message.
2198     EnumValidityAccessors.M deserialized =
2199         MessageNano.mergeFrom(new EnumValidityAccessors.M(), serialized);
2200     assertEquals(EnumValidityAccessors.default_, deserialized.getOptionalE());
2201     assertEquals(EnumValidityAccessors.BAZ, deserialized.getDefaultE());
2202 
2203     // Test 2: tests that invalid values do not override previous values in the field, including
2204     // pre-existing invalid values.
2205     deserialized.setOptionalE(EnumValidityAccessors.BAR);
2206     deserialized.setDefaultE(alsoInvalid);
2207     MessageNano.mergeFrom(deserialized, serialized);
2208     assertEquals(EnumValidityAccessors.BAR, deserialized.getOptionalE());
2209     assertEquals(alsoInvalid, deserialized.getDefaultE());
2210 
2211     // Test 3: reading by alternative forms
2212     EnumValidityAccessors.Alt alt =
2213         MessageNano.mergeFrom(new EnumValidityAccessors.Alt(), serialized);
2214     assertEquals(EnumValidityAccessors.BAR, // last valid value in m.repeatedE2
2215         alt.getRepeatedE2AsOptional());
2216   }
2217 
2218   /**
2219    * Tests that code generation correctly wraps a single message into its outer
2220    * class. The class {@code SingleMessageNano} is imported from the outer
2221    * class {@code UnittestSingleNano}, whose name is implicit. Any error would
2222    * cause this method to fail compilation.
2223    */
testNanoSingle()2224   public void testNanoSingle() throws Exception {
2225     SingleMessageNano msg = new SingleMessageNano();
2226     assertNotNull(msg);
2227   }
2228 
2229   /**
2230    * Tests that code generation correctly skips generating the outer class if
2231    * unnecessary, letting a file-scope entity have the same name. The class
2232    * {@code MultipleNameClashNano} shares the same name with the file's outer
2233    * class defined explicitly, but the file contains no other entities and has
2234    * java_multiple_files set. Any error would cause this method to fail
2235    * compilation.
2236    */
testNanoMultipleNameClash()2237   public void testNanoMultipleNameClash() throws Exception {
2238     MultipleNameClashNano msg = new MultipleNameClashNano();
2239     msg.field = 0;
2240   }
2241 
2242   /**
2243    * Tests that code generation correctly handles enums in different scopes in
2244    * a source file with the option java_multiple_files set to true. Any error
2245    * would cause this method to fail compilation.
2246    */
testNanoMultipleEnumScoping()2247   public void testNanoMultipleEnumScoping() throws Exception {
2248     FileScopeEnumRefNano msg1 = new FileScopeEnumRefNano();
2249     msg1.enumField = UnittestMultipleNano.ONE;
2250     MessageScopeEnumRefNano msg2 = new MessageScopeEnumRefNano();
2251     msg2.enumField = MessageScopeEnumRefNano.TWO;
2252   }
2253 
2254   /**
2255    * Tests that code generation with mixed values of the java_multiple_files
2256    * options between the main source file and the imported source files would
2257    * generate correct references. Any error would cause this method to fail
2258    * compilation.
2259    */
testNanoMultipleImportingNonMultiple()2260   public void testNanoMultipleImportingNonMultiple() throws Exception {
2261     UnittestImportNano.ImportMessageNano importMsg = new UnittestImportNano.ImportMessageNano();
2262     MultipleImportingNonMultipleNano1 nano1 = new MultipleImportingNonMultipleNano1();
2263     nano1.field = importMsg;
2264     MultipleImportingNonMultipleNano2 nano2 = new MultipleImportingNonMultipleNano2();
2265     nano2.nano1 = nano1;
2266   }
2267 
testNanoDefaults()2268   public void testNanoDefaults() throws Exception {
2269     TestAllTypesNano msg = new TestAllTypesNano();
2270     for (int i = 0; i < 2; i++) {
2271       assertEquals(41, msg.defaultInt32);
2272       assertEquals(42, msg.defaultInt64);
2273       assertEquals(43, msg.defaultUint32);
2274       assertEquals(44, msg.defaultUint64);
2275       assertEquals(-45, msg.defaultSint32);
2276       assertEquals(46, msg.defaultSint64);
2277       assertEquals(47, msg.defaultFixed32);
2278       assertEquals(48, msg.defaultFixed64);
2279       assertEquals(49, msg.defaultSfixed32);
2280       assertEquals(-50, msg.defaultSfixed64);
2281       assertTrue(51.5f == msg.defaultFloat);
2282       assertTrue(52.0e3 == msg.defaultDouble);
2283       assertEquals(true, msg.defaultBool);
2284       assertEquals("hello", msg.defaultString);
2285       assertEquals("world", new String(msg.defaultBytes, InternalNano.UTF_8));
2286       assertEquals("dünya", msg.defaultStringNonascii);
2287       assertEquals("dünyab", new String(msg.defaultBytesNonascii, InternalNano.UTF_8));
2288       assertEquals(TestAllTypesNano.BAR, msg.defaultNestedEnum);
2289       assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.defaultForeignEnum);
2290       assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.defaultImportEnum);
2291       assertEquals(Float.POSITIVE_INFINITY, msg.defaultFloatInf);
2292       assertEquals(Float.NEGATIVE_INFINITY, msg.defaultFloatNegInf);
2293       assertEquals(Float.NaN, msg.defaultFloatNan);
2294       assertEquals(Double.POSITIVE_INFINITY, msg.defaultDoubleInf);
2295       assertEquals(Double.NEGATIVE_INFINITY, msg.defaultDoubleNegInf);
2296       assertEquals(Double.NaN, msg.defaultDoubleNan);
2297 
2298       // Default values are not output, except for required fields.
2299       byte [] result = MessageNano.toByteArray(msg);
2300       int msgSerializedSize = msg.getSerializedSize();
2301       //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
2302       assertTrue(msgSerializedSize == 3);
2303       assertEquals(result.length, msgSerializedSize);
2304       msg.clear();
2305     }
2306   }
2307 
testDifferentStringLengthsNano()2308   public void testDifferentStringLengthsNano() throws Exception {
2309     // Test string serialization roundtrip using strings of the following lengths,
2310     // with ASCII and Unicode characters requiring different UTF-8 byte counts per
2311     // char, hence causing the length delimiter varint to sometimes require more
2312     // bytes for the Unicode strings than the ASCII string of the same length.
2313     int[] lengths = new int[] {
2314             0,
2315             1,
2316             (1 << 4) - 1,  // 1 byte for ASCII and Unicode
2317             (1 << 7) - 1,  // 1 byte for ASCII, 2 bytes for Unicode
2318             (1 << 11) - 1, // 2 bytes for ASCII and Unicode
2319             (1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
2320             (1 << 17) - 1, // 3 bytes for ASCII and Unicode
2321     };
2322     for (int i : lengths) {
2323       testEncodingOfString('q', i);      // 1 byte per char
2324       testEncodingOfString('\u07FF', i); // 2 bytes per char
2325       testEncodingOfString('\u0981', i); // 3 bytes per char
2326     }
2327   }
2328 
2329   /** Regression test for https://github.com/google/protobuf/issues/292 */
testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace()2330   public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
2331     String testCase = "Foooooooo";
2332     assertEquals(CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length()),
2333             CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length() * 3));
2334     assertEquals(11, CodedOutputByteBufferNano.computeStringSize(1, testCase));
2335     // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
2336     // An array of size 1 will cause a failure when trying to write the varint.
2337     for (int i = 0; i < 11; i++) {
2338       CodedOutputByteBufferNano bufferNano = CodedOutputByteBufferNano.newInstance(new byte[i]);
2339       try {
2340         bufferNano.writeString(1, testCase);
2341         fail("Should have thrown an out of space exception");
2342       } catch (CodedOutputByteBufferNano.OutOfSpaceException expected) {}
2343     }
2344   }
2345 
testEncodingOfString(char c, int length)2346   private void testEncodingOfString(char c, int length) throws InvalidProtocolBufferNanoException {
2347     TestAllTypesNano testAllTypesNano = new TestAllTypesNano();
2348     final String fullString = fullString(c, length);
2349     testAllTypesNano.optionalString = fullString;
2350     final TestAllTypesNano resultNano = new TestAllTypesNano();
2351     MessageNano.mergeFrom(resultNano, MessageNano.toByteArray(testAllTypesNano));
2352     assertEquals(fullString, resultNano.optionalString);
2353   }
2354 
fullString(char c, int length)2355   private String fullString(char c, int length) {
2356     char[] result = new char[length];
2357     Arrays.fill(result, c);
2358     return new String(result);
2359   }
2360 
testNanoWithHasParseFrom()2361   public void testNanoWithHasParseFrom() throws Exception {
2362     TestAllTypesNanoHas msg = null;
2363     // Test false on creation, after clear and upon empty parse.
2364     for (int i = 0; i < 3; i++) {
2365       if (i == 0) {
2366         msg = new TestAllTypesNanoHas();
2367       } else if (i == 1) {
2368         msg.clear();
2369       } else if (i == 2) {
2370         msg = TestAllTypesNanoHas.parseFrom(new byte[0]);
2371       }
2372       assertFalse(msg.hasOptionalInt32);
2373       assertFalse(msg.hasOptionalString);
2374       assertFalse(msg.hasOptionalBytes);
2375       assertFalse(msg.hasOptionalNestedEnum);
2376       assertFalse(msg.hasDefaultInt32);
2377       assertFalse(msg.hasDefaultString);
2378       assertFalse(msg.hasDefaultBytes);
2379       assertFalse(msg.hasDefaultFloatNan);
2380       assertFalse(msg.hasDefaultNestedEnum);
2381       assertFalse(msg.hasId);
2382       assertFalse(msg.hasRequiredEnum);
2383       msg.optionalInt32 = 123;
2384       msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
2385       msg.optionalNestedMessage.bb = 2;
2386       msg.optionalNestedEnum = TestAllTypesNano.BAZ;
2387     }
2388 
2389     byte [] result = MessageNano.toByteArray(msg);
2390     int msgSerializedSize = msg.getSerializedSize();
2391     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
2392     assertTrue(msgSerializedSize == 10);
2393     assertEquals(result.length, msgSerializedSize);
2394 
2395     // Has fields true upon parse.
2396     TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
2397     assertEquals(123, newMsg.optionalInt32);
2398     assertTrue(newMsg.hasOptionalInt32);
2399     assertEquals(2, newMsg.optionalNestedMessage.bb);
2400     assertTrue(newMsg.optionalNestedMessage.hasBb);
2401     assertEquals(TestAllTypesNanoHas.BAZ, newMsg.optionalNestedEnum);
2402     assertTrue(newMsg.hasOptionalNestedEnum);
2403   }
2404 
testNanoWithHasSerialize()2405   public void testNanoWithHasSerialize() throws Exception {
2406     TestAllTypesNanoHas msg = new TestAllTypesNanoHas();
2407     msg.hasOptionalInt32 = true;
2408     msg.hasOptionalString = true;
2409     msg.hasOptionalBytes = true;
2410     msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
2411     msg.optionalNestedMessage.hasBb = true;
2412     msg.hasOptionalNestedEnum = true;
2413     msg.hasDefaultInt32 = true;
2414     msg.hasDefaultString = true;
2415     msg.hasDefaultBytes = true;
2416     msg.hasDefaultFloatNan = true;
2417     msg.hasDefaultNestedEnum = true;
2418     msg.hasId = true;
2419     msg.hasRequiredEnum = true;
2420 
2421     byte [] result = MessageNano.toByteArray(msg);
2422     int msgSerializedSize = msg.getSerializedSize();
2423     assertEquals(result.length, msgSerializedSize);
2424 
2425     // Now deserialize and find that all fields are set and equal to their defaults.
2426     TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
2427     assertTrue(newMsg.hasOptionalInt32);
2428     assertTrue(newMsg.hasOptionalString);
2429     assertTrue(newMsg.hasOptionalBytes);
2430     assertTrue(newMsg.optionalNestedMessage.hasBb);
2431     assertTrue(newMsg.hasOptionalNestedEnum);
2432     assertTrue(newMsg.hasDefaultInt32);
2433     assertTrue(newMsg.hasDefaultString);
2434     assertTrue(newMsg.hasDefaultBytes);
2435     assertTrue(newMsg.hasDefaultFloatNan);
2436     assertTrue(newMsg.hasDefaultNestedEnum);
2437     assertTrue(newMsg.hasId);
2438     assertTrue(newMsg.hasRequiredEnum);
2439     assertEquals(0, newMsg.optionalInt32);
2440     assertEquals(0, newMsg.optionalString.length());
2441     assertEquals(0, newMsg.optionalBytes.length);
2442     assertEquals(0, newMsg.optionalNestedMessage.bb);
2443     assertEquals(TestAllTypesNanoHas.FOO, newMsg.optionalNestedEnum);
2444     assertEquals(41, newMsg.defaultInt32);
2445     assertEquals("hello", newMsg.defaultString);
2446     assertEquals("world", new String(newMsg.defaultBytes, InternalNano.UTF_8));
2447     assertEquals(TestAllTypesNanoHas.BAR, newMsg.defaultNestedEnum);
2448     assertEquals(Float.NaN, newMsg.defaultFloatNan);
2449     assertEquals(0, newMsg.id);
2450     assertEquals(TestAllTypesNanoHas.FOO, newMsg.requiredEnum);
2451   }
2452 
testNanoWithAccessorsBasic()2453   public void testNanoWithAccessorsBasic() throws Exception {
2454     TestNanoAccessors msg = new TestNanoAccessors();
2455 
2456     // Makes sure required, repeated, and message fields are still public
2457     msg.id = 3;
2458     msg.repeatedBytes = new byte[2][3];
2459     msg.optionalNestedMessage = null;
2460 
2461     // Test accessors
2462     assertEquals(0, msg.getOptionalInt32());
2463     assertFalse(msg.hasOptionalInt32());
2464     msg.setOptionalInt32(135);
2465     assertEquals(135, msg.getOptionalInt32());
2466     assertTrue(msg.hasOptionalInt32());
2467     msg.clearOptionalInt32();
2468     assertFalse(msg.hasOptionalInt32());
2469     msg.setOptionalInt32(0); // default value
2470     assertTrue(msg.hasOptionalInt32());
2471 
2472     // Test NPE
2473     try {
2474       msg.setOptionalBytes(null);
2475       fail();
2476     } catch (NullPointerException expected) {}
2477     try {
2478       msg.setOptionalString(null);
2479       fail();
2480     } catch (NullPointerException expected) {}
2481 
2482     // Test has bit on bytes field with defaults and clear() re-clones the default array
2483     assertFalse(msg.hasDefaultBytes());
2484     byte[] defaultBytes = msg.getDefaultBytes();
2485     msg.setDefaultBytes(defaultBytes);
2486     assertTrue(msg.hasDefaultBytes());
2487     msg.clearDefaultBytes();
2488     assertFalse(msg.hasDefaultBytes());
2489     defaultBytes[0]++; // modify original array
2490     assertFalse(Arrays.equals(defaultBytes, msg.getDefaultBytes()));
2491 
2492     // Test has bits that require additional bit fields
2493     assertFalse(msg.hasBitFieldCheck());
2494     msg.setBitFieldCheck(0);
2495     assertTrue(msg.hasBitFieldCheck());
2496     assertFalse(msg.hasBeforeBitFieldCheck()); // checks bit field does not leak
2497     assertFalse(msg.hasAfterBitFieldCheck());
2498 
2499     // Test clear() clears has bits
2500     msg.setOptionalString("hi");
2501     msg.setDefaultString("there");
2502     msg.clear();
2503     assertFalse(msg.hasOptionalString());
2504     assertFalse(msg.hasDefaultString());
2505     assertFalse(msg.hasBitFieldCheck());
2506 
2507     // Test set() and clear() returns itself (compiles = success)
2508     msg.clear()
2509         .setOptionalInt32(3)
2510         .clearDefaultBytes()
2511         .setOptionalString("4");
2512   }
2513 
testNanoWithAccessorsParseFrom()2514   public void testNanoWithAccessorsParseFrom() throws Exception {
2515     TestNanoAccessors msg = null;
2516     // Test false on creation, after clear and upon empty parse.
2517     for (int i = 0; i < 3; i++) {
2518       if (i == 0) {
2519         msg = new TestNanoAccessors();
2520       } else if (i == 1) {
2521         msg.clear();
2522       } else if (i == 2) {
2523         msg = TestNanoAccessors.parseFrom(new byte[0]);
2524       }
2525       assertFalse(msg.hasOptionalInt32());
2526       assertFalse(msg.hasOptionalString());
2527       assertFalse(msg.hasOptionalBytes());
2528       assertFalse(msg.hasOptionalNestedEnum());
2529       assertFalse(msg.hasDefaultInt32());
2530       assertFalse(msg.hasDefaultString());
2531       assertFalse(msg.hasDefaultBytes());
2532       assertFalse(msg.hasDefaultFloatNan());
2533       assertFalse(msg.hasDefaultNestedEnum());
2534       msg.optionalNestedMessage = new TestNanoAccessors.NestedMessage();
2535       msg.optionalNestedMessage.setBb(2);
2536       msg.setOptionalNestedEnum(TestNanoAccessors.BAZ);
2537       msg.setDefaultInt32(msg.getDefaultInt32());
2538     }
2539 
2540     byte [] result = MessageNano.toByteArray(msg);
2541     int msgSerializedSize = msg.getSerializedSize();
2542     //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
2543     assertTrue(msgSerializedSize == 14);
2544     assertEquals(result.length, msgSerializedSize);
2545 
2546     // Has fields true upon parse.
2547     TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result);
2548     assertEquals(2, newMsg.optionalNestedMessage.getBb());
2549     assertTrue(newMsg.optionalNestedMessage.hasBb());
2550     assertEquals(TestNanoAccessors.BAZ, newMsg.getOptionalNestedEnum());
2551     assertTrue(newMsg.hasOptionalNestedEnum());
2552 
2553     // Has field true on fields with explicit default values from wire.
2554     assertTrue(newMsg.hasDefaultInt32());
2555     assertEquals(41, newMsg.getDefaultInt32());
2556   }
2557 
testNanoWithAccessorsPublicFieldTypes()2558   public void testNanoWithAccessorsPublicFieldTypes() throws Exception {
2559     TestNanoAccessors msg = new TestNanoAccessors();
2560     assertNull(msg.optionalNestedMessage);
2561     assertEquals(0, msg.id);
2562     assertEquals(0, msg.repeatedNestedEnum.length);
2563 
2564     TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(MessageNano.toByteArray(msg));
2565     assertNull(newMsg.optionalNestedMessage);
2566     assertEquals(0, newMsg.id);
2567     assertEquals(0, newMsg.repeatedNestedEnum.length);
2568 
2569     TestNanoAccessors.NestedMessage nestedMessage = new TestNanoAccessors.NestedMessage();
2570     nestedMessage.setBb(5);
2571     newMsg.optionalNestedMessage = nestedMessage;
2572     newMsg.id = -1;
2573     newMsg.repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
2574 
2575     TestNanoAccessors newMsg2 = TestNanoAccessors.parseFrom(MessageNano.toByteArray(newMsg));
2576     assertEquals(nestedMessage.getBb(), newMsg2.optionalNestedMessage.getBb());
2577     assertEquals(-1, newMsg2.id);
2578     assertEquals(TestAllTypesNano.FOO, newMsg2.repeatedNestedEnum[0]);
2579 
2580     newMsg2.optionalNestedMessage = null;
2581     newMsg2.id = 0;
2582     newMsg2.repeatedNestedEnum = null;
2583 
2584     TestNanoAccessors newMsg3 = TestNanoAccessors.parseFrom(MessageNano.toByteArray(newMsg2));
2585     assertNull(newMsg3.optionalNestedMessage);
2586     assertEquals(0, newMsg3.id);
2587     assertEquals(0, newMsg3.repeatedNestedEnum.length);
2588   }
2589 
testNanoWithAccessorsSerialize()2590   public void testNanoWithAccessorsSerialize() throws Exception {
2591     TestNanoAccessors msg = new TestNanoAccessors();
2592     msg.setOptionalInt32(msg.getOptionalInt32());
2593     msg.setOptionalString(msg.getOptionalString());
2594     msg.setOptionalBytes(msg.getOptionalBytes());
2595     TestNanoAccessors.NestedMessage nestedMessage = new TestNanoAccessors.NestedMessage();
2596     nestedMessage.setBb(nestedMessage.getBb());
2597     msg.optionalNestedMessage = nestedMessage;
2598     msg.setOptionalNestedEnum(msg.getOptionalNestedEnum());
2599     msg.setDefaultInt32(msg.getDefaultInt32());
2600     msg.setDefaultString(msg.getDefaultString());
2601     msg.setDefaultBytes(msg.getDefaultBytes());
2602     msg.setDefaultFloatNan(msg.getDefaultFloatNan());
2603     msg.setDefaultNestedEnum(msg.getDefaultNestedEnum());
2604 
2605     byte [] result = MessageNano.toByteArray(msg);
2606     int msgSerializedSize = msg.getSerializedSize();
2607     assertEquals(result.length, msgSerializedSize);
2608 
2609     // Now deserialize and find that all fields are set and equal to their defaults.
2610     TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result);
2611     assertTrue(newMsg.hasOptionalInt32());
2612     assertTrue(newMsg.hasOptionalString());
2613     assertTrue(newMsg.hasOptionalBytes());
2614     assertTrue(newMsg.optionalNestedMessage.hasBb());
2615     assertTrue(newMsg.hasOptionalNestedEnum());
2616     assertTrue(newMsg.hasDefaultInt32());
2617     assertTrue(newMsg.hasDefaultString());
2618     assertTrue(newMsg.hasDefaultBytes());
2619     assertTrue(newMsg.hasDefaultFloatNan());
2620     assertTrue(newMsg.hasDefaultNestedEnum());
2621     assertEquals(0, newMsg.getOptionalInt32());
2622     assertEquals(0, newMsg.getOptionalString().length());
2623     assertEquals(0, newMsg.getOptionalBytes().length);
2624     assertEquals(0, newMsg.optionalNestedMessage.getBb());
2625     assertEquals(TestNanoAccessors.FOO, newMsg.getOptionalNestedEnum());
2626     assertEquals(41, newMsg.getDefaultInt32());
2627     assertEquals("hello", newMsg.getDefaultString());
2628     assertEquals("world", new String(newMsg.getDefaultBytes(), InternalNano.UTF_8));
2629     assertEquals(TestNanoAccessors.BAR, newMsg.getDefaultNestedEnum());
2630     assertEquals(Float.NaN, newMsg.getDefaultFloatNan());
2631     assertEquals(0, newMsg.id);
2632   }
2633 
testNanoJavaEnumStyle()2634   public void testNanoJavaEnumStyle() throws Exception {
2635     EnumClassNanos.EnumClassNano msg = new EnumClassNanos.EnumClassNano();
2636     assertEquals(EnumClassNanos.FileScopeEnum.ONE, msg.one);
2637     assertEquals(EnumClassNanos.EnumClassNano.MessageScopeEnum.TWO, msg.two);
2638 
2639     EnumClassNanoMultiple msg2 = new EnumClassNanoMultiple();
2640     assertEquals(FileScopeEnumMultiple.THREE, msg2.three);
2641     assertEquals(EnumClassNanoMultiple.MessageScopeEnumMultiple.FOUR, msg2.four);
2642   }
2643 
2644   /**
2645    * Tests that fields with a default value of NaN are not serialized when
2646    * set to NaN. This is a special case as NaN != NaN, so normal equality
2647    * checks don't work.
2648    */
testNanoNotANumberDefaults()2649   public void testNanoNotANumberDefaults() throws Exception {
2650     TestAllTypesNano msg = new TestAllTypesNano();
2651     msg.defaultDoubleNan = 0;
2652     msg.defaultFloatNan = 0;
2653     byte[] result = MessageNano.toByteArray(msg);
2654     int msgSerializedSize = msg.getSerializedSize();
2655     assertTrue(result.length == msgSerializedSize);
2656     assertTrue(msgSerializedSize > 3);
2657 
2658     msg.defaultDoubleNan = Double.NaN;
2659     msg.defaultFloatNan = Float.NaN;
2660     result = MessageNano.toByteArray(msg);
2661     msgSerializedSize = msg.getSerializedSize();
2662     assertEquals(3, result.length);
2663     assertEquals(3, msgSerializedSize);
2664   }
2665 
2666   /**
2667    * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
2668    * exactly up to a limit, this should not break things.
2669    */
testSkipRawBytesBug()2670   public void testSkipRawBytesBug() throws Exception {
2671     byte[] rawBytes = new byte[] { 1, 2 };
2672     CodedInputByteBufferNano input = CodedInputByteBufferNano.newInstance(rawBytes);
2673 
2674     int limit = input.pushLimit(1);
2675     input.skipRawBytes(1);
2676     input.popLimit(limit);
2677     assertEquals(2, input.readRawByte());
2678   }
2679 
2680   /**
2681    * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
2682    * past the end of a buffer with a limit that has been set past the end of
2683    * that buffer, this should not break things.
2684    */
testSkipRawBytesPastEndOfBufferWithLimit()2685   public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
2686     byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
2687     CodedInputByteBufferNano input = CodedInputByteBufferNano.newInstance(rawBytes);
2688 
2689     int limit = input.pushLimit(4);
2690     // In order to expose the bug we need to read at least one byte to prime the
2691     // buffer inside the CodedInputStream.
2692     assertEquals(1, input.readRawByte());
2693     // Skip to the end of the limit.
2694     input.skipRawBytes(3);
2695     assertTrue(input.isAtEnd());
2696     input.popLimit(limit);
2697     assertEquals(5, input.readRawByte());
2698   }
2699 
2700   // Test a smattering of various proto types for printing
testMessageNanoPrinter()2701   public void testMessageNanoPrinter() {
2702     TestAllTypesNano msg = new TestAllTypesNano();
2703     msg.optionalInt32 = 14;
2704     msg.optionalFloat = 42.3f;
2705     msg.optionalString = "String \"with' both quotes";
2706     msg.optionalBytes = new byte[] {'"', '\0', 1, 8};
2707     msg.optionalGroup = new TestAllTypesNano.OptionalGroup();
2708     msg.optionalGroup.a = 15;
2709     msg.repeatedInt64 = new long[2];
2710     msg.repeatedInt64[0] = 1L;
2711     msg.repeatedInt64[1] = -1L;
2712     msg.repeatedBytes = new byte[2][];
2713     msg.repeatedBytes[1] = new byte[] {'h', 'e', 'l', 'l', 'o'};
2714     msg.repeatedGroup = new TestAllTypesNano.RepeatedGroup[2];
2715     msg.repeatedGroup[0] = new TestAllTypesNano.RepeatedGroup();
2716     msg.repeatedGroup[0].a = -27;
2717     msg.repeatedGroup[1] = new TestAllTypesNano.RepeatedGroup();
2718     msg.repeatedGroup[1].a = -72;
2719     msg.optionalNestedMessage = new TestAllTypesNano.NestedMessage();
2720     msg.optionalNestedMessage.bb = 7;
2721     msg.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[2];
2722     msg.repeatedNestedMessage[0] = new TestAllTypesNano.NestedMessage();
2723     msg.repeatedNestedMessage[0].bb = 77;
2724     msg.repeatedNestedMessage[1] = new TestAllTypesNano.NestedMessage();
2725     msg.repeatedNestedMessage[1].bb = 88;
2726     msg.optionalNestedEnum = TestAllTypesNano.BAZ;
2727     msg.repeatedNestedEnum = new int[2];
2728     msg.repeatedNestedEnum[0] = TestAllTypesNano.BAR;
2729     msg.repeatedNestedEnum[1] = TestAllTypesNano.FOO;
2730     msg.repeatedStringPiece = new String[] {null, "world"};
2731     msg.setOneofString("hello");
2732 
2733     String protoPrint = msg.toString();
2734     assertTrue(protoPrint.contains("optional_int32: 14"));
2735     assertTrue(protoPrint.contains("optional_float: 42.3"));
2736     assertTrue(protoPrint.contains("optional_double: 0.0"));
2737     assertTrue(protoPrint.contains("optional_string: \"String \\u0022with\\u0027 both quotes\""));
2738     assertTrue(protoPrint.contains("optional_bytes: \"\\\"\\000\\001\\010\""));
2739     assertTrue(protoPrint.contains("optional_group <\n  a: 15\n>"));
2740 
2741     assertTrue(protoPrint.contains("repeated_int64: 1\nrepeated_int64: -1"));
2742     assertFalse(protoPrint.contains("repeated_bytes: \"\"")); // null should be dropped
2743     assertTrue(protoPrint.contains("repeated_bytes: \"hello\""));
2744     assertTrue(protoPrint.contains("repeated_group <\n  a: -27\n>\n"
2745             + "repeated_group <\n  a: -72\n>"));
2746     assertTrue(protoPrint.contains("optional_nested_message <\n  bb: 7\n>"));
2747     assertTrue(protoPrint.contains("repeated_nested_message <\n  bb: 77\n>\n"
2748             + "repeated_nested_message <\n  bb: 88\n>"));
2749     assertTrue(protoPrint.contains("optional_nested_enum: 3"));
2750     assertTrue(protoPrint.contains("repeated_nested_enum: 2\nrepeated_nested_enum: 1"));
2751     assertTrue(protoPrint.contains("default_int32: 41"));
2752     assertTrue(protoPrint.contains("default_string: \"hello\""));
2753     assertFalse(protoPrint.contains("repeated_string_piece: \"\""));  // null should be dropped
2754     assertTrue(protoPrint.contains("repeated_string_piece: \"world\""));
2755     assertTrue(protoPrint.contains("oneof_string: \"hello\""));
2756   }
2757 
testMessageNanoPrinterAccessors()2758   public void testMessageNanoPrinterAccessors() throws Exception {
2759     TestNanoAccessors msg = new TestNanoAccessors();
2760     msg.setOptionalInt32(13);
2761     msg.setOptionalString("foo");
2762     msg.setOptionalBytes(new byte[] {'"', '\0', 1, 8});
2763     msg.optionalNestedMessage = new TestNanoAccessors.NestedMessage();
2764     msg.optionalNestedMessage.setBb(7);
2765     msg.setOptionalNestedEnum(TestNanoAccessors.BAZ);
2766     msg.repeatedInt32 = new int[] { 1, -1 };
2767     msg.repeatedString = new String[] { "Hello", "world" };
2768     msg.repeatedBytes = new byte[2][];
2769     msg.repeatedBytes[1] = new byte[] {'h', 'e', 'l', 'l', 'o'};
2770     msg.repeatedNestedMessage = new TestNanoAccessors.NestedMessage[2];
2771     msg.repeatedNestedMessage[0] = new TestNanoAccessors.NestedMessage();
2772     msg.repeatedNestedMessage[0].setBb(5);
2773     msg.repeatedNestedMessage[1] = new TestNanoAccessors.NestedMessage();
2774     msg.repeatedNestedMessage[1].setBb(6);
2775     msg.repeatedNestedEnum = new int[] { TestNanoAccessors.FOO, TestNanoAccessors.BAR };
2776     msg.id = 33;
2777 
2778     String protoPrint = msg.toString();
2779     assertTrue(protoPrint.contains("optional_int32: 13"));
2780     assertTrue(protoPrint.contains("optional_string: \"foo\""));
2781     assertTrue(protoPrint.contains("optional_bytes: \"\\\"\\000\\001\\010\""));
2782     assertTrue(protoPrint.contains("optional_nested_message <\n  bb: 7\n>"));
2783     assertTrue(protoPrint.contains("optional_nested_enum: 3"));
2784     assertTrue(protoPrint.contains("repeated_int32: 1\nrepeated_int32: -1"));
2785     assertTrue(protoPrint.contains("repeated_string: \"Hello\"\nrepeated_string: \"world\""));
2786     assertFalse(protoPrint.contains("repeated_bytes: \"\"")); // null should be dropped
2787     assertTrue(protoPrint.contains("repeated_bytes: \"hello\""));
2788     assertTrue(protoPrint.contains("repeated_nested_message <\n  bb: 5\n>\n"
2789             + "repeated_nested_message <\n  bb: 6\n>"));
2790     assertTrue(protoPrint.contains("repeated_nested_enum: 1\nrepeated_nested_enum: 2"));
2791     assertTrue(protoPrint.contains("id: 33"));
2792   }
2793 
testMessageNanoPrinterForMaps()2794   public void testMessageNanoPrinterForMaps() throws Exception {
2795     TestMap msg = new TestMap();
2796     MessageValue msgValues[] = new MessageValue[] {
2797       new MessageValue(), new MessageValue()
2798     };
2799     msgValues[0].value = 1;
2800     msgValues[1].value = 2;
2801     msg.int32ToBytesField = new HashMap<Integer, byte[]>();
2802     msg.int32ToBytesField.put(1, new byte[] {'"', '\0'});
2803     msg.int32ToBytesField.put(2, new byte[] {1, 8});
2804     msg.stringToInt32Field = new HashMap<String, Integer>();
2805     msg.stringToInt32Field.put("hello", 1);
2806     msg.stringToInt32Field.put("world", 2);
2807     msg.int32ToMessageField = new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
2808     msg.int32ToMessageField.put(0, msgValues[0]);
2809     msg.int32ToMessageField.put(1, msgValues[1]);
2810     msg.int32ToEnumField = new HashMap<Integer, Integer>();
2811     msg.int32ToEnumField.put(1, 2);
2812     msg.int32ToEnumField.put(2, 3);
2813     String protoPrint = msg.toString();
2814 
2815     assertTrue(protoPrint.contains(
2816         "int32_to_bytes_field <\n  key: 1\n  value: \"\\\"\\000\"\n>"));
2817     assertTrue(protoPrint.contains(
2818         "int32_to_bytes_field <\n  key: 2\n  value: \"\\001\\010\"\n>"));
2819     assertTrue(protoPrint.contains(
2820         "string_to_int32_field <\n  key: \"hello\"\n  value: 1\n>"));
2821     assertTrue(protoPrint.contains(
2822         "string_to_int32_field <\n  key: \"world\"\n  value: 2\n>"));
2823     assertTrue(protoPrint.contains(
2824         "int32_to_message_field <\n  key: 0\n  value <\n    value: 1\n"));
2825     assertTrue(protoPrint.contains(
2826         "int32_to_message_field <\n  key: 1\n  value <\n    value: 2\n"));
2827     assertTrue(protoPrint.contains(
2828         "int32_to_enum_field <\n  key: 1\n  value: 2\n>"));
2829     assertTrue(protoPrint.contains(
2830         "int32_to_enum_field <\n  key: 2\n  value: 3\n>"));
2831   }
2832 
testExtensions()2833   public void testExtensions() throws Exception {
2834     Extensions.ExtendableMessage message = new Extensions.ExtendableMessage();
2835     message.field = 5;
2836     int[] int32s = {1, 2};
2837     int[] uint32s = {3, 4};
2838     int[] sint32s = {-5, -6};
2839     long[] int64s = {7, 8};
2840     long[] uint64s = {9, 10};
2841     long[] sint64s = {-11, -12};
2842     int[] fixed32s = {13, 14};
2843     int[] sfixed32s = {-15, -16};
2844     long[] fixed64s = {17, 18};
2845     long[] sfixed64s = {-19, -20};
2846     boolean[] bools = {true, false};
2847     float[] floats = {2.1f, 2.2f};
2848     double[] doubles = {2.3, 2.4};
2849     int[] enums = {Extensions.SECOND_VALUE, Extensions.FIRST_VALUE};
2850     String[] strings = {"vijfentwintig", "twenty-six"};
2851     byte[][] bytess = {{2, 7}, {2, 8}};
2852     AnotherMessage another1 = new AnotherMessage();
2853     another1.string = "er shi jiu";
2854     another1.value = false;
2855     AnotherMessage another2 = new AnotherMessage();
2856     another2.string = "trente";
2857     another2.value = true;
2858     AnotherMessage[] messages = {another1, another2};
2859     RepeatedExtensions.RepeatedGroup group1 = new RepeatedExtensions.RepeatedGroup();
2860     group1.a = 31;
2861     RepeatedExtensions.RepeatedGroup group2 = new RepeatedExtensions.RepeatedGroup();
2862     group2.a = 32;
2863     RepeatedExtensions.RepeatedGroup[] groups = {group1, group2};
2864     assertFalse(message.hasExtension(RepeatedExtensions.repeatedInt32));
2865     message.setExtension(RepeatedExtensions.repeatedInt32, int32s);
2866     assertTrue(message.hasExtension(RepeatedExtensions.repeatedInt32));
2867     assertFalse(message.hasExtension(RepeatedExtensions.repeatedUint32));
2868     message.setExtension(RepeatedExtensions.repeatedUint32, uint32s);
2869     assertTrue(message.hasExtension(RepeatedExtensions.repeatedUint32));
2870     message.setExtension(RepeatedExtensions.repeatedSint32, sint32s);
2871     assertFalse(message.hasExtension(RepeatedExtensions.repeatedInt64));
2872     message.setExtension(RepeatedExtensions.repeatedInt64, int64s);
2873     assertTrue(message.hasExtension(RepeatedExtensions.repeatedInt64));
2874     assertFalse(message.hasExtension(RepeatedExtensions.repeatedUint64));
2875     message.setExtension(RepeatedExtensions.repeatedUint64, uint64s);
2876     assertTrue(message.hasExtension(RepeatedExtensions.repeatedUint64));
2877     assertFalse(message.hasExtension(RepeatedExtensions.repeatedSint64));
2878     message.setExtension(RepeatedExtensions.repeatedSint64, sint64s);
2879     assertTrue(message.hasExtension(RepeatedExtensions.repeatedSint64));
2880     assertFalse(message.hasExtension(RepeatedExtensions.repeatedFixed32));
2881     message.setExtension(RepeatedExtensions.repeatedFixed32, fixed32s);
2882     assertTrue(message.hasExtension(RepeatedExtensions.repeatedFixed32));
2883     assertFalse(message.hasExtension(RepeatedExtensions.repeatedSfixed32));
2884     message.setExtension(RepeatedExtensions.repeatedSfixed32, sfixed32s);
2885     assertTrue(message.hasExtension(RepeatedExtensions.repeatedSfixed32));
2886     assertFalse(message.hasExtension(RepeatedExtensions.repeatedFixed64));
2887     message.setExtension(RepeatedExtensions.repeatedFixed64, fixed64s);
2888     assertTrue(message.hasExtension(RepeatedExtensions.repeatedFixed64));
2889     assertFalse(message.hasExtension(RepeatedExtensions.repeatedSfixed64));
2890     message.setExtension(RepeatedExtensions.repeatedSfixed64, sfixed64s);
2891     assertTrue(message.hasExtension(RepeatedExtensions.repeatedSfixed64));
2892     assertFalse(message.hasExtension(RepeatedExtensions.repeatedBool));
2893     message.setExtension(RepeatedExtensions.repeatedBool, bools);
2894     assertTrue(message.hasExtension(RepeatedExtensions.repeatedBool));
2895     assertFalse(message.hasExtension(RepeatedExtensions.repeatedFloat));
2896     message.setExtension(RepeatedExtensions.repeatedFloat, floats);
2897     assertTrue(message.hasExtension(RepeatedExtensions.repeatedFloat));
2898     assertFalse(message.hasExtension(RepeatedExtensions.repeatedDouble));
2899     message.setExtension(RepeatedExtensions.repeatedDouble, doubles);
2900     assertTrue(message.hasExtension(RepeatedExtensions.repeatedDouble));
2901     assertFalse(message.hasExtension(RepeatedExtensions.repeatedEnum));
2902     message.setExtension(RepeatedExtensions.repeatedEnum, enums);
2903     assertTrue(message.hasExtension(RepeatedExtensions.repeatedEnum));
2904     assertFalse(message.hasExtension(RepeatedExtensions.repeatedString));
2905     message.setExtension(RepeatedExtensions.repeatedString, strings);
2906     assertTrue(message.hasExtension(RepeatedExtensions.repeatedString));
2907     assertFalse(message.hasExtension(RepeatedExtensions.repeatedBytes));
2908     message.setExtension(RepeatedExtensions.repeatedBytes, bytess);
2909     assertTrue(message.hasExtension(RepeatedExtensions.repeatedBytes));
2910     assertFalse(message.hasExtension(RepeatedExtensions.repeatedMessage));
2911     message.setExtension(RepeatedExtensions.repeatedMessage, messages);
2912     assertTrue(message.hasExtension(RepeatedExtensions.repeatedMessage));
2913     assertFalse(message.hasExtension(RepeatedExtensions.repeatedGroup));
2914     message.setExtension(RepeatedExtensions.repeatedGroup, groups);
2915     assertTrue(message.hasExtension(RepeatedExtensions.repeatedGroup));
2916 
2917     byte[] data = MessageNano.toByteArray(message);
2918     message = Extensions.ExtendableMessage.parseFrom(data);
2919     assertEquals(5, message.field);
2920 
2921     // Test reading back using SingularExtensions: the retrieved value should equal the last
2922     // in each array.
2923     assertEquals(int32s[1], (int) message.getExtension(SingularExtensions.someInt32));
2924     assertEquals(uint32s[1], (int) message.getExtension(SingularExtensions.someUint32));
2925     assertEquals(sint32s[1], (int) message.getExtension(SingularExtensions.someSint32));
2926     assertEquals(int64s[1], (long) message.getExtension(SingularExtensions.someInt64));
2927     assertEquals(uint64s[1], (long) message.getExtension(SingularExtensions.someUint64));
2928     assertEquals(sint64s[1], (long) message.getExtension(SingularExtensions.someSint64));
2929     assertEquals(fixed32s[1], (int) message.getExtension(SingularExtensions.someFixed32));
2930     assertEquals(sfixed32s[1], (int) message.getExtension(SingularExtensions.someSfixed32));
2931     assertEquals(fixed64s[1], (long) message.getExtension(SingularExtensions.someFixed64));
2932     assertEquals(sfixed64s[1], (long) message.getExtension(SingularExtensions.someSfixed64));
2933     assertEquals(bools[1], (boolean) message.getExtension(SingularExtensions.someBool));
2934     assertEquals(floats[1], (float) message.getExtension(SingularExtensions.someFloat));
2935     assertEquals(doubles[1], (double) message.getExtension(SingularExtensions.someDouble));
2936     assertEquals(enums[1], (int) message.getExtension(SingularExtensions.someEnum));
2937     assertEquals(strings[1], message.getExtension(SingularExtensions.someString));
2938     assertTrue(Arrays.equals(bytess[1], message.getExtension(SingularExtensions.someBytes)));
2939     AnotherMessage deserializedMessage = message.getExtension(SingularExtensions.someMessage);
2940     assertEquals(another2.string, deserializedMessage.string);
2941     assertEquals(another2.value, deserializedMessage.value);
2942     assertEquals(group2.a, message.getExtension(SingularExtensions.someGroup).a);
2943 
2944     // Test reading back using RepeatedExtensions: the arrays should be equal.
2945     message = Extensions.ExtendableMessage.parseFrom(data);
2946     assertEquals(5, message.field);
2947     assertTrue(Arrays.equals(int32s, message.getExtension(RepeatedExtensions.repeatedInt32)));
2948     assertTrue(Arrays.equals(uint32s, message.getExtension(RepeatedExtensions.repeatedUint32)));
2949     assertTrue(Arrays.equals(sint32s, message.getExtension(RepeatedExtensions.repeatedSint32)));
2950     assertTrue(Arrays.equals(int64s, message.getExtension(RepeatedExtensions.repeatedInt64)));
2951     assertTrue(Arrays.equals(uint64s, message.getExtension(RepeatedExtensions.repeatedUint64)));
2952     assertTrue(Arrays.equals(sint64s, message.getExtension(RepeatedExtensions.repeatedSint64)));
2953     assertTrue(Arrays.equals(fixed32s, message.getExtension(RepeatedExtensions.repeatedFixed32)));
2954     assertTrue(Arrays.equals(sfixed32s, message.getExtension(RepeatedExtensions.repeatedSfixed32)));
2955     assertTrue(Arrays.equals(fixed64s, message.getExtension(RepeatedExtensions.repeatedFixed64)));
2956     assertTrue(Arrays.equals(sfixed64s, message.getExtension(RepeatedExtensions.repeatedSfixed64)));
2957     assertTrue(Arrays.equals(bools, message.getExtension(RepeatedExtensions.repeatedBool)));
2958     assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
2959     assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
2960     assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
2961     assertTrue(Arrays.equals(strings, message.getExtension(RepeatedExtensions.repeatedString)));
2962     byte[][] deserializedRepeatedBytes = message.getExtension(RepeatedExtensions.repeatedBytes);
2963     assertEquals(2, deserializedRepeatedBytes.length);
2964     assertTrue(Arrays.equals(bytess[0], deserializedRepeatedBytes[0]));
2965     assertTrue(Arrays.equals(bytess[1], deserializedRepeatedBytes[1]));
2966     AnotherMessage[] deserializedRepeatedMessage =
2967         message.getExtension(RepeatedExtensions.repeatedMessage);
2968     assertEquals(2, deserializedRepeatedMessage.length);
2969     assertEquals(another1.string, deserializedRepeatedMessage[0].string);
2970     assertEquals(another1.value, deserializedRepeatedMessage[0].value);
2971     assertEquals(another2.string, deserializedRepeatedMessage[1].string);
2972     assertEquals(another2.value, deserializedRepeatedMessage[1].value);
2973     RepeatedExtensions.RepeatedGroup[] deserializedRepeatedGroup =
2974         message.getExtension(RepeatedExtensions.repeatedGroup);
2975     assertEquals(2, deserializedRepeatedGroup.length);
2976     assertEquals(group1.a, deserializedRepeatedGroup[0].a);
2977     assertEquals(group2.a, deserializedRepeatedGroup[1].a);
2978 
2979     message = Extensions.ExtendableMessage.parseFrom(data);
2980     assertEquals(5, message.field);
2981     // Test hasExtension using PackedExtensions.
2982     assertTrue(message.hasExtension(PackedExtensions.packedInt32));
2983     assertTrue(message.hasExtension(PackedExtensions.packedUint32));
2984     assertTrue(message.hasExtension(PackedExtensions.packedSint32));
2985     assertTrue(message.hasExtension(PackedExtensions.packedInt64));
2986     assertTrue(message.hasExtension(PackedExtensions.packedUint64));
2987     assertTrue(message.hasExtension(PackedExtensions.packedSint64));
2988     assertTrue(message.hasExtension(PackedExtensions.packedFixed32));
2989     assertTrue(message.hasExtension(PackedExtensions.packedSfixed32));
2990     assertTrue(message.hasExtension(PackedExtensions.packedFixed64));
2991     assertTrue(message.hasExtension(PackedExtensions.packedSfixed64));
2992     assertTrue(message.hasExtension(PackedExtensions.packedBool));
2993     assertTrue(message.hasExtension(PackedExtensions.packedFloat));
2994     assertTrue(message.hasExtension(PackedExtensions.packedDouble));
2995     assertTrue(message.hasExtension(PackedExtensions.packedEnum));
2996 
2997     // Test reading back using PackedExtensions: the arrays should be equal, even the fields
2998     // are non-packed.
2999     assertTrue(Arrays.equals(int32s, message.getExtension(PackedExtensions.packedInt32)));
3000     assertTrue(Arrays.equals(uint32s, message.getExtension(PackedExtensions.packedUint32)));
3001     assertTrue(Arrays.equals(sint32s, message.getExtension(PackedExtensions.packedSint32)));
3002     assertTrue(Arrays.equals(int64s, message.getExtension(PackedExtensions.packedInt64)));
3003     assertTrue(Arrays.equals(uint64s, message.getExtension(PackedExtensions.packedUint64)));
3004     assertTrue(Arrays.equals(sint64s, message.getExtension(PackedExtensions.packedSint64)));
3005     assertTrue(Arrays.equals(fixed32s, message.getExtension(PackedExtensions.packedFixed32)));
3006     assertTrue(Arrays.equals(sfixed32s, message.getExtension(PackedExtensions.packedSfixed32)));
3007     assertTrue(Arrays.equals(fixed64s, message.getExtension(PackedExtensions.packedFixed64)));
3008     assertTrue(Arrays.equals(sfixed64s, message.getExtension(PackedExtensions.packedSfixed64)));
3009     assertTrue(Arrays.equals(bools, message.getExtension(PackedExtensions.packedBool)));
3010     assertTrue(Arrays.equals(floats, message.getExtension(PackedExtensions.packedFloat)));
3011     assertTrue(Arrays.equals(doubles, message.getExtension(PackedExtensions.packedDouble)));
3012     assertTrue(Arrays.equals(enums, message.getExtension(PackedExtensions.packedEnum)));
3013 
3014     // Now set the packable extension values using PackedExtensions so they're serialized packed.
3015     message.setExtension(PackedExtensions.packedInt32, int32s);
3016     message.setExtension(PackedExtensions.packedUint32, uint32s);
3017     message.setExtension(PackedExtensions.packedSint32, sint32s);
3018     message.setExtension(PackedExtensions.packedInt64, int64s);
3019     message.setExtension(PackedExtensions.packedUint64, uint64s);
3020     message.setExtension(PackedExtensions.packedSint64, sint64s);
3021     message.setExtension(PackedExtensions.packedFixed32, fixed32s);
3022     message.setExtension(PackedExtensions.packedSfixed32, sfixed32s);
3023     message.setExtension(PackedExtensions.packedFixed64, fixed64s);
3024     message.setExtension(PackedExtensions.packedSfixed64, sfixed64s);
3025     message.setExtension(PackedExtensions.packedBool, bools);
3026     message.setExtension(PackedExtensions.packedFloat, floats);
3027     message.setExtension(PackedExtensions.packedDouble, doubles);
3028     message.setExtension(PackedExtensions.packedEnum, enums);
3029 
3030     // And read back using non-packed RepeatedExtensions.
3031     byte[] data2 = MessageNano.toByteArray(message);
3032     message = MessageNano.mergeFrom(new Extensions.ExtendableMessage(), data2);
3033     assertTrue(Arrays.equals(int32s, message.getExtension(RepeatedExtensions.repeatedInt32)));
3034     assertTrue(Arrays.equals(uint32s, message.getExtension(RepeatedExtensions.repeatedUint32)));
3035     assertTrue(Arrays.equals(sint32s, message.getExtension(RepeatedExtensions.repeatedSint32)));
3036     assertTrue(Arrays.equals(int64s, message.getExtension(RepeatedExtensions.repeatedInt64)));
3037     assertTrue(Arrays.equals(uint64s, message.getExtension(RepeatedExtensions.repeatedUint64)));
3038     assertTrue(Arrays.equals(sint64s, message.getExtension(RepeatedExtensions.repeatedSint64)));
3039     assertTrue(Arrays.equals(fixed32s, message.getExtension(RepeatedExtensions.repeatedFixed32)));
3040     assertTrue(Arrays.equals(sfixed32s, message.getExtension(RepeatedExtensions.repeatedSfixed32)));
3041     assertTrue(Arrays.equals(fixed64s, message.getExtension(RepeatedExtensions.repeatedFixed64)));
3042     assertTrue(Arrays.equals(sfixed64s, message.getExtension(RepeatedExtensions.repeatedSfixed64)));
3043     assertTrue(Arrays.equals(bools, message.getExtension(RepeatedExtensions.repeatedBool)));
3044     assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
3045     assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
3046     assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
3047 
3048     // Clone the message and ensure it's still equal.
3049     Extensions.ExtendableMessage clone = message.clone();
3050     assertEquals(clone, message);
3051   }
3052 
testNullExtensions()3053   public void testNullExtensions() throws Exception {
3054     // Check that clearing the extension on an empty message is a no-op.
3055     Extensions.ExtendableMessage message = new Extensions.ExtendableMessage();
3056     assertFalse(message.hasExtension(SingularExtensions.someMessage));
3057     message.setExtension(SingularExtensions.someMessage, null);
3058     assertFalse(message.hasExtension(SingularExtensions.someMessage));
3059     assertEquals(0, MessageNano.toByteArray(message).length);
3060 
3061     // Check that the message is empty after setting and clearing an extension.
3062     AnotherMessage another = new AnotherMessage();
3063     assertFalse(message.hasExtension(SingularExtensions.someMessage));
3064     message.setExtension(SingularExtensions.someMessage, another);
3065     assertTrue(message.hasExtension(SingularExtensions.someMessage));
3066     assertTrue(MessageNano.toByteArray(message).length > 0);
3067     message.setExtension(SingularExtensions.someMessage, null);
3068     assertFalse(message.hasExtension(SingularExtensions.someMessage));
3069     assertEquals(0, MessageNano.toByteArray(message).length);
3070   }
3071 
testExtensionsMutation()3072   public void testExtensionsMutation() {
3073     Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
3074     extendableMessage.setExtension(SingularExtensions.someMessage,
3075         new Extensions.AnotherMessage());
3076 
3077     extendableMessage.getExtension(SingularExtensions.someMessage).string = "not empty";
3078 
3079     assertEquals("not empty",
3080         extendableMessage.getExtension(SingularExtensions.someMessage).string);
3081   }
3082 
testExtensionsMutation_Equals()3083   public void testExtensionsMutation_Equals() throws InvalidProtocolBufferNanoException {
3084     Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
3085     extendableMessage.field = 5;
3086     int int32 = 42;
3087     int[] uint32s = {3, 4};
3088     int[] sint32s = {-5, -6};
3089     long[] int64s = {7, 8};
3090     long[] uint64s = {9, 10};
3091     long[] sint64s = {-11, -12};
3092     int[] fixed32s = {13, 14};
3093     int[] sfixed32s = {-15, -16};
3094     long[] fixed64s = {17, 18};
3095     long[] sfixed64s = {-19, -20};
3096     boolean[] bools = {true, false};
3097     float[] floats = {2.1f, 2.2f};
3098     double[] doubles = {2.3, 2.4};
3099     int[] enums = {Extensions.SECOND_VALUE, Extensions.FIRST_VALUE};
3100     String[] strings = {"vijfentwintig", "twenty-six"};
3101     byte[][] bytess = {{2, 7}, {2, 8}};
3102     AnotherMessage another1 = new AnotherMessage();
3103     another1.string = "er shi jiu";
3104     another1.value = false;
3105     AnotherMessage another2 = new AnotherMessage();
3106     another2.string = "trente";
3107     another2.value = true;
3108     AnotherMessage[] messages = {another1, another2};
3109     RepeatedExtensions.RepeatedGroup group1 = new RepeatedExtensions.RepeatedGroup();
3110     group1.a = 31;
3111     RepeatedExtensions.RepeatedGroup group2 = new RepeatedExtensions.RepeatedGroup();
3112     group2.a = 32;
3113     RepeatedExtensions.RepeatedGroup[] groups = {group1, group2};
3114     extendableMessage.setExtension(SingularExtensions.someInt32, int32);
3115     extendableMessage.setExtension(RepeatedExtensions.repeatedUint32, uint32s);
3116     extendableMessage.setExtension(RepeatedExtensions.repeatedSint32, sint32s);
3117     extendableMessage.setExtension(RepeatedExtensions.repeatedInt64, int64s);
3118     extendableMessage.setExtension(RepeatedExtensions.repeatedUint64, uint64s);
3119     extendableMessage.setExtension(RepeatedExtensions.repeatedSint64, sint64s);
3120     extendableMessage.setExtension(RepeatedExtensions.repeatedFixed32, fixed32s);
3121     extendableMessage.setExtension(RepeatedExtensions.repeatedSfixed32, sfixed32s);
3122     extendableMessage.setExtension(RepeatedExtensions.repeatedFixed64, fixed64s);
3123     extendableMessage.setExtension(RepeatedExtensions.repeatedSfixed64, sfixed64s);
3124     extendableMessage.setExtension(RepeatedExtensions.repeatedBool, bools);
3125     extendableMessage.setExtension(RepeatedExtensions.repeatedFloat, floats);
3126     extendableMessage.setExtension(RepeatedExtensions.repeatedDouble, doubles);
3127     extendableMessage.setExtension(RepeatedExtensions.repeatedEnum, enums);
3128     extendableMessage.setExtension(RepeatedExtensions.repeatedString, strings);
3129     extendableMessage.setExtension(RepeatedExtensions.repeatedBytes, bytess);
3130     extendableMessage.setExtension(RepeatedExtensions.repeatedMessage, messages);
3131     extendableMessage.setExtension(RepeatedExtensions.repeatedGroup, groups);
3132 
3133     byte[] data = MessageNano.toByteArray(extendableMessage);
3134 
3135     extendableMessage = Extensions.ExtendableMessage.parseFrom(data);
3136     Extensions.ExtendableMessage messageCopy = Extensions.ExtendableMessage.parseFrom(data);
3137 
3138     // Without deserialising.
3139     assertEquals(extendableMessage, messageCopy);
3140     assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
3141 
3142     // Only one deserialized.
3143     extendableMessage.getExtension(SingularExtensions.someInt32);
3144     extendableMessage.getExtension(RepeatedExtensions.repeatedUint32);
3145     extendableMessage.getExtension(RepeatedExtensions.repeatedSint32);
3146     extendableMessage.getExtension(RepeatedExtensions.repeatedInt64);
3147     extendableMessage.getExtension(RepeatedExtensions.repeatedUint64);
3148     extendableMessage.getExtension(RepeatedExtensions.repeatedSint64);
3149     extendableMessage.getExtension(RepeatedExtensions.repeatedFixed32);
3150     extendableMessage.getExtension(RepeatedExtensions.repeatedSfixed32);
3151     extendableMessage.getExtension(RepeatedExtensions.repeatedFixed64);
3152     extendableMessage.getExtension(RepeatedExtensions.repeatedSfixed64);
3153     extendableMessage.getExtension(RepeatedExtensions.repeatedBool);
3154     extendableMessage.getExtension(RepeatedExtensions.repeatedFloat);
3155     extendableMessage.getExtension(RepeatedExtensions.repeatedDouble);
3156     extendableMessage.getExtension(RepeatedExtensions.repeatedEnum);
3157     extendableMessage.getExtension(RepeatedExtensions.repeatedString);
3158     extendableMessage.getExtension(RepeatedExtensions.repeatedBytes);
3159     extendableMessage.getExtension(RepeatedExtensions.repeatedMessage);
3160     extendableMessage.getExtension(RepeatedExtensions.repeatedGroup);
3161     assertEquals(extendableMessage, messageCopy);
3162     assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
3163 
3164     // Both deserialized.
3165     messageCopy.getExtension(SingularExtensions.someInt32);
3166     messageCopy.getExtension(RepeatedExtensions.repeatedUint32);
3167     messageCopy.getExtension(RepeatedExtensions.repeatedSint32);
3168     messageCopy.getExtension(RepeatedExtensions.repeatedInt64);
3169     messageCopy.getExtension(RepeatedExtensions.repeatedUint64);
3170     messageCopy.getExtension(RepeatedExtensions.repeatedSint64);
3171     messageCopy.getExtension(RepeatedExtensions.repeatedFixed32);
3172     messageCopy.getExtension(RepeatedExtensions.repeatedSfixed32);
3173     messageCopy.getExtension(RepeatedExtensions.repeatedFixed64);
3174     messageCopy.getExtension(RepeatedExtensions.repeatedSfixed64);
3175     messageCopy.getExtension(RepeatedExtensions.repeatedBool);
3176     messageCopy.getExtension(RepeatedExtensions.repeatedFloat);
3177     messageCopy.getExtension(RepeatedExtensions.repeatedDouble);
3178     messageCopy.getExtension(RepeatedExtensions.repeatedEnum);
3179     messageCopy.getExtension(RepeatedExtensions.repeatedString);
3180     messageCopy.getExtension(RepeatedExtensions.repeatedBytes);
3181     messageCopy.getExtension(RepeatedExtensions.repeatedMessage);
3182     messageCopy.getExtension(RepeatedExtensions.repeatedGroup);
3183     assertEquals(extendableMessage, messageCopy);
3184     assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
3185 
3186     // Change one, make sure they are still different.
3187     messageCopy.getExtension(RepeatedExtensions.repeatedMessage)[0].string = "not empty";
3188     assertFalse(extendableMessage.equals(messageCopy));
3189 
3190     // Even if the extension hasn't been deserialized.
3191     extendableMessage = Extensions.ExtendableMessage.parseFrom(data);
3192     assertFalse(extendableMessage.equals(messageCopy));
3193   }
3194 
testExtensionsCaching()3195   public void testExtensionsCaching() {
3196     Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
3197     extendableMessage.setExtension(SingularExtensions.someMessage,
3198         new Extensions.AnotherMessage());
3199     assertSame("Consecutive calls to getExtensions should return the same object",
3200         extendableMessage.getExtension(SingularExtensions.someMessage),
3201         extendableMessage.getExtension(SingularExtensions.someMessage));
3202   }
3203 
testUnknownFields()3204   public void testUnknownFields() throws Exception {
3205     // Check that we roundtrip (serialize and deserialize) unrecognized fields.
3206     AnotherMessage message = new AnotherMessage();
3207     message.string = "Hello World";
3208     message.value = false;
3209 
3210     byte[] bytes = MessageNano.toByteArray(message);
3211     int extraFieldSize = CodedOutputByteBufferNano.computeStringSize(
3212         1001, "This is an unknown field");
3213     byte[] newBytes = new byte[bytes.length + extraFieldSize];
3214     System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
3215     CodedOutputByteBufferNano.newInstance(newBytes, bytes.length, extraFieldSize)
3216         .writeString(1001, "This is an unknown field");
3217 
3218     // Deserialize with an unknown field.
3219     AnotherMessage deserialized = AnotherMessage.parseFrom(newBytes);
3220     byte[] serialized = MessageNano.toByteArray(deserialized);
3221 
3222     assertEquals(newBytes.length, serialized.length);
3223 
3224     // Clear, and make sure it clears everything.
3225     deserialized.clear();
3226     assertEquals(0, MessageNano.toByteArray(deserialized).length);
3227   }
3228 
testMergeFrom()3229   public void testMergeFrom() throws Exception {
3230     SimpleMessageNano message = new SimpleMessageNano();
3231     message.d = 123;
3232     byte[] bytes = MessageNano.toByteArray(message);
3233 
3234     SimpleMessageNano newMessage = MessageNano.mergeFrom(new SimpleMessageNano(), bytes);
3235     assertEquals(message.d, newMessage.d);
3236   }
3237 
testJavaKeyword()3238   public void testJavaKeyword() throws Exception {
3239     TestAllTypesNano msg = new TestAllTypesNano();
3240     msg.synchronized_ = 123;
3241     assertEquals(123, msg.synchronized_);
3242   }
3243 
testReferenceTypesForPrimitives()3244   public void testReferenceTypesForPrimitives() throws Exception {
3245     NanoReferenceTypes.TestAllTypesNano message = new NanoReferenceTypes.TestAllTypesNano();
3246 
3247     // Base check - when nothing is set, we serialize nothing.
3248     assertHasWireData(message, false);
3249 
3250     message.defaultBool = true;
3251     assertHasWireData(message, true);
3252 
3253     message.defaultBool = false;
3254     assertHasWireData(message, true);
3255 
3256     message.defaultBool = null;
3257     assertHasWireData(message, false);
3258 
3259     message.defaultInt32 = 5;
3260     assertHasWireData(message, true);
3261 
3262     message.defaultInt32 = null;
3263     assertHasWireData(message, false);
3264 
3265     message.defaultInt64 = 123456L;
3266     assertHasWireData(message, true);
3267 
3268     message.defaultInt64 = null;
3269     assertHasWireData(message, false);
3270 
3271     message.defaultFloat = 1f;
3272     assertHasWireData(message, true);
3273 
3274     message.defaultFloat = null;
3275     assertHasWireData(message, false);
3276 
3277     message.defaultDouble = 2.1;
3278     assertHasWireData(message, true);
3279 
3280     message.defaultDouble = null;
3281     assertHasWireData(message, false);
3282 
3283     message.defaultString = "hello";
3284     assertHasWireData(message, true);
3285 
3286     message.defaultString = null;
3287     assertHasWireData(message, false);
3288 
3289     message.defaultBytes = new byte[] { 1, 2, 3 };
3290     assertHasWireData(message, true);
3291 
3292     message.defaultBytes = null;
3293     assertHasWireData(message, false);
3294   }
3295 
testHashCodeEquals()3296   public void testHashCodeEquals() throws Exception {
3297     // Complete equality:
3298     TestAllTypesNano a = createMessageForHashCodeEqualsTest();
3299     TestAllTypesNano aEquivalent = createMessageForHashCodeEqualsTest();
3300 
3301     assertTrue(MessageNano.messageNanoEquals(a, aEquivalent));
3302     assertFalse(MessageNano.messageNanoEquals(a, new TestAllTypesNano()));
3303 
3304     // Null and empty array for repeated fields equality:
3305     TestAllTypesNano b = createMessageForHashCodeEqualsTest();
3306     b.repeatedBool = null;
3307     b.repeatedFloat = new float[0];
3308     TestAllTypesNano bEquivalent = createMessageForHashCodeEqualsTest();
3309     bEquivalent.repeatedBool = new boolean[0];
3310     bEquivalent.repeatedFloat = null;
3311 
3312     // Ref-element-type repeated fields use non-null subsequence equality:
3313     TestAllTypesNano c = createMessageForHashCodeEqualsTest();
3314     c.repeatedString = null;
3315     c.repeatedStringPiece = new String[] {null, "one", null, "two"};
3316     c.repeatedBytes = new byte[][] {{3, 4}, null};
3317     TestAllTypesNano cEquivalent = createMessageForHashCodeEqualsTest();
3318     cEquivalent.repeatedString = new String[3];
3319     cEquivalent.repeatedStringPiece = new String[] {"one", "two", null};
3320     cEquivalent.repeatedBytes = new byte[][] {{3, 4}};
3321 
3322     // Complete equality for messages with has fields:
3323     TestAllTypesNanoHas d = createMessageWithHasForHashCodeEqualsTest();
3324     TestAllTypesNanoHas dEquivalent = createMessageWithHasForHashCodeEqualsTest();
3325 
3326     // If has-fields exist, fields with the same default values but
3327     // different has-field values are different.
3328     TestAllTypesNanoHas e = createMessageWithHasForHashCodeEqualsTest();
3329     e.optionalInt32++; // make different from d
3330     e.hasDefaultString = false;
3331     TestAllTypesNanoHas eDifferent = createMessageWithHasForHashCodeEqualsTest();
3332     eDifferent.optionalInt32 = e.optionalInt32;
3333     eDifferent.hasDefaultString = true;
3334 
3335     // Complete equality for messages with accessors:
3336     TestNanoAccessors f = createMessageWithAccessorsForHashCodeEqualsTest();
3337     TestNanoAccessors fEquivalent = createMessageWithAccessorsForHashCodeEqualsTest();
3338 
3339     // If using accessors, explicitly setting a field to its default value
3340     // should make the message different.
3341     TestNanoAccessors g = createMessageWithAccessorsForHashCodeEqualsTest();
3342     g.setOptionalInt32(g.getOptionalInt32() + 1); // make different from f
3343     g.clearDefaultString();
3344     TestNanoAccessors gDifferent = createMessageWithAccessorsForHashCodeEqualsTest();
3345     gDifferent.setOptionalInt32(g.getOptionalInt32());
3346     gDifferent.setDefaultString(g.getDefaultString());
3347 
3348     // Complete equality for reference typed messages:
3349     NanoReferenceTypes.TestAllTypesNano h = createRefTypedMessageForHashCodeEqualsTest();
3350     NanoReferenceTypes.TestAllTypesNano hEquivalent = createRefTypedMessageForHashCodeEqualsTest();
3351 
3352     // Inequality of null and default value for reference typed messages:
3353     NanoReferenceTypes.TestAllTypesNano i = createRefTypedMessageForHashCodeEqualsTest();
3354     i.optionalInt32 = 1; // make different from h
3355     i.optionalFloat = null;
3356     NanoReferenceTypes.TestAllTypesNano iDifferent = createRefTypedMessageForHashCodeEqualsTest();
3357     iDifferent.optionalInt32 = i.optionalInt32;
3358     iDifferent.optionalFloat = 0.0f;
3359 
3360     HashMap<MessageNano, String> hashMap = new HashMap<MessageNano, String>();
3361     hashMap.put(a, "a");
3362     hashMap.put(b, "b");
3363     hashMap.put(c, "c");
3364     hashMap.put(d, "d");
3365     hashMap.put(e, "e");
3366     hashMap.put(f, "f");
3367     hashMap.put(g, "g");
3368     hashMap.put(h, "h");
3369     hashMap.put(i, "i");
3370 
3371     assertEquals(9, hashMap.size()); // a-i should be different from each other.
3372 
3373     assertEquals("a", hashMap.get(a));
3374     assertEquals("a", hashMap.get(aEquivalent));
3375 
3376     assertEquals("b", hashMap.get(b));
3377     assertEquals("b", hashMap.get(bEquivalent));
3378 
3379     assertEquals("c", hashMap.get(c));
3380     assertEquals("c", hashMap.get(cEquivalent));
3381 
3382     assertEquals("d", hashMap.get(d));
3383     assertEquals("d", hashMap.get(dEquivalent));
3384 
3385     assertEquals("e", hashMap.get(e));
3386     assertNull(hashMap.get(eDifferent));
3387 
3388     assertEquals("f", hashMap.get(f));
3389     assertEquals("f", hashMap.get(fEquivalent));
3390 
3391     assertEquals("g", hashMap.get(g));
3392     assertNull(hashMap.get(gDifferent));
3393 
3394     assertEquals("h", hashMap.get(h));
3395     assertEquals("h", hashMap.get(hEquivalent));
3396 
3397     assertEquals("i", hashMap.get(i));
3398     assertNull(hashMap.get(iDifferent));
3399   }
3400 
createMessageForHashCodeEqualsTest()3401   private TestAllTypesNano createMessageForHashCodeEqualsTest() {
3402     TestAllTypesNano message = new TestAllTypesNano();
3403     message.optionalInt32 = 5;
3404     message.optionalInt64 = 777;
3405     message.optionalFloat = 1.0f;
3406     message.optionalDouble = 2.0;
3407     message.optionalBool = true;
3408     message.optionalString = "Hello";
3409     message.optionalBytes = new byte[] { 1, 2, 3 };
3410     message.optionalNestedMessage = new TestAllTypesNano.NestedMessage();
3411     message.optionalNestedMessage.bb = 27;
3412     message.optionalNestedEnum = TestAllTypesNano.BAR;
3413     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
3414     message.repeatedInt64 = new long[] { 27L, 28L, 29L };
3415     message.repeatedFloat = new float[] { 5.0f, 6.0f };
3416     message.repeatedDouble = new double[] { 99.1, 22.5 };
3417     message.repeatedBool = new boolean[] { true, false, true };
3418     message.repeatedString = new String[] { "One", "Two" };
3419     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
3420     message.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
3421       message.optionalNestedMessage,
3422       message.optionalNestedMessage
3423     };
3424     message.repeatedNestedEnum = new int[] {
3425       TestAllTypesNano.BAR,
3426       TestAllTypesNano.BAZ
3427     };
3428     message.setOneofUint32(3);
3429     return message;
3430   }
3431 
createMessageWithHasForHashCodeEqualsTest()3432   private TestAllTypesNanoHas createMessageWithHasForHashCodeEqualsTest() {
3433     TestAllTypesNanoHas message = new TestAllTypesNanoHas();
3434     message.optionalInt32 = 5;
3435     message.optionalString = "Hello";
3436     message.optionalBytes = new byte[] { 1, 2, 3 };
3437     message.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
3438     message.optionalNestedMessage.bb = 27;
3439     message.optionalNestedEnum = TestAllTypesNano.BAR;
3440     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
3441     message.repeatedString = new String[] { "One", "Two" };
3442     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
3443     message.repeatedNestedMessage = new TestAllTypesNanoHas.NestedMessage[] {
3444       message.optionalNestedMessage,
3445       message.optionalNestedMessage
3446     };
3447     message.repeatedNestedEnum = new int[] {
3448       TestAllTypesNano.BAR,
3449       TestAllTypesNano.BAZ
3450     };
3451     return message;
3452   }
3453 
createMessageWithAccessorsForHashCodeEqualsTest()3454   private TestNanoAccessors createMessageWithAccessorsForHashCodeEqualsTest() {
3455     TestNanoAccessors message = new TestNanoAccessors()
3456         .setOptionalInt32(5)
3457         .setOptionalString("Hello")
3458         .setOptionalBytes(new byte[] {1, 2, 3})
3459         .setOptionalNestedEnum(TestNanoAccessors.BAR);
3460     message.optionalNestedMessage = new TestNanoAccessors.NestedMessage().setBb(27);
3461     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
3462     message.repeatedString = new String[] { "One", "Two" };
3463     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
3464     message.repeatedNestedMessage = new TestNanoAccessors.NestedMessage[] {
3465       message.optionalNestedMessage,
3466       message.optionalNestedMessage
3467     };
3468     message.repeatedNestedEnum = new int[] {
3469       TestAllTypesNano.BAR,
3470       TestAllTypesNano.BAZ
3471     };
3472     return message;
3473   }
3474 
createRefTypedMessageForHashCodeEqualsTest()3475   private NanoReferenceTypes.TestAllTypesNano createRefTypedMessageForHashCodeEqualsTest() {
3476     NanoReferenceTypes.TestAllTypesNano message = new NanoReferenceTypes.TestAllTypesNano();
3477     message.optionalInt32 = 5;
3478     message.optionalInt64 = 777L;
3479     message.optionalFloat = 1.0f;
3480     message.optionalDouble = 2.0;
3481     message.optionalBool = true;
3482     message.optionalString = "Hello";
3483     message.optionalBytes = new byte[] { 1, 2, 3 };
3484     message.optionalNestedMessage =
3485         new NanoReferenceTypes.TestAllTypesNano.NestedMessage();
3486     message.optionalNestedMessage.foo = 27;
3487     message.optionalNestedEnum = NanoReferenceTypes.TestAllTypesNano.BAR;
3488     message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
3489     message.repeatedInt64 = new long[] { 27L, 28L, 29L };
3490     message.repeatedFloat = new float[] { 5.0f, 6.0f };
3491     message.repeatedDouble = new double[] { 99.1, 22.5 };
3492     message.repeatedBool = new boolean[] { true, false, true };
3493     message.repeatedString = new String[] { "One", "Two" };
3494     message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
3495     message.repeatedNestedMessage =
3496         new NanoReferenceTypes.TestAllTypesNano.NestedMessage[] {
3497           message.optionalNestedMessage,
3498           message.optionalNestedMessage
3499         };
3500     message.repeatedNestedEnum = new int[] {
3501       NanoReferenceTypes.TestAllTypesNano.BAR,
3502       NanoReferenceTypes.TestAllTypesNano.BAZ
3503     };
3504     return message;
3505   }
3506 
testEqualsWithSpecialFloatingPointValues()3507   public void testEqualsWithSpecialFloatingPointValues() throws Exception {
3508     // Checks that the nano implementation complies with Object.equals() when treating
3509     // floating point numbers, i.e. NaN == NaN and +0.0 != -0.0.
3510     // This test assumes that the generated equals() implementations are symmetric, so
3511     // there will only be one direction for each equality check.
3512 
3513     TestAllTypesNano m1 = new TestAllTypesNano();
3514     m1.optionalFloat = Float.NaN;
3515     m1.optionalDouble = Double.NaN;
3516     TestAllTypesNano m2 = new TestAllTypesNano();
3517     m2.optionalFloat = Float.NaN;
3518     m2.optionalDouble = Double.NaN;
3519     assertTrue(m1.equals(m2));
3520     assertTrue(m1.equals(
3521         MessageNano.mergeFrom(new TestAllTypesNano(), MessageNano.toByteArray(m1))));
3522 
3523     m1.optionalFloat = +0f;
3524     m2.optionalFloat = -0f;
3525     assertFalse(m1.equals(m2));
3526 
3527     m1.optionalFloat = -0f;
3528     m1.optionalDouble = +0d;
3529     m2.optionalDouble = -0d;
3530     assertFalse(m1.equals(m2));
3531 
3532     m1.optionalDouble = -0d;
3533     assertTrue(m1.equals(m2));
3534     assertFalse(m1.equals(new TestAllTypesNano())); // -0 does not equals() the default +0
3535     assertTrue(m1.equals(
3536         MessageNano.mergeFrom(new TestAllTypesNano(), MessageNano.toByteArray(m1))));
3537 
3538     // -------
3539 
3540     TestAllTypesNanoHas m3 = new TestAllTypesNanoHas();
3541     m3.optionalFloat = Float.NaN;
3542     m3.hasOptionalFloat = true;
3543     m3.optionalDouble = Double.NaN;
3544     m3.hasOptionalDouble = true;
3545     TestAllTypesNanoHas m4 = new TestAllTypesNanoHas();
3546     m4.optionalFloat = Float.NaN;
3547     m4.hasOptionalFloat = true;
3548     m4.optionalDouble = Double.NaN;
3549     m4.hasOptionalDouble = true;
3550     assertTrue(m3.equals(m4));
3551     assertTrue(m3.equals(
3552         MessageNano.mergeFrom(new TestAllTypesNanoHas(), MessageNano.toByteArray(m3))));
3553 
3554     m3.optionalFloat = +0f;
3555     m4.optionalFloat = -0f;
3556     assertFalse(m3.equals(m4));
3557 
3558     m3.optionalFloat = -0f;
3559     m3.optionalDouble = +0d;
3560     m4.optionalDouble = -0d;
3561     assertFalse(m3.equals(m4));
3562 
3563     m3.optionalDouble = -0d;
3564     m3.hasOptionalFloat = false;  // -0 does not equals() the default +0,
3565     m3.hasOptionalDouble = false; // so these incorrect 'has' flags should be disregarded.
3566     assertTrue(m3.equals(m4));    // note: m4 has the 'has' flags set.
3567     assertFalse(m3.equals(new TestAllTypesNanoHas())); // note: the new message has +0 defaults
3568     assertTrue(m3.equals(
3569         MessageNano.mergeFrom(new TestAllTypesNanoHas(), MessageNano.toByteArray(m3))));
3570                                   // note: the deserialized message has the 'has' flags set.
3571 
3572     // -------
3573 
3574     TestNanoAccessors m5 = new TestNanoAccessors();
3575     m5.setOptionalFloat(Float.NaN);
3576     m5.setOptionalDouble(Double.NaN);
3577     TestNanoAccessors m6 = new TestNanoAccessors();
3578     m6.setOptionalFloat(Float.NaN);
3579     m6.setOptionalDouble(Double.NaN);
3580     assertTrue(m5.equals(m6));
3581     assertTrue(m5.equals(
3582         MessageNano.mergeFrom(new TestNanoAccessors(), MessageNano.toByteArray(m6))));
3583 
3584     m5.setOptionalFloat(+0f);
3585     m6.setOptionalFloat(-0f);
3586     assertFalse(m5.equals(m6));
3587 
3588     m5.setOptionalFloat(-0f);
3589     m5.setOptionalDouble(+0d);
3590     m6.setOptionalDouble(-0d);
3591     assertFalse(m5.equals(m6));
3592 
3593     m5.setOptionalDouble(-0d);
3594     assertTrue(m5.equals(m6));
3595     assertFalse(m5.equals(new TestNanoAccessors()));
3596     assertTrue(m5.equals(
3597         MessageNano.mergeFrom(new TestNanoAccessors(), MessageNano.toByteArray(m6))));
3598 
3599     // -------
3600 
3601     NanoReferenceTypes.TestAllTypesNano m7 = new NanoReferenceTypes.TestAllTypesNano();
3602     m7.optionalFloat = Float.NaN;
3603     m7.optionalDouble = Double.NaN;
3604     NanoReferenceTypes.TestAllTypesNano m8 = new NanoReferenceTypes.TestAllTypesNano();
3605     m8.optionalFloat = Float.NaN;
3606     m8.optionalDouble = Double.NaN;
3607     assertTrue(m7.equals(m8));
3608     assertTrue(m7.equals(MessageNano.mergeFrom(
3609         new NanoReferenceTypes.TestAllTypesNano(), MessageNano.toByteArray(m7))));
3610 
3611     m7.optionalFloat = +0f;
3612     m8.optionalFloat = -0f;
3613     assertFalse(m7.equals(m8));
3614 
3615     m7.optionalFloat = -0f;
3616     m7.optionalDouble = +0d;
3617     m8.optionalDouble = -0d;
3618     assertFalse(m7.equals(m8));
3619 
3620     m7.optionalDouble = -0d;
3621     assertTrue(m7.equals(m8));
3622     assertFalse(m7.equals(new NanoReferenceTypes.TestAllTypesNano()));
3623     assertTrue(m7.equals(MessageNano.mergeFrom(
3624         new NanoReferenceTypes.TestAllTypesNano(), MessageNano.toByteArray(m7))));
3625   }
3626 
generateMessageForOneof(int caseNumber)3627   private static TestAllTypesNano generateMessageForOneof(int caseNumber) {
3628     TestAllTypesNano result = new TestAllTypesNano();
3629     TestAllTypesNano.NestedMessage nested =
3630         new TestAllTypesNano.NestedMessage();
3631     nested.bb = 2;
3632     switch (caseNumber) {
3633       case TestAllTypesNano.ONEOF_UINT32_FIELD_NUMBER:
3634         result.setOneofUint32(1);
3635         break;
3636       case TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER:
3637         result.setOneofEnum(TestAllTypesNano.BAR);
3638         break;
3639       case TestAllTypesNano.ONEOF_NESTED_MESSAGE_FIELD_NUMBER:
3640         result.setOneofNestedMessage(nested);
3641         break;
3642       case TestAllTypesNano.ONEOF_BYTES_FIELD_NUMBER:
3643         result.setOneofBytes(new byte[] {1, 2});
3644         break;
3645       case TestAllTypesNano.ONEOF_STRING_FIELD_NUMBER:
3646         result.setOneofString("hello");
3647         break;
3648       case TestAllTypesNano.ONEOF_FIXED64_FIELD_NUMBER:
3649         result.setOneofFixed64(-1L);
3650         break;
3651       default:
3652         throw new RuntimeException("unexpected case number: " + caseNumber);
3653     }
3654     return result;
3655   }
3656 
testOneofHashCodeEquals()3657   public void testOneofHashCodeEquals() throws Exception {
3658     TestAllTypesNano m1 = generateMessageForOneof(
3659         TestAllTypesNano.ONEOF_UINT32_FIELD_NUMBER);
3660     assertEquals(m1, generateMessageForOneof(
3661         TestAllTypesNano.ONEOF_UINT32_FIELD_NUMBER));
3662     assertFalse(m1.equals(new TestAllTypesNano()));
3663 
3664     TestAllTypesNano m2 = generateMessageForOneof(
3665         TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER);
3666     assertEquals(m2, generateMessageForOneof(
3667         TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER));
3668     assertFalse(m2.equals(new TestAllTypesNano()));
3669 
3670     TestAllTypesNano m3 = generateMessageForOneof(
3671         TestAllTypesNano.ONEOF_NESTED_MESSAGE_FIELD_NUMBER);
3672     assertEquals(m3, generateMessageForOneof(
3673         TestAllTypesNano.ONEOF_NESTED_MESSAGE_FIELD_NUMBER));
3674     assertFalse(m3.equals(new TestAllTypesNano()));
3675 
3676     TestAllTypesNano m4 = generateMessageForOneof(
3677         TestAllTypesNano.ONEOF_BYTES_FIELD_NUMBER);
3678     assertEquals(m4, generateMessageForOneof(
3679         TestAllTypesNano.ONEOF_BYTES_FIELD_NUMBER));
3680     assertFalse(m4.equals(new TestAllTypesNano()));
3681 
3682     TestAllTypesNano m5 = generateMessageForOneof(
3683         TestAllTypesNano.ONEOF_STRING_FIELD_NUMBER);
3684     assertEquals(m5, generateMessageForOneof(
3685         TestAllTypesNano.ONEOF_STRING_FIELD_NUMBER));
3686     assertFalse(m5.equals(new TestAllTypesNano()));
3687 
3688     TestAllTypesNano m6 = generateMessageForOneof(
3689         TestAllTypesNano.ONEOF_FIXED64_FIELD_NUMBER);
3690     assertEquals(m6, generateMessageForOneof(
3691         TestAllTypesNano.ONEOF_FIXED64_FIELD_NUMBER));
3692     assertFalse(m6.equals(new TestAllTypesNano()));
3693 
3694     Map<TestAllTypesNano, Integer> map =
3695         new HashMap<TestAllTypesNano, Integer>();
3696     map.put(m1, 1);
3697     map.put(m2, 2);
3698     map.put(m3, 3);
3699     map.put(m4, 4);
3700     map.put(m5, 5);
3701     map.put(m6, 6);
3702 
3703     assertEquals(6, map.size());
3704   }
3705 
checkOneofCase(TestAllTypesNano nano, int field)3706   private void checkOneofCase(TestAllTypesNano nano, int field)
3707       throws Exception {
3708     assertEquals(field, nano.getOneofFieldCase());
3709     assertEquals(
3710         field == TestAllTypesNano.ONEOF_BYTES_FIELD_NUMBER,
3711         nano.hasOneofBytes());
3712     assertEquals(
3713         field == TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER,
3714         nano.hasOneofEnum());
3715     assertEquals(
3716         field == TestAllTypesNano.ONEOF_FIXED64_FIELD_NUMBER,
3717         nano.hasOneofFixed64());
3718     assertEquals(
3719         field == TestAllTypesNano.ONEOF_NESTED_MESSAGE_FIELD_NUMBER,
3720         nano.hasOneofNestedMessage());
3721     assertEquals(
3722         field == TestAllTypesNano.ONEOF_STRING_FIELD_NUMBER,
3723         nano.hasOneofString());
3724     assertEquals(
3725         field == TestAllTypesNano.ONEOF_UINT32_FIELD_NUMBER,
3726         nano.hasOneofUint32());
3727 
3728   }
3729 
testOneofDefault()3730   public void testOneofDefault() throws Exception {
3731     TestAllTypesNano m1 = new TestAllTypesNano();
3732     checkOneofCase(m1, 0);
3733     assertEquals(WireFormatNano.EMPTY_BYTES, m1.getOneofBytes());
3734     assertEquals(TestAllTypesNano.FOO, m1.getOneofEnum());
3735     assertEquals(0L, m1.getOneofFixed64());
3736     assertEquals(null, m1.getOneofNestedMessage());
3737     assertEquals("", m1.getOneofString());
3738     assertEquals(0, m1.getOneofUint32());
3739   }
3740 
testOneofExclusiveness()3741   public void testOneofExclusiveness() throws Exception {
3742     TestAllTypesNano m = new TestAllTypesNano();
3743     checkOneofCase(m, 0);
3744 
3745     m.setOneofBytes(new byte[]{0, 1});
3746     checkOneofCase(m, TestAllTypesNano.ONEOF_BYTES_FIELD_NUMBER);
3747     assertTrue(Arrays.equals(new byte[]{0,  1}, m.getOneofBytes()));
3748 
3749     m.setOneofEnum(TestAllTypesNano.BAZ);
3750     checkOneofCase(m, TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER);
3751     assertEquals(TestAllTypesNano.BAZ, m.getOneofEnum());
3752     assertEquals(WireFormatNano.EMPTY_BYTES, m.getOneofBytes());
3753 
3754     m.setOneofFixed64(-1L);
3755     checkOneofCase(m, TestAllTypesNano.ONEOF_FIXED64_FIELD_NUMBER);
3756     assertEquals(-1L, m.getOneofFixed64());
3757     assertEquals(TestAllTypesNano.FOO, m.getOneofEnum());
3758 
3759     m.setOneofNestedMessage(new TestAllTypesNano.NestedMessage());
3760     checkOneofCase(m, TestAllTypesNano.ONEOF_NESTED_MESSAGE_FIELD_NUMBER);
3761     assertEquals(
3762         new TestAllTypesNano.NestedMessage(), m.getOneofNestedMessage());
3763     assertEquals(0L, m.getOneofFixed64());
3764 
3765     m.setOneofString("hello");
3766     checkOneofCase(m, TestAllTypesNano.ONEOF_STRING_FIELD_NUMBER);
3767     assertEquals("hello", m.getOneofString());
3768     assertNull(m.getOneofNestedMessage());
3769 
3770     m.setOneofUint32(10);
3771     checkOneofCase(m, TestAllTypesNano.ONEOF_UINT32_FIELD_NUMBER);
3772     assertEquals(10, m.getOneofUint32());
3773     assertEquals("", m.getOneofString());
3774 
3775     m.setOneofBytes(new byte[]{0, 1});
3776     checkOneofCase(m, TestAllTypesNano.ONEOF_BYTES_FIELD_NUMBER);
3777     assertTrue(Arrays.equals(new byte[]{0,  1}, m.getOneofBytes()));
3778     assertEquals(0, m.getOneofUint32());
3779   }
3780 
testOneofClear()3781   public void testOneofClear() throws Exception {
3782     TestAllTypesNano m = new TestAllTypesNano();
3783     m.setOneofBytes(new byte[]{0, 1});
3784     m.clearOneofField();
3785     checkOneofCase(m, 0);
3786 
3787     m.setOneofEnum(TestAllTypesNano.BAZ);
3788     m.clearOneofField();
3789     checkOneofCase(m, 0);
3790 
3791     m.setOneofFixed64(-1L);
3792     m.clearOneofField();
3793     checkOneofCase(m, 0);
3794 
3795     m.setOneofNestedMessage(new TestAllTypesNano.NestedMessage());
3796     m.clearOneofField();
3797     checkOneofCase(m, 0);
3798 
3799     m.setOneofString("hello");
3800     m.clearOneofField();
3801     checkOneofCase(m, 0);
3802 
3803     m.setOneofUint32(10);
3804     m.clearOneofField();
3805     checkOneofCase(m, 0);
3806   }
3807 
testOneofMarshaling()3808   public void testOneofMarshaling() throws Exception {
3809     TestAllTypesNano m = new TestAllTypesNano();
3810     TestAllTypesNano parsed = new TestAllTypesNano();
3811     {
3812       m.setOneofBytes(new byte[]{0, 1});
3813       byte[] serialized = MessageNano.toByteArray(m);
3814       MessageNano.mergeFrom(parsed, serialized);
3815       checkOneofCase(parsed, TestAllTypesNano.ONEOF_BYTES_FIELD_NUMBER);
3816       assertTrue(Arrays.equals(new byte[]{0, 1}, parsed.getOneofBytes()));
3817     }
3818     {
3819       m.setOneofEnum(TestAllTypesNano.BAZ);
3820       byte[] serialized = MessageNano.toByteArray(m);
3821       MessageNano.mergeFrom(parsed, serialized);
3822       checkOneofCase(m, TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER);
3823       assertEquals(TestAllTypesNano.BAZ, m.getOneofEnum());
3824     }
3825     {
3826       m.setOneofEnum(TestAllTypesNano.BAZ);
3827       byte[] serialized = MessageNano.toByteArray(m);
3828       MessageNano.mergeFrom(parsed, serialized);
3829       checkOneofCase(m, TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER);
3830       assertEquals(TestAllTypesNano.BAZ, m.getOneofEnum());
3831     }
3832     {
3833       m.setOneofFixed64(-1L);
3834       byte[] serialized = MessageNano.toByteArray(m);
3835       MessageNano.mergeFrom(parsed, serialized);
3836       checkOneofCase(m, TestAllTypesNano.ONEOF_FIXED64_FIELD_NUMBER);
3837       assertEquals(-1L, m.getOneofFixed64());
3838     }
3839     {
3840       m.setOneofNestedMessage(new TestAllTypesNano.NestedMessage());
3841       byte[] serialized = MessageNano.toByteArray(m);
3842       MessageNano.mergeFrom(parsed, serialized);
3843       checkOneofCase(m, TestAllTypesNano.ONEOF_NESTED_MESSAGE_FIELD_NUMBER);
3844       assertEquals(
3845           new TestAllTypesNano.NestedMessage(), m.getOneofNestedMessage());
3846     }
3847     {
3848       m.setOneofString("hello");
3849       byte[] serialized = MessageNano.toByteArray(m);
3850       MessageNano.mergeFrom(parsed, serialized);
3851       assertEquals("hello", m.getOneofString());
3852       assertNull(m.getOneofNestedMessage());
3853     }
3854     {
3855       m.setOneofUint32(10);
3856       byte[] serialized = MessageNano.toByteArray(m);
3857       MessageNano.mergeFrom(parsed, serialized);
3858       checkOneofCase(m, TestAllTypesNano.ONEOF_UINT32_FIELD_NUMBER);
3859       assertEquals(10, m.getOneofUint32());
3860     }
3861   }
3862 
testOneofSerializedConcat()3863   public void testOneofSerializedConcat() throws Exception {
3864     TestAllTypesNano m1 = new TestAllTypesNano();
3865     m1.setOneofBytes(new byte[] {0, 1});
3866     byte[] b1 = MessageNano.toByteArray(m1);
3867     TestAllTypesNano m2 = new TestAllTypesNano();
3868     m2.setOneofEnum(TestAllTypesNano.BAZ);
3869     byte[] b2 = MessageNano.toByteArray(m2);
3870     byte[] b3 = new byte[b1.length + b2.length];
3871     System.arraycopy(b1, 0, b3, 0, b1.length);
3872     System.arraycopy(b2, 0, b3, b1.length, b2.length);
3873     TestAllTypesNano parsed = new TestAllTypesNano();
3874     MessageNano.mergeFrom(parsed, b3);
3875     // the last on the wire wins.
3876     checkOneofCase(parsed, TestAllTypesNano.ONEOF_ENUM_FIELD_NUMBER);
3877     assertEquals(TestAllTypesNano.BAZ, parsed.getOneofEnum());
3878   }
3879 
testNullRepeatedFields()3880   public void testNullRepeatedFields() throws Exception {
3881     // Check that serialization after explicitly setting a repeated field
3882     // to null doesn't NPE.
3883     TestAllTypesNano message = new TestAllTypesNano();
3884     message.repeatedInt32 = null;
3885     MessageNano.toByteArray(message);  // should not NPE
3886     message.toString(); // should not NPE
3887 
3888     message.repeatedNestedEnum = null;
3889     MessageNano.toByteArray(message);  // should not NPE
3890     message.toString(); // should not NPE
3891 
3892     message.repeatedBytes = null;
3893     MessageNano.toByteArray(message); // should not NPE
3894     message.toString(); // should not NPE
3895 
3896     message.repeatedNestedMessage = null;
3897     MessageNano.toByteArray(message); // should not NPE
3898     message.toString(); // should not NPE
3899 
3900     message.repeatedPackedInt32 = null;
3901     MessageNano.toByteArray(message); // should not NPE
3902     message.toString(); // should not NPE
3903 
3904     message.repeatedPackedNestedEnum = null;
3905     MessageNano.toByteArray(message); // should not NPE
3906     message.toString(); // should not NPE
3907 
3908     // Create a second message to merge into message.
3909     TestAllTypesNano secondMessage = new TestAllTypesNano();
3910     secondMessage.repeatedInt32 = new int[] {1, 2, 3};
3911     secondMessage.repeatedNestedEnum = new int[] {
3912       TestAllTypesNano.FOO, TestAllTypesNano.BAR
3913     };
3914     secondMessage.repeatedBytes = new byte[][] {{1, 2}, {3, 4}};
3915     TestAllTypesNano.NestedMessage nested =
3916         new TestAllTypesNano.NestedMessage();
3917     nested.bb = 55;
3918     secondMessage.repeatedNestedMessage =
3919         new TestAllTypesNano.NestedMessage[] {nested};
3920     secondMessage.repeatedPackedInt32 = new int[] {1, 2, 3};
3921     secondMessage.repeatedPackedNestedEnum = new int[] {
3922         TestAllTypesNano.FOO, TestAllTypesNano.BAR
3923       };
3924 
3925     // Should not NPE
3926     message.mergeFrom(CodedInputByteBufferNano.newInstance(
3927         MessageNano.toByteArray(secondMessage)));
3928     assertEquals(3, message.repeatedInt32.length);
3929     assertEquals(3, message.repeatedInt32[2]);
3930     assertEquals(2, message.repeatedNestedEnum.length);
3931     assertEquals(TestAllTypesNano.FOO, message.repeatedNestedEnum[0]);
3932     assertEquals(2, message.repeatedBytes.length);
3933     assertEquals(4, message.repeatedBytes[1][1]);
3934     assertEquals(1, message.repeatedNestedMessage.length);
3935     assertEquals(55, message.repeatedNestedMessage[0].bb);
3936     assertEquals(3, message.repeatedPackedInt32.length);
3937     assertEquals(2, message.repeatedPackedInt32[1]);
3938     assertEquals(2, message.repeatedPackedNestedEnum.length);
3939     assertEquals(TestAllTypesNano.BAR, message.repeatedPackedNestedEnum[1]);
3940   }
3941 
testNullRepeatedFieldElements()3942   public void testNullRepeatedFieldElements() throws Exception {
3943     // Check that serialization with null array elements doesn't NPE.
3944     String string1 = "1";
3945     String string2 = "2";
3946     byte[] bytes1 = {3, 4};
3947     byte[] bytes2 = {5, 6};
3948     TestAllTypesNano.NestedMessage msg1 = new TestAllTypesNano.NestedMessage();
3949     msg1.bb = 7;
3950     TestAllTypesNano.NestedMessage msg2 = new TestAllTypesNano.NestedMessage();
3951     msg2.bb = 8;
3952 
3953     TestAllTypesNano message = new TestAllTypesNano();
3954     message.repeatedString = new String[] {null, string1, string2};
3955     message.repeatedBytes = new byte[][] {bytes1, null, bytes2};
3956     message.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {msg1, msg2, null};
3957     message.repeatedGroup = new TestAllTypesNano.RepeatedGroup[] {null, null, null};
3958 
3959     byte[] serialized = MessageNano.toByteArray(message); // should not NPE
3960     TestAllTypesNano deserialized = MessageNano.mergeFrom(new TestAllTypesNano(), serialized);
3961     assertEquals(2, deserialized.repeatedString.length);
3962     assertEquals(string1, deserialized.repeatedString[0]);
3963     assertEquals(string2, deserialized.repeatedString[1]);
3964     assertEquals(2, deserialized.repeatedBytes.length);
3965     assertTrue(Arrays.equals(bytes1, deserialized.repeatedBytes[0]));
3966     assertTrue(Arrays.equals(bytes2, deserialized.repeatedBytes[1]));
3967     assertEquals(2, deserialized.repeatedNestedMessage.length);
3968     assertEquals(msg1.bb, deserialized.repeatedNestedMessage[0].bb);
3969     assertEquals(msg2.bb, deserialized.repeatedNestedMessage[1].bb);
3970     assertEquals(0, deserialized.repeatedGroup.length);
3971   }
3972 
testRepeatedMerge()3973   public void testRepeatedMerge() throws Exception {
3974     // Check that merging repeated fields cause the arrays to expand with
3975     // new data.
3976     TestAllTypesNano first = new TestAllTypesNano();
3977     first.repeatedInt32 = new int[] {1, 2, 3};
3978     TestAllTypesNano second = new TestAllTypesNano();
3979     second.repeatedInt32 = new int[] {4, 5};
3980     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
3981     assertEquals(5, first.repeatedInt32.length);
3982     assertEquals(1, first.repeatedInt32[0]);
3983     assertEquals(4, first.repeatedInt32[3]);
3984 
3985     first = new TestAllTypesNano();
3986     first.repeatedNestedEnum = new int[] {TestAllTypesNano.BAR};
3987     second = new TestAllTypesNano();
3988     second.repeatedNestedEnum = new int[] {TestAllTypesNano.FOO};
3989     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
3990     assertEquals(2, first.repeatedNestedEnum.length);
3991     assertEquals(TestAllTypesNano.BAR, first.repeatedNestedEnum[0]);
3992     assertEquals(TestAllTypesNano.FOO, first.repeatedNestedEnum[1]);
3993 
3994     first = new TestAllTypesNano();
3995     first.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
3996       new TestAllTypesNano.NestedMessage()
3997     };
3998     first.repeatedNestedMessage[0].bb = 3;
3999     second = new TestAllTypesNano();
4000     second.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
4001       new TestAllTypesNano.NestedMessage()
4002     };
4003     second.repeatedNestedMessage[0].bb = 5;
4004     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
4005     assertEquals(2, first.repeatedNestedMessage.length);
4006     assertEquals(3, first.repeatedNestedMessage[0].bb);
4007     assertEquals(5, first.repeatedNestedMessage[1].bb);
4008 
4009     first = new TestAllTypesNano();
4010     first.repeatedPackedSfixed64 = new long[] {-1, -2, -3};
4011     second = new TestAllTypesNano();
4012     second.repeatedPackedSfixed64 = new long[] {-4, -5};
4013     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
4014     assertEquals(5, first.repeatedPackedSfixed64.length);
4015     assertEquals(-1, first.repeatedPackedSfixed64[0]);
4016     assertEquals(-4, first.repeatedPackedSfixed64[3]);
4017 
4018     first = new TestAllTypesNano();
4019     first.repeatedPackedNestedEnum = new int[] {TestAllTypesNano.BAR};
4020     second = new TestAllTypesNano();
4021     second.repeatedPackedNestedEnum = new int[] {TestAllTypesNano.FOO};
4022     MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
4023     assertEquals(2, first.repeatedPackedNestedEnum.length);
4024     assertEquals(TestAllTypesNano.BAR, first.repeatedPackedNestedEnum[0]);
4025     assertEquals(TestAllTypesNano.FOO, first.repeatedPackedNestedEnum[1]);
4026 
4027     // Now test repeated merging in a nested scope
4028     TestRepeatedMergeNano firstContainer = new TestRepeatedMergeNano();
4029     firstContainer.contained = new TestAllTypesNano();
4030     firstContainer.contained.repeatedInt32 = new int[] {10, 20};
4031     TestRepeatedMergeNano secondContainer = new TestRepeatedMergeNano();
4032     secondContainer.contained = new TestAllTypesNano();
4033     secondContainer.contained.repeatedInt32 = new int[] {30};
4034     MessageNano.mergeFrom(firstContainer, MessageNano.toByteArray(secondContainer));
4035     assertEquals(3, firstContainer.contained.repeatedInt32.length);
4036     assertEquals(20, firstContainer.contained.repeatedInt32[1]);
4037     assertEquals(30, firstContainer.contained.repeatedInt32[2]);
4038   }
4039 
testRepeatedPackables()4040   public void testRepeatedPackables() throws Exception {
4041     // Check that repeated fields with packable types can accept both packed and unpacked
4042     // serialized forms.
4043     NanoRepeatedPackables.NonPacked nonPacked = new NanoRepeatedPackables.NonPacked();
4044     // Exaggerates the first values of varint-typed arrays. This is to test that the parsing code
4045     // of packed fields handles non-packed data correctly. If the code incorrectly thinks it is
4046     // reading from a packed tag, it will read the first value as the byte length of the field,
4047     // and the large number will cause the input to go out of bounds, thus capturing the error.
4048     nonPacked.int32S = new int[] {1000, 2, 3};
4049     nonPacked.int64S = new long[] {4000, 5, 6};
4050     nonPacked.uint32S = new int[] {7000, 8, 9};
4051     nonPacked.uint64S = new long[] {10000, 11, 12};
4052     nonPacked.sint32S = new int[] {13000, 14, 15};
4053     nonPacked.sint64S = new long[] {16000, 17, 18};
4054     nonPacked.fixed32S = new int[] {19, 20, 21};
4055     nonPacked.fixed64S = new long[] {22, 23, 24};
4056     nonPacked.sfixed32S = new int[] {25, 26, 27};
4057     nonPacked.sfixed64S = new long[] {28, 29, 30};
4058     nonPacked.floats = new float[] {31, 32, 33};
4059     nonPacked.doubles = new double[] {34, 35, 36};
4060     nonPacked.bools = new boolean[] {false, true};
4061     nonPacked.enums = new int[] {
4062       NanoRepeatedPackables.Enum.OPTION_ONE,
4063       NanoRepeatedPackables.Enum.OPTION_TWO,
4064     };
4065     nonPacked.noise = 13579;
4066 
4067     byte[] nonPackedSerialized = MessageNano.toByteArray(nonPacked);
4068 
4069     NanoRepeatedPackables.Packed packed =
4070         MessageNano.mergeFrom(new NanoRepeatedPackables.Packed(), nonPackedSerialized);
4071     assertRepeatedPackablesEqual(nonPacked, packed);
4072 
4073     byte[] packedSerialized = MessageNano.toByteArray(packed);
4074     // Just a cautious check that the two serialized forms are different,
4075     // to make sure the remaining of this test is useful:
4076     assertFalse(Arrays.equals(nonPackedSerialized, packedSerialized));
4077 
4078     nonPacked = MessageNano.mergeFrom(new NanoRepeatedPackables.NonPacked(), packedSerialized);
4079     assertRepeatedPackablesEqual(nonPacked, packed);
4080 
4081     // Test mixed serialized form.
4082     byte[] mixedSerialized = new byte[nonPackedSerialized.length + packedSerialized.length];
4083     System.arraycopy(nonPackedSerialized, 0, mixedSerialized, 0, nonPackedSerialized.length);
4084     System.arraycopy(packedSerialized, 0,
4085         mixedSerialized, nonPackedSerialized.length, packedSerialized.length);
4086 
4087     nonPacked = MessageNano.mergeFrom(new NanoRepeatedPackables.NonPacked(), mixedSerialized);
4088     packed = MessageNano.mergeFrom(new NanoRepeatedPackables.Packed(), mixedSerialized);
4089     assertRepeatedPackablesEqual(nonPacked, packed);
4090     assertTrue(Arrays.equals(new int[] {1000, 2, 3, 1000, 2, 3}, nonPacked.int32S));
4091     assertTrue(Arrays.equals(new int[] {13000, 14, 15, 13000, 14, 15}, nonPacked.sint32S));
4092     assertTrue(Arrays.equals(new int[] {25, 26, 27, 25, 26, 27}, nonPacked.sfixed32S));
4093     assertTrue(Arrays.equals(new boolean[] {false, true, false, true}, nonPacked.bools));
4094   }
4095 
testMapsSerializeAndParse()4096   public void testMapsSerializeAndParse() throws Exception {
4097     TestMap origin = new TestMap();
4098     setMapMessage(origin);
4099     assertMapMessageSet(origin);
4100 
4101     byte[] output = MessageNano.toByteArray(origin);
4102     TestMap parsed = new TestMap();
4103     MessageNano.mergeFrom(parsed, output);
4104   }
4105 
testMapSerializeRejectNull()4106   public void testMapSerializeRejectNull() throws Exception {
4107     TestMap primitiveMap = new TestMap();
4108     primitiveMap.int32ToInt32Field = new HashMap<Integer, Integer>();
4109     primitiveMap.int32ToInt32Field.put(null, 1);
4110     try {
4111       MessageNano.toByteArray(primitiveMap);
4112       fail("should reject null keys");
4113     } catch (IllegalStateException e) {
4114       // pass.
4115     }
4116 
4117     TestMap messageMap = new TestMap();
4118     messageMap.int32ToMessageField =
4119         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4120     messageMap.int32ToMessageField.put(0, null);
4121     try {
4122       MessageNano.toByteArray(messageMap);
4123       fail("should reject null values");
4124     } catch (IllegalStateException e) {
4125       // pass.
4126     }
4127   }
4128 
4129   /**
4130    * Tests that merging bytes containing conflicting keys with override the
4131    * message value instead of merging the message value into the existing entry.
4132    */
testMapMergeOverrideMessageValues()4133   public void testMapMergeOverrideMessageValues() throws Exception {
4134     TestMap.MessageValue origValue = new TestMap.MessageValue();
4135     origValue.value = 1;
4136     origValue.value2 = 2;
4137     TestMap.MessageValue newValue = new TestMap.MessageValue();
4138     newValue.value = 3;
4139 
4140     TestMap origMessage = new TestMap();
4141     origMessage.int32ToMessageField =
4142         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4143     origMessage.int32ToMessageField.put(1, origValue);
4144 
4145     TestMap newMessage = new TestMap();
4146     newMessage.int32ToMessageField =
4147         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4148     newMessage.int32ToMessageField.put(1, newValue);
4149     MessageNano.mergeFrom(origMessage,
4150         MessageNano.toByteArray(newMessage));
4151     TestMap.MessageValue mergedValue = origMessage.int32ToMessageField.get(1);
4152     assertEquals(3, mergedValue.value);
4153     assertEquals(0, mergedValue.value2);
4154   }
4155 
4156   /**
4157    * Tests that when merging with empty entries,
4158    * we will use default for the key and value, instead of null.
4159    */
testMapMergeEmptyEntry()4160   public void testMapMergeEmptyEntry() throws Exception {
4161     TestMap testMap = new TestMap();
4162     byte[] buffer = new byte[1024];
4163     CodedOutputByteBufferNano output =
4164         CodedOutputByteBufferNano.newInstance(buffer);
4165     // An empty entry for int32_to_int32 map.
4166     output.writeTag(1, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
4167     output.writeRawVarint32(0);
4168     // An empty entry for int32_to_message map.
4169     output.writeTag(5, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
4170     output.writeRawVarint32(0);
4171 
4172     CodedInputByteBufferNano input = CodedInputByteBufferNano.newInstance(
4173         buffer, 0, buffer.length - output.spaceLeft());
4174     testMap.mergeFrom(input);
4175     assertNotNull(testMap.int32ToInt32Field);;
4176     assertEquals(1, testMap.int32ToInt32Field.size());
4177     assertEquals(Integer.valueOf(0), testMap.int32ToInt32Field.get(0));
4178     assertNotNull(testMap.int32ToMessageField);
4179     assertEquals(1, testMap.int32ToMessageField.size());
4180     TestMap.MessageValue messageValue = testMap.int32ToMessageField.get(0);
4181     assertNotNull(messageValue);
4182     assertEquals(0, messageValue.value);
4183     assertEquals(0, messageValue.value2);
4184   }
4185 
testMapEquals()4186   public void testMapEquals() throws Exception {
4187     TestMap a = new TestMap();
4188     TestMap b = new TestMap();
4189 
4190     // empty and null map fields are equal.
4191     assertTestMapEqual(a, b);
4192     a.int32ToBytesField = new HashMap<Integer, byte[]>();
4193     assertTestMapEqual(a, b);
4194 
4195     a.int32ToInt32Field = new HashMap<Integer, Integer>();
4196     b.int32ToInt32Field = new HashMap<Integer, Integer>();
4197     setMap(a.int32ToInt32Field, deepCopy(int32Values), deepCopy(int32Values));
4198     setMap(b.int32ToInt32Field, deepCopy(int32Values), deepCopy(int32Values));
4199     assertTestMapEqual(a, b);
4200 
4201     a.int32ToMessageField =
4202         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4203     b.int32ToMessageField =
4204         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4205     setMap(a.int32ToMessageField,
4206         deepCopy(int32Values), deepCopy(messageValues));
4207     setMap(b.int32ToMessageField,
4208         deepCopy(int32Values), deepCopy(messageValues));
4209     assertTestMapEqual(a, b);
4210 
4211     a.stringToInt32Field = new HashMap<String, Integer>();
4212     b.stringToInt32Field = new HashMap<String, Integer>();
4213     setMap(a.stringToInt32Field, deepCopy(stringValues), deepCopy(int32Values));
4214     setMap(b.stringToInt32Field, deepCopy(stringValues), deepCopy(int32Values));
4215     assertTestMapEqual(a, b);
4216 
4217     a.int32ToBytesField = new HashMap<Integer, byte[]>();
4218     b.int32ToBytesField = new HashMap<Integer, byte[]>();
4219     setMap(a.int32ToBytesField, deepCopy(int32Values), deepCopy(bytesValues));
4220     setMap(b.int32ToBytesField, deepCopy(int32Values), deepCopy(bytesValues));
4221     assertTestMapEqual(a, b);
4222 
4223     // Make sure the map implementation does not matter.
4224     a.int32ToStringField = new TreeMap<Integer, String>();
4225     b.int32ToStringField = new HashMap<Integer, String>();
4226     setMap(a.int32ToStringField, deepCopy(int32Values), deepCopy(stringValues));
4227     setMap(b.int32ToStringField, deepCopy(int32Values), deepCopy(stringValues));
4228     assertTestMapEqual(a, b);
4229 
4230     a.clear();
4231     b.clear();
4232 
4233     // unequal cases: different value
4234     a.int32ToInt32Field = new HashMap<Integer, Integer>();
4235     b.int32ToInt32Field = new HashMap<Integer, Integer>();
4236     a.int32ToInt32Field.put(1, 1);
4237     b.int32ToInt32Field.put(1, 2);
4238     assertTestMapUnequal(a, b);
4239     // unequal case: additional entry
4240     b.int32ToInt32Field.put(1, 1);
4241     b.int32ToInt32Field.put(2, 1);
4242     assertTestMapUnequal(a, b);
4243     a.int32ToInt32Field.put(2, 1);
4244     assertTestMapEqual(a, b);
4245 
4246     // unequal case: different message value.
4247     a.int32ToMessageField =
4248         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4249     b.int32ToMessageField =
4250         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4251     MessageValue va = new MessageValue();
4252     va.value = 1;
4253     MessageValue vb = new MessageValue();
4254     vb.value = 1;
4255     a.int32ToMessageField.put(1, va);
4256     b.int32ToMessageField.put(1, vb);
4257     assertTestMapEqual(a, b);
4258     vb.value = 2;
4259     assertTestMapUnequal(a, b);
4260   }
4261 
assertTestMapEqual(TestMap a, TestMap b)4262   private static void assertTestMapEqual(TestMap a, TestMap b)
4263       throws Exception {
4264     assertEquals(a.hashCode(), b.hashCode());
4265     assertTrue(a.equals(b));
4266     assertTrue(b.equals(a));
4267   }
4268 
assertTestMapUnequal(TestMap a, TestMap b)4269   private static void assertTestMapUnequal(TestMap a, TestMap b)
4270       throws Exception {
4271     assertFalse(a.equals(b));
4272     assertFalse(b.equals(a));
4273   }
4274 
4275   private static final Integer[] int32Values = new Integer[] {
4276     0, 1, -1, Integer.MAX_VALUE, Integer.MIN_VALUE,
4277   };
4278 
4279   private static final Long[] int64Values = new Long[] {
4280     0L, 1L, -1L, Long.MAX_VALUE, Long.MIN_VALUE,
4281   };
4282 
4283   private static final String[] stringValues = new String[] {
4284     "", "hello", "world", "foo", "bar",
4285   };
4286 
4287   private static final byte[][] bytesValues = new byte[][] {
4288     new byte[] {},
4289     new byte[] {0},
4290     new byte[] {1, -1},
4291     new byte[] {127, -128},
4292     new byte[] {'a', 'b', '0', '1'},
4293   };
4294 
4295   private static final Boolean[] boolValues = new Boolean[] {
4296     false, true,
4297   };
4298 
4299   private static final Integer[] enumValues = new Integer[] {
4300     TestMap.FOO, TestMap.BAR, TestMap.BAZ, TestMap.QUX,
4301     Integer.MAX_VALUE /* unknown */,
4302   };
4303 
4304   private static final TestMap.MessageValue[] messageValues =
4305       new TestMap.MessageValue[] {
4306     newMapValueMessage(0),
4307     newMapValueMessage(1),
4308     newMapValueMessage(-1),
4309     newMapValueMessage(Integer.MAX_VALUE),
4310     newMapValueMessage(Integer.MIN_VALUE),
4311   };
4312 
newMapValueMessage(int value)4313   private static TestMap.MessageValue newMapValueMessage(int value) {
4314     TestMap.MessageValue result = new TestMap.MessageValue();
4315     result.value = value;
4316     return result;
4317   }
4318 
4319   @SuppressWarnings("unchecked")
deepCopy(T[] orig)4320   private static <T> T[] deepCopy(T[] orig) throws Exception {
4321     if (orig instanceof MessageValue[]) {
4322       MessageValue[] result = new MessageValue[orig.length];
4323       for (int i = 0; i < orig.length; i++) {
4324         result[i] = new MessageValue();
4325         MessageNano.mergeFrom(
4326             result[i], MessageNano.toByteArray((MessageValue) orig[i]));
4327       }
4328       return (T[]) result;
4329     }
4330     if (orig instanceof byte[][]) {
4331       byte[][] result = new byte[orig.length][];
4332       for (int i = 0; i < orig.length; i++) {
4333         byte[] origBytes = (byte[]) orig[i];
4334         result[i] = Arrays.copyOf(origBytes, origBytes.length);
4335       }
4336     }
4337     return Arrays.copyOf(orig, orig.length);
4338   }
4339 
setMap(Map<K, V> map, K[] keys, V[] values)4340   private <K, V> void setMap(Map<K, V> map, K[] keys, V[] values) {
4341     assert(keys.length == values.length);
4342     for (int i = 0; i < keys.length; i++) {
4343       map.put(keys[i], values[i]);
4344     }
4345   }
4346 
assertMapSet( Map<K, V> map, K[] keys, V[] values)4347   private <K, V> void assertMapSet(
4348       Map<K, V> map, K[] keys, V[] values) throws Exception {
4349     assert(keys.length == values.length);
4350     for (int i = 0; i < values.length; i++) {
4351       assertEquals(values[i], map.get(keys[i]));
4352     }
4353     assertEquals(keys.length, map.size());
4354   }
4355 
setMapMessage(TestMap testMap)4356   private void setMapMessage(TestMap testMap) {
4357     testMap.int32ToInt32Field = new HashMap<Integer, Integer>();
4358     testMap.int32ToBytesField = new HashMap<Integer, byte[]>();
4359     testMap.int32ToEnumField = new HashMap<Integer, Integer>();
4360     testMap.int32ToMessageField =
4361         new HashMap<Integer, MapTestProto.TestMap.MessageValue>();
4362     testMap.int32ToStringField = new HashMap<Integer, String>();
4363     testMap.stringToInt32Field = new HashMap<String, Integer>();
4364     testMap.boolToBoolField = new HashMap<Boolean, Boolean>();
4365     testMap.uint32ToUint32Field = new HashMap<Integer, Integer>();
4366     testMap.sint32ToSint32Field = new HashMap<Integer, Integer>();
4367     testMap.fixed32ToFixed32Field = new HashMap<Integer, Integer>();
4368     testMap.sfixed32ToSfixed32Field = new HashMap<Integer, Integer>();
4369     testMap.int64ToInt64Field = new HashMap<Long, Long>();
4370     testMap.uint64ToUint64Field = new HashMap<Long, Long>();
4371     testMap.sint64ToSint64Field = new HashMap<Long, Long>();
4372     testMap.fixed64ToFixed64Field = new HashMap<Long, Long>();
4373     testMap.sfixed64ToSfixed64Field = new HashMap<Long, Long>();
4374     setMap(testMap.int32ToInt32Field, int32Values, int32Values);
4375     setMap(testMap.int32ToBytesField, int32Values, bytesValues);
4376     setMap(testMap.int32ToEnumField, int32Values, enumValues);
4377     setMap(testMap.int32ToMessageField, int32Values, messageValues);
4378     setMap(testMap.int32ToStringField, int32Values, stringValues);
4379     setMap(testMap.stringToInt32Field, stringValues, int32Values);
4380     setMap(testMap.boolToBoolField, boolValues, boolValues);
4381     setMap(testMap.uint32ToUint32Field, int32Values, int32Values);
4382     setMap(testMap.sint32ToSint32Field, int32Values, int32Values);
4383     setMap(testMap.fixed32ToFixed32Field, int32Values, int32Values);
4384     setMap(testMap.sfixed32ToSfixed32Field, int32Values, int32Values);
4385     setMap(testMap.int64ToInt64Field, int64Values, int64Values);
4386     setMap(testMap.uint64ToUint64Field, int64Values, int64Values);
4387     setMap(testMap.sint64ToSint64Field, int64Values, int64Values);
4388     setMap(testMap.fixed64ToFixed64Field, int64Values, int64Values);
4389     setMap(testMap.sfixed64ToSfixed64Field, int64Values, int64Values);
4390   }
assertMapMessageSet(TestMap testMap)4391   private void assertMapMessageSet(TestMap testMap) throws Exception {
4392     assertMapSet(testMap.int32ToInt32Field, int32Values, int32Values);
4393     assertMapSet(testMap.int32ToBytesField, int32Values, bytesValues);
4394     assertMapSet(testMap.int32ToEnumField, int32Values, enumValues);
4395     assertMapSet(testMap.int32ToMessageField, int32Values, messageValues);
4396     assertMapSet(testMap.int32ToStringField, int32Values, stringValues);
4397     assertMapSet(testMap.stringToInt32Field, stringValues, int32Values);
4398     assertMapSet(testMap.boolToBoolField, boolValues, boolValues);
4399     assertMapSet(testMap.uint32ToUint32Field, int32Values, int32Values);
4400     assertMapSet(testMap.sint32ToSint32Field, int32Values, int32Values);
4401     assertMapSet(testMap.fixed32ToFixed32Field, int32Values, int32Values);
4402     assertMapSet(testMap.sfixed32ToSfixed32Field, int32Values, int32Values);
4403     assertMapSet(testMap.int64ToInt64Field, int64Values, int64Values);
4404     assertMapSet(testMap.uint64ToUint64Field, int64Values, int64Values);
4405     assertMapSet(testMap.sint64ToSint64Field, int64Values, int64Values);
4406     assertMapSet(testMap.fixed64ToFixed64Field, int64Values, int64Values);
4407     assertMapSet(testMap.sfixed64ToSfixed64Field, int64Values, int64Values);
4408   }
4409 
testRepeatedFieldInitializedInReftypesCompatMode()4410   public void testRepeatedFieldInitializedInReftypesCompatMode() {
4411     NanoReferenceTypesCompat.TestAllTypesNano proto = new NanoReferenceTypesCompat.TestAllTypesNano();
4412     assertNotNull(proto.repeatedString);
4413   }
4414 
assertRepeatedPackablesEqual( NanoRepeatedPackables.NonPacked nonPacked, NanoRepeatedPackables.Packed packed)4415   private void assertRepeatedPackablesEqual(
4416       NanoRepeatedPackables.NonPacked nonPacked, NanoRepeatedPackables.Packed packed) {
4417     // Not using MessageNano.equals() -- that belongs to a separate test.
4418     assertTrue(Arrays.equals(nonPacked.int32S, packed.int32S));
4419     assertTrue(Arrays.equals(nonPacked.int64S, packed.int64S));
4420     assertTrue(Arrays.equals(nonPacked.uint32S, packed.uint32S));
4421     assertTrue(Arrays.equals(nonPacked.uint64S, packed.uint64S));
4422     assertTrue(Arrays.equals(nonPacked.sint32S, packed.sint32S));
4423     assertTrue(Arrays.equals(nonPacked.sint64S, packed.sint64S));
4424     assertTrue(Arrays.equals(nonPacked.fixed32S, packed.fixed32S));
4425     assertTrue(Arrays.equals(nonPacked.fixed64S, packed.fixed64S));
4426     assertTrue(Arrays.equals(nonPacked.sfixed32S, packed.sfixed32S));
4427     assertTrue(Arrays.equals(nonPacked.sfixed64S, packed.sfixed64S));
4428     assertTrue(Arrays.equals(nonPacked.floats, packed.floats));
4429     assertTrue(Arrays.equals(nonPacked.doubles, packed.doubles));
4430     assertTrue(Arrays.equals(nonPacked.bools, packed.bools));
4431     assertTrue(Arrays.equals(nonPacked.enums, packed.enums));
4432   }
4433 
testClone()4434   public void testClone() throws Exception {
4435     // A simple message.
4436     AnotherMessage anotherMessage = new AnotherMessage();
4437     anotherMessage.string = "Hello";
4438     anotherMessage.value = true;
4439     anotherMessage.integers = new int[] { 1, 2, 3 };
4440 
4441     AnotherMessage clone = anotherMessage.clone();
4442     assertEquals(clone, anotherMessage);
4443 
4444     // Verify it was a deep clone - changes to the clone shouldn't affect the
4445     // original.
4446     clone.integers[1] = 100;
4447     assertFalse(clone.equals(anotherMessage));
4448   }
4449 
assertHasWireData(MessageNano message, boolean expected)4450   private void assertHasWireData(MessageNano message, boolean expected) {
4451     byte[] bytes = MessageNano.toByteArray(message);
4452     int wireLength = bytes.length;
4453     if (expected) {
4454       assertFalse(wireLength == 0);
4455     } else {
4456       if (wireLength != 0) {
4457         fail("Expected no wire data for message \n" + message
4458             + "\nBut got:\n"
4459             + hexDump(bytes));
4460       }
4461     }
4462   }
4463 
hexDump(byte[] bytes)4464   private static String hexDump(byte[] bytes) {
4465     StringBuilder sb = new StringBuilder();
4466     for (byte b : bytes) {
4467       sb.append(String.format("%02x ", b));
4468     }
4469     return sb.toString();
4470   }
4471 }
4472