Home | History | Annotate | Download | only in protobuf
      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 (at) 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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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>
    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>
    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 
    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
    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 
    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 
    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