protobuf/src/google/protobuf/extension_set_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 #include <google/protobuf/stubs/casts.h>
36 #include <google/protobuf/stubs/strutil.h>
37 #include <google/protobuf/stubs/logging.h>
38 #include <google/protobuf/stubs/common.h>
39 #include <google/protobuf/test_util.h>
40 #include <google/protobuf/test_util2.h>
41 #include <google/protobuf/unittest.pb.h>
42 #include <google/protobuf/unittest_mset.pb.h>
43 #include <google/protobuf/io/coded_stream.h>
44 #include <google/protobuf/io/zero_copy_stream_impl.h>
45 #include <google/protobuf/descriptor.pb.h>
46 #include <google/protobuf/arena.h>
47 #include <google/protobuf/descriptor.h>
48 #include <google/protobuf/dynamic_message.h>
49 #include <google/protobuf/extension_set.h>
50 #include <google/protobuf/wire_format.h>
51 #include <google/protobuf/testing/googletest.h>
52 #include <gtest/gtest.h>
53 #include <google/protobuf/stubs/stl_util.h>
54 
55 // Must be included last.
56 #include <google/protobuf/port_def.inc>
57 
58 
59 namespace google {
60 namespace protobuf {
61 namespace internal {
62 namespace {
63 
65 
66 // This test closely mirrors net/proto2/compiler/cpp/internal/unittest.cc
67 // except that it uses extensions rather than regular fields.
68 
69 TEST(ExtensionSetTest, Defaults) {
70  // Check that all default values are set correctly in the initial message.
71  unittest::TestAllExtensions message;
72 
73  TestUtil::ExpectExtensionsClear(message);
74 
75  // Messages should return pointers to default instances until first use.
76  // (This is not checked by ExpectClear() since it is not actually true after
77  // the fields have been set and then cleared.)
78  EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(),
79  &message.GetExtension(unittest::optionalgroup_extension));
80  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
81  &message.GetExtension(unittest::optional_nested_message_extension));
82  EXPECT_EQ(
83  &unittest::ForeignMessage::default_instance(),
84  &message.GetExtension(unittest::optional_foreign_message_extension));
85  EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
86  &message.GetExtension(unittest::optional_import_message_extension));
87 }
88 
89 TEST(ExtensionSetTest, Accessors) {
90  // Set every field to a unique value then go back and check all those
91  // values.
92  unittest::TestAllExtensions message;
93 
95  TestUtil::ExpectAllExtensionsSet(message);
96 
97  TestUtil::ModifyRepeatedExtensions(&message);
98  TestUtil::ExpectRepeatedExtensionsModified(message);
99 }
100 
101 TEST(ExtensionSetTest, Clear) {
102  // Set every field to a unique value, clear the message, then check that
103  // it is cleared.
104  unittest::TestAllExtensions message;
105 
107  message.Clear();
108  TestUtil::ExpectExtensionsClear(message);
109 
110  // Unlike with the defaults test, we do NOT expect that requesting embedded
111  // messages will return a pointer to the default instance. Instead, they
112  // should return the objects that were created when mutable_blah() was
113  // called.
114  EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
115  &message.GetExtension(unittest::optionalgroup_extension));
116  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
117  &message.GetExtension(unittest::optional_nested_message_extension));
118  EXPECT_NE(
119  &unittest::ForeignMessage::default_instance(),
120  &message.GetExtension(unittest::optional_foreign_message_extension));
121  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
122  &message.GetExtension(unittest::optional_import_message_extension));
123 
124  // Make sure setting stuff again after clearing works. (This takes slightly
125  // different code paths since the objects are reused.)
127  TestUtil::ExpectAllExtensionsSet(message);
128 }
129 
130 TEST(ExtensionSetTest, ClearOneField) {
131  // Set every field to a unique value, then clear one value and insure that
132  // only that one value is cleared.
133  unittest::TestAllExtensions message;
134 
136  int64 original_value =
137  message.GetExtension(unittest::optional_int64_extension);
138 
139  // Clear the field and make sure it shows up as cleared.
140  message.ClearExtension(unittest::optional_int64_extension);
141  EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
142  EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
143 
144  // Other adjacent fields should not be cleared.
145  EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
146  EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
147 
148  // Make sure if we set it again, then all fields are set.
149  message.SetExtension(unittest::optional_int64_extension, original_value);
150  TestUtil::ExpectAllExtensionsSet(message);
151 }
152 
153 TEST(ExtensionSetTest, SetAllocatedExtension) {
154  unittest::TestAllExtensions message;
155  EXPECT_FALSE(
156  message.HasExtension(unittest::optional_foreign_message_extension));
157  // Add a extension using SetAllocatedExtension
158  unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
159  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
160  foreign_message);
161  EXPECT_TRUE(
162  message.HasExtension(unittest::optional_foreign_message_extension));
163  EXPECT_EQ(foreign_message, message.MutableExtension(
164  unittest::optional_foreign_message_extension));
165  EXPECT_EQ(foreign_message, &message.GetExtension(
166  unittest::optional_foreign_message_extension));
167 
168  // SetAllocatedExtension should delete the previously existing extension.
169  // (We reply on unittest to check memory leaks for this case)
170  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
171  new unittest::ForeignMessage());
172 
173  // SetAllocatedExtension with nullptr is equivalent to ClearExtenion.
174  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
175  nullptr);
176  EXPECT_FALSE(
177  message.HasExtension(unittest::optional_foreign_message_extension));
178 }
179 
180 TEST(ExtensionSetTest, ReleaseExtension) {
181  proto2_wireformat_unittest::TestMessageSet message;
182  EXPECT_FALSE(message.HasExtension(
183  unittest::TestMessageSetExtension1::message_set_extension));
184  // Add a extension using SetAllocatedExtension
185  unittest::TestMessageSetExtension1* extension =
186  new unittest::TestMessageSetExtension1();
187  message.SetAllocatedExtension(
188  unittest::TestMessageSetExtension1::message_set_extension, extension);
189  EXPECT_TRUE(message.HasExtension(
190  unittest::TestMessageSetExtension1::message_set_extension));
191  // Release the extension using ReleaseExtension
192  unittest::TestMessageSetExtension1* released_extension =
193  message.ReleaseExtension(
194  unittest::TestMessageSetExtension1::message_set_extension);
195  EXPECT_EQ(extension, released_extension);
196  EXPECT_FALSE(message.HasExtension(
197  unittest::TestMessageSetExtension1::message_set_extension));
198  // ReleaseExtension will return the underlying object even after
199  // ClearExtension is called.
200  message.SetAllocatedExtension(
201  unittest::TestMessageSetExtension1::message_set_extension,
202  released_extension);
203  message.ClearExtension(
204  unittest::TestMessageSetExtension1::message_set_extension);
205  released_extension = message.ReleaseExtension(
206  unittest::TestMessageSetExtension1::message_set_extension);
207  EXPECT_TRUE(released_extension != nullptr);
208  delete released_extension;
209 }
210 
211 TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) {
212  Arena arena;
213  unittest::TestAllExtensions* message =
214  Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
215  unittest::ForeignMessage extension;
216  message->UnsafeArenaSetAllocatedExtension(
217  unittest::optional_foreign_message_extension, &extension);
218  // No copy when set.
219  unittest::ForeignMessage* mutable_extension =
220  message->MutableExtension(unittest::optional_foreign_message_extension);
221  EXPECT_EQ(&extension, mutable_extension);
222  // No copy when unsafe released.
223  unittest::ForeignMessage* released_extension =
224  message->UnsafeArenaReleaseExtension(
225  unittest::optional_foreign_message_extension);
226  EXPECT_EQ(&extension, released_extension);
227  EXPECT_FALSE(
228  message->HasExtension(unittest::optional_foreign_message_extension));
229  // Set the ownership back and let the destructors run. It should not take
230  // ownership, so this should not crash.
231  message->UnsafeArenaSetAllocatedExtension(
232  unittest::optional_foreign_message_extension, &extension);
233 }
234 
235 TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) {
236  unittest::TestAllExtensions message;
237  unittest::ForeignMessage* extension = new unittest::ForeignMessage();
238  message.UnsafeArenaSetAllocatedExtension(
239  unittest::optional_foreign_message_extension, extension);
240  // No copy when set.
241  unittest::ForeignMessage* mutable_extension =
242  message.MutableExtension(unittest::optional_foreign_message_extension);
243  EXPECT_EQ(extension, mutable_extension);
244  // No copy when unsafe released.
245  unittest::ForeignMessage* released_extension =
246  message.UnsafeArenaReleaseExtension(
247  unittest::optional_foreign_message_extension);
248  EXPECT_EQ(extension, released_extension);
249  EXPECT_FALSE(
250  message.HasExtension(unittest::optional_foreign_message_extension));
251  // Set the ownership back and let the destructors run. It should take
252  // ownership, so this should not leak.
253  message.UnsafeArenaSetAllocatedExtension(
254  unittest::optional_foreign_message_extension, extension);
255 }
256 
257 TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) {
258  Arena arena;
259  unittest::TestAllExtensions* message =
260  Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
261  unittest::ForeignMessage* extension = new unittest::ForeignMessage;
262  message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
263  extension);
264  // The arena should maintain ownership of the heap allocated proto because we
265  // used UnsafeArenaReleaseExtension. The leak checker will ensure this.
266  unittest::ForeignMessage* released_extension =
267  message->UnsafeArenaReleaseExtension(
268  unittest::optional_foreign_message_extension);
269  EXPECT_EQ(extension, released_extension);
270  EXPECT_FALSE(
271  message->HasExtension(unittest::optional_foreign_message_extension));
272 }
273 
274 
275 TEST(ExtensionSetTest, CopyFrom) {
276  unittest::TestAllExtensions message1, message2;
277 
278  TestUtil::SetAllExtensions(&message1);
279  message2.CopyFrom(message1);
280  TestUtil::ExpectAllExtensionsSet(message2);
281  message2.CopyFrom(message1); // exercise copy when fields already exist
282  TestUtil::ExpectAllExtensionsSet(message2);
283 }
284 
285 TEST(ExtensionSetTest, CopyFromPacked) {
286  unittest::TestPackedExtensions message1, message2;
287 
288  TestUtil::SetPackedExtensions(&message1);
289  message2.CopyFrom(message1);
290  TestUtil::ExpectPackedExtensionsSet(message2);
291  message2.CopyFrom(message1); // exercise copy when fields already exist
292  TestUtil::ExpectPackedExtensionsSet(message2);
293 }
294 
295 TEST(ExtensionSetTest, CopyFromUpcasted) {
296  unittest::TestAllExtensions message1, message2;
297  const Message& upcasted_message = message1;
298 
299  TestUtil::SetAllExtensions(&message1);
300  message2.CopyFrom(upcasted_message);
301  TestUtil::ExpectAllExtensionsSet(message2);
302  // exercise copy when fields already exist
303  message2.CopyFrom(upcasted_message);
304  TestUtil::ExpectAllExtensionsSet(message2);
305 }
306 
307 TEST(ExtensionSetTest, SwapWithEmpty) {
308  unittest::TestAllExtensions message1, message2;
309  TestUtil::SetAllExtensions(&message1);
310 
311  TestUtil::ExpectAllExtensionsSet(message1);
312  TestUtil::ExpectExtensionsClear(message2);
313  message1.Swap(&message2);
314  TestUtil::ExpectAllExtensionsSet(message2);
315  TestUtil::ExpectExtensionsClear(message1);
316 }
317 
318 TEST(ExtensionSetTest, SwapWithSelf) {
319  unittest::TestAllExtensions message;
321 
322  TestUtil::ExpectAllExtensionsSet(message);
323  message.Swap(&message);
324  TestUtil::ExpectAllExtensionsSet(message);
325 }
326 
327 TEST(ExtensionSetTest, SwapExtension) {
328  unittest::TestAllExtensions message1;
329  unittest::TestAllExtensions message2;
330 
331  TestUtil::SetAllExtensions(&message1);
332  std::vector<const FieldDescriptor*> fields;
333 
334  // Swap empty fields.
335  const Reflection* reflection = message1.GetReflection();
336  reflection->SwapFields(&message1, &message2, fields);
337  TestUtil::ExpectAllExtensionsSet(message1);
338  TestUtil::ExpectExtensionsClear(message2);
339 
340  // Swap two extensions.
341  fields.push_back(reflection->FindKnownExtensionByNumber(12));
342  fields.push_back(reflection->FindKnownExtensionByNumber(25));
343  reflection->SwapFields(&message1, &message2, fields);
344 
345  EXPECT_TRUE(message1.HasExtension(unittest::optional_int32_extension));
346  EXPECT_FALSE(message1.HasExtension(unittest::optional_double_extension));
347  EXPECT_FALSE(message1.HasExtension(unittest::optional_cord_extension));
348 
349  EXPECT_FALSE(message2.HasExtension(unittest::optional_int32_extension));
350  EXPECT_TRUE(message2.HasExtension(unittest::optional_double_extension));
351  EXPECT_TRUE(message2.HasExtension(unittest::optional_cord_extension));
352 }
353 
354 TEST(ExtensionSetTest, SwapExtensionWithEmpty) {
355  unittest::TestAllExtensions message1;
356  unittest::TestAllExtensions message2;
357  unittest::TestAllExtensions message3;
358 
359  TestUtil::SetAllExtensions(&message3);
360 
361  const Reflection* reflection = message3.GetReflection();
362  std::vector<const FieldDescriptor*> fields;
363  reflection->ListFields(message3, &fields);
364 
365  reflection->SwapFields(&message1, &message2, fields);
366 
367  TestUtil::ExpectExtensionsClear(message1);
368  TestUtil::ExpectExtensionsClear(message2);
369 }
370 
371 TEST(ExtensionSetTest, SwapExtensionBothFull) {
372  unittest::TestAllExtensions message1;
373  unittest::TestAllExtensions message2;
374 
375  TestUtil::SetAllExtensions(&message1);
376  TestUtil::SetAllExtensions(&message2);
377 
378  const Reflection* reflection = message1.GetReflection();
379  std::vector<const FieldDescriptor*> fields;
380  reflection->ListFields(message1, &fields);
381 
382  reflection->SwapFields(&message1, &message2, fields);
383 
384  TestUtil::ExpectAllExtensionsSet(message1);
385  TestUtil::ExpectAllExtensionsSet(message2);
386 }
387 
388 TEST(ExtensionSetTest, ArenaSetAllExtension) {
389  Arena arena1;
390  unittest::TestAllExtensions* message1 =
391  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
392  TestUtil::SetAllExtensions(message1);
393  TestUtil::ExpectAllExtensionsSet(*message1);
394 }
395 
396 TEST(ExtensionSetTest, ArenaCopyConstructor) {
397  Arena arena1;
398  unittest::TestAllExtensions* message1 =
399  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
400  TestUtil::SetAllExtensions(message1);
401  unittest::TestAllExtensions message2(*message1);
402  arena1.Reset();
403  TestUtil::ExpectAllExtensionsSet(message2);
404 }
405 
406 TEST(ExtensionSetTest, ArenaMergeFrom) {
407  Arena arena1;
408  unittest::TestAllExtensions* message1 =
409  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
410  TestUtil::SetAllExtensions(message1);
411  unittest::TestAllExtensions message2;
412  message2.MergeFrom(*message1);
413  arena1.Reset();
414  TestUtil::ExpectAllExtensionsSet(message2);
415 }
416 
417 TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) {
418  Arena arena;
419  unittest::TestAllExtensions* message =
420  Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
421  EXPECT_FALSE(
422  message->HasExtension(unittest::optional_foreign_message_extension));
423  // Add a extension using SetAllocatedExtension
424  unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
425  message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
426  foreign_message);
427  // foreign_message is now owned by the arena.
428  EXPECT_EQ(foreign_message, message->MutableExtension(
429  unittest::optional_foreign_message_extension));
430 
431  // Underlying message is copied, and returned.
432  unittest::ForeignMessage* released_message =
433  message->ReleaseExtension(unittest::optional_foreign_message_extension);
434  delete released_message;
435  EXPECT_FALSE(
436  message->HasExtension(unittest::optional_foreign_message_extension));
437 }
438 
439 TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) {
440  Arena arena1;
441  std::unique_ptr<Arena> arena2(new Arena());
442 
443  unittest::TestAllExtensions* message1 =
444  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
445  unittest::TestAllExtensions* message2 =
446  Arena::CreateMessage<unittest::TestAllExtensions>(arena2.get());
447 
448  TestUtil::SetAllExtensions(message1);
449  TestUtil::SetAllExtensions(message2);
450  message1->SetExtension(unittest::optional_int32_extension, 1);
451  message2->SetExtension(unittest::optional_int32_extension, 2);
452  message1->Swap(message2);
453  EXPECT_EQ(2, message1->GetExtension(unittest::optional_int32_extension));
454  EXPECT_EQ(1, message2->GetExtension(unittest::optional_int32_extension));
455  // Re-set the original values so ExpectAllExtensionsSet is happy.
456  message1->SetExtension(unittest::optional_int32_extension, 101);
457  message2->SetExtension(unittest::optional_int32_extension, 101);
458  TestUtil::ExpectAllExtensionsSet(*message1);
459  TestUtil::ExpectAllExtensionsSet(*message2);
460  arena2.reset(nullptr);
461  TestUtil::ExpectAllExtensionsSet(*message1);
462  // Test corner cases, when one is empty and other is not.
463  Arena arena3, arena4;
464 
465  unittest::TestAllExtensions* message3 =
466  Arena::CreateMessage<unittest::TestAllExtensions>(&arena3);
467  unittest::TestAllExtensions* message4 =
468  Arena::CreateMessage<unittest::TestAllExtensions>(&arena4);
469  TestUtil::SetAllExtensions(message3);
470  message3->Swap(message4);
471  arena3.Reset();
472  TestUtil::ExpectAllExtensionsSet(*message4);
473 }
474 
475 TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) {
476  Arena arena1;
477  Arena* arena2 = new Arena();
478 
479  unittest::TestAllExtensions* message1 =
480  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
481  unittest::TestAllExtensions* message2 =
482  Arena::CreateMessage<unittest::TestAllExtensions>(arena2);
483 
484  TestUtil::SetAllExtensions(message1);
485  TestUtil::SetAllExtensions(message2);
486 
487  const Reflection* reflection = message1->GetReflection();
488  std::vector<const FieldDescriptor*> fields;
489  reflection->ListFields(*message1, &fields);
490  reflection->SwapFields(message1, message2, fields);
491  TestUtil::ExpectAllExtensionsSet(*message1);
492  TestUtil::ExpectAllExtensionsSet(*message2);
493  delete arena2;
494  TestUtil::ExpectAllExtensionsSet(*message1);
495 }
496 
497 TEST(ExtensionSetTest, SwapExtensionWithSelf) {
498  unittest::TestAllExtensions message1;
499 
500  TestUtil::SetAllExtensions(&message1);
501 
502  std::vector<const FieldDescriptor*> fields;
503  const Reflection* reflection = message1.GetReflection();
504  reflection->ListFields(message1, &fields);
505  reflection->SwapFields(&message1, &message1, fields);
506 
507  TestUtil::ExpectAllExtensionsSet(message1);
508 }
509 
510 TEST(ExtensionSetTest, SerializationToArray) {
511  // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
512  // compatibility of extensions.
513  //
514  // This checks serialization to a flat array by explicitly reserving space in
515  // the string and calling the generated message's
516  // SerializeWithCachedSizesToArray.
517  unittest::TestAllExtensions source;
518  unittest::TestAllTypes destination;
520  size_t size = source.ByteSizeLong();
522  data.resize(size);
523  uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
524  uint8* end = source.SerializeWithCachedSizesToArray(target);
525  EXPECT_EQ(size, end - target);
526  EXPECT_TRUE(destination.ParseFromString(data));
527  TestUtil::ExpectAllFieldsSet(destination);
528 }
529 
530 TEST(ExtensionSetTest, SerializationToStream) {
531  // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
532  // compatibility of extensions.
533  //
534  // This checks serialization to an output stream by creating an array output
535  // stream that can only buffer 1 byte at a time - this prevents the message
536  // from ever jumping to the fast path, ensuring that serialization happens via
537  // the CodedOutputStream.
538  unittest::TestAllExtensions source;
539  unittest::TestAllTypes destination;
541  size_t size = source.ByteSizeLong();
543  data.resize(size);
544  {
545  io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
546  io::CodedOutputStream output_stream(&array_stream);
547  source.SerializeWithCachedSizes(&output_stream);
548  ASSERT_FALSE(output_stream.HadError());
549  }
550  EXPECT_TRUE(destination.ParseFromString(data));
551  TestUtil::ExpectAllFieldsSet(destination);
552 }
553 
554 TEST(ExtensionSetTest, PackedSerializationToArray) {
555  // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
556  // wire compatibility of extensions.
557  //
558  // This checks serialization to a flat array by explicitly reserving space in
559  // the string and calling the generated message's
560  // SerializeWithCachedSizesToArray.
561  unittest::TestPackedExtensions source;
562  unittest::TestPackedTypes destination;
563  TestUtil::SetPackedExtensions(&source);
564  size_t size = source.ByteSizeLong();
566  data.resize(size);
567  uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
568  uint8* end = source.SerializeWithCachedSizesToArray(target);
569  EXPECT_EQ(size, end - target);
570  EXPECT_TRUE(destination.ParseFromString(data));
571  TestUtil::ExpectPackedFieldsSet(destination);
572 }
573 
574 TEST(ExtensionSetTest, PackedSerializationToStream) {
575  // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
576  // wire compatibility of extensions.
577  //
578  // This checks serialization to an output stream by creating an array output
579  // stream that can only buffer 1 byte at a time - this prevents the message
580  // from ever jumping to the fast path, ensuring that serialization happens via
581  // the CodedOutputStream.
582  unittest::TestPackedExtensions source;
583  unittest::TestPackedTypes destination;
584  TestUtil::SetPackedExtensions(&source);
585  size_t size = source.ByteSizeLong();
587  data.resize(size);
588  {
589  io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
590  io::CodedOutputStream output_stream(&array_stream);
591  source.SerializeWithCachedSizes(&output_stream);
592  ASSERT_FALSE(output_stream.HadError());
593  }
594  EXPECT_TRUE(destination.ParseFromString(data));
595  TestUtil::ExpectPackedFieldsSet(destination);
596 }
597 
598 TEST(ExtensionSetTest, NestedExtensionGroup) {
599  // Serialize as TestGroup and parse as TestGroupExtension.
600  unittest::TestGroup source;
601  unittest::TestGroupExtension destination;
603 
604  source.mutable_optionalgroup()->set_a(117);
605  source.set_optional_foreign_enum(unittest::FOREIGN_BAZ);
606  source.SerializeToString(&data);
607  EXPECT_TRUE(destination.ParseFromString(data));
608  EXPECT_TRUE(
609  destination
610  .GetExtension(unittest::TestNestedExtension::optionalgroup_extension)
611  .has_a());
612  EXPECT_EQ(117, destination
613  .GetExtension(
614  unittest::TestNestedExtension::optionalgroup_extension)
615  .a());
616  EXPECT_TRUE(destination.HasExtension(
617  unittest::TestNestedExtension::optional_foreign_enum_extension));
618  EXPECT_EQ(
619  unittest::FOREIGN_BAZ,
620  destination.GetExtension(
621  unittest::TestNestedExtension::optional_foreign_enum_extension));
622 }
623 
624 TEST(ExtensionSetTest, Parsing) {
625  // Serialize as TestAllTypes and parse as TestAllExtensions.
626  unittest::TestAllTypes source;
627  unittest::TestAllExtensions destination;
629 
630  TestUtil::SetAllFields(&source);
631  source.SerializeToString(&data);
632  EXPECT_TRUE(destination.ParseFromString(data));
633  TestUtil::SetOneofFields(&destination);
634  TestUtil::ExpectAllExtensionsSet(destination);
635 }
636 
637 TEST(ExtensionSetTest, PackedParsing) {
638  // Serialize as TestPackedTypes and parse as TestPackedExtensions.
639  unittest::TestPackedTypes source;
640  unittest::TestPackedExtensions destination;
642 
643  TestUtil::SetPackedFields(&source);
644  source.SerializeToString(&data);
645  EXPECT_TRUE(destination.ParseFromString(data));
646  TestUtil::ExpectPackedExtensionsSet(destination);
647 }
648 
649 TEST(ExtensionSetTest, PackedToUnpackedParsing) {
650  unittest::TestPackedTypes source;
651  unittest::TestUnpackedExtensions destination;
653 
654  TestUtil::SetPackedFields(&source);
655  source.SerializeToString(&data);
656  EXPECT_TRUE(destination.ParseFromString(data));
657  TestUtil::ExpectUnpackedExtensionsSet(destination);
658 
659  // Reserialize
660  unittest::TestUnpackedTypes unpacked;
661  TestUtil::SetUnpackedFields(&unpacked);
662  // Serialized proto has to be the same size and parsed to the same message.
663  EXPECT_EQ(unpacked.SerializeAsString().size(),
664  destination.SerializeAsString().size());
665  EXPECT_TRUE(EqualsToSerialized(unpacked, destination.SerializeAsString()));
666 
667  // Make sure we can add extensions.
668  destination.AddExtension(unittest::unpacked_int32_extension, 1);
669  destination.AddExtension(unittest::unpacked_enum_extension,
670  protobuf_unittest::FOREIGN_BAR);
671 }
672 
673 TEST(ExtensionSetTest, UnpackedToPackedParsing) {
674  unittest::TestUnpackedTypes source;
675  unittest::TestPackedExtensions destination;
677 
678  TestUtil::SetUnpackedFields(&source);
679  source.SerializeToString(&data);
680  EXPECT_TRUE(destination.ParseFromString(data));
681  TestUtil::ExpectPackedExtensionsSet(destination);
682 
683  // Reserialize
684  unittest::TestPackedTypes packed;
685  TestUtil::SetPackedFields(&packed);
686  // Serialized proto has to be the same size and parsed to the same message.
687  EXPECT_EQ(packed.SerializeAsString().size(),
688  destination.SerializeAsString().size());
689  EXPECT_TRUE(EqualsToSerialized(packed, destination.SerializeAsString()));
690 
691  // Make sure we can add extensions.
692  destination.AddExtension(unittest::packed_int32_extension, 1);
693  destination.AddExtension(unittest::packed_enum_extension,
694  protobuf_unittest::FOREIGN_BAR);
695 }
696 
697 TEST(ExtensionSetTest, IsInitialized) {
698  // Test that IsInitialized() returns false if required fields in nested
699  // extensions are missing.
700  unittest::TestAllExtensions message;
701 
702  EXPECT_TRUE(message.IsInitialized());
703 
704  message.MutableExtension(unittest::TestRequired::single);
705  EXPECT_FALSE(message.IsInitialized());
706 
707  message.MutableExtension(unittest::TestRequired::single)->set_a(1);
708  EXPECT_FALSE(message.IsInitialized());
709  message.MutableExtension(unittest::TestRequired::single)->set_b(2);
710  EXPECT_FALSE(message.IsInitialized());
711  message.MutableExtension(unittest::TestRequired::single)->set_c(3);
712  EXPECT_TRUE(message.IsInitialized());
713 
714  message.AddExtension(unittest::TestRequired::multi);
715  EXPECT_FALSE(message.IsInitialized());
716 
717  message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
718  EXPECT_FALSE(message.IsInitialized());
719  message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
720  EXPECT_FALSE(message.IsInitialized());
721  message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
722  EXPECT_TRUE(message.IsInitialized());
723 }
724 
725 TEST(ExtensionSetTest, MutableString) {
726  // Test the mutable string accessors.
727  unittest::TestAllExtensions message;
728 
729  message.MutableExtension(unittest::optional_string_extension)->assign("foo");
730  EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
731  EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
732 
733  message.AddExtension(unittest::repeated_string_extension)->assign("bar");
734  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
735  EXPECT_EQ("bar",
736  message.GetExtension(unittest::repeated_string_extension, 0));
737 }
738 
739 TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
740  // Scalar primitive extensions should increase the extension set size by a
741  // minimum of the size of the primitive type.
742 #define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \
743  do { \
744  unittest::TestAllExtensions message; \
745  const int base_size = message.SpaceUsedLong(); \
746  message.SetExtension(unittest::optional_##type##_extension, value); \
747  int min_expected_size = \
748  base_size + \
749  sizeof(message.GetExtension(unittest::optional_##type##_extension)); \
750  EXPECT_LE(min_expected_size, message.SpaceUsedLong()); \
751  } while (0)
752 
759  TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32, 107);
760  TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64, 108);
761  TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
762  TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
766 #undef TEST_SCALAR_EXTENSIONS_SPACE_USED
767  {
768  unittest::TestAllExtensions message;
769  const int base_size = message.SpaceUsedLong();
770  message.SetExtension(unittest::optional_nested_enum_extension,
771  unittest::TestAllTypes::FOO);
772  int min_expected_size =
773  base_size +
774  sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
775  EXPECT_LE(min_expected_size, message.SpaceUsedLong());
776  }
777  {
778  // Strings may cause extra allocations depending on their length; ensure
779  // that gets included as well.
780  unittest::TestAllExtensions message;
781  const int base_size = message.SpaceUsedLong();
782  const std::string s(
783  "this is a fairly large string that will cause some "
784  "allocation in order to store it in the extension");
785  message.SetExtension(unittest::optional_string_extension, s);
786  int min_expected_size = base_size + s.length();
787  EXPECT_LE(min_expected_size, message.SpaceUsedLong());
788  }
789  {
790  // Messages also have additional allocation that need to be counted.
791  unittest::TestAllExtensions message;
792  const int base_size = message.SpaceUsedLong();
793  unittest::ForeignMessage foreign;
794  foreign.set_c(42);
795  message.MutableExtension(unittest::optional_foreign_message_extension)
796  ->CopyFrom(foreign);
797  int min_expected_size = base_size + foreign.SpaceUsedLong();
798  EXPECT_LE(min_expected_size, message.SpaceUsedLong());
799  }
800 
801  // Repeated primitive extensions will increase space used by at least a
802  // RepeatedField<T>, and will cause additional allocations when the array
803  // gets too big for the initial space.
804  // This macro:
805  // - Adds a value to the repeated extension, then clears it, establishing
806  // the base size.
807  // - Adds a small number of values, testing that it doesn't increase the
808  // SpaceUsedLong()
809  // - Adds a large number of values (requiring allocation in the repeated
810  // field), and ensures that that allocation is included in SpaceUsedLong()
811 #define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \
812  do { \
813  unittest::TestAllExtensions message; \
814  const size_t base_size = message.SpaceUsedLong(); \
815  size_t min_expected_size = sizeof(RepeatedField<cpptype>) + base_size; \
816  message.AddExtension(unittest::repeated_##type##_extension, value); \
817  message.ClearExtension(unittest::repeated_##type##_extension); \
818  const size_t empty_repeated_field_size = message.SpaceUsedLong(); \
819  EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \
820  message.AddExtension(unittest::repeated_##type##_extension, value); \
821  message.AddExtension(unittest::repeated_##type##_extension, value); \
822  EXPECT_EQ(empty_repeated_field_size, message.SpaceUsedLong()) << #type; \
823  message.ClearExtension(unittest::repeated_##type##_extension); \
824  const size_t old_capacity = \
825  message.GetRepeatedExtension(unittest::repeated_##type##_extension) \
826  .Capacity(); \
827  EXPECT_GE(old_capacity, kRepeatedFieldLowerClampLimit); \
828  for (int i = 0; i < 16; ++i) { \
829  message.AddExtension(unittest::repeated_##type##_extension, value); \
830  } \
831  int expected_size = \
832  sizeof(cpptype) * \
833  (message \
834  .GetRepeatedExtension(unittest::repeated_##type##_extension) \
835  .Capacity() - \
836  old_capacity) + \
837  empty_repeated_field_size; \
838  EXPECT_LE(expected_size, message.SpaceUsedLong()) << #type; \
839  } while (0)
840 
851  TEST_REPEATED_EXTENSIONS_SPACE_USED(float, float, 111);
852  TEST_REPEATED_EXTENSIONS_SPACE_USED(double, double, 112);
853  TEST_REPEATED_EXTENSIONS_SPACE_USED(bool, bool, true);
854  TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
855  unittest::TestAllTypes::FOO);
856 #undef TEST_REPEATED_EXTENSIONS_SPACE_USED
857  // Repeated strings
858  {
859  unittest::TestAllExtensions message;
860  const size_t base_size = message.SpaceUsedLong();
861  size_t min_expected_size =
862  sizeof(RepeatedPtrField<std::string>) + base_size;
863  const std::string value(256, 'x');
864  // Once items are allocated, they may stick around even when cleared so
865  // without the hardcore memory management accessors there isn't a notion of
866  // the empty repeated field memory usage as there is with primitive types.
867  for (int i = 0; i < 16; ++i) {
868  message.AddExtension(unittest::repeated_string_extension, value);
869  }
870  min_expected_size +=
871  (sizeof(value) + value.size()) * (16 - kRepeatedFieldLowerClampLimit);
872  EXPECT_LE(min_expected_size, message.SpaceUsedLong());
873  }
874  // Repeated messages
875  {
876  unittest::TestAllExtensions message;
877  const size_t base_size = message.SpaceUsedLong();
878  size_t min_expected_size =
879  sizeof(RepeatedPtrField<unittest::ForeignMessage>) + base_size;
880  unittest::ForeignMessage prototype;
881  prototype.set_c(2);
882  for (int i = 0; i < 16; ++i) {
883  message.AddExtension(unittest::repeated_foreign_message_extension)
884  ->CopyFrom(prototype);
885  }
886  min_expected_size +=
887  (16 - kRepeatedFieldLowerClampLimit) * prototype.SpaceUsedLong();
888  EXPECT_LE(min_expected_size, message.SpaceUsedLong());
889  }
890 }
891 
892 // N.B.: We do not test range-based for here because we remain C++03 compatible.
893 template <typename T, typename M, typename ID>
894 inline T SumAllExtensions(const M& message, ID extension, T zero) {
895  T sum = zero;
897  message.GetRepeatedExtension(extension).begin();
899  message.GetRepeatedExtension(extension).end();
900  for (; iter != end; ++iter) {
901  sum += *iter;
902  }
903  return sum;
904 }
905 
906 template <typename T, typename M, typename ID>
907 inline void IncAllExtensions(M* message, ID extension, T val) {
909  message->MutableRepeatedExtension(extension)->begin();
911  message->MutableRepeatedExtension(extension)->end();
912  for (; iter != end; ++iter) {
913  *iter += val;
914  }
915 }
916 
917 TEST(ExtensionSetTest, RepeatedFields) {
918  unittest::TestAllExtensions message;
919 
920  // Test empty repeated-field case (b/12926163)
921  ASSERT_EQ(
922  0,
923  message.GetRepeatedExtension(unittest::repeated_int32_extension).size());
924  ASSERT_EQ(
925  0, message.GetRepeatedExtension(unittest::repeated_nested_enum_extension)
926  .size());
927  ASSERT_EQ(
928  0,
929  message.GetRepeatedExtension(unittest::repeated_string_extension).size());
930  ASSERT_EQ(
931  0,
932  message.GetRepeatedExtension(unittest::repeated_nested_message_extension)
933  .size());
934 
935  unittest::TestAllTypes::NestedMessage nested_message;
936  nested_message.set_bb(42);
937  unittest::TestAllTypes::NestedEnum nested_enum =
938  unittest::TestAllTypes::NestedEnum_MIN;
939 
940  for (int i = 0; i < 10; ++i) {
941  message.AddExtension(unittest::repeated_int32_extension, 1);
942  message.AddExtension(unittest::repeated_int64_extension, 2);
943  message.AddExtension(unittest::repeated_uint32_extension, 3);
944  message.AddExtension(unittest::repeated_uint64_extension, 4);
945  message.AddExtension(unittest::repeated_sint32_extension, 5);
946  message.AddExtension(unittest::repeated_sint64_extension, 6);
947  message.AddExtension(unittest::repeated_fixed32_extension, 7);
948  message.AddExtension(unittest::repeated_fixed64_extension, 8);
949  message.AddExtension(unittest::repeated_sfixed32_extension, 7);
950  message.AddExtension(unittest::repeated_sfixed64_extension, 8);
951  message.AddExtension(unittest::repeated_float_extension, 9.0);
952  message.AddExtension(unittest::repeated_double_extension, 10.0);
953  message.AddExtension(unittest::repeated_bool_extension, true);
954  message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
955  message.AddExtension(unittest::repeated_string_extension,
956  std::string("test"));
957  message.AddExtension(unittest::repeated_bytes_extension,
958  std::string("test\xFF"));
959  message.AddExtension(unittest::repeated_nested_message_extension)
960  ->CopyFrom(nested_message);
961  message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
962  }
963 
964  ASSERT_EQ(10, SumAllExtensions<int32>(message,
965  unittest::repeated_int32_extension, 0));
966  IncAllExtensions<int32>(&message, unittest::repeated_int32_extension, 1);
967  ASSERT_EQ(20, SumAllExtensions<int32>(message,
968  unittest::repeated_int32_extension, 0));
969 
970  ASSERT_EQ(20, SumAllExtensions<int64>(message,
971  unittest::repeated_int64_extension, 0));
972  IncAllExtensions<int64>(&message, unittest::repeated_int64_extension, 1);
973  ASSERT_EQ(30, SumAllExtensions<int64>(message,
974  unittest::repeated_int64_extension, 0));
975 
976  ASSERT_EQ(30, SumAllExtensions<uint32>(
977  message, unittest::repeated_uint32_extension, 0));
978  IncAllExtensions<uint32>(&message, unittest::repeated_uint32_extension, 1);
979  ASSERT_EQ(40, SumAllExtensions<uint32>(
980  message, unittest::repeated_uint32_extension, 0));
981 
982  ASSERT_EQ(40, SumAllExtensions<uint64>(
983  message, unittest::repeated_uint64_extension, 0));
984  IncAllExtensions<uint64>(&message, unittest::repeated_uint64_extension, 1);
985  ASSERT_EQ(50, SumAllExtensions<uint64>(
986  message, unittest::repeated_uint64_extension, 0));
987 
988  ASSERT_EQ(50, SumAllExtensions<int32>(
989  message, unittest::repeated_sint32_extension, 0));
990  IncAllExtensions<int32>(&message, unittest::repeated_sint32_extension, 1);
991  ASSERT_EQ(60, SumAllExtensions<int32>(
992  message, unittest::repeated_sint32_extension, 0));
993 
994  ASSERT_EQ(60, SumAllExtensions<int64>(
995  message, unittest::repeated_sint64_extension, 0));
996  IncAllExtensions<int64>(&message, unittest::repeated_sint64_extension, 1);
997  ASSERT_EQ(70, SumAllExtensions<int64>(
998  message, unittest::repeated_sint64_extension, 0));
999 
1000  ASSERT_EQ(70, SumAllExtensions<uint32>(
1001  message, unittest::repeated_fixed32_extension, 0));
1002  IncAllExtensions<uint32>(&message, unittest::repeated_fixed32_extension, 1);
1003  ASSERT_EQ(80, SumAllExtensions<uint32>(
1004  message, unittest::repeated_fixed32_extension, 0));
1005 
1006  ASSERT_EQ(80, SumAllExtensions<uint64>(
1007  message, unittest::repeated_fixed64_extension, 0));
1008  IncAllExtensions<uint64>(&message, unittest::repeated_fixed64_extension, 1);
1009  ASSERT_EQ(90, SumAllExtensions<uint64>(
1010  message, unittest::repeated_fixed64_extension, 0));
1011 
1012  // Usually, floating-point arithmetic cannot be trusted to be exact, so it is
1013  // a Bad Idea to assert equality in a test like this. However, we're dealing
1014  // with integers with a small number of significant mantissa bits, so we
1015  // should actually have exact precision here.
1016  ASSERT_EQ(90, SumAllExtensions<float>(message,
1017  unittest::repeated_float_extension, 0));
1018  IncAllExtensions<float>(&message, unittest::repeated_float_extension, 1);
1019  ASSERT_EQ(100, SumAllExtensions<float>(
1020  message, unittest::repeated_float_extension, 0));
1021 
1022  ASSERT_EQ(100, SumAllExtensions<double>(
1023  message, unittest::repeated_double_extension, 0));
1024  IncAllExtensions<double>(&message, unittest::repeated_double_extension, 1);
1025  ASSERT_EQ(110, SumAllExtensions<double>(
1026  message, unittest::repeated_double_extension, 0));
1027 
1030  for (string_iter =
1031  message
1032  .MutableRepeatedExtension(unittest::repeated_string_extension)
1033  ->begin(),
1034  string_end =
1035  message
1036  .MutableRepeatedExtension(unittest::repeated_string_extension)
1037  ->end();
1038  string_iter != string_end; ++string_iter) {
1039  *string_iter += "test";
1040  }
1043  for (string_const_iter =
1044  message.GetRepeatedExtension(unittest::repeated_string_extension)
1045  .begin(),
1046  string_const_end =
1047  message.GetRepeatedExtension(unittest::repeated_string_extension)
1048  .end();
1049  string_iter != string_end; ++string_iter) {
1050  ASSERT_TRUE(*string_iter == "testtest");
1051  }
1052 
1055  for (enum_iter = message
1056  .MutableRepeatedExtension(
1057  unittest::repeated_nested_enum_extension)
1058  ->begin(),
1059  enum_end = message
1060  .MutableRepeatedExtension(
1061  unittest::repeated_nested_enum_extension)
1062  ->end();
1063  enum_iter != enum_end; ++enum_iter) {
1064  *enum_iter = unittest::TestAllTypes::NestedEnum_MAX;
1065  }
1067  enum_const_iter;
1069  enum_const_end;
1070  for (enum_const_iter =
1071  message
1072  .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
1073  .begin(),
1074  enum_const_end =
1075  message
1076  .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
1077  .end();
1078  enum_const_iter != enum_const_end; ++enum_const_iter) {
1079  ASSERT_EQ(*enum_const_iter, unittest::TestAllTypes::NestedEnum_MAX);
1080  }
1081 
1084  for (msg_iter = message
1085  .MutableRepeatedExtension(
1086  unittest::repeated_nested_message_extension)
1087  ->begin(),
1088  msg_end = message
1089  .MutableRepeatedExtension(
1090  unittest::repeated_nested_message_extension)
1091  ->end();
1092  msg_iter != msg_end; ++msg_iter) {
1093  msg_iter->set_bb(1234);
1094  }
1096  msg_const_iter;
1098  msg_const_end;
1099  for (msg_const_iter = message
1100  .GetRepeatedExtension(
1101  unittest::repeated_nested_message_extension)
1102  .begin(),
1103  msg_const_end = message
1104  .GetRepeatedExtension(
1105  unittest::repeated_nested_message_extension)
1106  .end();
1107  msg_const_iter != msg_const_end; ++msg_const_iter) {
1108  ASSERT_EQ(msg_const_iter->bb(), 1234);
1109  }
1110 
1111  // Test one primitive field.
1112  for (auto& x :
1113  *message.MutableRepeatedExtension(unittest::repeated_int32_extension)) {
1114  x = 4321;
1115  }
1116  for (const auto& x :
1117  message.GetRepeatedExtension(unittest::repeated_int32_extension)) {
1118  ASSERT_EQ(x, 4321);
1119  }
1120  // Test one string field.
1121  for (auto& x :
1122  *message.MutableRepeatedExtension(unittest::repeated_string_extension)) {
1123  x = "test_range_based_for";
1124  }
1125  for (const auto& x :
1126  message.GetRepeatedExtension(unittest::repeated_string_extension)) {
1127  ASSERT_TRUE(x == "test_range_based_for");
1128  }
1129  // Test one message field.
1130  for (auto& x : *message.MutableRepeatedExtension(
1131  unittest::repeated_nested_message_extension)) {
1132  x.set_bb(4321);
1133  }
1134  for (const auto& x : *message.MutableRepeatedExtension(
1135  unittest::repeated_nested_message_extension)) {
1136  ASSERT_EQ(x.bb(), 4321);
1137  }
1138 }
1139 
1140 // From b/12926163
1141 TEST(ExtensionSetTest, AbsentExtension) {
1142  unittest::TestAllExtensions message;
1143  message.MutableRepeatedExtension(unittest::repeated_nested_message_extension)
1144  ->Add()
1145  ->set_bb(123);
1146  ASSERT_EQ(1,
1147  message.ExtensionSize(unittest::repeated_nested_message_extension));
1148  EXPECT_EQ(123,
1149  message.GetExtension(unittest::repeated_nested_message_extension, 0)
1150  .bb());
1151 }
1152 
1153 #ifdef PROTOBUF_HAS_DEATH_TEST
1154 
1155 TEST(ExtensionSetTest, InvalidEnumDeath) {
1156  unittest::TestAllExtensions message;
1157  EXPECT_DEBUG_DEATH(
1158  message.SetExtension(unittest::optional_foreign_enum_extension,
1159  static_cast<unittest::ForeignEnum>(53)),
1160  "IsValid");
1161 }
1162 
1163 #endif // PROTOBUF_HAS_DEATH_TEST
1164 
1165 TEST(ExtensionSetTest, DynamicExtensions) {
1166  // Test adding a dynamic extension to a compiled-in message object.
1167 
1168  FileDescriptorProto dynamic_proto;
1169  dynamic_proto.set_name("dynamic_extensions_test.proto");
1170  dynamic_proto.add_dependency(
1172  dynamic_proto.set_package("dynamic_extensions");
1173 
1174  // Copy the fields and nested types from TestDynamicExtensions into our new
1175  // proto, converting the fields into extensions.
1176  const Descriptor* template_descriptor =
1178  DescriptorProto template_descriptor_proto;
1179  template_descriptor->CopyTo(&template_descriptor_proto);
1180  dynamic_proto.mutable_message_type()->MergeFrom(
1181  template_descriptor_proto.nested_type());
1182  dynamic_proto.mutable_enum_type()->MergeFrom(
1183  template_descriptor_proto.enum_type());
1184  dynamic_proto.mutable_extension()->MergeFrom(
1185  template_descriptor_proto.field());
1186 
1187  // For each extension that we added...
1188  for (int i = 0; i < dynamic_proto.extension_size(); i++) {
1189  // Set its extendee to TestAllExtensions.
1190  FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i);
1191  extension->set_extendee(
1193 
1194  // If the field refers to one of the types nested in TestDynamicExtensions,
1195  // make it refer to the type in our dynamic proto instead.
1196  std::string prefix = "." + template_descriptor->full_name() + ".";
1197  if (extension->has_type_name()) {
1198  std::string* type_name = extension->mutable_type_name();
1199  if (HasPrefixString(*type_name, prefix)) {
1200  type_name->replace(0, prefix.size(), ".dynamic_extensions.");
1201  }
1202  }
1203  }
1204 
1205  // Now build the file, using the generated pool as an underlay.
1207  const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto);
1208  ASSERT_TRUE(file != nullptr);
1209  DynamicMessageFactory dynamic_factory(&dynamic_pool);
1210  dynamic_factory.SetDelegateToGeneratedFactory(true);
1211 
1212  // Construct a message that we can parse with the extensions we defined.
1213  // Since the extensions were based off of the fields of TestDynamicExtensions,
1214  // we can use that message to create this test message.
1215  std::string data;
1216  unittest::TestDynamicExtensions dynamic_extension;
1217  {
1218  unittest::TestDynamicExtensions message;
1219  message.set_scalar_extension(123);
1220  message.set_enum_extension(unittest::FOREIGN_BAR);
1221  message.set_dynamic_enum_extension(
1222  unittest::TestDynamicExtensions::DYNAMIC_BAZ);
1223  message.mutable_message_extension()->set_c(456);
1224  message.mutable_dynamic_message_extension()->set_dynamic_field(789);
1225  message.add_repeated_extension("foo");
1226  message.add_repeated_extension("bar");
1227  message.add_packed_extension(12);
1228  message.add_packed_extension(-34);
1229  message.add_packed_extension(56);
1230  message.add_packed_extension(-78);
1231 
1232  // Also add some unknown fields.
1233 
1234  // An unknown enum value (for a known field).
1235  message.mutable_unknown_fields()->AddVarint(
1236  unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber,
1237  12345);
1238  // A regular unknown field.
1239  message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown");
1240 
1241  message.SerializeToString(&data);
1242  dynamic_extension = message;
1243  }
1244 
1245  // Now we can parse this using our dynamic extension definitions...
1246  unittest::TestAllExtensions message;
1247  {
1248  io::ArrayInputStream raw_input(data.data(), data.size());
1250  input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
1251  ASSERT_TRUE(message.ParseFromCodedStream(&input));
1252  ASSERT_TRUE(input.ConsumedEntireMessage());
1253  }
1254 
1255  // Can we print it?
1256  EXPECT_EQ(
1257  "[dynamic_extensions.scalar_extension]: 123\n"
1258  "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n"
1259  "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n"
1260  "[dynamic_extensions.message_extension] {\n"
1261  " c: 456\n"
1262  "}\n"
1263  "[dynamic_extensions.dynamic_message_extension] {\n"
1264  " dynamic_field: 789\n"
1265  "}\n"
1266  "[dynamic_extensions.repeated_extension]: \"foo\"\n"
1267  "[dynamic_extensions.repeated_extension]: \"bar\"\n"
1268  "[dynamic_extensions.packed_extension]: 12\n"
1269  "[dynamic_extensions.packed_extension]: -34\n"
1270  "[dynamic_extensions.packed_extension]: 56\n"
1271  "[dynamic_extensions.packed_extension]: -78\n"
1272  "2002: 12345\n"
1273  "54321: \"unknown\"\n",
1274  message.DebugString());
1275 
1276  // Can we serialize it?
1277  EXPECT_TRUE(
1278  EqualsToSerialized(dynamic_extension, message.SerializeAsString()));
1279 
1280  // What if we parse using the reflection-based parser?
1281  {
1282  unittest::TestAllExtensions message2;
1283  io::ArrayInputStream raw_input(data.data(), data.size());
1285  input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
1287  ASSERT_TRUE(input.ConsumedEntireMessage());
1288  EXPECT_EQ(message.DebugString(), message2.DebugString());
1289  }
1290 
1291  // Are the embedded generated types actually using the generated objects?
1292  {
1293  const FieldDescriptor* message_extension =
1294  file->FindExtensionByName("message_extension");
1295  ASSERT_TRUE(message_extension != nullptr);
1296  const Message& sub_message =
1297  message.GetReflection()->GetMessage(message, message_extension);
1298  const unittest::ForeignMessage* typed_sub_message =
1299 #if PROTOBUF_RTTI
1300  dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
1301 #else
1302  static_cast<const unittest::ForeignMessage*>(&sub_message);
1303 #endif
1304  ASSERT_TRUE(typed_sub_message != nullptr);
1305  EXPECT_EQ(456, typed_sub_message->c());
1306  }
1307 
1308  // What does GetMessage() return for the embedded dynamic type if it isn't
1309  // present?
1310  {
1311  const FieldDescriptor* dynamic_message_extension =
1312  file->FindExtensionByName("dynamic_message_extension");
1313  ASSERT_TRUE(dynamic_message_extension != nullptr);
1314  const Message& parent = unittest::TestAllExtensions::default_instance();
1315  const Message& sub_message = parent.GetReflection()->GetMessage(
1316  parent, dynamic_message_extension, &dynamic_factory);
1317  const Message* prototype =
1318  dynamic_factory.GetPrototype(dynamic_message_extension->message_type());
1319  EXPECT_EQ(prototype, &sub_message);
1320  }
1321 }
1322 
1323 TEST(ExtensionSetTest, BoolExtension) {
1324  unittest::TestAllExtensions msg;
1325  uint8 wire_bytes[2] = {13 * 8, 42 /* out of bounds payload for bool */};
1326  EXPECT_TRUE(msg.ParseFromArray(wire_bytes, 2));
1327  EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension));
1328 }
1329 
1330 TEST(ExtensionSetTest, ConstInit) {
1331  PROTOBUF_CONSTINIT static ExtensionSet set{};
1332  EXPECT_EQ(set.NumExtensions(), 0);
1333 }
1334 
1335 } // namespace
1336 } // namespace internal
1337 } // namespace protobuf
1338 } // namespace google
google::protobuf::RepeatedPtrField< std::string >::iterator
internal::RepeatedPtrIterator< std::string > iterator
Definition: bloaty/third_party/protobuf/src/google/protobuf/repeated_field.h:861
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
Arena
struct Arena Arena
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/arena.h:189
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2001
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
begin
char * begin
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1007
google::protobuf::int64
int64_t int64
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:151
tests.google.protobuf.internal.test_util.SetAllExtensions
def SetAllExtensions(message)
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:187
google::protobuf::uint8
uint8_t uint8
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:153
grpc::testing::sum
double sum(const T &container, F functor)
Definition: test/cpp/qps/stats.h:30
google::protobuf::python::cmessage::CopyFrom
static PyObject * CopyFrom(CMessage *self, PyObject *arg)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/message.cc:1862
Arena
Definition: arena.c:39
FieldDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1851
FileDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:128
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::uint32
uint32_t uint32
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:155
google::protobuf::TestUtil::EqualsToSerialized
bool EqualsToSerialized(const ProtoType &message, const std::string &data)
Definition: bloaty/third_party/protobuf/src/google/protobuf/test_util2.h:72
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
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
FileDescriptorProto::add_dependency
std::string * add_dependency()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7505
setup.name
name
Definition: setup.py:542
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
EXPECT_LE
#define EXPECT_LE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2030
FileDescriptorProto::mutable_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_extension(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7790
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
T
#define T(upbtypeconst, upbtype, ctype, default_value)
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
tests.google.protobuf.internal.test_util.SetAllFields
def SetAllFields(message)
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:182
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
FieldDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:133
google::protobuf::int32
int32_t int32
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:150
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
DescriptorProto::enum_type
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto & enum_type(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8472
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
FileDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7325
TEST_SCALAR_EXTENSIONS_SPACE_USED
#define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value)
FileDescriptorProto::set_package
void set_package(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7418
grpc::protobuf::io::CodedInputStream
GRPC_CUSTOM_CODEDINPUTSTREAM CodedInputStream
Definition: include/grpcpp/impl/codegen/config_protobuf.h:102
FileDescriptorProto::mutable_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * mutable_enum_type(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7712
google::protobuf::uint64
uint64_t uint64
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:156
tests.google.protobuf.internal.test_util.ExpectAllFieldsSet
def ExpectAllFieldsSet(test_case, message)
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:367
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
google::protobuf::RepeatedPtrField< std::string >::const_iterator
internal::RepeatedPtrIterator< const std::string > const_iterator
Definition: bloaty/third_party/protobuf/src/google/protobuf/repeated_field.h:862
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
add_person.raw_input
raw_input
Definition: bloaty/third_party/protobuf/examples/add_person.py:11
grpc::protobuf::io::CodedOutputStream
GRPC_CUSTOM_CODEDOUTPUTSTREAM CodedOutputStream
Definition: src/compiler/config.h:55
google::protobuf::string_as_array
char * string_as_array(string *str)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stl_util.h:63
FileDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:501
google::protobuf::HasPrefixString
bool HasPrefixString(const string &str, const string &prefix)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:115
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
FileDescriptorProto::mutable_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * mutable_message_type(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7673
TEST_REPEATED_EXTENSIONS_SPACE_USED
#define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value)
google::protobuf.internal.python_message.Clear
Clear
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:1430
FileDescriptorProto::extension_size
int extension_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7784
profile_analyzer.fields
list fields
Definition: profile_analyzer.py:266
google::protobuf::DescriptorPool::generated_pool
static const DescriptorPool * generated_pool()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1326
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
cpp.gmock_class.set
set
Definition: bloaty/third_party/googletest/googlemock/scripts/generator/cpp/gmock_class.py:44
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
ASSERT_FALSE
#define ASSERT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1976
DescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1312
google::protobuf.internal::WireFormat::ParseAndMergePartial
static bool ParseAndMergePartial(io::CodedInputStream *input, Message *message)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format.cc:331
google::protobuf.internal::TEST
TEST(GeneratedMapFieldTest, Accessors)
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/map_test.cc:1847
google::protobuf.internal.python_message.IsInitialized
IsInitialized
Definition: bloaty/third_party/protobuf/python/google/protobuf/internal/python_message.py:1245
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
internal
Definition: benchmark/test/output_test_helper.cc:20
google::protobuf.internal::kRepeatedFieldLowerClampLimit
constexpr int kRepeatedFieldLowerClampLimit
Definition: protobuf/src/google/protobuf/repeated_field.h:86
iter
Definition: test_winkernel.cpp:47
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
DescriptorPool
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:110
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
DescriptorProto::nested_type
const PROTOBUF_NAMESPACE_ID::DescriptorProto & nested_type(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8433
Message
Definition: protobuf/php/ext/google/protobuf/message.c:53
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
type_name
static const char * type_name(int type)
Definition: adig.c:889
DescriptorProto::field
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & field(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8355
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056
RepeatedField
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:403


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