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