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