Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // http://code.google.com/p/protobuf/
      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/test_util.h>
     38 #include <google/protobuf/descriptor.pb.h>
     39 #include <google/protobuf/descriptor.h>
     40 #include <google/protobuf/dynamic_message.h>
     41 #include <google/protobuf/wire_format.h>
     42 #include <google/protobuf/io/coded_stream.h>
     43 #include <google/protobuf/io/zero_copy_stream_impl.h>
     44 
     45 #include <google/protobuf/stubs/common.h>
     46 #include <google/protobuf/stubs/strutil.h>
     47 #include <google/protobuf/testing/googletest.h>
     48 #include <gtest/gtest.h>
     49 #include <google/protobuf/stubs/stl_util-inl.h>
     50 
     51 namespace google {
     52 namespace protobuf {
     53 namespace internal {
     54 namespace {
     55 
     56 // This test closely mirrors google/protobuf/compiler/cpp/unittest.cc
     57 // except that it uses extensions rather than regular fields.
     58 
     59 TEST(ExtensionSetTest, Defaults) {
     60   // Check that all default values are set correctly in the initial message.
     61   unittest::TestAllExtensions message;
     62 
     63   TestUtil::ExpectExtensionsClear(message);
     64 
     65   // Messages should return pointers to default instances until first use.
     66   // (This is not checked by ExpectClear() since it is not actually true after
     67   // the fields have been set and then cleared.)
     68   EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(),
     69             &message.GetExtension(unittest::optionalgroup_extension));
     70   EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
     71             &message.GetExtension(unittest::optional_nested_message_extension));
     72   EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
     73             &message.GetExtension(
     74               unittest::optional_foreign_message_extension));
     75   EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
     76             &message.GetExtension(unittest::optional_import_message_extension));
     77 }
     78 
     79 TEST(ExtensionSetTest, Accessors) {
     80   // Set every field to a unique value then go back and check all those
     81   // values.
     82   unittest::TestAllExtensions message;
     83 
     84   TestUtil::SetAllExtensions(&message);
     85   TestUtil::ExpectAllExtensionsSet(message);
     86 
     87   TestUtil::ModifyRepeatedExtensions(&message);
     88   TestUtil::ExpectRepeatedExtensionsModified(message);
     89 }
     90 
     91 TEST(ExtensionSetTest, Clear) {
     92   // Set every field to a unique value, clear the message, then check that
     93   // it is cleared.
     94   unittest::TestAllExtensions message;
     95 
     96   TestUtil::SetAllExtensions(&message);
     97   message.Clear();
     98   TestUtil::ExpectExtensionsClear(message);
     99 
    100   // Unlike with the defaults test, we do NOT expect that requesting embedded
    101   // messages will return a pointer to the default instance.  Instead, they
    102   // should return the objects that were created when mutable_blah() was
    103   // called.
    104   EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
    105             &message.GetExtension(unittest::optionalgroup_extension));
    106   EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
    107             &message.GetExtension(unittest::optional_nested_message_extension));
    108   EXPECT_NE(&unittest::ForeignMessage::default_instance(),
    109             &message.GetExtension(
    110               unittest::optional_foreign_message_extension));
    111   EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
    112             &message.GetExtension(unittest::optional_import_message_extension));
    113 
    114   // Make sure setting stuff again after clearing works.  (This takes slightly
    115   // different code paths since the objects are reused.)
    116   TestUtil::SetAllExtensions(&message);
    117   TestUtil::ExpectAllExtensionsSet(message);
    118 }
    119 
    120 TEST(ExtensionSetTest, ClearOneField) {
    121   // Set every field to a unique value, then clear one value and insure that
    122   // only that one value is cleared.
    123   unittest::TestAllExtensions message;
    124 
    125   TestUtil::SetAllExtensions(&message);
    126   int64 original_value =
    127     message.GetExtension(unittest::optional_int64_extension);
    128 
    129   // Clear the field and make sure it shows up as cleared.
    130   message.ClearExtension(unittest::optional_int64_extension);
    131   EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
    132   EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
    133 
    134   // Other adjacent fields should not be cleared.
    135   EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
    136   EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
    137 
    138   // Make sure if we set it again, then all fields are set.
    139   message.SetExtension(unittest::optional_int64_extension, original_value);
    140   TestUtil::ExpectAllExtensionsSet(message);
    141 }
    142 
    143 TEST(ExtensionSetTest, CopyFrom) {
    144   unittest::TestAllExtensions message1, message2;
    145   string data;
    146 
    147   TestUtil::SetAllExtensions(&message1);
    148   message2.CopyFrom(message1);
    149   TestUtil::ExpectAllExtensionsSet(message2);
    150 }
    151 
    152 TEST(ExtensionSetTest, CopyFromUpcasted) {
    153   unittest::TestAllExtensions message1, message2;
    154   string data;
    155   const Message& upcasted_message = message1;
    156 
    157   TestUtil::SetAllExtensions(&message1);
    158   message2.CopyFrom(upcasted_message);
    159   TestUtil::ExpectAllExtensionsSet(message2);
    160 }
    161 
    162 TEST(ExtensionSetTest, SwapWithEmpty) {
    163   unittest::TestAllExtensions message1, message2;
    164   TestUtil::SetAllExtensions(&message1);
    165 
    166   TestUtil::ExpectAllExtensionsSet(message1);
    167   TestUtil::ExpectExtensionsClear(message2);
    168   message1.Swap(&message2);
    169   TestUtil::ExpectAllExtensionsSet(message2);
    170   TestUtil::ExpectExtensionsClear(message1);
    171 }
    172 
    173 TEST(ExtensionSetTest, SwapWithSelf) {
    174   unittest::TestAllExtensions message;
    175   TestUtil::SetAllExtensions(&message);
    176 
    177   TestUtil::ExpectAllExtensionsSet(message);
    178   message.Swap(&message);
    179   TestUtil::ExpectAllExtensionsSet(message);
    180 }
    181 
    182 TEST(ExtensionSetTest, SerializationToArray) {
    183   // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
    184   // compatibility of extensions.
    185   //
    186   // This checks serialization to a flat array by explicitly reserving space in
    187   // the string and calling the generated message's
    188   // SerializeWithCachedSizesToArray.
    189   unittest::TestAllExtensions source;
    190   unittest::TestAllTypes destination;
    191   TestUtil::SetAllExtensions(&source);
    192   int size = source.ByteSize();
    193   string data;
    194   data.resize(size);
    195   uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
    196   uint8* end = source.SerializeWithCachedSizesToArray(target);
    197   EXPECT_EQ(size, end - target);
    198   EXPECT_TRUE(destination.ParseFromString(data));
    199   TestUtil::ExpectAllFieldsSet(destination);
    200 }
    201 
    202 TEST(ExtensionSetTest, SerializationToStream) {
    203   // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
    204   // compatibility of extensions.
    205   //
    206   // This checks serialization to an output stream by creating an array output
    207   // stream that can only buffer 1 byte at a time - this prevents the message
    208   // from ever jumping to the fast path, ensuring that serialization happens via
    209   // the CodedOutputStream.
    210   unittest::TestAllExtensions source;
    211   unittest::TestAllTypes destination;
    212   TestUtil::SetAllExtensions(&source);
    213   int size = source.ByteSize();
    214   string data;
    215   data.resize(size);
    216   {
    217     io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
    218     io::CodedOutputStream output_stream(&array_stream);
    219     source.SerializeWithCachedSizes(&output_stream);
    220     ASSERT_FALSE(output_stream.HadError());
    221   }
    222   EXPECT_TRUE(destination.ParseFromString(data));
    223   TestUtil::ExpectAllFieldsSet(destination);
    224 }
    225 
    226 TEST(ExtensionSetTest, PackedSerializationToArray) {
    227   // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
    228   // wire compatibility of extensions.
    229   //
    230   // This checks serialization to a flat array by explicitly reserving space in
    231   // the string and calling the generated message's
    232   // SerializeWithCachedSizesToArray.
    233   unittest::TestPackedExtensions source;
    234   unittest::TestPackedTypes destination;
    235   TestUtil::SetPackedExtensions(&source);
    236   int size = source.ByteSize();
    237   string data;
    238   data.resize(size);
    239   uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
    240   uint8* end = source.SerializeWithCachedSizesToArray(target);
    241   EXPECT_EQ(size, end - target);
    242   EXPECT_TRUE(destination.ParseFromString(data));
    243   TestUtil::ExpectPackedFieldsSet(destination);
    244 }
    245 
    246 TEST(ExtensionSetTest, PackedSerializationToStream) {
    247   // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
    248   // wire compatibility of extensions.
    249   //
    250   // This checks serialization to an output stream by creating an array output
    251   // stream that can only buffer 1 byte at a time - this prevents the message
    252   // from ever jumping to the fast path, ensuring that serialization happens via
    253   // the CodedOutputStream.
    254   unittest::TestPackedExtensions source;
    255   unittest::TestPackedTypes destination;
    256   TestUtil::SetPackedExtensions(&source);
    257   int size = source.ByteSize();
    258   string data;
    259   data.resize(size);
    260   {
    261     io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
    262     io::CodedOutputStream output_stream(&array_stream);
    263     source.SerializeWithCachedSizes(&output_stream);
    264     ASSERT_FALSE(output_stream.HadError());
    265   }
    266   EXPECT_TRUE(destination.ParseFromString(data));
    267   TestUtil::ExpectPackedFieldsSet(destination);
    268 }
    269 
    270 TEST(ExtensionSetTest, Parsing) {
    271   // Serialize as TestAllTypes and parse as TestAllExtensions.
    272   unittest::TestAllTypes source;
    273   unittest::TestAllExtensions destination;
    274   string data;
    275 
    276   TestUtil::SetAllFields(&source);
    277   source.SerializeToString(&data);
    278   EXPECT_TRUE(destination.ParseFromString(data));
    279   TestUtil::ExpectAllExtensionsSet(destination);
    280 }
    281 
    282 TEST(ExtensionSetTest, PackedParsing) {
    283   // Serialize as TestPackedTypes and parse as TestPackedExtensions.
    284   unittest::TestPackedTypes source;
    285   unittest::TestPackedExtensions destination;
    286   string data;
    287 
    288   TestUtil::SetPackedFields(&source);
    289   source.SerializeToString(&data);
    290   EXPECT_TRUE(destination.ParseFromString(data));
    291   TestUtil::ExpectPackedExtensionsSet(destination);
    292 }
    293 
    294 TEST(ExtensionSetTest, IsInitialized) {
    295   // Test that IsInitialized() returns false if required fields in nested
    296   // extensions are missing.
    297   unittest::TestAllExtensions message;
    298 
    299   EXPECT_TRUE(message.IsInitialized());
    300 
    301   message.MutableExtension(unittest::TestRequired::single);
    302   EXPECT_FALSE(message.IsInitialized());
    303 
    304   message.MutableExtension(unittest::TestRequired::single)->set_a(1);
    305   EXPECT_FALSE(message.IsInitialized());
    306   message.MutableExtension(unittest::TestRequired::single)->set_b(2);
    307   EXPECT_FALSE(message.IsInitialized());
    308   message.MutableExtension(unittest::TestRequired::single)->set_c(3);
    309   EXPECT_TRUE(message.IsInitialized());
    310 
    311   message.AddExtension(unittest::TestRequired::multi);
    312   EXPECT_FALSE(message.IsInitialized());
    313 
    314   message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
    315   EXPECT_FALSE(message.IsInitialized());
    316   message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
    317   EXPECT_FALSE(message.IsInitialized());
    318   message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
    319   EXPECT_TRUE(message.IsInitialized());
    320 }
    321 
    322 TEST(ExtensionSetTest, MutableString) {
    323   // Test the mutable string accessors.
    324   unittest::TestAllExtensions message;
    325 
    326   message.MutableExtension(unittest::optional_string_extension)->assign("foo");
    327   EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
    328   EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
    329 
    330   message.AddExtension(unittest::repeated_string_extension)->assign("bar");
    331   ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
    332   EXPECT_EQ("bar",
    333             message.GetExtension(unittest::repeated_string_extension, 0));
    334 }
    335 
    336 TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
    337   // Scalar primitive extensions should increase the extension set size by a
    338   // minimum of the size of the primitive type.
    339 #define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value)                        \
    340   do {                                                                        \
    341     unittest::TestAllExtensions message;                                      \
    342     const int base_size = message.SpaceUsed();                                \
    343     message.SetExtension(unittest::optional_##type##_extension, value);       \
    344     int min_expected_size = base_size +                                       \
    345         sizeof(message.GetExtension(unittest::optional_##type##_extension));  \
    346     EXPECT_LE(min_expected_size, message.SpaceUsed());                        \
    347   } while (0)
    348 
    349   TEST_SCALAR_EXTENSIONS_SPACE_USED(int32   , 101);
    350   TEST_SCALAR_EXTENSIONS_SPACE_USED(int64   , 102);
    351   TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32  , 103);
    352   TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64  , 104);
    353   TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32  , 105);
    354   TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64  , 106);
    355   TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32 , 107);
    356   TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64 , 108);
    357   TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
    358   TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
    359   TEST_SCALAR_EXTENSIONS_SPACE_USED(float   , 111);
    360   TEST_SCALAR_EXTENSIONS_SPACE_USED(double  , 112);
    361   TEST_SCALAR_EXTENSIONS_SPACE_USED(bool    , true);
    362 #undef TEST_SCALAR_EXTENSIONS_SPACE_USED
    363   {
    364     unittest::TestAllExtensions message;
    365     const int base_size = message.SpaceUsed();
    366     message.SetExtension(unittest::optional_nested_enum_extension,
    367                          unittest::TestAllTypes::FOO);
    368     int min_expected_size = base_size +
    369         sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
    370     EXPECT_LE(min_expected_size, message.SpaceUsed());
    371   }
    372   {
    373     // Strings may cause extra allocations depending on their length; ensure
    374     // that gets included as well.
    375     unittest::TestAllExtensions message;
    376     const int base_size = message.SpaceUsed();
    377     const string s("this is a fairly large string that will cause some "
    378                    "allocation in order to store it in the extension");
    379     message.SetExtension(unittest::optional_string_extension, s);
    380     int min_expected_size = base_size + s.length();
    381     EXPECT_LE(min_expected_size, message.SpaceUsed());
    382   }
    383   {
    384     // Messages also have additional allocation that need to be counted.
    385     unittest::TestAllExtensions message;
    386     const int base_size = message.SpaceUsed();
    387     unittest::ForeignMessage foreign;
    388     foreign.set_c(42);
    389     message.MutableExtension(unittest::optional_foreign_message_extension)->
    390         CopyFrom(foreign);
    391     int min_expected_size = base_size + foreign.SpaceUsed();
    392     EXPECT_LE(min_expected_size, message.SpaceUsed());
    393   }
    394 
    395   // Repeated primitive extensions will increase space used by at least a
    396   // RepeatedField<T>, and will cause additional allocations when the array
    397   // gets too big for the initial space.
    398   // This macro:
    399   //   - Adds a value to the repeated extension, then clears it, establishing
    400   //     the base size.
    401   //   - Adds a small number of values, testing that it doesn't increase the
    402   //     SpaceUsed()
    403   //   - Adds a large number of values (requiring allocation in the repeated
    404   //     field), and ensures that that allocation is included in SpaceUsed()
    405 #define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value)              \
    406   do {                                                                         \
    407     unittest::TestAllExtensions message;                                       \
    408     const int base_size = message.SpaceUsed();                                 \
    409     int min_expected_size = sizeof(RepeatedField<cpptype>) + base_size;        \
    410     message.AddExtension(unittest::repeated_##type##_extension, value);        \
    411     message.ClearExtension(unittest::repeated_##type##_extension);             \
    412     const int empty_repeated_field_size = message.SpaceUsed();                 \
    413     EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type;          \
    414     message.AddExtension(unittest::repeated_##type##_extension, value);        \
    415     message.AddExtension(unittest::repeated_##type##_extension, value);        \
    416     EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type;        \
    417     message.ClearExtension(unittest::repeated_##type##_extension);             \
    418     for (int i = 0; i < 16; ++i) {                                             \
    419       message.AddExtension(unittest::repeated_##type##_extension, value);      \
    420     }                                                                          \
    421     int expected_size = sizeof(cpptype) * 16 + empty_repeated_field_size;      \
    422     EXPECT_EQ(expected_size, message.SpaceUsed()) << #type;                    \
    423   } while (0)
    424 
    425   TEST_REPEATED_EXTENSIONS_SPACE_USED(int32   , int32 , 101);
    426   TEST_REPEATED_EXTENSIONS_SPACE_USED(int64   , int64 , 102);
    427   TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32  , uint32, 103);
    428   TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64  , uint64, 104);
    429   TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32  , int32 , 105);
    430   TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64  , int64 , 106);
    431   TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32 , uint32, 107);
    432   TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64 , uint64, 108);
    433   TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32 , 109);
    434   TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64 , 110);
    435   TEST_REPEATED_EXTENSIONS_SPACE_USED(float   , float , 111);
    436   TEST_REPEATED_EXTENSIONS_SPACE_USED(double  , double, 112);
    437   TEST_REPEATED_EXTENSIONS_SPACE_USED(bool    , bool  , true);
    438   TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
    439                                       unittest::TestAllTypes::FOO);
    440 #undef TEST_REPEATED_EXTENSIONS_SPACE_USED
    441   // Repeated strings
    442   {
    443     unittest::TestAllExtensions message;
    444     const int base_size = message.SpaceUsed();
    445     int min_expected_size = sizeof(RepeatedPtrField<string>) + base_size;
    446     const string value(256, 'x');
    447     // Once items are allocated, they may stick around even when cleared so
    448     // without the hardcore memory management accessors there isn't a notion of
    449     // the empty repeated field memory usage as there is with primitive types.
    450     for (int i = 0; i < 16; ++i) {
    451       message.AddExtension(unittest::repeated_string_extension, value);
    452     }
    453     min_expected_size += (sizeof(value) + value.size()) * 16;
    454     EXPECT_LE(min_expected_size, message.SpaceUsed());
    455   }
    456   // Repeated messages
    457   {
    458     unittest::TestAllExtensions message;
    459     const int base_size = message.SpaceUsed();
    460     int min_expected_size = sizeof(RepeatedPtrField<unittest::ForeignMessage>) +
    461         base_size;
    462     unittest::ForeignMessage prototype;
    463     prototype.set_c(2);
    464     for (int i = 0; i < 16; ++i) {
    465       message.AddExtension(unittest::repeated_foreign_message_extension)->
    466           CopyFrom(prototype);
    467     }
    468     min_expected_size += 16 * prototype.SpaceUsed();
    469     EXPECT_LE(min_expected_size, message.SpaceUsed());
    470   }
    471 }
    472 
    473 #ifdef GTEST_HAS_DEATH_TEST
    474 
    475 TEST(ExtensionSetTest, InvalidEnumDeath) {
    476   unittest::TestAllExtensions message;
    477   EXPECT_DEBUG_DEATH(
    478     message.SetExtension(unittest::optional_foreign_enum_extension,
    479                          static_cast<unittest::ForeignEnum>(53)),
    480     "IsValid");
    481 }
    482 
    483 #endif  // GTEST_HAS_DEATH_TEST
    484 
    485 TEST(ExtensionSetTest, DynamicExtensions) {
    486   // Test adding a dynamic extension to a compiled-in message object.
    487 
    488   FileDescriptorProto dynamic_proto;
    489   dynamic_proto.set_name("dynamic_extensions_test.proto");
    490   dynamic_proto.add_dependency(
    491       unittest::TestAllExtensions::descriptor()->file()->name());
    492   dynamic_proto.set_package("dynamic_extensions");
    493 
    494   // Copy the fields and nested types from TestDynamicExtensions into our new
    495   // proto, converting the fields into extensions.
    496   const Descriptor* template_descriptor =
    497       unittest::TestDynamicExtensions::descriptor();
    498   DescriptorProto template_descriptor_proto;
    499   template_descriptor->CopyTo(&template_descriptor_proto);
    500   dynamic_proto.mutable_message_type()->MergeFrom(
    501       template_descriptor_proto.nested_type());
    502   dynamic_proto.mutable_enum_type()->MergeFrom(
    503       template_descriptor_proto.enum_type());
    504   dynamic_proto.mutable_extension()->MergeFrom(
    505       template_descriptor_proto.field());
    506 
    507   // For each extension that we added...
    508   for (int i = 0; i < dynamic_proto.extension_size(); i++) {
    509     // Set its extendee to TestAllExtensions.
    510     FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i);
    511     extension->set_extendee(
    512         unittest::TestAllExtensions::descriptor()->full_name());
    513 
    514     // If the field refers to one of the types nested in TestDynamicExtensions,
    515     // make it refer to the type in our dynamic proto instead.
    516     string prefix = "." + template_descriptor->full_name() + ".";
    517     if (extension->has_type_name()) {
    518       string* type_name = extension->mutable_type_name();
    519       if (HasPrefixString(*type_name, prefix)) {
    520         type_name->replace(0, prefix.size(), ".dynamic_extensions.");
    521       }
    522     }
    523   }
    524 
    525   // Now build the file, using the generated pool as an underlay.
    526   DescriptorPool dynamic_pool(DescriptorPool::generated_pool());
    527   const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto);
    528   ASSERT_TRUE(file != NULL);
    529   DynamicMessageFactory dynamic_factory(&dynamic_pool);
    530   dynamic_factory.SetDelegateToGeneratedFactory(true);
    531 
    532   // Construct a message that we can parse with the extensions we defined.
    533   // Since the extensions were based off of the fields of TestDynamicExtensions,
    534   // we can use that message to create this test message.
    535   string data;
    536   {
    537     unittest::TestDynamicExtensions message;
    538     message.set_scalar_extension(123);
    539     message.set_enum_extension(unittest::FOREIGN_BAR);
    540     message.set_dynamic_enum_extension(
    541         unittest::TestDynamicExtensions::DYNAMIC_BAZ);
    542     message.mutable_message_extension()->set_c(456);
    543     message.mutable_dynamic_message_extension()->set_dynamic_field(789);
    544     message.add_repeated_extension("foo");
    545     message.add_repeated_extension("bar");
    546     message.add_packed_extension(12);
    547     message.add_packed_extension(-34);
    548     message.add_packed_extension(56);
    549     message.add_packed_extension(-78);
    550 
    551     // Also add some unknown fields.
    552 
    553     // An unknown enum value (for a known field).
    554     message.mutable_unknown_fields()->AddVarint(
    555       unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber,
    556       12345);
    557     // A regular unknown field.
    558     message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown");
    559 
    560     message.SerializeToString(&data);
    561   }
    562 
    563   // Now we can parse this using our dynamic extension definitions...
    564   unittest::TestAllExtensions message;
    565   {
    566     io::ArrayInputStream raw_input(data.data(), data.size());
    567     io::CodedInputStream input(&raw_input);
    568     input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
    569     ASSERT_TRUE(message.ParseFromCodedStream(&input));
    570     ASSERT_TRUE(input.ConsumedEntireMessage());
    571   }
    572 
    573   // Can we print it?
    574   EXPECT_EQ(
    575     "[dynamic_extensions.scalar_extension]: 123\n"
    576     "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n"
    577     "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n"
    578     "[dynamic_extensions.message_extension] {\n"
    579     "  c: 456\n"
    580     "}\n"
    581     "[dynamic_extensions.dynamic_message_extension] {\n"
    582     "  dynamic_field: 789\n"
    583     "}\n"
    584     "[dynamic_extensions.repeated_extension]: \"foo\"\n"
    585     "[dynamic_extensions.repeated_extension]: \"bar\"\n"
    586     "[dynamic_extensions.packed_extension]: 12\n"
    587     "[dynamic_extensions.packed_extension]: -34\n"
    588     "[dynamic_extensions.packed_extension]: 56\n"
    589     "[dynamic_extensions.packed_extension]: -78\n"
    590     "2002: 12345\n"
    591     "54321: \"unknown\"\n",
    592     message.DebugString());
    593 
    594   // Can we serialize it?
    595   // (Don't use EXPECT_EQ because we don't want to dump raw binary data to the
    596   // terminal on failure.)
    597   EXPECT_TRUE(message.SerializeAsString() == data);
    598 
    599   // What if we parse using the reflection-based parser?
    600   {
    601     unittest::TestAllExtensions message2;
    602     io::ArrayInputStream raw_input(data.data(), data.size());
    603     io::CodedInputStream input(&raw_input);
    604     input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
    605     ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2));
    606     ASSERT_TRUE(input.ConsumedEntireMessage());
    607     EXPECT_EQ(message.DebugString(), message2.DebugString());
    608   }
    609 
    610   // Are the embedded generated types actually using the generated objects?
    611   {
    612     const FieldDescriptor* message_extension =
    613         file->FindExtensionByName("message_extension");
    614     ASSERT_TRUE(message_extension != NULL);
    615     const Message& sub_message =
    616         message.GetReflection()->GetMessage(message, message_extension);
    617     const unittest::ForeignMessage* typed_sub_message =
    618         dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
    619     ASSERT_TRUE(typed_sub_message != NULL);
    620     EXPECT_EQ(456, typed_sub_message->c());
    621   }
    622 
    623   // What does GetMessage() return for the embedded dynamic type if it isn't
    624   // present?
    625   {
    626     const FieldDescriptor* dynamic_message_extension =
    627         file->FindExtensionByName("dynamic_message_extension");
    628     ASSERT_TRUE(dynamic_message_extension != NULL);
    629     const Message& parent = unittest::TestAllExtensions::default_instance();
    630     const Message& sub_message =
    631         parent.GetReflection()->GetMessage(parent, dynamic_message_extension,
    632                                            &dynamic_factory);
    633     const Message* prototype =
    634         dynamic_factory.GetPrototype(dynamic_message_extension->message_type());
    635     EXPECT_EQ(prototype, &sub_message);
    636   }
    637 }
    638 
    639 }  // namespace
    640 }  // namespace internal
    641 }  // namespace protobuf
    642 }  // namespace google
    643