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