preserve_unknown_enum_test.cc
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 #include <google/protobuf/unittest.pb.h>
32 #include <google/protobuf/unittest_preserve_unknown_enum.pb.h>
33 #include <google/protobuf/unittest_preserve_unknown_enum2.pb.h>
36 #include <gtest/gtest.h>
37 
38 namespace google {
39 namespace protobuf {
40 namespace {
41 
42 void FillMessage(
43  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra* message) {
44  message->set_e(proto3_preserve_unknown_enum_unittest::E_EXTRA);
45  message->add_repeated_e(proto3_preserve_unknown_enum_unittest::E_EXTRA);
46  message->add_repeated_packed_e(
47  proto3_preserve_unknown_enum_unittest::E_EXTRA);
48  message->add_repeated_packed_unexpected_e(
49  proto3_preserve_unknown_enum_unittest::E_EXTRA);
50  message->set_oneof_e_1(proto3_preserve_unknown_enum_unittest::E_EXTRA);
51 }
52 
53 void CheckMessage(
54  const proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra& message) {
55  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA, message.e());
56  EXPECT_EQ(1, message.repeated_e_size());
57  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
58  message.repeated_e(0));
59  EXPECT_EQ(1, message.repeated_packed_e_size());
60  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
61  message.repeated_packed_e(0));
62  EXPECT_EQ(1, message.repeated_packed_unexpected_e_size());
63  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
64  message.repeated_packed_unexpected_e(0));
65  EXPECT_EQ(proto3_preserve_unknown_enum_unittest::E_EXTRA,
66  message.oneof_e_1());
67 }
68 
69 void CheckMessage(
70  const proto3_preserve_unknown_enum_unittest::MyMessage& message) {
71  EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
72  static_cast<int>(message.e()));
73  EXPECT_EQ(1, message.repeated_e_size());
74  EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
75  static_cast<int>(message.repeated_e(0)));
76  EXPECT_EQ(1, message.repeated_packed_e_size());
77  EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
78  static_cast<int>(message.repeated_packed_e(0)));
79  EXPECT_EQ(1, message.repeated_packed_unexpected_e_size());
80  EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
81  static_cast<int>(message.repeated_packed_unexpected_e(0)));
82  EXPECT_EQ(static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA),
83  static_cast<int>(message.oneof_e_1()));
84 }
85 
86 } // anonymous namespace
87 
88 // Test that parsing preserves an unknown value in the enum field and does not
89 // punt it to the UnknownFieldSet.
90 TEST(PreserveUnknownEnumTest, PreserveParseAndSerialize) {
91  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
92  FillMessage(&orig_message);
93  std::string serialized;
94  orig_message.SerializeToString(&serialized);
95 
96  proto3_preserve_unknown_enum_unittest::MyMessage message;
97  EXPECT_EQ(true, message.ParseFromString(serialized));
98  CheckMessage(message);
99 
100  serialized.clear();
101  message.SerializeToString(&serialized);
102  EXPECT_EQ(true, orig_message.ParseFromString(serialized));
103  CheckMessage(orig_message);
104 }
105 
106 // Test that reflection based implementation also keeps unknown enum values and
107 // doesn't put them into UnknownFieldSet.
108 TEST(PreserveUnknownEnumTest, PreserveParseAndSerializeDynamicMessage) {
109  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
110  FillMessage(&orig_message);
111  std::string serialized = orig_message.SerializeAsString();
112 
113  DynamicMessageFactory factory;
114  std::unique_ptr<Message> message(
115  factory
116  .GetPrototype(
118  ->New());
119  EXPECT_EQ(true, message->ParseFromString(serialized));
120  message->DiscardUnknownFields();
121 
122  serialized = message->SerializeAsString();
123  EXPECT_EQ(true, orig_message.ParseFromString(serialized));
124  CheckMessage(orig_message);
125 }
126 
127 // Test that for proto2 messages, unknown values are in unknown fields.
128 TEST(PreserveUnknownEnumTest, Proto2HidesUnknownValues) {
129  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
130  FillMessage(&orig_message);
131 
132  std::string serialized;
133  orig_message.SerializeToString(&serialized);
134 
135  proto2_preserve_unknown_enum_unittest::MyMessage message;
136  EXPECT_EQ(true, message.ParseFromString(serialized));
137  // The intermediate message has everything in its "unknown fields".
138  proto2_preserve_unknown_enum_unittest::MyMessage message2 = message;
139  message2.DiscardUnknownFields();
140  EXPECT_EQ(0, message2.ByteSize());
141 
142  // But when we pass it to the correct structure, all values are there.
143  serialized.clear();
144  message.SerializeToString(&serialized);
145  EXPECT_EQ(true, orig_message.ParseFromString(serialized));
146  CheckMessage(orig_message);
147 }
148 
149 // Same as before, for a dynamic message.
150 TEST(PreserveUnknownEnumTest, DynamicProto2HidesUnknownValues) {
151  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
152  FillMessage(&orig_message);
153 
154  std::string serialized;
155  orig_message.SerializeToString(&serialized);
156 
157  DynamicMessageFactory factory;
158  std::unique_ptr<Message> message(
159  factory
160  .GetPrototype(
162  ->New());
163  EXPECT_EQ(true, message->ParseFromString(serialized));
164  // The intermediate message has everything in its "unknown fields".
165  proto2_preserve_unknown_enum_unittest::MyMessage message2;
166  message2.CopyFrom(*message);
167  message2.DiscardUnknownFields();
168  EXPECT_EQ(0, message2.ByteSize());
169 
170  // But when we pass it to the correct structure, all values are there.
171  serialized.clear();
172  message->SerializeToString(&serialized);
173  EXPECT_EQ(true, orig_message.ParseFromString(serialized));
174  CheckMessage(orig_message);
175 }
176 
177 // Test that reflection provides EnumValueDescriptors for unknown values.
178 TEST(PreserveUnknownEnumTest, DynamicEnumValueDescriptors) {
179  proto3_preserve_unknown_enum_unittest::MyMessagePlusExtra orig_message;
180  FillMessage(&orig_message);
181  std::string serialized;
182  orig_message.SerializeToString(&serialized);
183 
184  proto3_preserve_unknown_enum_unittest::MyMessage message;
185  EXPECT_EQ(true, message.ParseFromString(serialized));
186  CheckMessage(message);
187 
188  const Reflection* r = message.GetReflection();
189  const Descriptor* d = message.GetDescriptor();
190  const FieldDescriptor* field = d->FindFieldByName("e");
191 
192  // This should dynamically create an EnumValueDescriptor.
193  const EnumValueDescriptor* enum_value = r->GetEnum(message, field);
194  EXPECT_EQ(enum_value->number(),
195  static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
196 
197  // Fetching value for a second time should return the same pointer.
198  const EnumValueDescriptor* enum_value_second = r->GetEnum(message, field);
199  EXPECT_EQ(enum_value, enum_value_second);
200 
201  // Check the repeated case too.
202  const FieldDescriptor* repeated_field = d->FindFieldByName("repeated_e");
203  enum_value = r->GetRepeatedEnum(message, repeated_field, 0);
204  EXPECT_EQ(enum_value->number(),
205  static_cast<int>(proto3_preserve_unknown_enum_unittest::E_EXTRA));
206  // Should reuse the same EnumValueDescriptor, even for a different field.
207  EXPECT_EQ(enum_value, enum_value_second);
208 
209  // We should be able to use the returned value descriptor to set a value on
210  // another message.
211  Message* m = message.New();
212  r->SetEnum(m, field, enum_value);
213  EXPECT_EQ(enum_value, r->GetEnum(*m, field));
214  delete m;
215 }
216 
217 // Test that the new integer-based enum reflection API works.
218 TEST(PreserveUnknownEnumTest, IntegerEnumReflectionAPI) {
219  proto3_preserve_unknown_enum_unittest::MyMessage message;
220  const Reflection* r = message.GetReflection();
221  const Descriptor* d = message.GetDescriptor();
222 
223  const FieldDescriptor* singular_field = d->FindFieldByName("e");
224  const FieldDescriptor* repeated_field = d->FindFieldByName("repeated_e");
225 
226  r->SetEnumValue(&message, singular_field, 42);
227  EXPECT_EQ(42, r->GetEnumValue(message, singular_field));
228  r->AddEnumValue(&message, repeated_field, 42);
229  r->AddEnumValue(&message, repeated_field, 42);
230  EXPECT_EQ(42, r->GetRepeatedEnumValue(message, repeated_field, 0));
231  r->SetRepeatedEnumValue(&message, repeated_field, 1, 84);
232  EXPECT_EQ(84, r->GetRepeatedEnumValue(message, repeated_field, 1));
233  const EnumValueDescriptor* enum_value = r->GetEnum(message, singular_field);
234  EXPECT_EQ(42, enum_value->number());
235 }
236 
237 // Test that the EnumValue API works properly for proto2 messages as well.
238 TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) {
239  protobuf_unittest::TestAllTypes message; // proto2 message
240  const Reflection* r = message.GetReflection();
241  const Descriptor* d = message.GetDescriptor();
243  d->FindFieldByName("repeated_nested_enum");
244  // Add one element to the repeated field so that we can test
245  // SetRepeatedEnumValue.
246  const EnumValueDescriptor* enum_value =
247  repeated_field->enum_type()->FindValueByName("BAR");
248  EXPECT_TRUE(enum_value != NULL);
249  r->AddEnum(&message, repeated_field, enum_value);
250 
251  const FieldDescriptor* singular_field =
252  d->FindFieldByName("optional_nested_enum");
253  // Enum-field integer-based setters treat as unknown integer values as
254  // unknown fields.
255  r->SetEnumValue(&message, singular_field, 4242);
256  EXPECT_EQ(r->GetEnum(message, singular_field)->number(),
257  protobuf_unittest::TestAllTypes::FOO);
258  r->SetRepeatedEnumValue(&message, repeated_field, 0, 4242);
259  // repeated_nested_enum was set to bar above, this should not have changed.
260  EXPECT_EQ(r->GetRepeatedEnum(message, repeated_field, 0)->number(),
261  protobuf_unittest::TestAllTypes::BAR);
262  r->AddEnumValue(&message, repeated_field, 4242);
263  // No element should be added
264  EXPECT_EQ(message.repeated_nested_enum_size(), 1);
265 
266  // We require the enums to end up in unknown field set
267  ASSERT_EQ(message.unknown_fields().field_count(), 3);
268  EXPECT_EQ(message.unknown_fields().field(0).number(),
269  singular_field->number());
270  EXPECT_EQ(message.unknown_fields().field(0).varint(), 4242);
271  EXPECT_EQ(message.unknown_fields().field(1).number(),
272  repeated_field->number());
273  EXPECT_EQ(message.unknown_fields().field(1).varint(), 4242);
274  EXPECT_EQ(message.unknown_fields().field(2).number(),
275  repeated_field->number());
276  EXPECT_EQ(message.unknown_fields().field(2).varint(), 4242);
277 }
278 
279 TEST(PreserveUnknownEnumTest, SupportsUnknownEnumValuesAPI) {
280  protobuf_unittest::TestAllTypes proto2_message;
281  proto3_preserve_unknown_enum_unittest::MyMessage new_message;
282 
283  const Reflection* proto2_reflection = proto2_message.GetReflection();
284  const Reflection* new_reflection = new_message.GetReflection();
285 
286  EXPECT_FALSE(proto2_reflection->SupportsUnknownEnumValues());
287  EXPECT_TRUE(new_reflection->SupportsUnknownEnumValues());
288 }
289 } // namespace protobuf
290 } // namespace google
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
NULL
NULL
Definition: test_security_zap.cpp:405
gtest.h
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: glog/src/googletest.h:155
google::protobuf::Reflection::SupportsUnknownEnumValues
bool SupportsUnknownEnumValues() const
Definition: generated_message_reflection.cc:1823
dynamic_message.h
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::Reflection
Definition: src/google/protobuf/message.h:400
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:2082
repeated_field
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern repeated_field
Definition: array.c:486
google::protobuf::python::cdescriptor_pool::New
static PyObject * New(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Definition: descriptor_pool.cc:177
google::protobuf::EnumValueDescriptor::number
int number() const
google::protobuf::FieldDescriptor::number
int number() const
google::protobuf::TEST
TEST(ArenaTest, ArenaConstructable)
Definition: arena_unittest.cc:156
EXPECT_TRUE
#define EXPECT_TRUE(cond)
Definition: glog/src/googletest.h:137
d
d
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::DynamicMessageFactory
Definition: dynamic_message.h:80
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
EXPECT_FALSE
#define EXPECT_FALSE(cond)
Definition: glog/src/googletest.h:145
m
const upb_json_parsermethod * m
Definition: ruby/ext/google/protobuf_c/upb.h:10501
google::protobuf::EnumValueDescriptor
Definition: src/google/protobuf/descriptor.h:1075
r
GLboolean r
Definition: glcorearb.h:3228
google::protobuf::Descriptor
Definition: src/google/protobuf/descriptor.h:231
descriptor.h
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695


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