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