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
31// Author: kenton@google.com (Kenton Varda)
32//  Based on original Protocol Buffers design by
33//  Sanjay Ghemawat, Jeff Dean, and others.
34//
35// To test GeneratedMessageReflection, we actually let the protocol compiler
36// generate a full protocol message implementation and then test its
37// reflection interface.  This is much easier and more maintainable than
38// trying to create our own Message class for GeneratedMessageReflection
39// to wrap.
40//
41// The tests here closely mirror some of the tests in
42// compiler/cpp/unittest, except using the reflection interface
43// rather than generated accessors.
44
45#include <google/protobuf/generated_message_reflection.h>
46#include <google/protobuf/descriptor.h>
47#include <google/protobuf/test_util.h>
48#include <google/protobuf/unittest.pb.h>
49
50#include <google/protobuf/stubs/common.h>
51#include <google/protobuf/testing/googletest.h>
52#include <gtest/gtest.h>
53
54namespace google {
55namespace protobuf {
56
57namespace {
58
59// Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
60const FieldDescriptor* F(const string& name) {
61  const FieldDescriptor* result =
62    unittest::TestAllTypes::descriptor()->FindFieldByName(name);
63  GOOGLE_CHECK(result != NULL);
64  return result;
65}
66
67TEST(GeneratedMessageReflectionTest, Defaults) {
68  // Check that all default values are set correctly in the initial message.
69  unittest::TestAllTypes message;
70  TestUtil::ReflectionTester reflection_tester(
71    unittest::TestAllTypes::descriptor());
72
73  reflection_tester.ExpectClearViaReflection(message);
74
75  const Reflection* reflection = message.GetReflection();
76
77  // Messages should return pointers to default instances until first use.
78  // (This is not checked by ExpectClear() since it is not actually true after
79  // the fields have been set and then cleared.)
80  EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(),
81            &reflection->GetMessage(message, F("optionalgroup")));
82  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
83            &reflection->GetMessage(message, F("optional_nested_message")));
84  EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
85            &reflection->GetMessage(message, F("optional_foreign_message")));
86  EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
87            &reflection->GetMessage(message, F("optional_import_message")));
88}
89
90TEST(GeneratedMessageReflectionTest, Accessors) {
91  // Set every field to a unique value then go back and check all those
92  // values.
93  unittest::TestAllTypes message;
94  TestUtil::ReflectionTester reflection_tester(
95    unittest::TestAllTypes::descriptor());
96
97  reflection_tester.SetAllFieldsViaReflection(&message);
98  TestUtil::ExpectAllFieldsSet(message);
99  reflection_tester.ExpectAllFieldsSetViaReflection(message);
100
101  reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
102  TestUtil::ExpectRepeatedFieldsModified(message);
103}
104
105TEST(GeneratedMessageReflectionTest, GetStringReference) {
106  // Test that GetStringReference() returns the underlying string when it is
107  // a normal string field.
108  unittest::TestAllTypes message;
109  message.set_optional_string("foo");
110  message.add_repeated_string("foo");
111
112  const Reflection* reflection = message.GetReflection();
113  string scratch;
114
115  EXPECT_EQ(&message.optional_string(),
116      &reflection->GetStringReference(message, F("optional_string"), &scratch))
117    << "For simple string fields, GetStringReference() should return a "
118       "reference to the underlying string.";
119  EXPECT_EQ(&message.repeated_string(0),
120      &reflection->GetRepeatedStringReference(message, F("repeated_string"),
121                                              0, &scratch))
122    << "For simple string fields, GetRepeatedStringReference() should return "
123       "a reference to the underlying string.";
124}
125
126
127TEST(GeneratedMessageReflectionTest, DefaultsAfterClear) {
128  // Check that after setting all fields and then clearing, getting an
129  // embedded message does NOT return the default instance.
130  unittest::TestAllTypes message;
131  TestUtil::ReflectionTester reflection_tester(
132    unittest::TestAllTypes::descriptor());
133
134  TestUtil::SetAllFields(&message);
135  message.Clear();
136
137  const Reflection* reflection = message.GetReflection();
138
139  EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
140            &reflection->GetMessage(message, F("optionalgroup")));
141  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
142            &reflection->GetMessage(message, F("optional_nested_message")));
143  EXPECT_NE(&unittest::ForeignMessage::default_instance(),
144            &reflection->GetMessage(message, F("optional_foreign_message")));
145  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
146            &reflection->GetMessage(message, F("optional_import_message")));
147}
148
149
150TEST(GeneratedMessageReflectionTest, Swap) {
151  unittest::TestAllTypes message1;
152  unittest::TestAllTypes message2;
153
154  TestUtil::SetAllFields(&message1);
155
156  const Reflection* reflection = message1.GetReflection();
157  reflection->Swap(&message1, &message2);
158
159  TestUtil::ExpectClear(message1);
160  TestUtil::ExpectAllFieldsSet(message2);
161}
162
163TEST(GeneratedMessageReflectionTest, SwapWithBothSet) {
164  unittest::TestAllTypes message1;
165  unittest::TestAllTypes message2;
166
167  TestUtil::SetAllFields(&message1);
168  TestUtil::SetAllFields(&message2);
169  TestUtil::ModifyRepeatedFields(&message2);
170
171  const Reflection* reflection = message1.GetReflection();
172  reflection->Swap(&message1, &message2);
173
174  TestUtil::ExpectRepeatedFieldsModified(message1);
175  TestUtil::ExpectAllFieldsSet(message2);
176
177  message1.set_optional_int32(532819);
178
179  reflection->Swap(&message1, &message2);
180
181  EXPECT_EQ(532819, message2.optional_int32());
182}
183
184TEST(GeneratedMessageReflectionTest, SwapExtensions) {
185  unittest::TestAllExtensions message1;
186  unittest::TestAllExtensions message2;
187
188  TestUtil::SetAllExtensions(&message1);
189
190  const Reflection* reflection = message1.GetReflection();
191  reflection->Swap(&message1, &message2);
192
193  TestUtil::ExpectExtensionsClear(message1);
194  TestUtil::ExpectAllExtensionsSet(message2);
195}
196
197TEST(GeneratedMessageReflectionTest, SwapUnknown) {
198  unittest::TestEmptyMessage message1, message2;
199
200  message1.mutable_unknown_fields()->AddVarint(1234, 1);
201
202  EXPECT_EQ(1, message1.unknown_fields().field_count());
203  EXPECT_EQ(0, message2.unknown_fields().field_count());
204  const Reflection* reflection = message1.GetReflection();
205  reflection->Swap(&message1, &message2);
206  EXPECT_EQ(0, message1.unknown_fields().field_count());
207  EXPECT_EQ(1, message2.unknown_fields().field_count());
208}
209
210TEST(GeneratedMessageReflectionTest, RemoveLast) {
211  unittest::TestAllTypes message;
212  TestUtil::ReflectionTester reflection_tester(
213    unittest::TestAllTypes::descriptor());
214
215  TestUtil::SetAllFields(&message);
216
217  reflection_tester.RemoveLastRepeatedsViaReflection(&message);
218
219  TestUtil::ExpectLastRepeatedsRemoved(message);
220}
221
222TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) {
223  unittest::TestAllExtensions message;
224  TestUtil::ReflectionTester reflection_tester(
225    unittest::TestAllExtensions::descriptor());
226
227  TestUtil::SetAllExtensions(&message);
228
229  reflection_tester.RemoveLastRepeatedsViaReflection(&message);
230
231  TestUtil::ExpectLastRepeatedExtensionsRemoved(message);
232}
233
234TEST(GeneratedMessageReflectionTest, ReleaseLast) {
235  unittest::TestAllTypes message;
236  const Descriptor* descriptor = message.GetDescriptor();
237  TestUtil::ReflectionTester reflection_tester(descriptor);
238
239  TestUtil::SetAllFields(&message);
240
241  reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false);
242
243  TestUtil::ExpectLastRepeatedsReleased(message);
244
245  // Now test that we actually release the right message.
246  message.Clear();
247  TestUtil::SetAllFields(&message);
248  ASSERT_EQ(2, message.repeated_foreign_message_size());
249  const protobuf_unittest::ForeignMessage* expected =
250      message.mutable_repeated_foreign_message(1);
251  scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
252      &message, descriptor->FindFieldByName("repeated_foreign_message")));
253  EXPECT_EQ(expected, released.get());
254}
255
256TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) {
257  unittest::TestAllExtensions message;
258  const Descriptor* descriptor = message.GetDescriptor();
259  TestUtil::ReflectionTester reflection_tester(descriptor);
260
261  TestUtil::SetAllExtensions(&message);
262
263  reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true);
264
265  TestUtil::ExpectLastRepeatedExtensionsReleased(message);
266
267  // Now test that we actually release the right message.
268  message.Clear();
269  TestUtil::SetAllExtensions(&message);
270  ASSERT_EQ(2, message.ExtensionSize(
271      unittest::repeated_foreign_message_extension));
272  const protobuf_unittest::ForeignMessage* expected = message.MutableExtension(
273      unittest::repeated_foreign_message_extension, 1);
274  scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
275      &message, descriptor->file()->FindExtensionByName(
276          "repeated_foreign_message_extension")));
277  EXPECT_EQ(expected, released.get());
278
279}
280
281TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) {
282  unittest::TestAllTypes message;
283  TestUtil::ReflectionTester reflection_tester(
284    unittest::TestAllTypes::descriptor());
285
286  TestUtil::SetAllFields(&message);
287
288  // Swap and test that fields are all swapped.
289  reflection_tester.SwapRepeatedsViaReflection(&message);
290  TestUtil::ExpectRepeatedsSwapped(message);
291
292  // Swap back and test that fields are all back to original values.
293  reflection_tester.SwapRepeatedsViaReflection(&message);
294  TestUtil::ExpectAllFieldsSet(message);
295}
296
297TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) {
298  unittest::TestAllExtensions message;
299  TestUtil::ReflectionTester reflection_tester(
300    unittest::TestAllExtensions::descriptor());
301
302  TestUtil::SetAllExtensions(&message);
303
304  // Swap and test that fields are all swapped.
305  reflection_tester.SwapRepeatedsViaReflection(&message);
306  TestUtil::ExpectRepeatedExtensionsSwapped(message);
307
308  // Swap back and test that fields are all back to original values.
309  reflection_tester.SwapRepeatedsViaReflection(&message);
310  TestUtil::ExpectAllExtensionsSet(message);
311}
312
313TEST(GeneratedMessageReflectionTest, Extensions) {
314  // Set every extension to a unique value then go back and check all those
315  // values.
316  unittest::TestAllExtensions message;
317  TestUtil::ReflectionTester reflection_tester(
318    unittest::TestAllExtensions::descriptor());
319
320  reflection_tester.SetAllFieldsViaReflection(&message);
321  TestUtil::ExpectAllExtensionsSet(message);
322  reflection_tester.ExpectAllFieldsSetViaReflection(message);
323
324  reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
325  TestUtil::ExpectRepeatedExtensionsModified(message);
326}
327
328TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
329  const Reflection* reflection =
330    unittest::TestAllExtensions::default_instance().GetReflection();
331
332  const FieldDescriptor* extension1 =
333    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
334      "optional_int32_extension");
335  const FieldDescriptor* extension2 =
336    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
337      "repeated_string_extension");
338
339  EXPECT_EQ(extension1,
340            reflection->FindKnownExtensionByNumber(extension1->number()));
341  EXPECT_EQ(extension2,
342            reflection->FindKnownExtensionByNumber(extension2->number()));
343
344  // Non-existent extension.
345  EXPECT_TRUE(reflection->FindKnownExtensionByNumber(62341) == NULL);
346
347  // Extensions of TestAllExtensions should not show up as extensions of
348  // other types.
349  EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
350              FindKnownExtensionByNumber(extension1->number()) == NULL);
351}
352
353TEST(GeneratedMessageReflectionTest, FindKnownExtensionByName) {
354  const Reflection* reflection =
355    unittest::TestAllExtensions::default_instance().GetReflection();
356
357  const FieldDescriptor* extension1 =
358    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
359      "optional_int32_extension");
360  const FieldDescriptor* extension2 =
361    unittest::TestAllExtensions::descriptor()->file()->FindExtensionByName(
362      "repeated_string_extension");
363
364  EXPECT_EQ(extension1,
365            reflection->FindKnownExtensionByName(extension1->full_name()));
366  EXPECT_EQ(extension2,
367            reflection->FindKnownExtensionByName(extension2->full_name()));
368
369  // Non-existent extension.
370  EXPECT_TRUE(reflection->FindKnownExtensionByName("no_such_ext") == NULL);
371
372  // Extensions of TestAllExtensions should not show up as extensions of
373  // other types.
374  EXPECT_TRUE(unittest::TestAllTypes::default_instance().GetReflection()->
375              FindKnownExtensionByName(extension1->full_name()) == NULL);
376}
377
378TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) {
379  unittest::TestAllTypes message;
380  TestUtil::ReflectionTester reflection_tester(
381    unittest::TestAllTypes::descriptor());
382
383  // When nothing is set, we expect all released messages to be NULL.
384  reflection_tester.ExpectMessagesReleasedViaReflection(
385      &message, TestUtil::ReflectionTester::IS_NULL);
386
387  // After fields are set we should get non-NULL releases.
388  reflection_tester.SetAllFieldsViaReflection(&message);
389  reflection_tester.ExpectMessagesReleasedViaReflection(
390      &message, TestUtil::ReflectionTester::NOT_NULL);
391
392  // After Clear() we may or may not get a message from ReleaseMessage().
393  // This is implementation specific.
394  reflection_tester.SetAllFieldsViaReflection(&message);
395  message.Clear();
396  reflection_tester.ExpectMessagesReleasedViaReflection(
397      &message, TestUtil::ReflectionTester::CAN_BE_NULL);
398
399  // Test a different code path for setting after releasing.
400  TestUtil::SetAllFields(&message);
401  TestUtil::ExpectAllFieldsSet(message);
402}
403
404TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) {
405  unittest::TestAllExtensions message;
406  TestUtil::ReflectionTester reflection_tester(
407    unittest::TestAllExtensions::descriptor());
408
409  // When nothing is set, we expect all released messages to be NULL.
410  reflection_tester.ExpectMessagesReleasedViaReflection(
411      &message, TestUtil::ReflectionTester::IS_NULL);
412
413  // After fields are set we should get non-NULL releases.
414  reflection_tester.SetAllFieldsViaReflection(&message);
415  reflection_tester.ExpectMessagesReleasedViaReflection(
416      &message, TestUtil::ReflectionTester::NOT_NULL);
417
418  // After Clear() we may or may not get a message from ReleaseMessage().
419  // This is implementation specific.
420  reflection_tester.SetAllFieldsViaReflection(&message);
421  message.Clear();
422  reflection_tester.ExpectMessagesReleasedViaReflection(
423      &message, TestUtil::ReflectionTester::CAN_BE_NULL);
424
425  // Test a different code path for setting after releasing.
426  TestUtil::SetAllExtensions(&message);
427  TestUtil::ExpectAllExtensionsSet(message);
428}
429
430#ifdef PROTOBUF_HAS_DEATH_TEST
431
432TEST(GeneratedMessageReflectionTest, UsageErrors) {
433  unittest::TestAllTypes message;
434  const Reflection* reflection = message.GetReflection();
435  const Descriptor* descriptor = message.GetDescriptor();
436
437#define f(NAME) descriptor->FindFieldByName(NAME)
438
439  // Testing every single failure mode would be too much work.  Let's just
440  // check a few.
441  EXPECT_DEATH(
442    reflection->GetInt32(
443      message, descriptor->FindFieldByName("optional_int64")),
444    "Protocol Buffer reflection usage error:\n"
445    "  Method      : google::protobuf::Reflection::GetInt32\n"
446    "  Message type: protobuf_unittest\\.TestAllTypes\n"
447    "  Field       : protobuf_unittest\\.TestAllTypes\\.optional_int64\n"
448    "  Problem     : Field is not the right type for this message:\n"
449    "    Expected  : CPPTYPE_INT32\n"
450    "    Field type: CPPTYPE_INT64");
451  EXPECT_DEATH(
452    reflection->GetInt32(
453      message, descriptor->FindFieldByName("repeated_int32")),
454    "Protocol Buffer reflection usage error:\n"
455    "  Method      : google::protobuf::Reflection::GetInt32\n"
456    "  Message type: protobuf_unittest.TestAllTypes\n"
457    "  Field       : protobuf_unittest.TestAllTypes.repeated_int32\n"
458    "  Problem     : Field is repeated; the method requires a singular field.");
459  EXPECT_DEATH(
460    reflection->GetInt32(
461      message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
462    "Protocol Buffer reflection usage error:\n"
463    "  Method      : google::protobuf::Reflection::GetInt32\n"
464    "  Message type: protobuf_unittest.TestAllTypes\n"
465    "  Field       : protobuf_unittest.ForeignMessage.c\n"
466    "  Problem     : Field does not match message type.");
467  EXPECT_DEATH(
468    reflection->HasField(
469      message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
470    "Protocol Buffer reflection usage error:\n"
471    "  Method      : google::protobuf::Reflection::HasField\n"
472    "  Message type: protobuf_unittest.TestAllTypes\n"
473    "  Field       : protobuf_unittest.ForeignMessage.c\n"
474    "  Problem     : Field does not match message type.");
475
476#undef f
477}
478
479#endif  // PROTOBUF_HAS_DEATH_TEST
480
481
482}  // namespace
483}  // namespace protobuf
484}  // namespace google
485