• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 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;
32 
33 import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
34 import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
35 import protobuf_unittest.UnittestMset.RawMessageSet;
36 import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
37 import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
38 import protobuf_unittest.UnittestProto;
39 import protobuf_unittest.UnittestProto.TestAllExtensions;
40 import protobuf_unittest.UnittestProto.TestAllTypes;
41 import protobuf_unittest.UnittestProto.TestFieldOrderings;
42 import protobuf_unittest.UnittestProto.TestOneof2;
43 import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible;
44 import protobuf_unittest.UnittestProto.TestPackedExtensions;
45 import protobuf_unittest.UnittestProto.TestPackedTypes;
46 import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet;
47 
48 import junit.framework.TestCase;
49 
50 import java.io.ByteArrayInputStream;
51 import java.io.ByteArrayOutputStream;
52 import java.util.List;
53 
54 /**
55  * Tests related to parsing and serialization.
56  *
57  * @author kenton@google.com (Kenton Varda)
58  */
59 public class WireFormatTest extends TestCase {
testSerialization()60   public void testSerialization() throws Exception {
61     TestAllTypes message = TestUtil.getAllSet();
62 
63     ByteString rawBytes = message.toByteString();
64     assertEquals(rawBytes.size(), message.getSerializedSize());
65 
66     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
67 
68     TestUtil.assertAllFieldsSet(message2);
69   }
70 
testSerializationPacked()71   public void testSerializationPacked() throws Exception {
72     TestPackedTypes message = TestUtil.getPackedSet();
73 
74     ByteString rawBytes = message.toByteString();
75     assertEquals(rawBytes.size(), message.getSerializedSize());
76 
77     TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
78 
79     TestUtil.assertPackedFieldsSet(message2);
80   }
81 
testSerializeExtensions()82   public void testSerializeExtensions() throws Exception {
83     // TestAllTypes and TestAllExtensions should have compatible wire formats,
84     // so if we serialize a TestAllExtensions then parse it as TestAllTypes
85     // it should work.
86 
87     TestAllExtensions message = TestUtil.getAllExtensionsSet();
88     ByteString rawBytes = message.toByteString();
89     assertEquals(rawBytes.size(), message.getSerializedSize());
90 
91     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
92 
93     TestUtil.assertAllFieldsSet(message2);
94   }
95 
testSerializePackedExtensions()96   public void testSerializePackedExtensions() throws Exception {
97     // TestPackedTypes and TestPackedExtensions should have compatible wire
98     // formats; check that they serialize to the same string.
99     TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
100     ByteString rawBytes = message.toByteString();
101 
102     TestPackedTypes message2 = TestUtil.getPackedSet();
103     ByteString rawBytes2 = message2.toByteString();
104 
105     assertEquals(rawBytes, rawBytes2);
106   }
107 
testSerializationPackedWithoutGetSerializedSize()108   public void testSerializationPackedWithoutGetSerializedSize()
109       throws Exception {
110     // Write directly to an OutputStream, without invoking getSerializedSize()
111     // This used to be a bug where the size of a packed field was incorrect,
112     // since getSerializedSize() was never invoked.
113     TestPackedTypes message = TestUtil.getPackedSet();
114 
115     // Directly construct a CodedOutputStream around the actual OutputStream,
116     // in case writeTo(OutputStream output) invokes getSerializedSize();
117     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
118     CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream);
119 
120     message.writeTo(codedOutput);
121 
122     codedOutput.flush();
123 
124     TestPackedTypes message2 = TestPackedTypes.parseFrom(
125         outputStream.toByteArray());
126 
127     TestUtil.assertPackedFieldsSet(message2);
128   }
129 
testSerializeExtensionsLite()130   public void testSerializeExtensionsLite() throws Exception {
131     // TestAllTypes and TestAllExtensions should have compatible wire formats,
132     // so if we serialize a TestAllExtensions then parse it as TestAllTypes
133     // it should work.
134 
135     TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet();
136     ByteString rawBytes = message.toByteString();
137     assertEquals(rawBytes.size(), message.getSerializedSize());
138 
139     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
140 
141     TestUtil.assertAllFieldsSet(message2);
142   }
143 
testSerializePackedExtensionsLite()144   public void testSerializePackedExtensionsLite() throws Exception {
145     // TestPackedTypes and TestPackedExtensions should have compatible wire
146     // formats; check that they serialize to the same string.
147     TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
148     ByteString rawBytes = message.toByteString();
149 
150     TestPackedTypes message2 = TestUtil.getPackedSet();
151     ByteString rawBytes2 = message2.toByteString();
152 
153     assertEquals(rawBytes, rawBytes2);
154   }
155 
testParseExtensions()156   public void testParseExtensions() throws Exception {
157     // TestAllTypes and TestAllExtensions should have compatible wire formats,
158     // so if we serialize a TestAllTypes then parse it as TestAllExtensions
159     // it should work.
160 
161     TestAllTypes message = TestUtil.getAllSet();
162     ByteString rawBytes = message.toByteString();
163 
164     ExtensionRegistry registry = TestUtil.getExtensionRegistry();
165 
166     TestAllExtensions message2 =
167       TestAllExtensions.parseFrom(rawBytes, registry);
168 
169     TestUtil.assertAllExtensionsSet(message2);
170   }
171 
testParsePackedExtensions()172   public void testParsePackedExtensions() throws Exception {
173     // Ensure that packed extensions can be properly parsed.
174     TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
175     ByteString rawBytes = message.toByteString();
176 
177     ExtensionRegistry registry = TestUtil.getExtensionRegistry();
178 
179     TestPackedExtensions message2 =
180         TestPackedExtensions.parseFrom(rawBytes, registry);
181 
182     TestUtil.assertPackedExtensionsSet(message2);
183   }
184 
testParseExtensionsLite()185   public void testParseExtensionsLite() throws Exception {
186     // TestAllTypes and TestAllExtensions should have compatible wire formats,
187     // so if we serialize a TestAllTypes then parse it as TestAllExtensions
188     // it should work.
189 
190     TestAllTypes message = TestUtil.getAllSet();
191     ByteString rawBytes = message.toByteString();
192 
193     ExtensionRegistryLite registry_lite = TestUtilLite.getExtensionRegistryLite();
194 
195     TestAllExtensionsLite message2 =
196       TestAllExtensionsLite.parseFrom(rawBytes, registry_lite);
197 
198     TestUtil.assertAllExtensionsSet(message2);
199 
200     // Try again using a full extension registry.
201     ExtensionRegistry registry = TestUtil.getExtensionRegistry();
202 
203     TestAllExtensionsLite message3 =
204       TestAllExtensionsLite.parseFrom(rawBytes, registry);
205 
206     TestUtil.assertAllExtensionsSet(message3);
207   }
208 
testParsePackedExtensionsLite()209   public void testParsePackedExtensionsLite() throws Exception {
210     // Ensure that packed extensions can be properly parsed.
211     TestPackedExtensionsLite message = TestUtilLite.getLitePackedExtensionsSet();
212     ByteString rawBytes = message.toByteString();
213 
214     ExtensionRegistryLite registry = TestUtilLite.getExtensionRegistryLite();
215 
216     TestPackedExtensionsLite message2 =
217         TestPackedExtensionsLite.parseFrom(rawBytes, registry);
218 
219     TestUtil.assertPackedExtensionsSet(message2);
220   }
221 
testExtensionsSerializedSize()222   public void testExtensionsSerializedSize() throws Exception {
223     assertNotSame(TestUtil.getAllSet().getSerializedSize(),
224                   TestUtil.getAllExtensionsSet().getSerializedSize());
225   }
226 
testSerializeDelimited()227   public void testSerializeDelimited() throws Exception {
228     ByteArrayOutputStream output = new ByteArrayOutputStream();
229     TestUtil.getAllSet().writeDelimitedTo(output);
230     output.write(12);
231     TestUtil.getPackedSet().writeDelimitedTo(output);
232     output.write(34);
233 
234     ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
235 
236     TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input));
237     assertEquals(12, input.read());
238     TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input));
239     assertEquals(34, input.read());
240     assertEquals(-1, input.read());
241 
242     // We're at EOF, so parsing again should return null.
243     assertTrue(TestAllTypes.parseDelimitedFrom(input) == null);
244   }
245 
assertFieldsInOrder(ByteString data)246   private void assertFieldsInOrder(ByteString data) throws Exception {
247     CodedInputStream input = data.newCodedInput();
248     int previousTag = 0;
249 
250     while (true) {
251       int tag = input.readTag();
252       if (tag == 0) {
253         break;
254       }
255 
256       assertTrue(tag > previousTag);
257       previousTag = tag;
258       input.skipField(tag);
259     }
260   }
261 
testInterleavedFieldsAndExtensions()262   public void testInterleavedFieldsAndExtensions() throws Exception {
263     // Tests that fields are written in order even when extension ranges
264     // are interleaved with field numbers.
265     ByteString data =
266       TestFieldOrderings.newBuilder()
267         .setMyInt(1)
268         .setMyString("foo")
269         .setMyFloat(1.0F)
270         .setExtension(UnittestProto.myExtensionInt, 23)
271         .setExtension(UnittestProto.myExtensionString, "bar")
272         .build().toByteString();
273     assertFieldsInOrder(data);
274 
275     Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
276     ByteString dynamic_data =
277       DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
278         .setField(descriptor.findFieldByName("my_int"), 1L)
279         .setField(descriptor.findFieldByName("my_string"), "foo")
280         .setField(descriptor.findFieldByName("my_float"), 1.0F)
281         .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
282         .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
283         .build().toByteString();
284     assertFieldsInOrder(dynamic_data);
285   }
286 
getTestFieldOrderingsRegistry()287   private ExtensionRegistry getTestFieldOrderingsRegistry() {
288     ExtensionRegistry result = ExtensionRegistry.newInstance();
289     result.add(UnittestProto.myExtensionInt);
290     result.add(UnittestProto.myExtensionString);
291     return result;
292   }
293 
testParseMultipleExtensionRanges()294   public void testParseMultipleExtensionRanges() throws Exception {
295     // Make sure we can parse a message that contains multiple extensions
296     // ranges.
297     TestFieldOrderings source =
298       TestFieldOrderings.newBuilder()
299         .setMyInt(1)
300         .setMyString("foo")
301         .setMyFloat(1.0F)
302         .setExtension(UnittestProto.myExtensionInt, 23)
303         .setExtension(UnittestProto.myExtensionString, "bar")
304         .build();
305     TestFieldOrderings dest =
306       TestFieldOrderings.parseFrom(source.toByteString(),
307                                    getTestFieldOrderingsRegistry());
308     assertEquals(source, dest);
309   }
310 
testParseMultipleExtensionRangesDynamic()311   public void testParseMultipleExtensionRangesDynamic() throws Exception {
312     // Same as above except with DynamicMessage.
313     Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
314     DynamicMessage source =
315       DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
316         .setField(descriptor.findFieldByName("my_int"), 1L)
317         .setField(descriptor.findFieldByName("my_string"), "foo")
318         .setField(descriptor.findFieldByName("my_float"), 1.0F)
319         .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
320         .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
321         .build();
322     DynamicMessage dest =
323       DynamicMessage.parseFrom(descriptor, source.toByteString(),
324                                getTestFieldOrderingsRegistry());
325     assertEquals(source, dest);
326   }
327 
328   private static final int UNKNOWN_TYPE_ID = 1550055;
329   private static final int TYPE_ID_1 =
330     TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber();
331   private static final int TYPE_ID_2 =
332     TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber();
333 
testSerializeMessageSetEagerly()334   public void testSerializeMessageSetEagerly() throws Exception {
335     testSerializeMessageSetWithFlag(true);
336   }
337 
testSerializeMessageSetNotEagerly()338   public void testSerializeMessageSetNotEagerly() throws Exception {
339     testSerializeMessageSetWithFlag(false);
340   }
341 
testSerializeMessageSetWithFlag(boolean eagerParsing)342   private void testSerializeMessageSetWithFlag(boolean eagerParsing)
343       throws Exception {
344     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
345     // Set up a TestMessageSet with two known messages and an unknown one.
346     TestMessageSet messageSet =
347       TestMessageSet.newBuilder()
348         .setExtension(
349           TestMessageSetExtension1.messageSetExtension,
350           TestMessageSetExtension1.newBuilder().setI(123).build())
351         .setExtension(
352           TestMessageSetExtension2.messageSetExtension,
353           TestMessageSetExtension2.newBuilder().setStr("foo").build())
354         .setUnknownFields(
355           UnknownFieldSet.newBuilder()
356             .addField(UNKNOWN_TYPE_ID,
357               UnknownFieldSet.Field.newBuilder()
358                 .addLengthDelimited(ByteString.copyFromUtf8("bar"))
359                 .build())
360             .build())
361         .build();
362 
363     ByteString data = messageSet.toByteString();
364 
365     // Parse back using RawMessageSet and check the contents.
366     RawMessageSet raw = RawMessageSet.parseFrom(data);
367 
368     assertTrue(raw.getUnknownFields().asMap().isEmpty());
369 
370     assertEquals(3, raw.getItemCount());
371     assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId());
372     assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId());
373     assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId());
374 
375     TestMessageSetExtension1 message1 =
376       TestMessageSetExtension1.parseFrom(
377         raw.getItem(0).getMessage().toByteArray());
378     assertEquals(123, message1.getI());
379 
380     TestMessageSetExtension2 message2 =
381       TestMessageSetExtension2.parseFrom(
382         raw.getItem(1).getMessage().toByteArray());
383     assertEquals("foo", message2.getStr());
384 
385     assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8());
386   }
387 
testParseMessageSetEagerly()388   public void testParseMessageSetEagerly() throws Exception {
389     testParseMessageSetWithFlag(true);
390   }
391 
testParseMessageSetNotEagerly()392   public void testParseMessageSetNotEagerly()throws Exception {
393     testParseMessageSetWithFlag(false);
394   }
395 
testParseMessageSetWithFlag(boolean eagerParsing)396   private void testParseMessageSetWithFlag(boolean eagerParsing)
397       throws Exception {
398     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
399     ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
400     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
401     extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
402 
403     // Set up a RawMessageSet with two known messages and an unknown one.
404     RawMessageSet raw =
405       RawMessageSet.newBuilder()
406         .addItem(
407           RawMessageSet.Item.newBuilder()
408             .setTypeId(TYPE_ID_1)
409             .setMessage(
410               TestMessageSetExtension1.newBuilder()
411                 .setI(123)
412                 .build().toByteString())
413             .build())
414         .addItem(
415           RawMessageSet.Item.newBuilder()
416             .setTypeId(TYPE_ID_2)
417             .setMessage(
418               TestMessageSetExtension2.newBuilder()
419                 .setStr("foo")
420                 .build().toByteString())
421             .build())
422         .addItem(
423           RawMessageSet.Item.newBuilder()
424             .setTypeId(UNKNOWN_TYPE_ID)
425             .setMessage(ByteString.copyFromUtf8("bar"))
426             .build())
427         .build();
428 
429     ByteString data = raw.toByteString();
430 
431     // Parse as a TestMessageSet and check the contents.
432     TestMessageSet messageSet =
433       TestMessageSet.parseFrom(data, extensionRegistry);
434 
435     assertEquals(123, messageSet.getExtension(
436       TestMessageSetExtension1.messageSetExtension).getI());
437     assertEquals("foo", messageSet.getExtension(
438       TestMessageSetExtension2.messageSetExtension).getStr());
439 
440     // Check for unknown field with type LENGTH_DELIMITED,
441     //   number UNKNOWN_TYPE_ID, and contents "bar".
442     UnknownFieldSet unknownFields = messageSet.getUnknownFields();
443     assertEquals(1, unknownFields.asMap().size());
444     assertTrue(unknownFields.hasField(UNKNOWN_TYPE_ID));
445 
446     UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID);
447     assertEquals(1, field.getLengthDelimitedList().size());
448     assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8());
449   }
450 
testParseMessageSetExtensionEagerly()451   public void testParseMessageSetExtensionEagerly() throws Exception {
452     testParseMessageSetExtensionWithFlag(true);
453   }
454 
testParseMessageSetExtensionNotEagerly()455   public void testParseMessageSetExtensionNotEagerly() throws Exception {
456     testParseMessageSetExtensionWithFlag(false);
457   }
458 
testParseMessageSetExtensionWithFlag(boolean eagerParsing)459   private void testParseMessageSetExtensionWithFlag(boolean eagerParsing)
460       throws Exception {
461     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
462     ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
463     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
464 
465     // Set up a RawMessageSet with a known messages.
466     int TYPE_ID_1 =
467         TestMessageSetExtension1
468             .getDescriptor().getExtensions().get(0).getNumber();
469     RawMessageSet raw =
470       RawMessageSet.newBuilder()
471         .addItem(
472           RawMessageSet.Item.newBuilder()
473             .setTypeId(TYPE_ID_1)
474             .setMessage(
475               TestMessageSetExtension1.newBuilder()
476                 .setI(123)
477                 .build().toByteString())
478             .build())
479         .build();
480 
481     ByteString data = raw.toByteString();
482 
483     // Parse as a TestMessageSet and check the contents.
484     TestMessageSet messageSet =
485         TestMessageSet.parseFrom(data, extensionRegistry);
486     assertEquals(123, messageSet.getExtension(
487         TestMessageSetExtension1.messageSetExtension).getI());
488   }
489 
testMergeLazyMessageSetExtensionEagerly()490   public void testMergeLazyMessageSetExtensionEagerly() throws Exception {
491     testMergeLazyMessageSetExtensionWithFlag(true);
492   }
493 
testMergeLazyMessageSetExtensionNotEagerly()494   public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception {
495     testMergeLazyMessageSetExtensionWithFlag(false);
496   }
497 
testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)498   private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)
499       throws Exception {
500     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
501     ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
502     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
503 
504     // Set up a RawMessageSet with a known messages.
505     int TYPE_ID_1 =
506         TestMessageSetExtension1
507             .getDescriptor().getExtensions().get(0).getNumber();
508     RawMessageSet raw =
509       RawMessageSet.newBuilder()
510         .addItem(
511           RawMessageSet.Item.newBuilder()
512             .setTypeId(TYPE_ID_1)
513             .setMessage(
514               TestMessageSetExtension1.newBuilder()
515                 .setI(123)
516                 .build().toByteString())
517             .build())
518         .build();
519 
520     ByteString data = raw.toByteString();
521 
522     // Parse as a TestMessageSet and store value into lazy field
523     TestMessageSet messageSet =
524         TestMessageSet.parseFrom(data, extensionRegistry);
525     // Merge lazy field check the contents.
526     messageSet =
527         messageSet.toBuilder().mergeFrom(data, extensionRegistry).build();
528     assertEquals(123, messageSet.getExtension(
529         TestMessageSetExtension1.messageSetExtension).getI());
530   }
531 
testMergeMessageSetExtensionEagerly()532   public void testMergeMessageSetExtensionEagerly() throws Exception {
533     testMergeMessageSetExtensionWithFlag(true);
534   }
535 
testMergeMessageSetExtensionNotEagerly()536   public void testMergeMessageSetExtensionNotEagerly() throws Exception {
537     testMergeMessageSetExtensionWithFlag(false);
538   }
539 
testMergeMessageSetExtensionWithFlag(boolean eagerParsing)540   private void testMergeMessageSetExtensionWithFlag(boolean eagerParsing)
541       throws Exception {
542     ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
543     ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
544     extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
545 
546     // Set up a RawMessageSet with a known messages.
547     int TYPE_ID_1 =
548         TestMessageSetExtension1
549             .getDescriptor().getExtensions().get(0).getNumber();
550     RawMessageSet raw =
551       RawMessageSet.newBuilder()
552         .addItem(
553           RawMessageSet.Item.newBuilder()
554             .setTypeId(TYPE_ID_1)
555             .setMessage(
556               TestMessageSetExtension1.newBuilder()
557                 .setI(123)
558                 .build().toByteString())
559             .build())
560         .build();
561 
562     // Serialize RawMessageSet unnormally (message value before type id)
563     ByteString.CodedBuilder out = ByteString.newCodedBuilder(
564         raw.getSerializedSize());
565     CodedOutputStream output = out.getCodedOutput();
566     List<RawMessageSet.Item> items = raw.getItemList();
567     for (int i = 0; i < items.size(); i++) {
568       RawMessageSet.Item item = items.get(i);
569       output.writeTag(1, WireFormat.WIRETYPE_START_GROUP);
570       output.writeBytes(3, item.getMessage());
571       output.writeInt32(2, item.getTypeId());
572       output.writeTag(1, WireFormat.WIRETYPE_END_GROUP);
573     }
574     ByteString data = out.build();
575 
576     // Merge bytes into TestMessageSet and check the contents.
577     TestMessageSet messageSet =
578         TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build();
579     assertEquals(123, messageSet.getExtension(
580         TestMessageSetExtension1.messageSetExtension).getI());
581   }
582 
583   // ================================================================
584   // oneof
testOneofWireFormat()585   public void testOneofWireFormat() throws Exception {
586     TestOneof2.Builder builder = TestOneof2.newBuilder();
587     TestUtil.setOneof(builder);
588     TestOneof2 message = builder.build();
589     ByteString rawBytes = message.toByteString();
590 
591     assertEquals(rawBytes.size(), message.getSerializedSize());
592 
593     TestOneof2 message2 = TestOneof2.parseFrom(rawBytes);
594     TestUtil.assertOneofSet(message2);
595   }
596 
testOneofOnlyLastSet()597   public void testOneofOnlyLastSet() throws Exception {
598     TestOneofBackwardsCompatible source = TestOneofBackwardsCompatible
599         .newBuilder().setFooInt(100).setFooString("101").build();
600 
601     ByteString rawBytes = source.toByteString();
602     TestOneof2 message = TestOneof2.parseFrom(rawBytes);
603     assertFalse(message.hasFooInt());
604     assertTrue(message.hasFooString());
605   }
606 }
607