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 
36 
40 #include <google/protobuf/unittest.pb.h>
41 #include <google/protobuf/unittest_mset.pb.h>
45 #include <google/protobuf/arena.h>
50 
54 #include <gtest/gtest.h>
56 
57 
58 namespace google {
59 namespace protobuf {
60 namespace internal {
61 namespace {
62 
64 
65 // This test closely mirrors net/proto2/compiler/cpp/internal/unittest.cc
66 // except that it uses extensions rather than regular fields.
67 
68 TEST(ExtensionSetTest, Defaults) {
69  // Check that all default values are set correctly in the initial message.
70  unittest::TestAllExtensions message;
71 
72  TestUtil::ExpectExtensionsClear(message);
73 
74  // Messages should return pointers to default instances until first use.
75  // (This is not checked by ExpectClear() since it is not actually true after
76  // the fields have been set and then cleared.)
77  EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(),
78  &message.GetExtension(unittest::optionalgroup_extension));
79  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
80  &message.GetExtension(unittest::optional_nested_message_extension));
81  EXPECT_EQ(
82  &unittest::ForeignMessage::default_instance(),
83  &message.GetExtension(unittest::optional_foreign_message_extension));
84  EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
85  &message.GetExtension(unittest::optional_import_message_extension));
86 }
87 
88 TEST(ExtensionSetTest, Accessors) {
89  // Set every field to a unique value then go back and check all those
90  // values.
91  unittest::TestAllExtensions message;
92 
94  TestUtil::ExpectAllExtensionsSet(message);
95 
96  TestUtil::ModifyRepeatedExtensions(&message);
97  TestUtil::ExpectRepeatedExtensionsModified(message);
98 }
99 
100 TEST(ExtensionSetTest, Clear) {
101  // Set every field to a unique value, clear the message, then check that
102  // it is cleared.
103  unittest::TestAllExtensions message;
104 
106  message.Clear();
107  TestUtil::ExpectExtensionsClear(message);
108 
109  // Unlike with the defaults test, we do NOT expect that requesting embedded
110  // messages will return a pointer to the default instance. Instead, they
111  // should return the objects that were created when mutable_blah() was
112  // called.
113  EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
114  &message.GetExtension(unittest::optionalgroup_extension));
115  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
116  &message.GetExtension(unittest::optional_nested_message_extension));
117  EXPECT_NE(
118  &unittest::ForeignMessage::default_instance(),
119  &message.GetExtension(unittest::optional_foreign_message_extension));
120  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
121  &message.GetExtension(unittest::optional_import_message_extension));
122 
123  // Make sure setting stuff again after clearing works. (This takes slightly
124  // different code paths since the objects are reused.)
126  TestUtil::ExpectAllExtensionsSet(message);
127 }
128 
129 TEST(ExtensionSetTest, ClearOneField) {
130  // Set every field to a unique value, then clear one value and insure that
131  // only that one value is cleared.
132  unittest::TestAllExtensions message;
133 
135  int64 original_value =
136  message.GetExtension(unittest::optional_int64_extension);
137 
138  // Clear the field and make sure it shows up as cleared.
139  message.ClearExtension(unittest::optional_int64_extension);
140  EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
141  EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
142 
143  // Other adjacent fields should not be cleared.
144  EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
145  EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
146 
147  // Make sure if we set it again, then all fields are set.
148  message.SetExtension(unittest::optional_int64_extension, original_value);
149  TestUtil::ExpectAllExtensionsSet(message);
150 }
151 
152 TEST(ExtensionSetTest, SetAllocatedExtension) {
153  unittest::TestAllExtensions message;
154  EXPECT_FALSE(
155  message.HasExtension(unittest::optional_foreign_message_extension));
156  // Add a extension using SetAllocatedExtension
157  unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
158  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
159  foreign_message);
160  EXPECT_TRUE(
161  message.HasExtension(unittest::optional_foreign_message_extension));
162  EXPECT_EQ(foreign_message, message.MutableExtension(
163  unittest::optional_foreign_message_extension));
164  EXPECT_EQ(foreign_message, &message.GetExtension(
165  unittest::optional_foreign_message_extension));
166 
167  // SetAllocatedExtension should delete the previously existing extension.
168  // (We reply on unittest to check memory leaks for this case)
169  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
170  new unittest::ForeignMessage());
171 
172  // SetAllocatedExtension with a NULL parameter is equivalent to ClearExtenion.
173  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
174  NULL);
175  EXPECT_FALSE(
176  message.HasExtension(unittest::optional_foreign_message_extension));
177 }
178 
179 TEST(ExtensionSetTest, ReleaseExtension) {
180  proto2_wireformat_unittest::TestMessageSet message;
181  EXPECT_FALSE(message.HasExtension(
182  unittest::TestMessageSetExtension1::message_set_extension));
183  // Add a extension using SetAllocatedExtension
184  unittest::TestMessageSetExtension1* extension =
185  new unittest::TestMessageSetExtension1();
186  message.SetAllocatedExtension(
187  unittest::TestMessageSetExtension1::message_set_extension, extension);
188  EXPECT_TRUE(message.HasExtension(
189  unittest::TestMessageSetExtension1::message_set_extension));
190  // Release the extension using ReleaseExtension
191  unittest::TestMessageSetExtension1* released_extension =
192  message.ReleaseExtension(
193  unittest::TestMessageSetExtension1::message_set_extension);
194  EXPECT_EQ(extension, released_extension);
195  EXPECT_FALSE(message.HasExtension(
196  unittest::TestMessageSetExtension1::message_set_extension));
197  // ReleaseExtension will return the underlying object even after
198  // ClearExtension is called.
199  message.SetAllocatedExtension(
200  unittest::TestMessageSetExtension1::message_set_extension, extension);
201  message.ClearExtension(
202  unittest::TestMessageSetExtension1::message_set_extension);
203  released_extension = message.ReleaseExtension(
204  unittest::TestMessageSetExtension1::message_set_extension);
205  EXPECT_TRUE(released_extension != NULL);
206  delete released_extension;
207 }
208 
209 TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) {
210  Arena arena;
211  unittest::TestAllExtensions* message =
212  Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
213  unittest::ForeignMessage extension;
214  message->UnsafeArenaSetAllocatedExtension(
215  unittest::optional_foreign_message_extension, &extension);
216  // No copy when set.
217  unittest::ForeignMessage* mutable_extension =
218  message->MutableExtension(unittest::optional_foreign_message_extension);
219  EXPECT_EQ(&extension, mutable_extension);
220  // No copy when unsafe released.
221  unittest::ForeignMessage* released_extension =
222  message->UnsafeArenaReleaseExtension(
223  unittest::optional_foreign_message_extension);
224  EXPECT_EQ(&extension, released_extension);
225  EXPECT_FALSE(
226  message->HasExtension(unittest::optional_foreign_message_extension));
227  // Set the ownership back and let the destructors run. It should not take
228  // ownership, so this should not crash.
229  message->UnsafeArenaSetAllocatedExtension(
230  unittest::optional_foreign_message_extension, &extension);
231 }
232 
233 TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) {
234  unittest::TestAllExtensions message;
235  unittest::ForeignMessage* extension = new unittest::ForeignMessage();
236  message.UnsafeArenaSetAllocatedExtension(
237  unittest::optional_foreign_message_extension, extension);
238  // No copy when set.
239  unittest::ForeignMessage* mutable_extension =
240  message.MutableExtension(unittest::optional_foreign_message_extension);
241  EXPECT_EQ(extension, mutable_extension);
242  // No copy when unsafe released.
243  unittest::ForeignMessage* released_extension =
244  message.UnsafeArenaReleaseExtension(
245  unittest::optional_foreign_message_extension);
246  EXPECT_EQ(extension, released_extension);
247  EXPECT_FALSE(
248  message.HasExtension(unittest::optional_foreign_message_extension));
249  // Set the ownership back and let the destructors run. It should take
250  // ownership, so this should not leak.
251  message.UnsafeArenaSetAllocatedExtension(
252  unittest::optional_foreign_message_extension, extension);
253 }
254 
255 TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) {
256  Arena arena;
257  unittest::TestAllExtensions* message =
258  Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
259  unittest::ForeignMessage* extension = new unittest::ForeignMessage;
260  message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
261  extension);
262  // The arena should maintain ownership of the heap allocated proto because we
263  // used UnsafeArenaReleaseExtension. The leak checker will ensure this.
264  unittest::ForeignMessage* released_extension =
265  message->UnsafeArenaReleaseExtension(
266  unittest::optional_foreign_message_extension);
267  EXPECT_EQ(extension, released_extension);
268  EXPECT_FALSE(
269  message->HasExtension(unittest::optional_foreign_message_extension));
270 }
271 
272 
273 TEST(ExtensionSetTest, CopyFrom) {
274  unittest::TestAllExtensions message1, message2;
275 
276  TestUtil::SetAllExtensions(&message1);
277  message2.CopyFrom(message1);
278  TestUtil::ExpectAllExtensionsSet(message2);
279  message2.CopyFrom(message1); // exercise copy when fields already exist
280  TestUtil::ExpectAllExtensionsSet(message2);
281 }
282 
283 TEST(ExtensionSetTest, CopyFromPacked) {
284  unittest::TestPackedExtensions message1, message2;
285 
286  TestUtil::SetPackedExtensions(&message1);
287  message2.CopyFrom(message1);
288  TestUtil::ExpectPackedExtensionsSet(message2);
289  message2.CopyFrom(message1); // exercise copy when fields already exist
290  TestUtil::ExpectPackedExtensionsSet(message2);
291 }
292 
293 TEST(ExtensionSetTest, CopyFromUpcasted) {
294  unittest::TestAllExtensions message1, message2;
295  const Message& upcasted_message = message1;
296 
297  TestUtil::SetAllExtensions(&message1);
298  message2.CopyFrom(upcasted_message);
299  TestUtil::ExpectAllExtensionsSet(message2);
300  // exercise copy when fields already exist
301  message2.CopyFrom(upcasted_message);
302  TestUtil::ExpectAllExtensionsSet(message2);
303 }
304 
305 TEST(ExtensionSetTest, SwapWithEmpty) {
306  unittest::TestAllExtensions message1, message2;
307  TestUtil::SetAllExtensions(&message1);
308 
309  TestUtil::ExpectAllExtensionsSet(message1);
310  TestUtil::ExpectExtensionsClear(message2);
311  message1.Swap(&message2);
312  TestUtil::ExpectAllExtensionsSet(message2);
313  TestUtil::ExpectExtensionsClear(message1);
314 }
315 
316 TEST(ExtensionSetTest, SwapWithSelf) {
317  unittest::TestAllExtensions message;
319 
320  TestUtil::ExpectAllExtensionsSet(message);
321  message.Swap(&message);
322  TestUtil::ExpectAllExtensionsSet(message);
323 }
324 
325 TEST(ExtensionSetTest, SwapExtension) {
326  unittest::TestAllExtensions message1;
327  unittest::TestAllExtensions message2;
328 
329  TestUtil::SetAllExtensions(&message1);
330  std::vector<const FieldDescriptor*> fields;
331 
332  // Swap empty fields.
333  const Reflection* reflection = message1.GetReflection();
334  reflection->SwapFields(&message1, &message2, fields);
335  TestUtil::ExpectAllExtensionsSet(message1);
336  TestUtil::ExpectExtensionsClear(message2);
337 
338  // Swap two extensions.
339  fields.push_back(reflection->FindKnownExtensionByNumber(12));
340  fields.push_back(reflection->FindKnownExtensionByNumber(25));
341  reflection->SwapFields(&message1, &message2, fields);
342 
343  EXPECT_TRUE(message1.HasExtension(unittest::optional_int32_extension));
344  EXPECT_FALSE(message1.HasExtension(unittest::optional_double_extension));
345  EXPECT_FALSE(message1.HasExtension(unittest::optional_cord_extension));
346 
347  EXPECT_FALSE(message2.HasExtension(unittest::optional_int32_extension));
348  EXPECT_TRUE(message2.HasExtension(unittest::optional_double_extension));
349  EXPECT_TRUE(message2.HasExtension(unittest::optional_cord_extension));
350 }
351 
352 TEST(ExtensionSetTest, SwapExtensionWithEmpty) {
353  unittest::TestAllExtensions message1;
354  unittest::TestAllExtensions message2;
355  unittest::TestAllExtensions message3;
356 
357  TestUtil::SetAllExtensions(&message3);
358 
359  const Reflection* reflection = message3.GetReflection();
360  std::vector<const FieldDescriptor*> fields;
361  reflection->ListFields(message3, &fields);
362 
363  reflection->SwapFields(&message1, &message2, fields);
364 
365  TestUtil::ExpectExtensionsClear(message1);
366  TestUtil::ExpectExtensionsClear(message2);
367 }
368 
369 TEST(ExtensionSetTest, SwapExtensionBothFull) {
370  unittest::TestAllExtensions message1;
371  unittest::TestAllExtensions message2;
372 
373  TestUtil::SetAllExtensions(&message1);
374  TestUtil::SetAllExtensions(&message2);
375 
376  const Reflection* reflection = message1.GetReflection();
377  std::vector<const FieldDescriptor*> fields;
378  reflection->ListFields(message1, &fields);
379 
380  reflection->SwapFields(&message1, &message2, fields);
381 
382  TestUtil::ExpectAllExtensionsSet(message1);
383  TestUtil::ExpectAllExtensionsSet(message2);
384 }
385 
386 TEST(ExtensionSetTest, ArenaSetAllExtension) {
387  Arena arena1;
388  unittest::TestAllExtensions* message1 =
389  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
390  TestUtil::SetAllExtensions(message1);
391  TestUtil::ExpectAllExtensionsSet(*message1);
392 }
393 
394 TEST(ExtensionSetTest, ArenaCopyConstructor) {
395  Arena arena1;
396  unittest::TestAllExtensions* message1 =
397  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
398  TestUtil::SetAllExtensions(message1);
399  unittest::TestAllExtensions message2(*message1);
400  arena1.Reset();
401  TestUtil::ExpectAllExtensionsSet(message2);
402 }
403 
404 TEST(ExtensionSetTest, ArenaMergeFrom) {
405  Arena arena1;
406  unittest::TestAllExtensions* message1 =
407  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
408  TestUtil::SetAllExtensions(message1);
409  unittest::TestAllExtensions message2;
410  message2.MergeFrom(*message1);
411  arena1.Reset();
412  TestUtil::ExpectAllExtensionsSet(message2);
413 }
414 
415 TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) {
416  Arena arena;
417  unittest::TestAllExtensions* message =
418  Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
419  EXPECT_FALSE(
420  message->HasExtension(unittest::optional_foreign_message_extension));
421  // Add a extension using SetAllocatedExtension
422  unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
423  message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
424  foreign_message);
425  // foreign_message is now owned by the arena.
426  EXPECT_EQ(foreign_message, message->MutableExtension(
427  unittest::optional_foreign_message_extension));
428 
429  // Underlying message is copied, and returned.
430  unittest::ForeignMessage* released_message =
431  message->ReleaseExtension(unittest::optional_foreign_message_extension);
432  delete released_message;
433  EXPECT_FALSE(
434  message->HasExtension(unittest::optional_foreign_message_extension));
435 }
436 
437 TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) {
438  Arena arena1;
439  std::unique_ptr<Arena> arena2(new Arena());
440 
441  unittest::TestAllExtensions* message1 =
442  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
443  unittest::TestAllExtensions* message2 =
444  Arena::CreateMessage<unittest::TestAllExtensions>(arena2.get());
445 
446  TestUtil::SetAllExtensions(message1);
447  TestUtil::SetAllExtensions(message2);
448  message1->SetExtension(unittest::optional_int32_extension, 1);
449  message2->SetExtension(unittest::optional_int32_extension, 2);
450  message1->Swap(message2);
451  EXPECT_EQ(2, message1->GetExtension(unittest::optional_int32_extension));
452  EXPECT_EQ(1, message2->GetExtension(unittest::optional_int32_extension));
453  // Re-set the original values so ExpectAllExtensionsSet is happy.
454  message1->SetExtension(unittest::optional_int32_extension, 101);
455  message2->SetExtension(unittest::optional_int32_extension, 101);
456  TestUtil::ExpectAllExtensionsSet(*message1);
457  TestUtil::ExpectAllExtensionsSet(*message2);
458  arena2.reset(NULL);
459  TestUtil::ExpectAllExtensionsSet(*message1);
460  // Test corner cases, when one is empty and other is not.
461  Arena arena3, arena4;
462 
463  unittest::TestAllExtensions* message3 =
464  Arena::CreateMessage<unittest::TestAllExtensions>(&arena3);
465  unittest::TestAllExtensions* message4 =
466  Arena::CreateMessage<unittest::TestAllExtensions>(&arena4);
467  TestUtil::SetAllExtensions(message3);
468  message3->Swap(message4);
469  arena3.Reset();
470  TestUtil::ExpectAllExtensionsSet(*message4);
471 }
472 
473 TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) {
474  Arena arena1;
475  Arena* arena2 = new Arena();
476 
477  unittest::TestAllExtensions* message1 =
478  Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
479  unittest::TestAllExtensions* message2 =
480  Arena::CreateMessage<unittest::TestAllExtensions>(arena2);
481 
482  TestUtil::SetAllExtensions(message1);
483  TestUtil::SetAllExtensions(message2);
484 
485  const Reflection* reflection = message1->GetReflection();
486  std::vector<const FieldDescriptor*> fields;
487  reflection->ListFields(*message1, &fields);
488  reflection->SwapFields(message1, message2, fields);
489  TestUtil::ExpectAllExtensionsSet(*message1);
490  TestUtil::ExpectAllExtensionsSet(*message2);
491  delete arena2;
492  TestUtil::ExpectAllExtensionsSet(*message1);
493 }
494 
495 TEST(ExtensionSetTest, SwapExtensionWithSelf) {
496  unittest::TestAllExtensions message1;
497 
498  TestUtil::SetAllExtensions(&message1);
499 
500  std::vector<const FieldDescriptor*> fields;
501  const Reflection* reflection = message1.GetReflection();
502  reflection->ListFields(message1, &fields);
503  reflection->SwapFields(&message1, &message1, fields);
504 
505  TestUtil::ExpectAllExtensionsSet(message1);
506 }
507 
508 TEST(ExtensionSetTest, SerializationToArray) {
509  // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
510  // compatibility of extensions.
511  //
512  // This checks serialization to a flat array by explicitly reserving space in
513  // the string and calling the generated message's
514  // SerializeWithCachedSizesToArray.
515  unittest::TestAllExtensions source;
516  unittest::TestAllTypes destination;
518  int size = source.ByteSize();
520  data.resize(size);
521  uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
522  uint8* end = source.SerializeWithCachedSizesToArray(target);
523  EXPECT_EQ(size, end - target);
524  EXPECT_TRUE(destination.ParseFromString(data));
525  TestUtil::ExpectAllFieldsSet(destination);
526 }
527 
528 TEST(ExtensionSetTest, SerializationToStream) {
529  // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
530  // compatibility of extensions.
531  //
532  // This checks serialization to an output stream by creating an array output
533  // stream that can only buffer 1 byte at a time - this prevents the message
534  // from ever jumping to the fast path, ensuring that serialization happens via
535  // the CodedOutputStream.
536  unittest::TestAllExtensions source;
537  unittest::TestAllTypes destination;
539  int size = source.ByteSize();
541  data.resize(size);
542  {
543  io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
544  io::CodedOutputStream output_stream(&array_stream);
545  source.SerializeWithCachedSizes(&output_stream);
546  ASSERT_FALSE(output_stream.HadError());
547  }
548  EXPECT_TRUE(destination.ParseFromString(data));
549  TestUtil::ExpectAllFieldsSet(destination);
550 }
551 
552 TEST(ExtensionSetTest, PackedSerializationToArray) {
553  // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
554  // wire compatibility of extensions.
555  //
556  // This checks serialization to a flat array by explicitly reserving space in
557  // the string and calling the generated message's
558  // SerializeWithCachedSizesToArray.
559  unittest::TestPackedExtensions source;
560  unittest::TestPackedTypes destination;
561  TestUtil::SetPackedExtensions(&source);
562  int size = source.ByteSize();
564  data.resize(size);
565  uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
566  uint8* end = source.SerializeWithCachedSizesToArray(target);
567  EXPECT_EQ(size, end - target);
568  EXPECT_TRUE(destination.ParseFromString(data));
569  TestUtil::ExpectPackedFieldsSet(destination);
570 }
571 
572 TEST(ExtensionSetTest, PackedSerializationToStream) {
573  // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
574  // wire compatibility of extensions.
575  //
576  // This checks serialization to an output stream by creating an array output
577  // stream that can only buffer 1 byte at a time - this prevents the message
578  // from ever jumping to the fast path, ensuring that serialization happens via
579  // the CodedOutputStream.
580  unittest::TestPackedExtensions source;
581  unittest::TestPackedTypes destination;
582  TestUtil::SetPackedExtensions(&source);
583  int size = source.ByteSize();
585  data.resize(size);
586  {
587  io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
588  io::CodedOutputStream output_stream(&array_stream);
589  source.SerializeWithCachedSizes(&output_stream);
590  ASSERT_FALSE(output_stream.HadError());
591  }
592  EXPECT_TRUE(destination.ParseFromString(data));
593  TestUtil::ExpectPackedFieldsSet(destination);
594 }
595 
596 TEST(ExtensionSetTest, NestedExtensionGroup) {
597  // Serialize as TestGroup and parse as TestGroupExtension.
598  unittest::TestGroup source;
599  unittest::TestGroupExtension destination;
601 
602  source.mutable_optionalgroup()->set_a(117);
603  source.set_optional_foreign_enum(unittest::FOREIGN_BAZ);
604  source.SerializeToString(&data);
605  EXPECT_TRUE(destination.ParseFromString(data));
606  EXPECT_TRUE(
607  destination
608  .GetExtension(unittest::TestNestedExtension::optionalgroup_extension)
609  .has_a());
610  EXPECT_EQ(117, destination
611  .GetExtension(
612  unittest::TestNestedExtension::optionalgroup_extension)
613  .a());
614  EXPECT_TRUE(destination.HasExtension(
615  unittest::TestNestedExtension::optional_foreign_enum_extension));
616  EXPECT_EQ(
617  unittest::FOREIGN_BAZ,
618  destination.GetExtension(
619  unittest::TestNestedExtension::optional_foreign_enum_extension));
620 }
621 
622 TEST(ExtensionSetTest, Parsing) {
623  // Serialize as TestAllTypes and parse as TestAllExtensions.
624  unittest::TestAllTypes source;
625  unittest::TestAllExtensions destination;
627 
629  source.SerializeToString(&data);
630  EXPECT_TRUE(destination.ParseFromString(data));
631  TestUtil::SetOneofFields(&destination);
632  TestUtil::ExpectAllExtensionsSet(destination);
633 }
634 
635 TEST(ExtensionSetTest, PackedParsing) {
636  // Serialize as TestPackedTypes and parse as TestPackedExtensions.
637  unittest::TestPackedTypes source;
638  unittest::TestPackedExtensions destination;
640 
641  TestUtil::SetPackedFields(&source);
642  source.SerializeToString(&data);
643  EXPECT_TRUE(destination.ParseFromString(data));
644  TestUtil::ExpectPackedExtensionsSet(destination);
645 }
646 
647 TEST(ExtensionSetTest, PackedToUnpackedParsing) {
648  unittest::TestPackedTypes source;
649  unittest::TestUnpackedExtensions destination;
651 
652  TestUtil::SetPackedFields(&source);
653  source.SerializeToString(&data);
654  EXPECT_TRUE(destination.ParseFromString(data));
655  TestUtil::ExpectUnpackedExtensionsSet(destination);
656 
657  // Reserialize
658  unittest::TestUnpackedTypes unpacked;
659  TestUtil::SetUnpackedFields(&unpacked);
660  // Serialized proto has to be the same size and parsed to the same message.
661  EXPECT_EQ(unpacked.SerializeAsString().size(),
662  destination.SerializeAsString().size());
663  EXPECT_TRUE(EqualsToSerialized(unpacked, destination.SerializeAsString()));
664 
665  // Make sure we can add extensions.
666  destination.AddExtension(unittest::unpacked_int32_extension, 1);
667  destination.AddExtension(unittest::unpacked_enum_extension,
668  protobuf_unittest::FOREIGN_BAR);
669 }
670 
671 TEST(ExtensionSetTest, UnpackedToPackedParsing) {
672  unittest::TestUnpackedTypes source;
673  unittest::TestPackedExtensions destination;
675 
676  TestUtil::SetUnpackedFields(&source);
677  source.SerializeToString(&data);
678  EXPECT_TRUE(destination.ParseFromString(data));
679  TestUtil::ExpectPackedExtensionsSet(destination);
680 
681  // Reserialize
682  unittest::TestPackedTypes packed;
683  TestUtil::SetPackedFields(&packed);
684  // Serialized proto has to be the same size and parsed to the same message.
685  EXPECT_EQ(packed.SerializeAsString().size(),
686  destination.SerializeAsString().size());
687  EXPECT_TRUE(EqualsToSerialized(packed, destination.SerializeAsString()));
688 
689  // Make sure we can add extensions.
690  destination.AddExtension(unittest::packed_int32_extension, 1);
691  destination.AddExtension(unittest::packed_enum_extension,
692  protobuf_unittest::FOREIGN_BAR);
693 }
694 
695 TEST(ExtensionSetTest, IsInitialized) {
696  // Test that IsInitialized() returns false if required fields in nested
697  // extensions are missing.
698  unittest::TestAllExtensions message;
699 
700  EXPECT_TRUE(message.IsInitialized());
701 
702  message.MutableExtension(unittest::TestRequired::single);
703  EXPECT_FALSE(message.IsInitialized());
704 
705  message.MutableExtension(unittest::TestRequired::single)->set_a(1);
706  EXPECT_FALSE(message.IsInitialized());
707  message.MutableExtension(unittest::TestRequired::single)->set_b(2);
708  EXPECT_FALSE(message.IsInitialized());
709  message.MutableExtension(unittest::TestRequired::single)->set_c(3);
710  EXPECT_TRUE(message.IsInitialized());
711 
712  message.AddExtension(unittest::TestRequired::multi);
713  EXPECT_FALSE(message.IsInitialized());
714 
715  message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
716  EXPECT_FALSE(message.IsInitialized());
717  message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
718  EXPECT_FALSE(message.IsInitialized());
719  message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
720  EXPECT_TRUE(message.IsInitialized());
721 }
722 
723 TEST(ExtensionSetTest, MutableString) {
724  // Test the mutable string accessors.
725  unittest::TestAllExtensions message;
726 
727  message.MutableExtension(unittest::optional_string_extension)->assign("foo");
728  EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
729  EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
730 
731  message.AddExtension(unittest::repeated_string_extension)->assign("bar");
732  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
733  EXPECT_EQ("bar",
734  message.GetExtension(unittest::repeated_string_extension, 0));
735 }
736 
737 TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
738  // Scalar primitive extensions should increase the extension set size by a
739  // minimum of the size of the primitive type.
740 #define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \
741  do { \
742  unittest::TestAllExtensions message; \
743  const int base_size = message.SpaceUsed(); \
744  message.SetExtension(unittest::optional_##type##_extension, value); \
745  int min_expected_size = \
746  base_size + \
747  sizeof(message.GetExtension(unittest::optional_##type##_extension)); \
748  EXPECT_LE(min_expected_size, message.SpaceUsed()); \
749  } while (0)
750 
757  TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32, 107);
758  TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64, 108);
759  TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
760  TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
764 #undef TEST_SCALAR_EXTENSIONS_SPACE_USED
765  {
766  unittest::TestAllExtensions message;
767  const int base_size = message.SpaceUsed();
768  message.SetExtension(unittest::optional_nested_enum_extension,
769  unittest::TestAllTypes::FOO);
770  int min_expected_size =
771  base_size +
772  sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
773  EXPECT_LE(min_expected_size, message.SpaceUsed());
774  }
775  {
776  // Strings may cause extra allocations depending on their length; ensure
777  // that gets included as well.
778  unittest::TestAllExtensions message;
779  const int base_size = message.SpaceUsed();
780  const std::string s(
781  "this is a fairly large string that will cause some "
782  "allocation in order to store it in the extension");
783  message.SetExtension(unittest::optional_string_extension, s);
784  int min_expected_size = base_size + s.length();
785  EXPECT_LE(min_expected_size, message.SpaceUsed());
786  }
787  {
788  // Messages also have additional allocation that need to be counted.
789  unittest::TestAllExtensions message;
790  const int base_size = message.SpaceUsed();
791  unittest::ForeignMessage foreign;
792  foreign.set_c(42);
793  message.MutableExtension(unittest::optional_foreign_message_extension)
794  ->CopyFrom(foreign);
795  int min_expected_size = base_size + foreign.SpaceUsed();
796  EXPECT_LE(min_expected_size, message.SpaceUsed());
797  }
798 
799  // Repeated primitive extensions will increase space used by at least a
800  // RepeatedField<T>, and will cause additional allocations when the array
801  // gets too big for the initial space.
802  // This macro:
803  // - Adds a value to the repeated extension, then clears it, establishing
804  // the base size.
805  // - Adds a small number of values, testing that it doesn't increase the
806  // SpaceUsed()
807  // - Adds a large number of values (requiring allocation in the repeated
808  // field), and ensures that that allocation is included in SpaceUsed()
809 #define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \
810  do { \
811  unittest::TestAllExtensions message; \
812  const int base_size = message.SpaceUsed(); \
813  int min_expected_size = sizeof(RepeatedField<cpptype>) + base_size; \
814  message.AddExtension(unittest::repeated_##type##_extension, value); \
815  message.ClearExtension(unittest::repeated_##type##_extension); \
816  const int empty_repeated_field_size = message.SpaceUsed(); \
817  EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \
818  message.AddExtension(unittest::repeated_##type##_extension, value); \
819  message.AddExtension(unittest::repeated_##type##_extension, value); \
820  EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type; \
821  message.ClearExtension(unittest::repeated_##type##_extension); \
822  const int old_capacity = \
823  message.GetRepeatedExtension(unittest::repeated_##type##_extension) \
824  .Capacity(); \
825  EXPECT_GE(old_capacity, kMinRepeatedFieldAllocationSize); \
826  for (int i = 0; i < 16; ++i) { \
827  message.AddExtension(unittest::repeated_##type##_extension, value); \
828  } \
829  int expected_size = \
830  sizeof(cpptype) * \
831  (message \
832  .GetRepeatedExtension(unittest::repeated_##type##_extension) \
833  .Capacity() - \
834  old_capacity) + \
835  empty_repeated_field_size; \
836  EXPECT_LE(expected_size, message.SpaceUsed()) << #type; \
837  } while (0)
838 
849  TEST_REPEATED_EXTENSIONS_SPACE_USED(float, float, 111);
850  TEST_REPEATED_EXTENSIONS_SPACE_USED(double, double, 112);
851  TEST_REPEATED_EXTENSIONS_SPACE_USED(bool, bool, true);
852  TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
853  unittest::TestAllTypes::FOO);
854 #undef TEST_REPEATED_EXTENSIONS_SPACE_USED
855  // Repeated strings
856  {
857  unittest::TestAllExtensions message;
858  const int base_size = message.SpaceUsed();
859  int min_expected_size = sizeof(RepeatedPtrField<std::string>) + base_size;
860  const std::string value(256, 'x');
861  // Once items are allocated, they may stick around even when cleared so
862  // without the hardcore memory management accessors there isn't a notion of
863  // the empty repeated field memory usage as there is with primitive types.
864  for (int i = 0; i < 16; ++i) {
865  message.AddExtension(unittest::repeated_string_extension, value);
866  }
867  min_expected_size +=
868  (sizeof(value) + value.size()) * (16 - kMinRepeatedFieldAllocationSize);
869  EXPECT_LE(min_expected_size, message.SpaceUsed());
870  }
871  // Repeated messages
872  {
873  unittest::TestAllExtensions message;
874  const int base_size = message.SpaceUsed();
875  int min_expected_size =
876  sizeof(RepeatedPtrField<unittest::ForeignMessage>) + base_size;
877  unittest::ForeignMessage prototype;
878  prototype.set_c(2);
879  for (int i = 0; i < 16; ++i) {
880  message.AddExtension(unittest::repeated_foreign_message_extension)
881  ->CopyFrom(prototype);
882  }
883  min_expected_size +=
884  (16 - kMinRepeatedFieldAllocationSize) * prototype.SpaceUsed();
885  EXPECT_LE(min_expected_size, message.SpaceUsed());
886  }
887 }
888 
889 // N.B.: We do not test range-based for here because we remain C++03 compatible.
890 template <typename T, typename M, typename ID>
891 inline T SumAllExtensions(const M& message, ID extension, T zero) {
892  T sum = zero;
893  typename RepeatedField<T>::const_iterator iter =
894  message.GetRepeatedExtension(extension).begin();
896  message.GetRepeatedExtension(extension).end();
897  for (; iter != end; ++iter) {
898  sum += *iter;
899  }
900  return sum;
901 }
902 
903 template <typename T, typename M, typename ID>
904 inline void IncAllExtensions(M* message, ID extension, T val) {
905  typename RepeatedField<T>::iterator iter =
906  message->MutableRepeatedExtension(extension)->begin();
908  message->MutableRepeatedExtension(extension)->end();
909  for (; iter != end; ++iter) {
910  *iter += val;
911  }
912 }
913 
914 TEST(ExtensionSetTest, RepeatedFields) {
915  unittest::TestAllExtensions message;
916 
917  // Test empty repeated-field case (b/12926163)
918  ASSERT_EQ(
919  0,
920  message.GetRepeatedExtension(unittest::repeated_int32_extension).size());
921  ASSERT_EQ(
922  0, message.GetRepeatedExtension(unittest::repeated_nested_enum_extension)
923  .size());
924  ASSERT_EQ(
925  0,
926  message.GetRepeatedExtension(unittest::repeated_string_extension).size());
927  ASSERT_EQ(
928  0,
929  message.GetRepeatedExtension(unittest::repeated_nested_message_extension)
930  .size());
931 
932  unittest::TestAllTypes::NestedMessage nested_message;
933  nested_message.set_bb(42);
934  unittest::TestAllTypes::NestedEnum nested_enum =
935  unittest::TestAllTypes::NestedEnum_MIN;
936 
937  for (int i = 0; i < 10; ++i) {
938  message.AddExtension(unittest::repeated_int32_extension, 1);
939  message.AddExtension(unittest::repeated_int64_extension, 2);
940  message.AddExtension(unittest::repeated_uint32_extension, 3);
941  message.AddExtension(unittest::repeated_uint64_extension, 4);
942  message.AddExtension(unittest::repeated_sint32_extension, 5);
943  message.AddExtension(unittest::repeated_sint64_extension, 6);
944  message.AddExtension(unittest::repeated_fixed32_extension, 7);
945  message.AddExtension(unittest::repeated_fixed64_extension, 8);
946  message.AddExtension(unittest::repeated_sfixed32_extension, 7);
947  message.AddExtension(unittest::repeated_sfixed64_extension, 8);
948  message.AddExtension(unittest::repeated_float_extension, 9.0);
949  message.AddExtension(unittest::repeated_double_extension, 10.0);
950  message.AddExtension(unittest::repeated_bool_extension, true);
951  message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
952  message.AddExtension(unittest::repeated_string_extension,
953  std::string("test"));
954  message.AddExtension(unittest::repeated_bytes_extension,
955  std::string("test\xFF"));
956  message.AddExtension(unittest::repeated_nested_message_extension)
957  ->CopyFrom(nested_message);
958  message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
959  }
960 
961  ASSERT_EQ(10, SumAllExtensions<int32>(message,
962  unittest::repeated_int32_extension, 0));
963  IncAllExtensions<int32>(&message, unittest::repeated_int32_extension, 1);
964  ASSERT_EQ(20, SumAllExtensions<int32>(message,
965  unittest::repeated_int32_extension, 0));
966 
967  ASSERT_EQ(20, SumAllExtensions<int64>(message,
968  unittest::repeated_int64_extension, 0));
969  IncAllExtensions<int64>(&message, unittest::repeated_int64_extension, 1);
970  ASSERT_EQ(30, SumAllExtensions<int64>(message,
971  unittest::repeated_int64_extension, 0));
972 
973  ASSERT_EQ(30, SumAllExtensions<uint32>(
974  message, unittest::repeated_uint32_extension, 0));
975  IncAllExtensions<uint32>(&message, unittest::repeated_uint32_extension, 1);
976  ASSERT_EQ(40, SumAllExtensions<uint32>(
977  message, unittest::repeated_uint32_extension, 0));
978 
979  ASSERT_EQ(40, SumAllExtensions<uint64>(
980  message, unittest::repeated_uint64_extension, 0));
981  IncAllExtensions<uint64>(&message, unittest::repeated_uint64_extension, 1);
982  ASSERT_EQ(50, SumAllExtensions<uint64>(
983  message, unittest::repeated_uint64_extension, 0));
984 
985  ASSERT_EQ(50, SumAllExtensions<int32>(
986  message, unittest::repeated_sint32_extension, 0));
987  IncAllExtensions<int32>(&message, unittest::repeated_sint32_extension, 1);
988  ASSERT_EQ(60, SumAllExtensions<int32>(
989  message, unittest::repeated_sint32_extension, 0));
990 
991  ASSERT_EQ(60, SumAllExtensions<int64>(
992  message, unittest::repeated_sint64_extension, 0));
993  IncAllExtensions<int64>(&message, unittest::repeated_sint64_extension, 1);
994  ASSERT_EQ(70, SumAllExtensions<int64>(
995  message, unittest::repeated_sint64_extension, 0));
996 
997  ASSERT_EQ(70, SumAllExtensions<uint32>(
998  message, unittest::repeated_fixed32_extension, 0));
999  IncAllExtensions<uint32>(&message, unittest::repeated_fixed32_extension, 1);
1000  ASSERT_EQ(80, SumAllExtensions<uint32>(
1001  message, unittest::repeated_fixed32_extension, 0));
1002 
1003  ASSERT_EQ(80, SumAllExtensions<uint64>(
1004  message, unittest::repeated_fixed64_extension, 0));
1005  IncAllExtensions<uint64>(&message, unittest::repeated_fixed64_extension, 1);
1006  ASSERT_EQ(90, SumAllExtensions<uint64>(
1007  message, unittest::repeated_fixed64_extension, 0));
1008 
1009  // Usually, floating-point arithmetic cannot be trusted to be exact, so it is
1010  // a Bad Idea to assert equality in a test like this. However, we're dealing
1011  // with integers with a small number of significant mantissa bits, so we
1012  // should actually have exact precision here.
1013  ASSERT_EQ(90, SumAllExtensions<float>(message,
1014  unittest::repeated_float_extension, 0));
1015  IncAllExtensions<float>(&message, unittest::repeated_float_extension, 1);
1016  ASSERT_EQ(100, SumAllExtensions<float>(
1017  message, unittest::repeated_float_extension, 0));
1018 
1019  ASSERT_EQ(100, SumAllExtensions<double>(
1020  message, unittest::repeated_double_extension, 0));
1021  IncAllExtensions<double>(&message, unittest::repeated_double_extension, 1);
1022  ASSERT_EQ(110, SumAllExtensions<double>(
1023  message, unittest::repeated_double_extension, 0));
1024 
1027  for (string_iter =
1028  message
1029  .MutableRepeatedExtension(unittest::repeated_string_extension)
1030  ->begin(),
1031  string_end =
1032  message
1033  .MutableRepeatedExtension(unittest::repeated_string_extension)
1034  ->end();
1035  string_iter != string_end; ++string_iter) {
1036  *string_iter += "test";
1037  }
1040  for (string_const_iter =
1041  message.GetRepeatedExtension(unittest::repeated_string_extension)
1042  .begin(),
1043  string_const_end =
1044  message.GetRepeatedExtension(unittest::repeated_string_extension)
1045  .end();
1046  string_iter != string_end; ++string_iter) {
1047  ASSERT_TRUE(*string_iter == "testtest");
1048  }
1049 
1052  for (enum_iter = message
1053  .MutableRepeatedExtension(
1054  unittest::repeated_nested_enum_extension)
1055  ->begin(),
1056  enum_end = message
1057  .MutableRepeatedExtension(
1058  unittest::repeated_nested_enum_extension)
1059  ->end();
1060  enum_iter != enum_end; ++enum_iter) {
1061  *enum_iter = unittest::TestAllTypes::NestedEnum_MAX;
1062  }
1064  enum_const_iter;
1066  enum_const_end;
1067  for (enum_const_iter =
1068  message
1069  .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
1070  .begin(),
1071  enum_const_end =
1072  message
1073  .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
1074  .end();
1075  enum_const_iter != enum_const_end; ++enum_const_iter) {
1076  ASSERT_EQ(*enum_const_iter, unittest::TestAllTypes::NestedEnum_MAX);
1077  }
1078 
1081  for (msg_iter = message
1082  .MutableRepeatedExtension(
1083  unittest::repeated_nested_message_extension)
1084  ->begin(),
1085  msg_end = message
1086  .MutableRepeatedExtension(
1087  unittest::repeated_nested_message_extension)
1088  ->end();
1089  msg_iter != msg_end; ++msg_iter) {
1090  msg_iter->set_bb(1234);
1091  }
1093  msg_const_iter;
1095  msg_const_end;
1096  for (msg_const_iter = message
1097  .GetRepeatedExtension(
1098  unittest::repeated_nested_message_extension)
1099  .begin(),
1100  msg_const_end = message
1101  .GetRepeatedExtension(
1102  unittest::repeated_nested_message_extension)
1103  .end();
1104  msg_const_iter != msg_const_end; ++msg_const_iter) {
1105  ASSERT_EQ(msg_const_iter->bb(), 1234);
1106  }
1107 
1108  // Test range-based for as well, but only if compiled as C++11.
1109 #if __cplusplus >= 201103L
1110  // Test one primitive field.
1111  for (auto& x :
1112  *message.MutableRepeatedExtension(unittest::repeated_int32_extension)) {
1113  x = 4321;
1114  }
1115  for (const auto& x :
1116  message.GetRepeatedExtension(unittest::repeated_int32_extension)) {
1117  ASSERT_EQ(x, 4321);
1118  }
1119  // Test one string field.
1120  for (auto& x :
1121  *message.MutableRepeatedExtension(unittest::repeated_string_extension)) {
1122  x = "test_range_based_for";
1123  }
1124  for (const auto& x :
1125  message.GetRepeatedExtension(unittest::repeated_string_extension)) {
1126  ASSERT_TRUE(x == "test_range_based_for");
1127  }
1128  // Test one message field.
1129  for (auto& x : *message.MutableRepeatedExtension(
1130  unittest::repeated_nested_message_extension)) {
1131  x.set_bb(4321);
1132  }
1133  for (const auto& x : *message.MutableRepeatedExtension(
1134  unittest::repeated_nested_message_extension)) {
1135  ASSERT_EQ(x.bb(), 4321);
1136  }
1137 #endif
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.
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 != NULL);
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());
1249  io::CodedInputStream input(&raw_input);
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());
1284  io::CodedInputStream input(&raw_input);
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 != NULL);
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 != NULL);
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 != NULL);
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 } // namespace
1324 } // namespace internal
1325 } // namespace protobuf
1326 } // namespace google
google::protobuf::RepeatedPtrField< std::string >::iterator
internal::RepeatedPtrIterator< std::string > iterator
Definition: repeated_field.h:875
ASSERT_FALSE
#define ASSERT_FALSE(condition)
Definition: gtest.h:1998
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
google::protobuf::value
const Descriptor::ReservedRange value
Definition: src/google/protobuf/descriptor.h:1954
zero_copy_stream_impl.h
EXPECT_LE
#define EXPECT_LE(val1, val2)
Definition: gtest.h:2054
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: src/google/protobuf/descriptor.h:2001
end
GLuint GLuint end
Definition: glcorearb.h:2858
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
tests.google.protobuf.internal.test_util.SetAllExtensions
def SetAllExtensions(message)
Definition: compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:187
input
std::string input
Definition: tokenizer_unittest.cc:197
extension_set.h
google::protobuf::uint8
uint8_t uint8
Definition: protobuf/src/google/protobuf/stubs/port.h:153
gtest.h
s
XmlRpcServer s
google::protobuf::python::cmessage::CopyFrom
static PyObject * CopyFrom(CMessage *self, PyObject *arg)
Definition: python/google/protobuf/pyext/message.cc:1861
FieldDescriptorProto
Definition: descriptor.pb.h:1678
FileDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:125
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: glog/src/googletest.h:155
google::protobuf::uint32
uint32_t uint32
Definition: protobuf/src/google/protobuf/stubs/port.h:155
msg_end
static bool msg_end(void *closure, const void *hd, upb_status *status)
Definition: ruby/ext/google/protobuf_c/upb.c:9255
google::protobuf::TestUtil::EqualsToSerialized
bool EqualsToSerialized(const ProtoType &message, const std::string &data)
Definition: test_util2.h:73
FileDescriptorProto::add_dependency
std::string * add_dependency()
Definition: descriptor.pb.h:6761
dynamic_message.h
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
target
GLenum target
Definition: glcorearb.h:3739
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
x
GLint GLenum GLint x
Definition: glcorearb.h:2834
FileDescriptorProto::mutable_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_extension(int index)
Definition: descriptor.pb.h:6950
T
#define T(upbtypeconst, upbtype, ctype, default_value)
Descriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:113
tests.google.protobuf.internal.test_util.SetAllFields
def SetAllFields(message)
Definition: compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:182
TEST_REPEATED_EXTENSIONS_SPACE_USED
#define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value)
test_util2.h
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:2082
FieldDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:129
DescriptorProto::field
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & field(int index) const
Definition: descriptor.pb.h:7413
begin
static size_t begin(const upb_table *t)
Definition: php/ext/google/protobuf/upb.c:4898
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
strutil.h
FileDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:6580
coded_stream.h
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: glog/src/googletest.h:156
prefix
static const char prefix[]
Definition: test_pair_ipc.cpp:26
TEST_SCALAR_EXTENSIONS_SPACE_USED
#define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value)
FileDescriptorProto::set_package
void set_package(const std::string &value)
Definition: descriptor.pb.h:6660
FileDescriptorProto::mutable_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * mutable_enum_type(int index)
Definition: descriptor.pb.h:6890
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
tests.google.protobuf.internal.test_util.ExpectAllFieldsSet
def ExpectAllFieldsSet(test_case, message)
Definition: compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:367
google::protobuf::RepeatedPtrField< std::string >::const_iterator
internal::RepeatedPtrIterator< const std::string > const_iterator
Definition: repeated_field.h:876
add_person.raw_input
raw_input
Definition: add_person.py:11
EXPECT_TRUE
#define EXPECT_TRUE(cond)
Definition: glog/src/googletest.h:137
google::protobuf::string_as_array
char * string_as_array(string *str)
Definition: stl_util.h:83
FileDescriptorProto
Definition: descriptor.pb.h:501
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: gtest.h:1995
source
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:3072
google::protobuf::HasPrefixString
bool HasPrefixString(const string &str, const string &prefix)
Definition: strutil.h:115
casts.h
FileDescriptorProto::mutable_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * mutable_message_type(int index)
Definition: descriptor.pb.h:6860
i
int i
Definition: gmock-matchers_test.cc:764
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
google::protobuf.internal.python_message.Clear
Clear
Definition: python_message.py:1431
common.h
google::protobuf.internal::kMinRepeatedFieldAllocationSize
static const int kMinRepeatedFieldAllocationSize
Definition: repeated_field.h:92
DescriptorProto::nested_type
const PROTOBUF_NAMESPACE_ID::DescriptorProto & nested_type(int index) const
Definition: descriptor.pb.h:7473
FileDescriptorProto::extension_size
int extension_size() const
Definition: descriptor.pb.h:6944
size
GLsizeiptr size
Definition: glcorearb.h:2943
stl_util.h
googletest.h
EXPECT_FALSE
#define EXPECT_FALSE(cond)
Definition: glog/src/googletest.h:145
arena.h
google::protobuf::DescriptorPool::generated_pool
static const DescriptorPool * generated_pool()
Definition: src/google/protobuf/descriptor.cc:1346
wire_format.h
logging.h
DescriptorProto
Definition: descriptor.pb.h:1203
google::protobuf.internal::WireFormat::ParseAndMergePartial
static bool ParseAndMergePartial(io::CodedInputStream *input, Message *message)
Definition: wire_format.cc:384
descriptor.h
google::protobuf.internal::TEST
TEST(GeneratedMapFieldTest, Accessors)
Definition: src/google/protobuf/map_test.cc:1837
google::protobuf.internal.python_message.IsInitialized
IsInitialized
Definition: python_message.py:1246
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
internal
Definition: any.pb.h:40
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
descriptor.pb.h
DescriptorPool
Definition: ruby/ext/google/protobuf_c/protobuf.h:109
test_util.h
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:3228
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
DescriptorProto::enum_type
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto & enum_type(int index) const
Definition: descriptor.pb.h:7503
RepeatedField
Definition: ruby/ext/google/protobuf_c/protobuf.h:395


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