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