1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://code.google.com/p/protobuf/
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
31package com.google.protobuf;
32
33import protobuf_unittest.UnittestProto.TestAllTypes;
34import protobuf_unittest.UnittestProto.TestAllExtensions;
35import protobuf_unittest.UnittestProto.TestPackedTypes;
36
37import junit.framework.TestCase;
38import java.util.Arrays;
39
40/**
41 * Unit test for {@link DynamicMessage}.  See also {@link MessageTest}, which
42 * tests some {@link DynamicMessage} functionality.
43 *
44 * @author kenton@google.com Kenton Varda
45 */
46public class DynamicMessageTest extends TestCase {
47  TestUtil.ReflectionTester reflectionTester =
48    new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
49
50  TestUtil.ReflectionTester extensionsReflectionTester =
51    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
52                                  TestUtil.getExtensionRegistry());
53  TestUtil.ReflectionTester packedReflectionTester =
54    new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null);
55
56  public void testDynamicMessageAccessors() throws Exception {
57    Message.Builder builder =
58      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
59    reflectionTester.setAllFieldsViaReflection(builder);
60    Message message = builder.build();
61    reflectionTester.assertAllFieldsSetViaReflection(message);
62  }
63
64  public void testDoubleBuildError() throws Exception {
65    Message.Builder builder =
66      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
67    builder.build();
68    try {
69      builder.build();
70      fail("Should have thrown exception.");
71    } catch (IllegalStateException e) {
72      // Success.
73    }
74  }
75
76  public void testClearAfterBuildError() throws Exception {
77    Message.Builder builder =
78      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
79    builder.build();
80    try {
81      builder.clear();
82      fail("Should have thrown exception.");
83    } catch (IllegalStateException e) {
84      // Success.
85    }
86  }
87
88  public void testDynamicMessageSettersRejectNull() throws Exception {
89    Message.Builder builder =
90      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
91    reflectionTester.assertReflectionSettersRejectNull(builder);
92  }
93
94  public void testDynamicMessageExtensionAccessors() throws Exception {
95    // We don't need to extensively test DynamicMessage's handling of
96    // extensions because, frankly, it doesn't do anything special with them.
97    // It treats them just like any other fields.
98    Message.Builder builder =
99      DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
100    extensionsReflectionTester.setAllFieldsViaReflection(builder);
101    Message message = builder.build();
102    extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
103  }
104
105  public void testDynamicMessageExtensionSettersRejectNull() throws Exception {
106    Message.Builder builder =
107      DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
108    extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
109  }
110
111  public void testDynamicMessageRepeatedSetters() throws Exception {
112    Message.Builder builder =
113      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
114    reflectionTester.setAllFieldsViaReflection(builder);
115    reflectionTester.modifyRepeatedFieldsViaReflection(builder);
116    Message message = builder.build();
117    reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
118  }
119
120  public void testDynamicMessageRepeatedSettersRejectNull() throws Exception {
121    Message.Builder builder =
122      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
123    reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
124  }
125
126  public void testDynamicMessageDefaults() throws Exception {
127    reflectionTester.assertClearViaReflection(
128      DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor()));
129    reflectionTester.assertClearViaReflection(
130      DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build());
131  }
132
133  public void testDynamicMessageSerializedSize() throws Exception {
134    TestAllTypes message = TestUtil.getAllSet();
135
136    Message.Builder dynamicBuilder =
137      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
138    reflectionTester.setAllFieldsViaReflection(dynamicBuilder);
139    Message dynamicMessage = dynamicBuilder.build();
140
141    assertEquals(message.getSerializedSize(),
142                 dynamicMessage.getSerializedSize());
143  }
144
145  public void testDynamicMessageSerialization() throws Exception {
146    Message.Builder builder =
147      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
148    reflectionTester.setAllFieldsViaReflection(builder);
149    Message message = builder.build();
150
151    ByteString rawBytes = message.toByteString();
152    TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
153
154    TestUtil.assertAllFieldsSet(message2);
155
156    // In fact, the serialized forms should be exactly the same, byte-for-byte.
157    assertEquals(TestUtil.getAllSet().toByteString(), rawBytes);
158  }
159
160  public void testDynamicMessageParsing() throws Exception {
161    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
162    TestUtil.setAllFields(builder);
163    TestAllTypes message = builder.build();
164
165    ByteString rawBytes = message.toByteString();
166
167    Message message2 =
168      DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), rawBytes);
169    reflectionTester.assertAllFieldsSetViaReflection(message2);
170  }
171
172  public void testDynamicMessagePackedSerialization() throws Exception {
173    Message.Builder builder =
174        DynamicMessage.newBuilder(TestPackedTypes.getDescriptor());
175    packedReflectionTester.setPackedFieldsViaReflection(builder);
176    Message message = builder.build();
177
178    ByteString rawBytes = message.toByteString();
179    TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
180
181    TestUtil.assertPackedFieldsSet(message2);
182
183    // In fact, the serialized forms should be exactly the same, byte-for-byte.
184    assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes);
185  }
186
187  public void testDynamicMessagePackedParsing() throws Exception {
188    TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
189    TestUtil.setPackedFields(builder);
190    TestPackedTypes message = builder.build();
191
192    ByteString rawBytes = message.toByteString();
193
194    Message message2 =
195      DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes);
196    packedReflectionTester.assertPackedFieldsSetViaReflection(message2);
197  }
198
199  public void testDynamicMessageCopy() throws Exception {
200    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
201    TestUtil.setAllFields(builder);
202    TestAllTypes message = builder.build();
203
204    DynamicMessage copy = DynamicMessage.newBuilder(message).build();
205    reflectionTester.assertAllFieldsSetViaReflection(copy);
206  }
207
208  public void testToBuilder() throws Exception {
209    DynamicMessage.Builder builder =
210        DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
211    reflectionTester.setAllFieldsViaReflection(builder);
212    int unknownFieldNum = 9;
213    long unknownFieldVal = 90;
214    builder.setUnknownFields(UnknownFieldSet.newBuilder()
215        .addField(unknownFieldNum,
216            UnknownFieldSet.Field.newBuilder()
217                .addVarint(unknownFieldVal).build())
218        .build());
219    DynamicMessage message = builder.build();
220
221    DynamicMessage derived = message.toBuilder().build();
222    reflectionTester.assertAllFieldsSetViaReflection(derived);
223    assertEquals(Arrays.asList(unknownFieldVal),
224        derived.getUnknownFields().getField(unknownFieldNum).getVarintList());
225  }
226}
227