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