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