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