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