protobuf/src/google/protobuf/dynamic_message_unittest.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 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // Since the reflection interface for DynamicMessage is implemented by
36 // GenericMessageReflection, the only thing we really have to test is
37 // that DynamicMessage correctly sets up the information that
38 // GenericMessageReflection needs to use. So, we focus on that in this
39 // test. Other tests, such as generic_message_reflection_unittest and
40 // reflection_ops_unittest, cover the rest of the functionality used by
41 // DynamicMessage.
42 
43 #include <memory>
44 
45 #include <google/protobuf/test_util.h>
46 #include <google/protobuf/unittest.pb.h>
47 #include <google/protobuf/unittest_no_field_presence.pb.h>
48 #include <google/protobuf/descriptor.pb.h>
49 #include <google/protobuf/descriptor.h>
50 #include <google/protobuf/dynamic_message.h>
51 
52 #include <google/protobuf/stubs/logging.h>
53 #include <google/protobuf/stubs/common.h>
54 #include <google/protobuf/testing/googletest.h>
55 #include <gtest/gtest.h>
56 
57 namespace google {
58 namespace protobuf {
59 
60 class DynamicMessageTest : public ::testing::TestWithParam<bool> {
61  protected:
64  const Descriptor* descriptor_;
65  const Message* prototype_;
74 
76 
77  void SetUp() override {
78  // We want to make sure that DynamicMessage works (particularly with
79  // extensions) even if we use descriptors that are *not* from compiled-in
80  // types, so we make copies of the descriptors for unittest.proto and
81  // unittest_import.proto.
82  FileDescriptorProto unittest_file;
83  FileDescriptorProto unittest_import_file;
84  FileDescriptorProto unittest_import_public_file;
85  FileDescriptorProto unittest_no_field_presence_file;
86 
87  unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
89  &unittest_import_file);
91  &unittest_import_public_file);
93  &unittest_no_field_presence_file);
94 
95  ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != nullptr);
96  ASSERT_TRUE(pool_.BuildFile(unittest_import_file) != nullptr);
97  ASSERT_TRUE(pool_.BuildFile(unittest_file) != nullptr);
98  ASSERT_TRUE(pool_.BuildFile(unittest_no_field_presence_file) != nullptr);
99 
100  descriptor_ = pool_.FindMessageTypeByName("protobuf_unittest.TestAllTypes");
101  ASSERT_TRUE(descriptor_ != nullptr);
103 
105  pool_.FindMessageTypeByName("protobuf_unittest.TestAllExtensions");
108 
110  pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
111  ASSERT_TRUE(packed_descriptor_ != nullptr);
113 
115  pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2");
116  ASSERT_TRUE(oneof_descriptor_ != nullptr);
118 
120  "proto2_nofieldpresence_unittest.TestAllTypes");
121  ASSERT_TRUE(proto3_descriptor_ != nullptr);
123  }
124 };
125 
126 TEST_F(DynamicMessageTest, Descriptor) {
127  // Check that the descriptor on the DynamicMessage matches the descriptor
128  // passed to GetPrototype().
129  EXPECT_EQ(prototype_->GetDescriptor(), descriptor_);
130 }
131 
132 TEST_F(DynamicMessageTest, OnePrototype) {
133  // Check that requesting the same prototype twice produces the same object.
134  EXPECT_EQ(prototype_, factory_.GetPrototype(descriptor_));
135 }
136 
137 TEST_F(DynamicMessageTest, Defaults) {
138  // Check that all default values are set correctly in the initial message.
139  TestUtil::ReflectionTester reflection_tester(descriptor_);
140  reflection_tester.ExpectClearViaReflection(*prototype_);
141 }
142 
143 TEST_P(DynamicMessageTest, IndependentOffsets) {
144  // Check that all fields have independent offsets by setting each
145  // one to a unique value then checking that they all still have those
146  // unique values (i.e. they don't stomp each other).
147  Arena arena;
148  Message* message = prototype_->New(GetParam() ? &arena : nullptr);
149  TestUtil::ReflectionTester reflection_tester(descriptor_);
150 
151  reflection_tester.SetAllFieldsViaReflection(message);
152  reflection_tester.ExpectAllFieldsSetViaReflection(*message);
153 
154  if (!GetParam()) {
155  delete message;
156  }
157 }
158 
159 TEST_P(DynamicMessageTest, Extensions) {
160  // Check that extensions work.
161  Arena arena;
162  Message* message = extensions_prototype_->New(GetParam() ? &arena : nullptr);
163  TestUtil::ReflectionTester reflection_tester(extensions_descriptor_);
164 
165  reflection_tester.SetAllFieldsViaReflection(message);
166  reflection_tester.ExpectAllFieldsSetViaReflection(*message);
167 
168  if (!GetParam()) {
169  delete message;
170  }
171 }
172 
173 TEST_P(DynamicMessageTest, PackedFields) {
174  // Check that packed fields work properly.
175  Arena arena;
176  Message* message = packed_prototype_->New(GetParam() ? &arena : nullptr);
177  TestUtil::ReflectionTester reflection_tester(packed_descriptor_);
178 
179  reflection_tester.SetPackedFieldsViaReflection(message);
180  reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
181 
182  if (!GetParam()) {
183  delete message;
184  }
185 }
186 
187 TEST_P(DynamicMessageTest, Oneof) {
188  // Check that oneof fields work properly.
189  Arena arena;
190  Message* message = oneof_prototype_->New(GetParam() ? &arena : nullptr);
191 
192  // Check default values.
193  const Descriptor* descriptor = message->GetDescriptor();
194  const Reflection* reflection = message->GetReflection();
195  EXPECT_EQ(0, reflection->GetInt32(*message,
196  descriptor->FindFieldByName("foo_int")));
197  EXPECT_EQ("", reflection->GetString(
198  *message, descriptor->FindFieldByName("foo_string")));
199  EXPECT_EQ("", reflection->GetString(*message,
200  descriptor->FindFieldByName("foo_cord")));
201  EXPECT_EQ("", reflection->GetString(
202  *message, descriptor->FindFieldByName("foo_string_piece")));
203  EXPECT_EQ("", reflection->GetString(
204  *message, descriptor->FindFieldByName("foo_bytes")));
205  EXPECT_EQ(
206  unittest::TestOneof2::FOO,
207  reflection->GetEnum(*message, descriptor->FindFieldByName("foo_enum"))
208  ->number());
209  const Descriptor* nested_descriptor;
210  const Message* nested_prototype;
211  nested_descriptor =
212  pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.NestedMessage");
213  nested_prototype = factory_.GetPrototype(nested_descriptor);
214  EXPECT_EQ(nested_prototype,
215  &reflection->GetMessage(
216  *message, descriptor->FindFieldByName("foo_message")));
217  const Descriptor* foogroup_descriptor;
218  const Message* foogroup_prototype;
219  foogroup_descriptor =
220  pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.FooGroup");
221  foogroup_prototype = factory_.GetPrototype(foogroup_descriptor);
222  EXPECT_EQ(foogroup_prototype,
223  &reflection->GetMessage(*message,
224  descriptor->FindFieldByName("foogroup")));
225  EXPECT_NE(foogroup_prototype,
226  &reflection->GetMessage(
227  *message, descriptor->FindFieldByName("foo_lazy_message")));
228  EXPECT_EQ(5, reflection->GetInt32(*message,
229  descriptor->FindFieldByName("bar_int")));
230  EXPECT_EQ("STRING", reflection->GetString(
231  *message, descriptor->FindFieldByName("bar_string")));
232  EXPECT_EQ("CORD", reflection->GetString(
233  *message, descriptor->FindFieldByName("bar_cord")));
234  EXPECT_EQ("SPIECE",
235  reflection->GetString(
236  *message, descriptor->FindFieldByName("bar_string_piece")));
237  EXPECT_EQ("BYTES", reflection->GetString(
238  *message, descriptor->FindFieldByName("bar_bytes")));
239  EXPECT_EQ(
240  unittest::TestOneof2::BAR,
241  reflection->GetEnum(*message, descriptor->FindFieldByName("bar_enum"))
242  ->number());
243 
244  // Check set functions.
245  TestUtil::ReflectionTester reflection_tester(oneof_descriptor_);
246  reflection_tester.SetOneofViaReflection(message);
247  reflection_tester.ExpectOneofSetViaReflection(*message);
248 
249  if (!GetParam()) {
250  delete message;
251  }
252 }
253 
254 TEST_P(DynamicMessageTest, SpaceUsed) {
255  // Test that SpaceUsedLong() works properly
256 
257  // Since we share the implementation with generated messages, we don't need
258  // to test very much here. Just make sure it appears to be working.
259 
260  Arena arena;
261  Message* message = prototype_->New(GetParam() ? &arena : nullptr);
262  TestUtil::ReflectionTester reflection_tester(descriptor_);
263 
264  size_t initial_space_used = message->SpaceUsedLong();
265 
266  reflection_tester.SetAllFieldsViaReflection(message);
267  EXPECT_LT(initial_space_used, message->SpaceUsedLong());
268 
269  if (!GetParam()) {
270  delete message;
271  }
272 }
273 
274 TEST_F(DynamicMessageTest, Arena) {
275  Arena arena;
276  Message* message = prototype_->New(&arena);
277  Message* extension_message = extensions_prototype_->New(&arena);
278  Message* packed_message = packed_prototype_->New(&arena);
279  Message* oneof_message = oneof_prototype_->New(&arena);
280 
281  // avoid unused-variable error.
282  (void)message;
283  (void)extension_message;
284  (void)packed_message;
285  (void)oneof_message;
286  // Return without freeing: should not leak.
287 }
288 
289 
290 TEST_F(DynamicMessageTest, Proto3) {
291  Message* message = proto3_prototype_->New();
292  const Reflection* refl = message->GetReflection();
293  const Descriptor* desc = message->GetDescriptor();
294 
295  // Just test a single primitive and single message field here to make sure we
296  // are getting the no-field-presence semantics elsewhere. DynamicMessage uses
297  // GeneratedMessageReflection under the hood, so the rest should be fine as
298  // long as GMR recognizes that we're using a proto3 message.
299  const FieldDescriptor* optional_int32 =
300  desc->FindFieldByName("optional_int32");
301  const FieldDescriptor* optional_msg =
302  desc->FindFieldByName("optional_nested_message");
303  EXPECT_TRUE(optional_int32 != nullptr);
304  EXPECT_TRUE(optional_msg != nullptr);
305 
306  EXPECT_EQ(false, refl->HasField(*message, optional_int32));
307  refl->SetInt32(message, optional_int32, 42);
308  EXPECT_EQ(true, refl->HasField(*message, optional_int32));
309  refl->SetInt32(message, optional_int32, 0);
310  EXPECT_EQ(false, refl->HasField(*message, optional_int32));
311 
312  EXPECT_EQ(false, refl->HasField(*message, optional_msg));
313  refl->MutableMessage(message, optional_msg);
314  EXPECT_EQ(true, refl->HasField(*message, optional_msg));
315  delete refl->ReleaseMessage(message, optional_msg);
316  EXPECT_EQ(false, refl->HasField(*message, optional_msg));
317 
318  // Also ensure that the default instance handles field presence properly.
319  EXPECT_EQ(false, refl->HasField(*proto3_prototype_, optional_msg));
320 
321  delete message;
322 }
323 
324 INSTANTIATE_TEST_SUITE_P(UseArena, DynamicMessageTest, ::testing::Bool());
325 
326 } // namespace protobuf
327 } // namespace google
descriptor_
string_view descriptor_
Definition: elf.cc:154
google::protobuf::DescriptorPool::BuildFile
const FileDescriptor * BuildFile(const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3529
google::protobuf::DynamicMessageTest::DynamicMessageTest
DynamicMessageTest()
Definition: protobuf/src/google/protobuf/dynamic_message_unittest.cc:75
google::protobuf::INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(UseArena, DynamicMessageTest, ::testing::Bool())
UseArena
@ UseArena
Definition: upb/benchmarks/benchmark.cc:206
google::protobuf::DynamicMessageTest::oneof_prototype_
const Message * oneof_prototype_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:71
Arena
Definition: arena.c:39
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
grpc::protobuf::DynamicMessageFactory
GRPC_CUSTOM_DYNAMICMESSAGEFACTORY DynamicMessageFactory
Definition: config_grpc_cli.h:54
pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:181
google::protobuf::DynamicMessageTest::descriptor_
const Descriptor * descriptor_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:64
google::protobuf::DynamicMessageTest::SetUp
void SetUp() override
Definition: protobuf/src/google/protobuf/dynamic_message_unittest.cc:77
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
Descriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:121
arena
grpc_core::ScopedArenaPtr arena
Definition: binder_transport_test.cc:237
testing::TestWithParam
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1883
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
Oneof
struct Oneof Oneof
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:664
FieldDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:133
google::protobuf.internal.python_message.Extensions
Extensions
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:584
google::protobuf::TEST_P
TEST_P(DynamicMessageTest, IndependentOffsets)
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:143
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
google::protobuf::DynamicMessageTest::packed_prototype_
const Message * packed_prototype_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:69
google::protobuf::DynamicMessageTest::extensions_descriptor_
const Descriptor * extensions_descriptor_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:66
google::protobuf::DynamicMessageTest::pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:62
FileDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:501
google::protobuf::DynamicMessageTest::oneof_descriptor_
const Descriptor * oneof_descriptor_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:70
google::protobuf::DynamicMessageTest::extensions_prototype_
const Message * extensions_prototype_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:67
google::protobuf::TEST_F
TEST_F(DynamicMessageTest, Descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:126
EXPECT_LT
#define EXPECT_LT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2032
google::protobuf::DynamicMessageTest::prototype_
const Message * prototype_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:65
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
desc
#define desc
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:338
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
google::protobuf::DynamicMessageTest::factory_
DynamicMessageFactory factory_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:63
google::protobuf::DynamicMessageTest::packed_descriptor_
const Descriptor * packed_descriptor_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:68
DescriptorPool
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:110
testing::Bool
internal::ParamGenerator< bool > Bool()
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:359
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
google::protobuf::DynamicMessageTest::proto3_prototype_
const Message * proto3_prototype_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:73
Message
Definition: protobuf/php/ext/google/protobuf/message.c:53
google::protobuf::DynamicMessageFactory::GetPrototype
const Message * GetPrototype(const Descriptor *type) override
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message.cc:653
google::protobuf::DynamicMessageTest::proto3_descriptor_
const Descriptor * proto3_descriptor_
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message_unittest.cc:72
google::protobuf::DescriptorPool::FindMessageTypeByName
const Descriptor * FindMessageTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1410


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:18