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