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