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.Descriptors.EnumDescriptor;
34 import com.google.protobuf.Descriptors.FieldDescriptor;
35 import com.google.protobuf.Descriptors.OneofDescriptor;
36 import protobuf_unittest.UnittestProto.TestAllExtensions;
37 import protobuf_unittest.UnittestProto.TestAllTypes;
38 import protobuf_unittest.UnittestProto.TestEmptyMessage;
39 import protobuf_unittest.UnittestProto.TestPackedTypes;
40 
41 import junit.framework.TestCase;
42 
43 import java.util.Arrays;
44 
45 /**
46  * Unit test for {@link DynamicMessage}.  See also {@link MessageTest}, which
47  * tests some {@link DynamicMessage} functionality.
48  *
49  * @author kenton@google.com Kenton Varda
50  */
51 public class DynamicMessageTest extends TestCase {
52   TestUtil.ReflectionTester reflectionTester =
53     new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
54 
55   TestUtil.ReflectionTester extensionsReflectionTester =
56     new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
57                                   TestUtil.getExtensionRegistry());
58   TestUtil.ReflectionTester packedReflectionTester =
59     new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null);
60 
testDynamicMessageAccessors()61   public void testDynamicMessageAccessors() throws Exception {
62     Message.Builder builder =
63       DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
64     reflectionTester.setAllFieldsViaReflection(builder);
65     Message message = builder.build();
66     reflectionTester.assertAllFieldsSetViaReflection(message);
67   }
68 
testSettersAfterBuild()69   public void testSettersAfterBuild() throws Exception {
70     Message.Builder builder =
71       DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
72     Message firstMessage = builder.build();
73     // double build()
74     builder.build();
75     // clear() after build()
76     builder.clear();
77     // setters after build()
78     reflectionTester.setAllFieldsViaReflection(builder);
79     Message message = builder.build();
80     reflectionTester.assertAllFieldsSetViaReflection(message);
81     // repeated setters after build()
82     reflectionTester.modifyRepeatedFieldsViaReflection(builder);
83     message = builder.build();
84     reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
85     // firstMessage shouldn't have been modified.
86     reflectionTester.assertClearViaReflection(firstMessage);
87   }
88 
testUnknownFields()89   public void testUnknownFields() throws Exception {
90     Message.Builder builder =
91         DynamicMessage.newBuilder(TestEmptyMessage.getDescriptor());
92     builder.setUnknownFields(UnknownFieldSet.newBuilder()
93         .addField(1, UnknownFieldSet.Field.newBuilder().addVarint(1).build())
94         .addField(2, UnknownFieldSet.Field.newBuilder().addFixed32(1).build())
95         .build());
96     Message message = builder.build();
97     assertEquals(2, message.getUnknownFields().asMap().size());
98     // clone() with unknown fields
99     Message.Builder newBuilder = builder.clone();
100     assertEquals(2, newBuilder.getUnknownFields().asMap().size());
101     // clear() with unknown fields
102     newBuilder.clear();
103     assertTrue(newBuilder.getUnknownFields().asMap().isEmpty());
104     // serialize/parse with unknown fields
105     newBuilder.mergeFrom(message.toByteString());
106     assertEquals(2, newBuilder.getUnknownFields().asMap().size());
107   }
108 
testDynamicMessageSettersRejectNull()109   public void testDynamicMessageSettersRejectNull() throws Exception {
110     Message.Builder builder =
111       DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
112     reflectionTester.assertReflectionSettersRejectNull(builder);
113   }
114 
testDynamicMessageExtensionAccessors()115   public void testDynamicMessageExtensionAccessors() throws Exception {
116     // We don't need to extensively test DynamicMessage's handling of
117     // extensions because, frankly, it doesn't do anything special with them.
118     // It treats them just like any other fields.
119     Message.Builder builder =
120       DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
121     extensionsReflectionTester.setAllFieldsViaReflection(builder);
122     Message message = builder.build();
123     extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
124   }
125 
testDynamicMessageExtensionSettersRejectNull()126   public void testDynamicMessageExtensionSettersRejectNull() throws Exception {
127     Message.Builder builder =
128       DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
129     extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
130   }
131 
testDynamicMessageRepeatedSetters()132   public void testDynamicMessageRepeatedSetters() throws Exception {
133     Message.Builder builder =
134       DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
135     reflectionTester.setAllFieldsViaReflection(builder);
136     reflectionTester.modifyRepeatedFieldsViaReflection(builder);
137     Message message = builder.build();
138     reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
139   }
140 
testDynamicMessageRepeatedSettersRejectNull()141   public void testDynamicMessageRepeatedSettersRejectNull() throws Exception {
142     Message.Builder builder =
143       DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
144     reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
145   }
146 
testDynamicMessageDefaults()147   public void testDynamicMessageDefaults() throws Exception {
148     reflectionTester.assertClearViaReflection(
149       DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor()));
150     reflectionTester.assertClearViaReflection(
151       DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build());
152   }
153 
testDynamicMessageSerializedSize()154   public void testDynamicMessageSerializedSize() throws Exception {
155     TestAllTypes message = TestUtil.getAllSet();
156 
157     Message.Builder dynamicBuilder =
158       DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
159     reflectionTester.setAllFieldsViaReflection(dynamicBuilder);
160     Message dynamicMessage = dynamicBuilder.build();
161 
162     assertEquals(message.getSerializedSize(),
163                  dynamicMessage.getSerializedSize());
164   }
165 
testDynamicMessageSerialization()166   public void testDynamicMessageSerialization() throws Exception {
167     Message.Builder builder =
168       DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
169     reflectionTester.setAllFieldsViaReflection(builder);
170     Message message = builder.build();
171 
172     ByteString rawBytes = message.toByteString();
173     TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
174 
175     TestUtil.assertAllFieldsSet(message2);
176 
177     // In fact, the serialized forms should be exactly the same, byte-for-byte.
178     assertEquals(TestUtil.getAllSet().toByteString(), rawBytes);
179   }
180 
testDynamicMessageParsing()181   public void testDynamicMessageParsing() throws Exception {
182     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
183     TestUtil.setAllFields(builder);
184     TestAllTypes message = builder.build();
185 
186     ByteString rawBytes = message.toByteString();
187 
188     Message message2 =
189       DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), rawBytes);
190     reflectionTester.assertAllFieldsSetViaReflection(message2);
191 
192     // Test Parser interface.
193     Message message3 = message2.getParserForType().parseFrom(rawBytes);
194     reflectionTester.assertAllFieldsSetViaReflection(message3);
195   }
196 
testDynamicMessageExtensionParsing()197   public void testDynamicMessageExtensionParsing() throws Exception {
198     ByteString rawBytes = TestUtil.getAllExtensionsSet().toByteString();
199     Message message = DynamicMessage.parseFrom(
200         TestAllExtensions.getDescriptor(), rawBytes,
201         TestUtil.getExtensionRegistry());
202     extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
203 
204     // Test Parser interface.
205     Message message2 = message.getParserForType().parseFrom(
206         rawBytes, TestUtil.getExtensionRegistry());
207     extensionsReflectionTester.assertAllFieldsSetViaReflection(message2);
208   }
209 
testDynamicMessagePackedSerialization()210   public void testDynamicMessagePackedSerialization() throws Exception {
211     Message.Builder builder =
212         DynamicMessage.newBuilder(TestPackedTypes.getDescriptor());
213     packedReflectionTester.setPackedFieldsViaReflection(builder);
214     Message message = builder.build();
215 
216     ByteString rawBytes = message.toByteString();
217     TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
218 
219     TestUtil.assertPackedFieldsSet(message2);
220 
221     // In fact, the serialized forms should be exactly the same, byte-for-byte.
222     assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes);
223   }
224 
testDynamicMessagePackedParsing()225   public void testDynamicMessagePackedParsing() throws Exception {
226     TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
227     TestUtil.setPackedFields(builder);
228     TestPackedTypes message = builder.build();
229 
230     ByteString rawBytes = message.toByteString();
231 
232     Message message2 =
233       DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes);
234     packedReflectionTester.assertPackedFieldsSetViaReflection(message2);
235 
236     // Test Parser interface.
237     Message message3 = message2.getParserForType().parseFrom(rawBytes);
238     packedReflectionTester.assertPackedFieldsSetViaReflection(message3);
239   }
240 
testDynamicMessageCopy()241   public void testDynamicMessageCopy() throws Exception {
242     TestAllTypes.Builder builder = TestAllTypes.newBuilder();
243     TestUtil.setAllFields(builder);
244     TestAllTypes message = builder.build();
245 
246     DynamicMessage copy = DynamicMessage.newBuilder(message).build();
247     reflectionTester.assertAllFieldsSetViaReflection(copy);
248 
249     // Test oneof behavior
250     FieldDescriptor bytesField =
251         TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
252     FieldDescriptor uint32Field =
253         TestAllTypes.getDescriptor().findFieldByName("oneof_uint32");
254     assertTrue(copy.hasField(bytesField));
255     assertFalse(copy.hasField(uint32Field));
256     DynamicMessage copy2 =
257         DynamicMessage.newBuilder(message).setField(uint32Field, 123).build();
258     assertFalse(copy2.hasField(bytesField));
259     assertTrue(copy2.hasField(uint32Field));
260     assertEquals(123, copy2.getField(uint32Field));
261   }
262 
testToBuilder()263   public void testToBuilder() throws Exception {
264     DynamicMessage.Builder builder =
265         DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
266     reflectionTester.setAllFieldsViaReflection(builder);
267     int unknownFieldNum = 9;
268     long unknownFieldVal = 90;
269     builder.setUnknownFields(UnknownFieldSet.newBuilder()
270         .addField(unknownFieldNum,
271             UnknownFieldSet.Field.newBuilder()
272                 .addVarint(unknownFieldVal).build())
273         .build());
274     DynamicMessage message = builder.build();
275 
276     DynamicMessage derived = message.toBuilder().build();
277     reflectionTester.assertAllFieldsSetViaReflection(derived);
278     assertEquals(Arrays.asList(unknownFieldVal),
279         derived.getUnknownFields().getField(unknownFieldNum).getVarintList());
280   }
281 
testDynamicOneofMessage()282   public void testDynamicOneofMessage() throws Exception {
283     DynamicMessage.Builder builder =
284         DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
285     OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0);
286     assertFalse(builder.hasOneof(oneof));
287     assertSame(null, builder.getOneofFieldDescriptor(oneof));
288 
289     reflectionTester.setAllFieldsViaReflection(builder);
290     assertTrue(builder.hasOneof(oneof));
291     FieldDescriptor field = oneof.getField(3);
292     assertSame(field, builder.getOneofFieldDescriptor(oneof));
293 
294     DynamicMessage message = builder.buildPartial();
295     assertTrue(message.hasOneof(oneof));
296 
297     DynamicMessage.Builder mergedBuilder =
298         DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
299     FieldDescriptor mergedField = oneof.getField(0);
300     mergedBuilder.setField(mergedField, 123);
301     assertTrue(mergedBuilder.hasField(mergedField));
302     mergedBuilder.mergeFrom(message);
303     assertTrue(mergedBuilder.hasField(field));
304     assertFalse(mergedBuilder.hasField(mergedField));
305 
306     builder.clearOneof(oneof);
307     assertSame(null, builder.getOneofFieldDescriptor(oneof));
308     message = builder.build();
309     assertSame(null, message.getOneofFieldDescriptor(oneof));
310   }
311 
312   // Regression test for a bug that makes setField() not work for repeated
313   // enum fields.
testSettersForRepeatedEnumField()314   public void testSettersForRepeatedEnumField() throws Exception {
315     DynamicMessage.Builder builder =
316         DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
317     FieldDescriptor repeatedEnumField =
318         TestAllTypes.getDescriptor().findFieldByName(
319             "repeated_nested_enum");
320     EnumDescriptor enumDescriptor = TestAllTypes.NestedEnum.getDescriptor();
321     builder.setField(repeatedEnumField, enumDescriptor.getValues());
322     DynamicMessage message = builder.build();
323     assertEquals(
324         enumDescriptor.getValues(), message.getField(repeatedEnumField));
325   }
326 }
327