FieldPresenceTest.java
Go to the documentation of this file.
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 
37 import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
38 import com.google.protobuf.FieldPresenceTestProto.TestOptionalFieldsOnly;
39 import com.google.protobuf.FieldPresenceTestProto.TestRepeatedFieldsOnly;
40 import protobuf_unittest.UnittestProto;
41 import junit.framework.TestCase;
42 
46 public class FieldPresenceTest extends TestCase {
47  private static boolean hasMethod(Class<?> clazz, String name) {
48  try {
49  if (clazz.getMethod(name) != null) {
50  return true;
51  } else {
52  return false;
53  }
54  } catch (NoSuchMethodException e) {
55  return false;
56  }
57  }
58 
59  private static void assertHasMethodRemoved(
60  Class<?> classWithFieldPresence, Class<?> classWithoutFieldPresence, String camelName) {
61  assertTrue(hasMethod(classWithFieldPresence, "get" + camelName));
62  assertTrue(hasMethod(classWithFieldPresence, "has" + camelName));
63  assertTrue(hasMethod(classWithoutFieldPresence, "get" + camelName));
64  assertFalse(hasMethod(classWithoutFieldPresence, "has" + camelName));
65  }
66 
67  public void testHasMethod() {
68  // Optional non-message fields don't have a hasFoo() method generated.
69  assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalInt32");
70  assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalString");
71  assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalBytes");
73  UnittestProto.TestAllTypes.class, TestAllTypes.class, "OptionalNestedEnum");
74 
76  UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalInt32");
78  UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalString");
80  UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalBytes");
82  UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OptionalNestedEnum");
83 
84  // message fields still have the hasFoo() method generated.
85  assertFalse(TestAllTypes.getDefaultInstance().hasOptionalNestedMessage());
86  assertFalse(TestAllTypes.newBuilder().hasOptionalNestedMessage());
87 
88  // oneof fields don't have hasFoo() methods for non-message types.
89  assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OneofUint32");
90  assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OneofString");
91  assertHasMethodRemoved(UnittestProto.TestAllTypes.class, TestAllTypes.class, "OneofBytes");
92  assertFalse(TestAllTypes.getDefaultInstance().hasOneofNestedMessage());
93  assertFalse(TestAllTypes.newBuilder().hasOneofNestedMessage());
94 
96  UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofUint32");
98  UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofString");
100  UnittestProto.TestAllTypes.Builder.class, TestAllTypes.Builder.class, "OneofBytes");
101  }
102 
103  public void testOneofEquals() throws Exception {
104  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
105  TestAllTypes message1 = builder.build();
106  // Set message2's oneof_uint32 field to defalut value. The two
107  // messages should be different when check with oneof case.
108  builder.setOneofUint32(0);
109  TestAllTypes message2 = builder.build();
110  assertFalse(message1.equals(message2));
111  }
112 
113  public void testLazyField() throws Exception {
114  // Test default constructed message.
115  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
116  TestAllTypes message = builder.build();
117  assertFalse(message.hasOptionalLazyMessage());
118  assertEquals(0, message.getSerializedSize());
119  assertEquals(ByteString.EMPTY, message.toByteString());
120 
121  // Set default instance to the field.
122  builder.setOptionalLazyMessage(TestAllTypes.NestedMessage.getDefaultInstance());
123  message = builder.build();
124  assertTrue(message.hasOptionalLazyMessage());
125  assertEquals(2, message.getSerializedSize());
126 
127  // Test parse zero-length from wire sets the presence.
128  TestAllTypes parsed = TestAllTypes.parseFrom(message.toByteString());
129  assertTrue(parsed.hasOptionalLazyMessage());
130  assertEquals(message.getOptionalLazyMessage(), parsed.getOptionalLazyMessage());
131  }
132 
133  public void testFieldPresence() {
134  // Optional non-message fields set to their default value are treated the
135  // same way as not set.
136 
137  // Serialization will ignore such fields.
138  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
139  builder.setOptionalInt32(0);
140  builder.setOptionalString("");
141  builder.setOptionalBytes(ByteString.EMPTY);
142  builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO);
143  TestAllTypes message = builder.build();
144  assertEquals(0, message.getSerializedSize());
145 
146  // mergeFrom() will ignore such fields.
147  TestAllTypes.Builder a = TestAllTypes.newBuilder();
148  a.setOptionalInt32(1);
149  a.setOptionalString("x");
150  a.setOptionalBytes(ByteString.copyFromUtf8("y"));
151  a.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
152  TestAllTypes.Builder b = TestAllTypes.newBuilder();
153  b.setOptionalInt32(0);
154  b.setOptionalString("");
155  b.setOptionalBytes(ByteString.EMPTY);
156  b.setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO);
157  a.mergeFrom(b.build());
158  message = a.build();
159  assertEquals(1, message.getOptionalInt32());
160  assertEquals("x", message.getOptionalString());
161  assertEquals(ByteString.copyFromUtf8("y"), message.getOptionalBytes());
162  assertEquals(TestAllTypes.NestedEnum.BAR, message.getOptionalNestedEnum());
163 
164  // equals()/hashCode() should produce the same results.
165  TestAllTypes empty = TestAllTypes.getDefaultInstance();
166  message = builder.build();
167  assertEquals(message, empty);
168  assertEquals(empty, message);
169  assertEquals(empty.hashCode(), message.hashCode());
170  }
171 
173  Descriptor descriptor = TestAllTypes.getDescriptor();
174  FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32");
175  FieldDescriptor optionalStringField = descriptor.findFieldByName("optional_string");
176  FieldDescriptor optionalBytesField = descriptor.findFieldByName("optional_bytes");
177  FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
178 
179  // Field not present.
180  TestAllTypes message = TestAllTypes.getDefaultInstance();
181  assertFalse(message.hasField(optionalInt32Field));
182  assertFalse(message.hasField(optionalStringField));
183  assertFalse(message.hasField(optionalBytesField));
184  assertFalse(message.hasField(optionalNestedEnumField));
185  assertEquals(0, message.getAllFields().size());
186 
187  // Field set to default value is seen as not present.
188  message =
189  TestAllTypes.newBuilder()
190  .setOptionalInt32(0)
191  .setOptionalString("")
192  .setOptionalBytes(ByteString.EMPTY)
193  .setOptionalNestedEnum(TestAllTypes.NestedEnum.FOO)
194  .build();
195  assertFalse(message.hasField(optionalInt32Field));
196  assertFalse(message.hasField(optionalStringField));
197  assertFalse(message.hasField(optionalBytesField));
198  assertFalse(message.hasField(optionalNestedEnumField));
199  assertEquals(0, message.getAllFields().size());
200 
201  // Field set to non-default value is seen as present.
202  message =
203  TestAllTypes.newBuilder()
204  .setOptionalInt32(1)
205  .setOptionalString("x")
206  .setOptionalBytes(ByteString.copyFromUtf8("y"))
207  .setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR)
208  .build();
209  assertTrue(message.hasField(optionalInt32Field));
210  assertTrue(message.hasField(optionalStringField));
211  assertTrue(message.hasField(optionalBytesField));
212  assertTrue(message.hasField(optionalNestedEnumField));
213  assertEquals(4, message.getAllFields().size());
214  }
215 
217  Descriptor descriptor = TestAllTypes.getDescriptor();
218  FieldDescriptor optionalInt32Field = descriptor.findFieldByName("optional_int32");
219  FieldDescriptor optionalStringField = descriptor.findFieldByName("optional_string");
220  FieldDescriptor optionalBytesField = descriptor.findFieldByName("optional_bytes");
221  FieldDescriptor optionalNestedEnumField = descriptor.findFieldByName("optional_nested_enum");
222  EnumDescriptor enumDescriptor = optionalNestedEnumField.getEnumType();
223  EnumValueDescriptor defaultEnumValueDescriptor = enumDescriptor.getValues().get(0);
224  EnumValueDescriptor nonDefaultEnumValueDescriptor = enumDescriptor.getValues().get(1);
225 
227  // Field not present.
228  DynamicMessage message = defaultInstance.newBuilderForType().build();
229  assertFalse(message.hasField(optionalInt32Field));
230  assertFalse(message.hasField(optionalStringField));
231  assertFalse(message.hasField(optionalBytesField));
232  assertFalse(message.hasField(optionalNestedEnumField));
233  assertEquals(0, message.getAllFields().size());
234 
235  // Field set to non-default value is seen as present.
236  message =
237  defaultInstance
239  .setField(optionalInt32Field, 1)
240  .setField(optionalStringField, "x")
241  .setField(optionalBytesField, ByteString.copyFromUtf8("y"))
242  .setField(optionalNestedEnumField, nonDefaultEnumValueDescriptor)
243  .build();
244  assertTrue(message.hasField(optionalInt32Field));
245  assertTrue(message.hasField(optionalStringField));
246  assertTrue(message.hasField(optionalBytesField));
247  assertTrue(message.hasField(optionalNestedEnumField));
248  assertEquals(4, message.getAllFields().size());
249 
250  // Field set to default value is seen as not present.
251  message =
252  message
253  .toBuilder()
254  .setField(optionalInt32Field, 0)
255  .setField(optionalStringField, "")
256  .setField(optionalBytesField, ByteString.EMPTY)
257  .setField(optionalNestedEnumField, defaultEnumValueDescriptor)
258  .build();
259  assertFalse(message.hasField(optionalInt32Field));
260  assertFalse(message.hasField(optionalStringField));
261  assertFalse(message.hasField(optionalBytesField));
262  assertFalse(message.hasField(optionalNestedEnumField));
263  assertEquals(0, message.getAllFields().size());
264  }
265 
266  public void testMessageField() {
267  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
268  assertFalse(builder.hasOptionalNestedMessage());
269  assertFalse(builder.build().hasOptionalNestedMessage());
270 
271  TestAllTypes.NestedMessage.Builder nestedBuilder = builder.getOptionalNestedMessageBuilder();
272  assertTrue(builder.hasOptionalNestedMessage());
273  assertTrue(builder.build().hasOptionalNestedMessage());
274 
275  nestedBuilder.setValue(1);
276  assertEquals(1, builder.build().getOptionalNestedMessage().getValue());
277 
278  builder.clearOptionalNestedMessage();
279  assertFalse(builder.hasOptionalNestedMessage());
280  assertFalse(builder.build().hasOptionalNestedMessage());
281 
282  // Unlike non-message fields, if we set a message field to its default value (i.e.,
283  // default instance), the field should be seen as present.
284  builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
285  assertTrue(builder.hasOptionalNestedMessage());
286  assertTrue(builder.build().hasOptionalNestedMessage());
287  }
288 
289  public void testSerializeAndParse() throws Exception {
290  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
291  builder.setOptionalInt32(1234);
292  builder.setOptionalString("hello");
293  builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
294  // Set an oneof field to its default value and expect it to be serialized (i.e.,
295  // an oneof field set to the default value should be treated as present).
296  builder.setOneofInt32(0);
297  ByteString data = builder.build().toByteString();
298 
299  TestAllTypes message = TestAllTypes.parseFrom(data);
300  assertEquals(1234, message.getOptionalInt32());
301  assertEquals("hello", message.getOptionalString());
302  // Fields not set will have the default value.
303  assertEquals(ByteString.EMPTY, message.getOptionalBytes());
304  assertEquals(TestAllTypes.NestedEnum.FOO, message.getOptionalNestedEnum());
305  // The message field is set despite that it's set with a default instance.
306  assertTrue(message.hasOptionalNestedMessage());
307  assertEquals(0, message.getOptionalNestedMessage().getValue());
308  // The oneof field set to its default value is also present.
309  assertEquals(TestAllTypes.OneofFieldCase.ONEOF_INT32, message.getOneofFieldCase());
310  }
311 
312  // Regression test for b/16173397
313  // Make sure we haven't screwed up the code generation for repeated fields.
314  public void testRepeatedFields() throws Exception {
315  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
316  builder.setOptionalInt32(1234);
317  builder.setOptionalString("hello");
318  builder.setOptionalNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
319  builder.addRepeatedInt32(4321);
320  builder.addRepeatedString("world");
321  builder.addRepeatedNestedMessage(TestAllTypes.NestedMessage.getDefaultInstance());
322  ByteString data = builder.build().toByteString();
323 
324  TestOptionalFieldsOnly optionalOnlyMessage = TestOptionalFieldsOnly.parseFrom(data);
325  assertEquals(1234, optionalOnlyMessage.getOptionalInt32());
326  assertEquals("hello", optionalOnlyMessage.getOptionalString());
327  assertTrue(optionalOnlyMessage.hasOptionalNestedMessage());
328  assertEquals(0, optionalOnlyMessage.getOptionalNestedMessage().getValue());
329 
330  TestRepeatedFieldsOnly repeatedOnlyMessage = TestRepeatedFieldsOnly.parseFrom(data);
331  assertEquals(1, repeatedOnlyMessage.getRepeatedInt32Count());
332  assertEquals(4321, repeatedOnlyMessage.getRepeatedInt32(0));
333  assertEquals(1, repeatedOnlyMessage.getRepeatedStringCount());
334  assertEquals("world", repeatedOnlyMessage.getRepeatedString(0));
335  assertEquals(1, repeatedOnlyMessage.getRepeatedNestedMessageCount());
336  assertEquals(0, repeatedOnlyMessage.getRepeatedNestedMessage(0).getValue());
337  }
338 
339  public void testIsInitialized() throws Exception {
340  TestAllTypes.Builder builder = TestAllTypes.newBuilder();
341 
342  // Test optional proto2 message fields.
343  UnittestProto.TestRequired.Builder proto2Builder = builder.getOptionalProto2MessageBuilder();
344  assertFalse(builder.isInitialized());
345  assertFalse(builder.buildPartial().isInitialized());
346 
347  proto2Builder.setA(1).setB(2).setC(3);
348  assertTrue(builder.isInitialized());
349  assertTrue(builder.buildPartial().isInitialized());
350 
351  // Test oneof proto2 message fields.
352  proto2Builder = builder.getOneofProto2MessageBuilder();
353  assertFalse(builder.isInitialized());
354  assertFalse(builder.buildPartial().isInitialized());
355 
356  proto2Builder.setA(1).setB(2).setC(3);
357  assertTrue(builder.isInitialized());
358  assertTrue(builder.buildPartial().isInitialized());
359 
360  // Test repeated proto2 message fields.
361  proto2Builder = builder.addRepeatedProto2MessageBuilder();
362  assertFalse(builder.isInitialized());
363  assertFalse(builder.buildPartial().isInitialized());
364 
365  proto2Builder.setA(1).setB(2).setC(3);
366  assertTrue(builder.isInitialized());
367  assertTrue(builder.buildPartial().isInitialized());
368  }
369 
370 }
com.google.protobuf.Descriptors
Definition: Descriptors.java:80
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
com.google.protobuf.DynamicMessage.Builder.setField
Builder setField(FieldDescriptor field, Object value)
Definition: DynamicMessage.java:523
com.google.protobuf.FieldPresenceTest.testOneofEquals
void testOneofEquals()
Definition: FieldPresenceTest.java:103
com.google.protobuf.FieldPresenceTest.testMessageField
void testMessageField()
Definition: FieldPresenceTest.java:266
com.google.protobuf.FieldPresenceTest
Definition: FieldPresenceTest.java:46
com.google.protobuf.FieldPresenceTest.testFieldPresenceByReflection
void testFieldPresenceByReflection()
Definition: FieldPresenceTest.java:172
com.google.protobuf.FieldPresenceTest.testHasMethod
void testHasMethod()
Definition: FieldPresenceTest.java:67
com.google.protobuf
Definition: ProtoCaliperBenchmark.java:2
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
com.google.protobuf.ByteString.EMPTY
static final ByteString EMPTY
Definition: ByteString.java:85
com.google.protobuf.FieldPresenceTest.hasMethod
static boolean hasMethod(Class<?> clazz, String name)
Definition: FieldPresenceTest.java:47
TestOptionalFieldsOnly
b
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:3228
TestAllTypes
com.google.protobuf.DynamicMessage.newBuilderForType
Builder newBuilderForType()
Definition: DynamicMessage.java:273
com.google.protobuf.FieldPresenceTest.testFieldPresence
void testFieldPresence()
Definition: FieldPresenceTest.java:133
com.google.protobuf.FieldPresenceTest.testIsInitialized
void testIsInitialized()
Definition: FieldPresenceTest.java:339
com.google.protobuf.FieldPresenceTest.testLazyField
void testLazyField()
Definition: FieldPresenceTest.java:113
com.google.protobuf.FieldPresenceTest.assertHasMethodRemoved
static void assertHasMethodRemoved(Class<?> classWithFieldPresence, Class<?> classWithoutFieldPresence, String camelName)
Definition: FieldPresenceTest.java:59
com.google.protobuf.DynamicMessage.getDefaultInstance
static DynamicMessage getDefaultInstance(Descriptor type)
Definition: DynamicMessage.java:78
com.google.protobuf.Descriptors.EnumDescriptor
Definition: Descriptors.java:1583
com.google.protobuf.FieldPresenceTest.testRepeatedFields
void testRepeatedFields()
Definition: FieldPresenceTest.java:314
com.google.protobuf.Descriptors.Descriptor
Definition: Descriptors.java:629
com.google.protobuf.DynamicMessage.Builder.build
DynamicMessage build()
Definition: DynamicMessage.java:395
protobuf_unittest
Definition: map_test_util_impl.h:39
com.google.protobuf.DynamicMessage
Definition: DynamicMessage.java:51
com.google
com
com.google.protobuf.Descriptors.EnumDescriptor.getValues
List< EnumValueDescriptor > getValues()
Definition: Descriptors.java:1633
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
com.google.protobuf.Descriptors.EnumValueDescriptor
Definition: Descriptors.java:1774
gmock_test_utils.TestCase
TestCase
Definition: gmock_test_utils.py:97
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:3228
TestRepeatedFieldsOnly
com.google.protobuf.FieldPresenceTest.testFieldPresenceDynamicMessage
void testFieldPresenceDynamicMessage()
Definition: FieldPresenceTest.java:216
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
com.google.protobuf.FieldPresenceTest.testSerializeAndParse
void testSerializeAndParse()
Definition: FieldPresenceTest.java:289
com.google.protobuf.Descriptors.FieldDescriptor.getEnumType
EnumDescriptor getEnumType()
Definition: Descriptors.java:1168
com.google.protobuf.Descriptors.FieldDescriptor
Definition: Descriptors.java:949
com.google.protobuf.ByteString
Definition: ByteString.java:67


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:51