• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 package com.google.protobuf;
9 
10 import static com.google.common.truth.Truth.assertThat;
11 import static com.google.common.truth.Truth.assertWithMessage;
12 import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
13 
14 import com.google.protobuf.UnittestLite.ForeignEnumLite;
15 import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
16 import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
17 import map_test.MapForProto2TestProto;
18 import map_test.MapTestProto.TestMap;
19 import protobuf_unittest.UnittestMset.RawMessageSet;
20 import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
21 import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
22 import protobuf_unittest.UnittestProto;
23 import protobuf_unittest.UnittestProto.TestAllExtensions;
24 import protobuf_unittest.UnittestProto.TestAllTypes;
25 import protobuf_unittest.UnittestProto.TestExtensionInsideTable;
26 import protobuf_unittest.UnittestProto.TestFieldOrderings;
27 import protobuf_unittest.UnittestProto.TestOneof2;
28 import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible;
29 import protobuf_unittest.UnittestProto.TestPackedExtensions;
30 import protobuf_unittest.UnittestProto.TestPackedTypes;
31 import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet;
32 import proto3_unittest.UnittestProto3;
33 import java.io.ByteArrayInputStream;
34 import java.io.ByteArrayOutputStream;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.util.List;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.junit.runners.JUnit4;
41 
42 @RunWith(JUnit4.class)
43 public class WireFormatLiteTest {
44 
45   @Test
testSerializeExtensionsLite()46   public void testSerializeExtensionsLite() throws Exception {
47     // TestAllTypes and TestAllExtensions should have compatible wire formats,
48     // so if we serialize a TestAllExtensions then parse it as TestAllTypes
49     // it should work.
50 
51     TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet();
52     ByteString rawBytes = message.toByteString();
53     assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size());
54 
55     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
56 
57     TestUtil.assertAllFieldsSet(message2);
58   }
59 
60   @Test
testSerializePackedExtensionsLite()61   public void testSerializePackedExtensionsLite() throws Exception {
62     // TestPackedTypes and TestPackedExtensions should have compatible wire
63     // formats; check that they serialize to the same string.
64     TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
65     ByteString rawBytes = message.toByteString();
66 
67     TestPackedTypes message2 = TestUtil.getPackedSet();
68     ByteString rawBytes2 = message2.toByteString();
69 
70     assertThat(rawBytes2).isEqualTo(rawBytes);
71   }
72 
73   @Test
testParseExtensionsLite()74   public void testParseExtensionsLite() throws Exception {
75     // TestAllTypes and TestAllExtensions should have compatible wire formats,
76     // so if we serialize a TestAllTypes then parse it as TestAllExtensions
77     // it should work.
78 
79     TestAllTypes message = TestUtil.getAllSet();
80     ByteString rawBytes = message.toByteString();
81 
82     ExtensionRegistryLite registryLite = TestUtilLite.getExtensionRegistryLite();
83 
84     TestAllExtensionsLite message2 = TestAllExtensionsLite.parseFrom(rawBytes, registryLite);
85     TestUtil.assertAllExtensionsSet(message2);
86     message2 = TestAllExtensionsLite.parseFrom(message.toByteArray(), registryLite);
87     TestUtil.assertAllExtensionsSet(message2);
88   }
89 
90   @Test
testParsePackedExtensionsLite()91   public void testParsePackedExtensionsLite() throws Exception {
92     // Ensure that packed extensions can be properly parsed.
93     TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
94     ByteString rawBytes = message.toByteString();
95 
96     ExtensionRegistryLite registry = TestUtilLite.getExtensionRegistryLite();
97 
98     TestPackedExtensionsLite message2 = TestPackedExtensionsLite.parseFrom(rawBytes, registry);
99     TestUtil.assertPackedExtensionsSet(message2);
100     message2 = TestPackedExtensionsLite.parseFrom(message.toByteArray(), registry);
101     TestUtil.assertPackedExtensionsSet(message2);
102   }
103 
104   @Test
testSerialization()105   public void testSerialization() throws Exception {
106     TestAllTypes message = TestUtil.getAllSet();
107 
108     ByteString rawBytes = message.toByteString();
109     assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size());
110 
111     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
112 
113     TestUtil.assertAllFieldsSet(message2);
114   }
115 
116   @Test
testSerializationPacked()117   public void testSerializationPacked() throws Exception {
118     TestPackedTypes message = TestUtil.getPackedSet();
119 
120     ByteString rawBytes = message.toByteString();
121     assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size());
122 
123     TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
124 
125     TestUtil.assertPackedFieldsSet(message2);
126   }
127 
128   @Test
testSerializeExtensions()129   public void testSerializeExtensions() throws Exception {
130     // TestAllTypes and TestAllExtensions should have compatible wire formats,
131     // so if we serialize a TestAllExtensions then parse it as TestAllTypes
132     // it should work.
133 
134     TestAllExtensions message = TestUtil.getAllExtensionsSet();
135     ByteString rawBytes = message.toByteString();
136     assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size());
137 
138     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
139 
140     TestUtil.assertAllFieldsSet(message2);
141   }
142 
143   @Test
testSerializePackedExtensions()144   public void testSerializePackedExtensions() throws Exception {
145     // TestPackedTypes and TestPackedExtensions should have compatible wire
146     // formats; check that they serialize to the same string.
147     TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
148     ByteString rawBytes = message.toByteString();
149 
150     TestPackedTypes message2 = TestUtil.getPackedSet();
151     ByteString rawBytes2 = message2.toByteString();
152 
153     assertThat(rawBytes2).isEqualTo(rawBytes);
154   }
155 
156   @Test
testSerializationPackedWithoutGetSerializedSize()157   public void testSerializationPackedWithoutGetSerializedSize() throws Exception {
158     // Write directly to an OutputStream, without invoking getSerializedSize()
159     // This used to be a bug where the size of a packed field was incorrect,
160     // since getSerializedSize() was never invoked.
161     TestPackedTypes message = TestUtil.getPackedSet();
162 
163     // Directly construct a CodedOutputStream around the actual OutputStream,
164     // in case writeTo(OutputStream output) invokes getSerializedSize();
165     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
166     CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream);
167 
168     message.writeTo(codedOutput);
169 
170     codedOutput.flush();
171 
172     TestPackedTypes message2 = TestPackedTypes.parseFrom(outputStream.toByteArray());
173 
174     TestUtil.assertPackedFieldsSet(message2);
175   }
176 
177   @Test
testParseExtensions()178   public void testParseExtensions() throws Exception {
179     // TestAllTypes and TestAllExtensions should have compatible wire formats,
180     // so if we serialize a TestAllTypes then parse it as TestAllExtensions
181     // it should work.
182 
183     TestAllTypes message = TestUtil.getAllSet();
184     ByteString rawBytes = message.toByteString();
185 
186     ExtensionRegistryLite registry = TestUtil.getExtensionRegistry();
187 
188     TestAllExtensions message2 = TestAllExtensions.parseFrom(rawBytes, registry);
189 
190     TestUtil.assertAllExtensionsSet(message2);
191   }
192 
193   @Test
testParsePackedExtensions()194   public void testParsePackedExtensions() throws Exception {
195     // Ensure that packed extensions can be properly parsed.
196     TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
197     ByteString rawBytes = message.toByteString();
198 
199     ExtensionRegistryLite registry = TestUtil.getExtensionRegistry();
200 
201     TestPackedExtensions message2 = TestPackedExtensions.parseFrom(rawBytes, registry);
202 
203     TestUtil.assertPackedExtensionsSet(message2);
204   }
205 
206   @Test
testSerializeDelimited()207   public void testSerializeDelimited() throws Exception {
208     ByteArrayOutputStream output = new ByteArrayOutputStream();
209     TestUtil.getAllSet().writeDelimitedTo(output);
210     output.write(12);
211     TestUtil.getPackedSet().writeDelimitedTo(output);
212     output.write(34);
213 
214     ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
215 
216     TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input));
217     assertThat(input.read()).isEqualTo(12);
218     TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input));
219     assertThat(input.read()).isEqualTo(34);
220     assertThat(input.read()).isEqualTo(-1);
221 
222     // We're at EOF, so parsing again should return null.
223     assertThat(TestAllTypes.parseDelimitedFrom(input)).isNull();
224   }
225 
getTestFieldOrderingsRegistry()226   private ExtensionRegistryLite getTestFieldOrderingsRegistry() {
227     ExtensionRegistryLite result = ExtensionRegistryLite.newInstance();
228     result.add(UnittestProto.myExtensionInt);
229     result.add(UnittestProto.myExtensionString);
230     return result;
231   }
232 
233   @Test
testParseMultipleExtensionRanges()234   public void testParseMultipleExtensionRanges() throws Exception {
235     // Make sure we can parse a message that contains multiple extensions
236     // ranges.
237     TestFieldOrderings source =
238         TestFieldOrderings.newBuilder()
239             .setMyInt(1)
240             .setMyString("foo")
241             .setMyFloat(1.0F)
242             .setExtension(UnittestProto.myExtensionInt, 23)
243             .setExtension(UnittestProto.myExtensionString, "bar")
244             .build();
245     TestFieldOrderings dest =
246         TestFieldOrderings.parseFrom(source.toByteString(), getTestFieldOrderingsRegistry());
247     assertThat(dest).isEqualTo(source);
248   }
249 
getTestExtensionInsideTableRegistry()250   private static ExtensionRegistryLite getTestExtensionInsideTableRegistry() {
251     ExtensionRegistryLite result = ExtensionRegistryLite.newInstance();
252     result.add(UnittestProto.testExtensionInsideTableExtension);
253     return result;
254   }
255 
256   @Test
testExtensionInsideTable()257   public void testExtensionInsideTable() throws Exception {
258     // Make sure the extension within the range of table is parsed correctly in experimental
259     // runtime.
260     TestExtensionInsideTable source =
261         TestExtensionInsideTable.newBuilder()
262             .setField1(1)
263             .setExtension(UnittestProto.testExtensionInsideTableExtension, 23)
264             .build();
265     TestExtensionInsideTable dest =
266         TestExtensionInsideTable.parseFrom(
267             source.toByteString(), getTestExtensionInsideTableRegistry());
268     assertThat(dest).isEqualTo(source);
269   }
270 
271   private static final int UNKNOWN_TYPE_ID = 1550055;
272   private static final int TYPE_ID_1 = 1545008;
273   private static final int TYPE_ID_2 = 1547769;
274 
275   @Test
testSerializeMessageSetEagerly()276   public void testSerializeMessageSetEagerly() throws Exception {
277     testSerializeMessageSetWithFlag(true);
278   }
279 
280   @Test
testSerializeMessageSetNotEagerly()281   public void testSerializeMessageSetNotEagerly() throws Exception {
282     testSerializeMessageSetWithFlag(false);
283   }
284 
testSerializeMessageSetWithFlag(boolean eagerParsing)285   private void testSerializeMessageSetWithFlag(boolean eagerParsing) throws Exception {
286     ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
287     CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream);
288     output.writeRawMessageSetExtension(UNKNOWN_TYPE_ID, ByteString.copyFromUtf8("bar"));
289     output.flush();
290     byte[] messageSetBytes = byteArrayOutputStream.toByteArray();
291 
292     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
293     // Set up a TestMessageSet with two known messages and an unknown one.
294     TestMessageSet messageSet =
295         TestMessageSet.newBuilder()
296             .setExtension(
297                 TestMessageSetExtension1.messageSetExtension,
298                 TestMessageSetExtension1.newBuilder().setI(123).build())
299             .setExtension(
300                 TestMessageSetExtension2.messageSetExtension,
301                 TestMessageSetExtension2.newBuilder().setStr("foo").build())
302             .mergeFrom(messageSetBytes)
303             .build();
304 
305     ByteString data = messageSet.toByteString();
306 
307     // Parse back using RawMessageSet and check the contents.
308     RawMessageSet raw = RawMessageSet.parseFrom(data);
309 
310     assertThat(raw.getItemCount()).isEqualTo(3);
311     assertThat(raw.getItem(0).getTypeId()).isEqualTo(TYPE_ID_1);
312     assertThat(raw.getItem(1).getTypeId()).isEqualTo(TYPE_ID_2);
313     assertThat(raw.getItem(2).getTypeId()).isEqualTo(UNKNOWN_TYPE_ID);
314 
315     TestMessageSetExtension1 message1 =
316         TestMessageSetExtension1.parseFrom(raw.getItem(0).getMessage());
317     assertThat(message1.getI()).isEqualTo(123);
318 
319     TestMessageSetExtension2 message2 =
320         TestMessageSetExtension2.parseFrom(raw.getItem(1).getMessage());
321     assertThat(message2.getStr()).isEqualTo("foo");
322 
323     assertThat(raw.getItem(2).getMessage().toStringUtf8()).isEqualTo("bar");
324   }
325 
326   @Test
testParseMessageSetEagerly()327   public void testParseMessageSetEagerly() throws Exception {
328     testParseMessageSetWithFlag(true);
329   }
330 
331   @Test
testParseMessageSetNotEagerly()332   public void testParseMessageSetNotEagerly() throws Exception {
333     testParseMessageSetWithFlag(false);
334   }
335 
testParseMessageSetWithFlag(boolean eagerParsing)336   private void testParseMessageSetWithFlag(boolean eagerParsing) throws Exception {
337     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
338     ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance();
339     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
340     extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
341 
342     // Set up a RawMessageSet with two known messages and an unknown one.
343     RawMessageSet raw =
344         RawMessageSet.newBuilder()
345             .addItem(
346                 RawMessageSet.Item.newBuilder()
347                     .setTypeId(TYPE_ID_1)
348                     .setMessage(
349                         TestMessageSetExtension1.newBuilder().setI(123).build().toByteString())
350                     .build())
351             .addItem(
352                 RawMessageSet.Item.newBuilder()
353                     .setTypeId(TYPE_ID_2)
354                     .setMessage(
355                         TestMessageSetExtension2.newBuilder().setStr("foo").build().toByteString())
356                     .build())
357             .addItem(
358                 RawMessageSet.Item.newBuilder()
359                     .setTypeId(UNKNOWN_TYPE_ID)
360                     .setMessage(ByteString.copyFromUtf8("bar"))
361                     .build())
362             .build();
363 
364     ByteString data = raw.toByteString();
365 
366     // Parse as a TestMessageSet and check the contents.
367     TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry);
368 
369     assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI())
370         .isEqualTo(123);
371     assertThat(messageSet.getExtension(TestMessageSetExtension2.messageSetExtension).getStr())
372         .isEqualTo("foo");
373   }
374 
375   @Test
testParseMessageSetExtensionEagerly()376   public void testParseMessageSetExtensionEagerly() throws Exception {
377     testParseMessageSetExtensionWithFlag(true);
378   }
379 
380   @Test
testParseMessageSetExtensionNotEagerly()381   public void testParseMessageSetExtensionNotEagerly() throws Exception {
382     testParseMessageSetExtensionWithFlag(false);
383   }
384 
testParseMessageSetExtensionWithFlag(boolean eagerParsing)385   private void testParseMessageSetExtensionWithFlag(boolean eagerParsing) throws Exception {
386     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
387     ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance();
388     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
389 
390     // Set up a RawMessageSet with a known messages.
391     int typeId1 = 1545008;
392     RawMessageSet raw =
393         RawMessageSet.newBuilder()
394             .addItem(
395                 RawMessageSet.Item.newBuilder()
396                     .setTypeId(typeId1)
397                     .setMessage(
398                         TestMessageSetExtension1.newBuilder().setI(123).build().toByteString())
399                     .build())
400             .build();
401 
402     ByteString data = raw.toByteString();
403 
404     // Parse as a TestMessageSet and check the contents.
405     TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry);
406     assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI())
407         .isEqualTo(123);
408   }
409 
410   @Test
testMergeLazyMessageSetExtensionEagerly()411   public void testMergeLazyMessageSetExtensionEagerly() throws Exception {
412     testMergeLazyMessageSetExtensionWithFlag(true);
413   }
414 
415   @Test
testMergeLazyMessageSetExtensionNotEagerly()416   public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception {
417     testMergeLazyMessageSetExtensionWithFlag(false);
418   }
419 
testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)420   private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing) throws Exception {
421     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
422     ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance();
423     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
424 
425     // Set up a RawMessageSet with a known messages.
426     int typeId1 = 1545008;
427     RawMessageSet raw =
428         RawMessageSet.newBuilder()
429             .addItem(
430                 RawMessageSet.Item.newBuilder()
431                     .setTypeId(typeId1)
432                     .setMessage(
433                         TestMessageSetExtension1.newBuilder().setI(123).build().toByteString())
434                     .build())
435             .build();
436 
437     ByteString data = raw.toByteString();
438 
439     // Parse as a TestMessageSet and store value into lazy field
440     TestMessageSet messageSet = TestMessageSet.parseFrom(data, extensionRegistry);
441     // Merge lazy field check the contents.
442     messageSet = messageSet.toBuilder().mergeFrom(data, extensionRegistry).build();
443     assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI())
444         .isEqualTo(123);
445   }
446 
447   @Test
testMergeMessageSetExtensionEagerly()448   public void testMergeMessageSetExtensionEagerly() throws Exception {
449     testMergeMessageSetExtensionWithFlag(true);
450   }
451 
452   @Test
testMergeMessageSetExtensionNotEagerly()453   public void testMergeMessageSetExtensionNotEagerly() throws Exception {
454     testMergeMessageSetExtensionWithFlag(false);
455   }
456 
testMergeMessageSetExtensionWithFlag(boolean eagerParsing)457   private void testMergeMessageSetExtensionWithFlag(boolean eagerParsing) throws Exception {
458     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
459     ExtensionRegistryLite extensionRegistry = ExtensionRegistryLite.newInstance();
460     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
461 
462     // Set up a RawMessageSet with a known messages.
463     int typeId1 = 1545008;
464     RawMessageSet raw =
465         RawMessageSet.newBuilder()
466             .addItem(
467                 RawMessageSet.Item.newBuilder()
468                     .setTypeId(typeId1)
469                     .setMessage(
470                         TestMessageSetExtension1.newBuilder().setI(123).build().toByteString())
471                     .build())
472             .build();
473 
474     // Serialize RawMessageSet unnormally (message value before type id)
475     ByteString.CodedBuilder out = ByteString.newCodedBuilder(raw.getSerializedSize());
476     CodedOutputStream output = out.getCodedOutput();
477     List<RawMessageSet.Item> items = raw.getItemList();
478     for (RawMessageSet.Item item : items) {
479       output.writeTag(1, WireFormat.WIRETYPE_START_GROUP);
480       output.writeBytes(3, item.getMessage());
481       output.writeInt32(2, item.getTypeId());
482       output.writeTag(1, WireFormat.WIRETYPE_END_GROUP);
483     }
484     ByteString data = out.build();
485 
486     // Merge bytes into TestMessageSet and check the contents.
487     TestMessageSet messageSet =
488         TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build();
489     assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension).getI())
490         .isEqualTo(123);
491   }
492 
493   // ================================================================
494   // oneof
495   @Test
testOneofWireFormat()496   public void testOneofWireFormat() throws Exception {
497     TestOneof2.Builder builder = TestOneof2.newBuilder();
498     TestUtil.setOneof(builder);
499     TestOneof2 message = builder.build();
500     ByteString rawBytes = message.toByteString();
501 
502     assertThat(message.getSerializedSize()).isEqualTo(rawBytes.size());
503 
504     TestOneof2 message2 = TestOneof2.parseFrom(rawBytes);
505     TestUtil.assertOneofSet(message2);
506   }
507 
508   @Test
testOneofOnlyLastSet()509   public void testOneofOnlyLastSet() throws Exception {
510     TestOneofBackwardsCompatible source =
511         TestOneofBackwardsCompatible.newBuilder().setFooInt(100).setFooString("101").build();
512 
513     ByteString rawBytes = source.toByteString();
514     TestOneof2 message = TestOneof2.parseFrom(rawBytes);
515     assertThat(message.hasFooInt()).isFalse();
516     assertThat(message.hasFooString()).isTrue();
517   }
518 
assertInvalidWireFormat( MessageLite defaultInstance, byte[] data, int offset, int length)519   private void assertInvalidWireFormat(
520       MessageLite defaultInstance, byte[] data, int offset, int length) {
521     // Test all combinations: (builder vs parser) x (byte[] vs. InputStream).
522     try {
523       defaultInstance.newBuilderForType().mergeFrom(data, offset, length);
524       assertWithMessage("Expected exception").fail();
525     } catch (InvalidProtocolBufferException e) {
526       // Pass.
527     }
528     try {
529       defaultInstance.getParserForType().parseFrom(data, offset, length);
530       assertWithMessage("Expected exception").fail();
531     } catch (InvalidProtocolBufferException e) {
532       // Pass.
533     }
534     try {
535       InputStream input = new ByteArrayInputStream(data, offset, length);
536       defaultInstance.newBuilderForType().mergeFrom(input);
537       assertWithMessage("Expected exception").fail();
538     } catch (IOException e) {
539       // Pass.
540     }
541     try {
542       InputStream input = new ByteArrayInputStream(data, offset, length);
543       defaultInstance.getParserForType().parseFrom(input);
544       assertWithMessage("Expected exception").fail();
545     } catch (IOException e) {
546       // Pass.
547     }
548   }
549 
assertInvalidWireFormat(MessageLite defaultInstance, byte[] data)550   private void assertInvalidWireFormat(MessageLite defaultInstance, byte[] data) {
551     assertInvalidWireFormat(defaultInstance, data, 0, data.length);
552   }
553 
assertInvalidWireFormat(byte[] data)554   private void assertInvalidWireFormat(byte[] data) {
555     assertInvalidWireFormat(TestAllTypes.getDefaultInstance(), data);
556     assertInvalidWireFormat(UnittestProto3.TestAllTypes.getDefaultInstance(), data);
557   }
558 
559   @Test
testParserRejectInvalidTag()560   public void testParserRejectInvalidTag() throws Exception {
561     byte[] invalidTags =
562         new byte[] {
563           // Zero tag is not allowed.
564           0,
565           // Invalid wire types.
566           (byte) WireFormat.makeTag(1, 6),
567           (byte) WireFormat.makeTag(1, 7),
568           // Field number 0 is not allowed.
569           (byte) WireFormat.makeTag(0, WireFormat.WIRETYPE_VARINT),
570         };
571     for (byte invalidTag : invalidTags) {
572       // Add a trailing 0 to make sure the parsing actually fails on the tag.
573       byte[] data = new byte[] {invalidTag, 0};
574       assertInvalidWireFormat(data);
575 
576       // Invalid tag in an unknown group field.
577       data =
578           new byte[] {
579             (byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_START_GROUP),
580             invalidTag,
581             0,
582             (byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_END_GROUP),
583           };
584       assertInvalidWireFormat(data);
585 
586       // Invalid tag in a MessageSet item.
587       data =
588           new byte[] {
589             (byte) WireFormat.MESSAGE_SET_ITEM_TAG,
590             (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG,
591             100, // TYPE_ID = 100
592             (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG,
593             0, // empty payload
594             invalidTag,
595             0,
596             (byte) WireFormat.MESSAGE_SET_ITEM_END_TAG,
597           };
598       assertInvalidWireFormat(TestMessageSet.getDefaultInstance(), data);
599 
600       // Invalid tag inside a MessageSet item's unknown group.
601       data =
602           new byte[] {
603             (byte) WireFormat.MESSAGE_SET_ITEM_TAG,
604             (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG,
605             100, // TYPE_ID = 100
606             (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG,
607             0, // empty payload
608             (byte) WireFormat.makeTag(4, WireFormat.WIRETYPE_START_GROUP),
609             invalidTag,
610             0,
611             (byte) WireFormat.makeTag(4, WireFormat.WIRETYPE_END_GROUP),
612             (byte) WireFormat.MESSAGE_SET_ITEM_END_TAG,
613           };
614       assertInvalidWireFormat(TestMessageSet.getDefaultInstance(), data);
615 
616       // Invalid tag inside a map field.
617       data =
618           new byte[] {
619             (byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), 2, invalidTag, 0,
620           };
621       assertInvalidWireFormat(TestMap.getDefaultInstance(), data);
622     }
623   }
624 
625   @Test
testUnmatchedGroupTag()626   public void testUnmatchedGroupTag() throws Exception {
627     int startTag = WireFormat.makeTag(16, WireFormat.WIRETYPE_START_GROUP);
628     byte[] data =
629         new byte[] {
630           (byte) ((startTag & 0x7F) | 0x80), (byte) ((startTag >>> 7) & 0x7F),
631         };
632     assertInvalidWireFormat(data);
633 
634     // Unmatched group tags inside a MessageSet item.
635     data =
636         new byte[] {
637           (byte) WireFormat.MESSAGE_SET_ITEM_TAG,
638           (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG,
639           100, // TYPE_ID = 100
640           (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG,
641           0, // empty payload
642           (byte) WireFormat.makeTag(4, WireFormat.WIRETYPE_START_GROUP),
643         };
644     assertInvalidWireFormat(TestMessageSet.getDefaultInstance(), data);
645   }
646 
assertAccepted(MessageLite defaultInstance, byte[] data)647   private void assertAccepted(MessageLite defaultInstance, byte[] data) throws Exception {
648     MessageLite message1 = defaultInstance.newBuilderForType().mergeFrom(data).build();
649     MessageLite message2 = defaultInstance.getParserForType().parseFrom(data);
650     MessageLite message3 =
651         defaultInstance.newBuilderForType().mergeFrom(new ByteArrayInputStream(data)).build();
652     MessageLite message4 =
653         defaultInstance.getParserForType().parseFrom(new ByteArrayInputStream(data));
654     assertThat(message2).isEqualTo(message1);
655     assertThat(message3).isEqualTo(message2);
656     assertThat(message4).isEqualTo(message3);
657   }
658 
659   @Test
testUnmatchedWireType()660   public void testUnmatchedWireType() throws Exception {
661     // Build a payload with all fields from 1 to 128 being varints. Parsing it into TestAllTypes
662     // or other message types should succeed even though the wire type doesn't match for some
663     // fields.
664     ByteArrayOutputStream output = new ByteArrayOutputStream();
665     CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
666     for (int i = 1; i <= 128; i++) {
667       codedOutput.writeInt32(i, 0);
668     }
669     codedOutput.flush();
670     byte[] data = output.toByteArray();
671     // It can be parsed into any message type that doesn't have required fields.
672     assertAccepted(TestAllTypes.getDefaultInstance(), data);
673     assertAccepted(UnittestProto3.TestAllTypes.getDefaultInstance(), data);
674     assertAccepted(TestMap.getDefaultInstance(), data);
675     assertAccepted(MapForProto2TestProto.TestMap.getDefaultInstance(), data);
676   }
677 
678   @Test
testParseTruncatedPackedFields()679   public void testParseTruncatedPackedFields() throws Exception {
680     TestPackedTypes all = TestUtil.getPackedSet();
681     TestPackedTypes[] messages =
682         new TestPackedTypes[] {
683           TestPackedTypes.newBuilder().addAllPackedInt32(all.getPackedInt32List()).build(),
684           TestPackedTypes.newBuilder().addAllPackedInt64(all.getPackedInt64List()).build(),
685           TestPackedTypes.newBuilder().addAllPackedUint32(all.getPackedUint32List()).build(),
686           TestPackedTypes.newBuilder().addAllPackedUint64(all.getPackedUint64List()).build(),
687           TestPackedTypes.newBuilder().addAllPackedSint32(all.getPackedSint32List()).build(),
688           TestPackedTypes.newBuilder().addAllPackedSint64(all.getPackedSint64List()).build(),
689           TestPackedTypes.newBuilder().addAllPackedFixed32(all.getPackedFixed32List()).build(),
690           TestPackedTypes.newBuilder().addAllPackedFixed64(all.getPackedFixed64List()).build(),
691           TestPackedTypes.newBuilder().addAllPackedSfixed32(all.getPackedSfixed32List()).build(),
692           TestPackedTypes.newBuilder().addAllPackedSfixed64(all.getPackedSfixed64List()).build(),
693           TestPackedTypes.newBuilder().addAllPackedFloat(all.getPackedFloatList()).build(),
694           TestPackedTypes.newBuilder().addAllPackedDouble(all.getPackedDoubleList()).build(),
695           TestPackedTypes.newBuilder().addAllPackedEnum(all.getPackedEnumList()).build(),
696         };
697     for (TestPackedTypes message : messages) {
698       byte[] data = message.toByteArray();
699       // Parsing truncated payload should fail.
700       for (int i = 1; i < data.length; i++) {
701         assertInvalidWireFormat(TestPackedTypes.getDefaultInstance(), data, 0, i);
702       }
703     }
704   }
705 
706   @Test
testParsePackedFieldsWithIncorrectLength()707   public void testParsePackedFieldsWithIncorrectLength() throws Exception {
708     // Set the length-prefix to 1 with a 4-bytes payload to test what happens when reading a packed
709     // element moves the reading position past the given length limit. It should result in an
710     // InvalidProtocolBufferException but an implementation may forget to check it especially for
711     // packed varint fields.
712     byte[] data =
713         new byte[] {
714           0,
715           0, // first two bytes is reserved for the tag.
716           1, // length is 1
717           (byte) 0x80,
718           (byte) 0x80,
719           (byte) 0x80,
720           (byte) 0x01, // a 4-bytes varint
721         };
722     // All fields that can read a 4-bytes varint (all varint fields and fixed 32-bit fields).
723     int[] fieldNumbers =
724         new int[] {
725           TestPackedTypes.PACKED_INT32_FIELD_NUMBER,
726           TestPackedTypes.PACKED_INT64_FIELD_NUMBER,
727           TestPackedTypes.PACKED_UINT32_FIELD_NUMBER,
728           TestPackedTypes.PACKED_UINT64_FIELD_NUMBER,
729           TestPackedTypes.PACKED_SINT32_FIELD_NUMBER,
730           TestPackedTypes.PACKED_SINT64_FIELD_NUMBER,
731           TestPackedTypes.PACKED_FIXED32_FIELD_NUMBER,
732           TestPackedTypes.PACKED_SFIXED32_FIELD_NUMBER,
733           TestPackedTypes.PACKED_FLOAT_FIELD_NUMBER,
734           TestPackedTypes.PACKED_BOOL_FIELD_NUMBER,
735           TestPackedTypes.PACKED_ENUM_FIELD_NUMBER,
736         };
737     for (int number : fieldNumbers) {
738       // Set the tag.
739       data[0] =
740           (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) & 0x7F) | 0x80);
741       data[1] =
742           (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) >>> 7) & 0x7F);
743       assertInvalidWireFormat(TestPackedTypes.getDefaultInstance(), data);
744     }
745 
746     // Data with 8-bytes payload to test some fixed 64-bit fields.
747     byte[] data8Bytes =
748         new byte[] {
749           0,
750           0, // first two bytes is reserved for the tag.
751           1, // length is 1
752           (byte) 0x80,
753           (byte) 0x80,
754           (byte) 0x80,
755           (byte) 0x80,
756           (byte) 0x80,
757           (byte) 0x80,
758           (byte) 0x80,
759           (byte) 0x01, // a 8-bytes varint
760         };
761     // All fields that can only read 8-bytes data.
762     int[] fieldNumbers8Bytes =
763         new int[] {
764           TestPackedTypes.PACKED_FIXED64_FIELD_NUMBER,
765           TestPackedTypes.PACKED_SFIXED64_FIELD_NUMBER,
766           TestPackedTypes.PACKED_DOUBLE_FIELD_NUMBER,
767         };
768     for (int number : fieldNumbers8Bytes) {
769       // Set the tag.
770       data8Bytes[0] =
771           (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) & 0x7F) | 0x80);
772       data8Bytes[1] =
773           (byte) ((WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED) >>> 7) & 0x7F);
774       assertInvalidWireFormat(TestPackedTypes.getDefaultInstance(), data8Bytes);
775     }
776   }
777 
778   @Test
testParseVarintMinMax()779   public void testParseVarintMinMax() throws Exception {
780     TestAllTypes message =
781         TestAllTypes.newBuilder()
782             .setOptionalInt32(Integer.MIN_VALUE)
783             .addRepeatedInt32(Integer.MAX_VALUE)
784             .setOptionalInt64(Long.MIN_VALUE)
785             .addRepeatedInt64(Long.MAX_VALUE)
786             .build();
787     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
788     assertThat(parsed.getOptionalInt32()).isEqualTo(Integer.MIN_VALUE);
789     assertThat(parsed.getRepeatedInt32(0)).isEqualTo(Integer.MAX_VALUE);
790     assertThat(parsed.getOptionalInt64()).isEqualTo(Long.MIN_VALUE);
791     assertThat(parsed.getRepeatedInt64(0)).isEqualTo(Long.MAX_VALUE);
792   }
793 
794   @Test
testParseAllVarintBits()795   public void testParseAllVarintBits() throws Exception {
796     for (int i = 0; i < 32; i++) {
797       final int value = 1 << i;
798       TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt32(value).build();
799       TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
800       assertThat(parsed.getOptionalInt32()).isEqualTo(value);
801     }
802     for (int i = 0; i < 64; i++) {
803       final long value = 1L << i;
804       TestAllTypes message = TestAllTypes.newBuilder().setOptionalInt64(value).build();
805       TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
806       assertThat(parsed.getOptionalInt64()).isEqualTo(value);
807     }
808   }
809 
810   @Test
testParseEmptyUnknownLengthDelimitedField()811   public void testParseEmptyUnknownLengthDelimitedField() throws Exception {
812     byte[] data =
813         new byte[] {(byte) WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED), 0};
814     TestAllTypes parsed = TestAllTypes.parseFrom(data);
815     assertThat(parsed.toByteArray()).isEqualTo(data);
816   }
817 
818   @Test
testParseEmptyString()819   public void testParseEmptyString() throws Exception {
820     TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("").build();
821     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
822     assertThat(parsed.getOptionalString()).isEmpty();
823   }
824 
825   @Test
testParseEmptyStringProto3()826   public void testParseEmptyStringProto3() throws Exception {
827     TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("").build();
828     // Note that we are parsing from a proto2 proto to a proto3 proto because empty string field is
829     // not serialized in proto3.
830     UnittestProto3.TestAllTypes parsed =
831         UnittestProto3.TestAllTypes.parseFrom(message.toByteArray());
832     assertThat(parsed.getOptionalString()).isEmpty();
833   }
834 
835   @Test
testParseEmptyBytes()836   public void testParseEmptyBytes() throws Exception {
837     TestAllTypes message = TestAllTypes.newBuilder().setOptionalBytes(ByteString.EMPTY).build();
838     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
839     assertThat(parsed.getOptionalBytes()).isEqualTo(ByteString.EMPTY);
840   }
841 
842   @Test
testParseEmptyRepeatedStringField()843   public void testParseEmptyRepeatedStringField() throws Exception {
844     TestAllTypes message =
845         TestAllTypes.newBuilder()
846             .addRepeatedString("")
847             .addRepeatedString("")
848             .addRepeatedString("0")
849             .build();
850     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
851     assertThat(parsed.getRepeatedStringCount()).isEqualTo(3);
852     assertThat(parsed.getRepeatedString(0)).isEmpty();
853     assertThat(parsed.getRepeatedString(1)).isEmpty();
854     assertThat(parsed.getRepeatedString(2)).isEqualTo("0");
855   }
856 
857   @Test
testParseEmptyRepeatedStringFieldProto3()858   public void testParseEmptyRepeatedStringFieldProto3() throws Exception {
859     TestAllTypes message =
860         TestAllTypes.newBuilder()
861             .addRepeatedString("")
862             .addRepeatedString("")
863             .addRepeatedString("0")
864             .addRepeatedBytes(ByteString.EMPTY)
865             .build();
866     UnittestProto3.TestAllTypes parsed =
867         UnittestProto3.TestAllTypes.parseFrom(message.toByteArray());
868     assertThat(parsed.getRepeatedStringCount()).isEqualTo(3);
869     assertThat(parsed.getRepeatedString(0)).isEmpty();
870     assertThat(parsed.getRepeatedString(1)).isEmpty();
871     assertThat(parsed.getRepeatedString(2)).isEqualTo("0");
872   }
873 
874   @Test
testParseEmptyRepeatedBytesField()875   public void testParseEmptyRepeatedBytesField() throws Exception {
876     ByteString oneByte = ByteString.copyFrom(new byte[] {1});
877     TestAllTypes message =
878         TestAllTypes.newBuilder()
879             .addRepeatedBytes(ByteString.EMPTY)
880             .addRepeatedBytes(ByteString.EMPTY)
881             .addRepeatedBytes(oneByte)
882             .build();
883     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
884     assertThat(parsed.getRepeatedBytesCount()).isEqualTo(3);
885     assertThat(parsed.getRepeatedBytes(0)).isEqualTo(ByteString.EMPTY);
886     assertThat(parsed.getRepeatedBytes(1)).isEqualTo(ByteString.EMPTY);
887     assertThat(parsed.getRepeatedBytes(2)).isEqualTo(oneByte);
888   }
889 
890   @Test
testSkipUnknownFieldInMessageSetItem()891   public void testSkipUnknownFieldInMessageSetItem() throws Exception {
892     ByteArrayOutputStream output = new ByteArrayOutputStream();
893     // MessageSet item's start tag.
894     output.write((byte) WireFormat.MESSAGE_SET_ITEM_TAG);
895     // Put all field types into the item.
896     TestUtil.getAllSet().writeTo(output);
897     // Closing the item with the real payload and closing tag.
898     output.write(
899         new byte[] {
900           (byte) WireFormat.MESSAGE_SET_TYPE_ID_TAG,
901           100, // TYPE_ID = 100
902           (byte) WireFormat.MESSAGE_SET_MESSAGE_TAG,
903           0, // empty payload
904           (byte) WireFormat.MESSAGE_SET_ITEM_END_TAG,
905         });
906     byte[] data = output.toByteArray();
907     TestMessageSet parsed = TestMessageSet.parseFrom(data);
908 
909     // Convert to RawMessageSet for inspection.
910     RawMessageSet raw = RawMessageSet.parseFrom(parsed.toByteArray());
911     assertThat(raw.getItemCount()).isEqualTo(1);
912     assertThat(raw.getItem(0).getTypeId()).isEqualTo(100);
913     assertThat(raw.getItem(0).getMessage().size()).isEqualTo(0);
914   }
915 
916   @Test
testProto2UnknownEnumValuesInOptionalField()917   public void testProto2UnknownEnumValuesInOptionalField() throws Exception {
918     // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with
919     // unknown enum values
920     UnittestProto3.TestAllTypes message =
921         UnittestProto3.TestAllTypes.newBuilder().setOptionalNestedEnumValue(4321).build();
922     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
923     assertThat(parsed.hasOptionalNestedEnum()).isFalse();
924     // Make sure unknown enum values are preserved.
925     UnittestProto3.TestAllTypes actual =
926         UnittestProto3.TestAllTypes.parseFrom(parsed.toByteArray());
927     assertThat(actual.getOptionalNestedEnumValue()).isEqualTo(4321);
928   }
929 
930   @Test
testProto2UnknownEnumValuesInRepeatedField()931   public void testProto2UnknownEnumValuesInRepeatedField() throws Exception {
932     // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with
933     // unknown enum values
934     UnittestProto3.TestAllTypes message =
935         UnittestProto3.TestAllTypes.newBuilder().addRepeatedNestedEnumValue(5432).build();
936     TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteArray());
937     assertThat(parsed.getRepeatedNestedEnumCount()).isEqualTo(0);
938     // Make sure unknown enum values are preserved.
939     UnittestProto3.TestAllTypes actual =
940         UnittestProto3.TestAllTypes.parseFrom(parsed.toByteArray());
941     assertThat(actual.getRepeatedNestedEnumCount()).isEqualTo(1);
942     assertThat(actual.getRepeatedNestedEnumValue(0)).isEqualTo(5432);
943   }
944 
945   @Test
testProto2UnknownEnumValuesInMapField()946   public void testProto2UnknownEnumValuesInMapField() throws Exception {
947     // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with
948     // unknown enum values
949     TestMap message = TestMap.newBuilder().putInt32ToEnumFieldValue(1, 4321).build();
950     MapForProto2TestProto.TestMap parsed =
951         MapForProto2TestProto.TestMap.parseFrom(message.toByteArray());
952     assertThat(parsed.getInt32ToEnumFieldMap()).isEmpty();
953     // Make sure unknown enum values are preserved.
954     TestMap actual = TestMap.parseFrom(parsed.toByteArray());
955     assertThat(actual.getInt32ToEnumFieldMap()).hasSize(1);
956     assertThat(actual.getInt32ToEnumFieldValueOrThrow(1)).isEqualTo(4321);
957   }
958 
959   @Test
testProto2UnknownEnumValuesInOneof()960   public void testProto2UnknownEnumValuesInOneof() throws Exception {
961     // Proto2 doesn't allow setting unknown enum values so we use proto3 to build a message with
962     // unknown enum values
963     UnittestProto3.TestOneof2 message =
964         UnittestProto3.TestOneof2.newBuilder().setFooEnumValue(1234).build();
965     TestOneof2 parsed = TestOneof2.parseFrom(message.toByteArray());
966     assertThat(parsed.hasFooEnum()).isFalse();
967     // Make sure unknown enum values are preserved.
968     UnittestProto3.TestOneof2 actual = UnittestProto3.TestOneof2.parseFrom(parsed.toByteArray());
969     assertThat(actual.getFooEnumValue()).isEqualTo(1234);
970   }
971 
972   @Test
testProto2UnknownEnumValuesInExtension()973   public void testProto2UnknownEnumValuesInExtension() throws Exception {
974     ExtensionRegistryLite extensionRegistry = TestUtilLite.getExtensionRegistryLite();
975     // Raw bytes for "[.optional_foreign_enum_extension_lite]: 10"
976     final byte[] rawBytes = new byte[]{-80, 1, 10};
977     TestAllExtensionsLite testAllExtensionsLite =
978         TestAllExtensionsLite.parseFrom(rawBytes, extensionRegistry);
979     assertThat(testAllExtensionsLite.getExtension(optionalForeignEnumExtensionLite))
980         .isEqualTo(ForeignEnumLite.FOREIGN_LITE_FOO);
981     final byte[] resultRawBytes = testAllExtensionsLite.toByteArray();
982     assertThat(resultRawBytes).hasLength(rawBytes.length);
983     for (int i = 0; i < rawBytes.length; i++) {
984       assertThat(resultRawBytes[i]).isEqualTo(rawBytes[i]);
985     }
986   }
987 
988   @Test
testProto3UnknownEnumValuesInOptionalField()989   public void testProto3UnknownEnumValuesInOptionalField() throws Exception {
990     UnittestProto3.TestAllTypes message =
991         UnittestProto3.TestAllTypes.newBuilder().setOptionalNestedEnumValue(4321).build();
992     UnittestProto3.TestAllTypes parsed =
993         UnittestProto3.TestAllTypes.parseFrom(message.toByteArray());
994     assertThat(parsed.getOptionalNestedEnumValue()).isEqualTo(4321);
995   }
996 
997   @Test
testProto3UnknownEnumValuesInRepeatedField()998   public void testProto3UnknownEnumValuesInRepeatedField() throws Exception {
999     UnittestProto3.TestAllTypes message =
1000         UnittestProto3.TestAllTypes.newBuilder().addRepeatedNestedEnumValue(5432).build();
1001     UnittestProto3.TestAllTypes parsed =
1002         UnittestProto3.TestAllTypes.parseFrom(message.toByteArray());
1003     assertThat(parsed.getRepeatedNestedEnumCount()).isEqualTo(1);
1004     assertThat(parsed.getRepeatedNestedEnumValue(0)).isEqualTo(5432);
1005   }
1006 
1007   @Test
testProto3UnknownEnumValuesInMapField()1008   public void testProto3UnknownEnumValuesInMapField() throws Exception {
1009     TestMap message = TestMap.newBuilder().putInt32ToEnumFieldValue(1, 4321).build();
1010     TestMap parsed = TestMap.parseFrom(message.toByteArray());
1011     assertThat(parsed.getInt32ToEnumFieldMap()).hasSize(1);
1012     assertThat(parsed.getInt32ToEnumFieldValueOrThrow(1)).isEqualTo(4321);
1013   }
1014 
1015   @Test
testProto3UnknownEnumValuesInOneof()1016   public void testProto3UnknownEnumValuesInOneof() throws Exception {
1017     UnittestProto3.TestOneof2 message =
1018         UnittestProto3.TestOneof2.newBuilder().setFooEnumValue(1234).build();
1019     UnittestProto3.TestOneof2 parsed = UnittestProto3.TestOneof2.parseFrom(message.toByteArray());
1020     assertThat(parsed.getFooEnumValue()).isEqualTo(1234);
1021   }
1022 
1023   @Test
testProto3MessageFieldMergeBehavior()1024   public void testProto3MessageFieldMergeBehavior() throws Exception {
1025     UnittestProto3.NestedTestAllTypes message1 =
1026         UnittestProto3.NestedTestAllTypes.newBuilder()
1027             .setPayload(
1028                 UnittestProto3.TestAllTypes.newBuilder()
1029                     .setOptionalInt32(1234)
1030                     .setOptionalInt64(5678))
1031             .build();
1032     UnittestProto3.NestedTestAllTypes message2 =
1033         UnittestProto3.NestedTestAllTypes.newBuilder()
1034             .setPayload(
1035                 UnittestProto3.TestAllTypes.newBuilder()
1036                     .setOptionalInt32(4321)
1037                     .setOptionalUint32(8765))
1038             .build();
1039 
1040     UnittestProto3.NestedTestAllTypes merged =
1041         UnittestProto3.NestedTestAllTypes.newBuilder()
1042             .mergeFrom(message1.toByteArray())
1043             .mergeFrom(message2.toByteArray())
1044             .build();
1045     // Field values coming later in the stream override earlier values.
1046     assertThat(merged.getPayload().getOptionalInt32()).isEqualTo(4321);
1047     // Field values present in either message should be present in the merged result.
1048     assertThat(merged.getPayload().getOptionalInt64()).isEqualTo(5678);
1049     assertThat(merged.getPayload().getOptionalUint32()).isEqualTo(8765);
1050   }
1051 
1052   @Test
testMergeFromPartialByteArray()1053   public void testMergeFromPartialByteArray() throws Exception {
1054     byte[] data = TestUtil.getAllSet().toByteArray();
1055     byte[] dataWithPaddings = new byte[data.length + 2];
1056     System.arraycopy(data, 0, dataWithPaddings, 1, data.length);
1057     // Parsing will fail if the builder (or parser) interprets offset or length incorrectly.
1058     TestAllTypes.newBuilder().mergeFrom(dataWithPaddings, 1, data.length);
1059     TestAllTypes.parser().parseFrom(dataWithPaddings, 1, data.length);
1060   }
1061 }
1062