1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 package com.google.protobuf;
33 import com.google.protobuf.UnittestLite.TestAllTypesLite;
34 import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
35 import com.google.protobuf.UnittestLite.TestParsingMergeLite;
36 import com.google.protobuf.UnittestLite;
37 import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
38 import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
39 import protobuf_unittest.UnittestOptimizeFor;
40 import protobuf_unittest.UnittestProto.ForeignMessage;
41 import protobuf_unittest.UnittestProto.TestAllTypes;
42 import protobuf_unittest.UnittestProto.TestEmptyMessage;
43 import protobuf_unittest.UnittestProto.TestRequired;
44 import protobuf_unittest.UnittestProto.TestParsingMerge;
45 import protobuf_unittest.UnittestProto;
47 import junit.framework.TestCase;
49 import java.io.ByteArrayInputStream;
50 import java.io.ByteArrayOutputStream;
51 import java.io.IOException;
52 import java.io.InputStream;
55 * Unit test for {@link Parser}.
57 * @author liujisi@google.com (Pherl Liu)
59 public class ParserTest extends TestCase {
60 public void testGeneratedMessageParserSingleton() throws Exception {
61 for (int i = 0; i < 10; i++) {
62 assertEquals(TestAllTypes.PARSER,
63 TestUtil.getAllSet().getParserForType());
67 private void assertRoundTripEquals(MessageLite message,
68 ExtensionRegistryLite registry)
70 final byte[] data = message.toByteArray();
71 final int offset = 20;
72 final int length = data.length;
73 final int padding = 30;
74 Parser<? extends MessageLite> parser = message.getParserForType();
75 assertMessageEquals(message, parser.parseFrom(data, registry));
76 assertMessageEquals(message, parser.parseFrom(
77 generatePaddingArray(data, offset, padding),
78 offset, length, registry));
79 assertMessageEquals(message, parser.parseFrom(
80 message.toByteString(), registry));
81 assertMessageEquals(message, parser.parseFrom(
82 new ByteArrayInputStream(data), registry));
83 assertMessageEquals(message, parser.parseFrom(
84 CodedInputStream.newInstance(data), registry));
87 private void assertRoundTripEquals(MessageLite message) throws Exception {
88 final byte[] data = message.toByteArray();
89 final int offset = 20;
90 final int length = data.length;
91 final int padding = 30;
92 Parser<? extends MessageLite> parser = message.getParserForType();
93 assertMessageEquals(message, parser.parseFrom(data));
94 assertMessageEquals(message, parser.parseFrom(
95 generatePaddingArray(data, offset, padding),
97 assertMessageEquals(message, parser.parseFrom(message.toByteString()));
98 assertMessageEquals(message, parser.parseFrom(
99 new ByteArrayInputStream(data)));
100 assertMessageEquals(message, parser.parseFrom(
101 CodedInputStream.newInstance(data)));
104 private void assertMessageEquals(MessageLite expected, MessageLite actual)
106 if (expected instanceof Message) {
107 assertEquals(expected, actual);
109 assertEquals(expected.toByteString(), actual.toByteString());
113 private byte[] generatePaddingArray(byte[] data, int offset, int padding) {
114 byte[] result = new byte[offset + data.length + padding];
115 System.arraycopy(data, 0, result, offset, data.length);
119 public void testNormalMessage() throws Exception {
120 assertRoundTripEquals(TestUtil.getAllSet());
123 public void testParsePartial() throws Exception {
124 Parser<TestRequired> parser = TestRequired.PARSER;
125 final String errorString =
126 "Should throw exceptions when the parsed message isn't initialized.";
128 // TestRequired.b and TestRequired.c are not set.
129 TestRequired partialMessage = TestRequired.newBuilder()
130 .setA(1).buildPartial();
132 // parsePartialFrom should pass.
133 byte[] data = partialMessage.toByteArray();
134 assertEquals(partialMessage, parser.parsePartialFrom(data));
135 assertEquals(partialMessage, parser.parsePartialFrom(
136 partialMessage.toByteString()));
137 assertEquals(partialMessage, parser.parsePartialFrom(
138 new ByteArrayInputStream(data)));
139 assertEquals(partialMessage, parser.parsePartialFrom(
140 CodedInputStream.newInstance(data)));
142 // parseFrom(ByteArray)
144 parser.parseFrom(partialMessage.toByteArray());
146 } catch (InvalidProtocolBufferException e) {
150 // parseFrom(ByteString)
152 parser.parseFrom(partialMessage.toByteString());
154 } catch (InvalidProtocolBufferException e) {
158 // parseFrom(InputStream)
160 parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray()));
162 } catch (IOException e) {
166 // parseFrom(CodedInputStream)
168 parser.parseFrom(CodedInputStream.newInstance(
169 partialMessage.toByteArray()));
171 } catch (IOException e) {
176 public void testParseExtensions() throws Exception {
177 assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
178 TestUtil.getExtensionRegistry());
179 assertRoundTripEquals(TestUtil.getAllLiteExtensionsSet(),
180 TestUtil.getExtensionRegistryLite());
183 public void testParsePacked() throws Exception {
184 assertRoundTripEquals(TestUtil.getPackedSet());
185 assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
186 TestUtil.getExtensionRegistry());
187 assertRoundTripEquals(TestUtil.getLitePackedExtensionsSet(),
188 TestUtil.getExtensionRegistryLite());
191 public void testParseDelimitedTo() throws Exception {
192 // Write normal Message.
193 TestAllTypes normalMessage = TestUtil.getAllSet();
194 ByteArrayOutputStream output = new ByteArrayOutputStream();
195 normalMessage.writeDelimitedTo(output);
197 // Write MessageLite with packed extension fields.
198 TestPackedExtensionsLite packedMessage =
199 TestUtil.getLitePackedExtensionsSet();
200 packedMessage.writeDelimitedTo(output);
202 InputStream input = new ByteArrayInputStream(output.toByteArray());
205 normalMessage.getParserForType().parseDelimitedFrom(input));
208 packedMessage.getParserForType().parseDelimitedFrom(
209 input, TestUtil.getExtensionRegistryLite()));
212 public void testParseUnknownFields() throws Exception {
213 // All fields will be treated as unknown fields in emptyMessage.
214 TestEmptyMessage emptyMessage = TestEmptyMessage.PARSER.parseFrom(
215 TestUtil.getAllSet().toByteString());
217 TestUtil.getAllSet().toByteString(),
218 emptyMessage.toByteString());
221 public void testOptimizeForSize() throws Exception {
222 TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
223 builder.setI(12).setMsg(ForeignMessage.newBuilder().setC(34).build());
224 builder.setExtension(TestOptimizedForSize.testExtension, 56);
225 builder.setExtension(TestOptimizedForSize.testExtension2,
226 TestRequiredOptimizedForSize.newBuilder().setX(78).build());
228 TestOptimizedForSize message = builder.build();
229 ExtensionRegistry registry = ExtensionRegistry.newInstance();
230 UnittestOptimizeFor.registerAllExtensions(registry);
232 assertRoundTripEquals(message, registry);
235 /** Helper method for {@link #testParsingMerge()}.*/
236 private void assertMessageMerged(TestAllTypes allTypes)
238 assertEquals(3, allTypes.getOptionalInt32());
239 assertEquals(2, allTypes.getOptionalInt64());
240 assertEquals("hello", allTypes.getOptionalString());
243 /** Helper method for {@link #testParsingMergeLite()}.*/
244 private void assertMessageMerged(TestAllTypesLite allTypes)
246 assertEquals(3, allTypes.getOptionalInt32());
247 assertEquals(2, allTypes.getOptionalInt64());
248 assertEquals("hello", allTypes.getOptionalString());
251 public void testParsingMerge() throws Exception {
253 TestAllTypes.Builder builder = TestAllTypes.newBuilder();
254 TestAllTypes msg1 = builder.setOptionalInt32(1).build();
256 TestAllTypes msg2 = builder.setOptionalInt64(2).build();
258 TestAllTypes msg3 = builder.setOptionalInt32(3)
259 .setOptionalString("hello").build();
262 TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG1 =
263 TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
264 .setField1(msg1).build();
265 TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG2 =
266 TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
267 .setField1(msg2).build();
268 TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG3 =
269 TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
270 .setField1(msg3).build();
271 TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG1 =
272 TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
273 .setField1(msg1).build();
274 TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG2 =
275 TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
276 .setField1(msg2).build();
277 TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG3 =
278 TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
279 .setField1(msg3).build();
281 // Assign and serialize RepeatedFieldsGenerator.
282 ByteString data = TestParsingMerge.RepeatedFieldsGenerator.newBuilder()
283 .addField1(msg1).addField1(msg2).addField1(msg3)
284 .addField2(msg1).addField2(msg2).addField2(msg3)
285 .addField3(msg1).addField3(msg2).addField3(msg3)
286 .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3)
287 .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3)
288 .addExt1(msg1).addExt1(msg2).addExt1(msg3)
289 .addExt2(msg1).addExt2(msg2).addExt2(msg3)
290 .build().toByteString();
292 // Parse TestParsingMerge.
293 ExtensionRegistry registry = ExtensionRegistry.newInstance();
294 UnittestProto.registerAllExtensions(registry);
295 TestParsingMerge parsingMerge =
296 TestParsingMerge.PARSER.parseFrom(data, registry);
298 // Required and optional fields should be merged.
299 assertMessageMerged(parsingMerge.getRequiredAllTypes());
300 assertMessageMerged(parsingMerge.getOptionalAllTypes());
302 parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
303 assertMessageMerged(parsingMerge.getExtension(
304 TestParsingMerge.optionalExt));
306 // Repeated fields should not be merged.
307 assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
308 assertEquals(3, parsingMerge.getRepeatedGroupCount());
309 assertEquals(3, parsingMerge.getExtensionCount(
310 TestParsingMerge.repeatedExt));
313 public void testParsingMergeLite() throws Exception {
315 TestAllTypesLite.Builder builder =
316 TestAllTypesLite.newBuilder();
317 TestAllTypesLite msg1 = builder.setOptionalInt32(1).build();
319 TestAllTypesLite msg2 = builder.setOptionalInt64(2).build();
321 TestAllTypesLite msg3 = builder.setOptionalInt32(3)
322 .setOptionalString("hello").build();
325 TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG1 =
326 TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
327 .setField1(msg1).build();
328 TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG2 =
329 TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
330 .setField1(msg2).build();
331 TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG3 =
332 TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
333 .setField1(msg3).build();
334 TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG1 =
335 TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
336 .setField1(msg1).build();
337 TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG2 =
338 TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
339 .setField1(msg2).build();
340 TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG3 =
341 TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
342 .setField1(msg3).build();
344 // Assign and serialize RepeatedFieldsGenerator.
345 ByteString data = TestParsingMergeLite.RepeatedFieldsGenerator.newBuilder()
346 .addField1(msg1).addField1(msg2).addField1(msg3)
347 .addField2(msg1).addField2(msg2).addField2(msg3)
348 .addField3(msg1).addField3(msg2).addField3(msg3)
349 .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3)
350 .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3)
351 .addExt1(msg1).addExt1(msg2).addExt1(msg3)
352 .addExt2(msg1).addExt2(msg2).addExt2(msg3)
353 .build().toByteString();
355 // Parse TestParsingMergeLite.
356 ExtensionRegistry registry = ExtensionRegistry.newInstance();
357 UnittestLite.registerAllExtensions(registry);
358 TestParsingMergeLite parsingMerge =
359 TestParsingMergeLite.PARSER.parseFrom(data, registry);
361 // Required and optional fields should be merged.
362 assertMessageMerged(parsingMerge.getRequiredAllTypes());
363 assertMessageMerged(parsingMerge.getOptionalAllTypes());
365 parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
366 assertMessageMerged(parsingMerge.getExtension(
367 TestParsingMergeLite.optionalExt));
369 // Repeated fields should not be merged.
370 assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
371 assertEquals(3, parsingMerge.getRepeatedGroupCount());
372 assertEquals(3, parsingMerge.getExtensionCount(
373 TestParsingMergeLite.repeatedExt));