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