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 52namespace google { 53 54namespace protobuf { 55namespace internal { 56namespace { 57 58// This test closely mirrors google/protobuf/compiler/cpp/unittest.cc 59// except that it uses extensions rather than regular fields. 60 61TEST(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 81TEST(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 93TEST(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 122TEST(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 145TEST(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 174TEST(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 207TEST(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 217TEST(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 227TEST(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 239TEST(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 250TEST(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 259TEST(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 288TEST(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 305TEST(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 322TEST(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 335TEST(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 355TEST(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 379TEST(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 399TEST(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 423TEST(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 436TEST(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 448TEST(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 469TEST(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 490TEST(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 518TEST(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 532TEST(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. 673template<typename T, typename M, typename ID> 674inline 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 686template<typename T, typename M, typename ID> 687inline 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 698TEST(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 911TEST(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 924TEST(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 934TEST(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