1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #include <google/protobuf/unittest.pb.h>
32 #include <gmock/gmock.h>
33 #include <gtest/gtest.h>
34 #include <google/protobuf/descriptor.h>
35
36 namespace google {
37 namespace protobuf {
38 namespace compiler {
39 namespace cpp {
40
41 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
42 namespace cpp_unittest {
43
44
45 #if !defined(GOOGLE_CHECK_MESSAGE_SIZE)
46 #define GOOGLE_CHECK_MESSAGE_SIZE(t, expected)
47 #endif
48
49 // Mock structures to lock down the size of messages in a platform-independent
50 // way. The commented sizes only apply when build with clang x86_64.
51 struct MockMessageBase {
52 virtual ~MockMessageBase() = default; // 8 bytes vtable
53 void* internal_metadata; // 8 bytes
54 };
55 GOOGLE_CHECK_MESSAGE_SIZE(MockMessageBase, 16);
56
57 struct MockZeroFieldsBase : public MockMessageBase {
58 int cached_size; // 4 bytes
59 // + 4 bytes padding
60 };
61 GOOGLE_CHECK_MESSAGE_SIZE(MockZeroFieldsBase, 24);
62
63 struct MockExtensionSet {
64 void* arena; // 8 bytes
65 int16_t capacity; // 4 bytes
66 int16_t size; // 4 bytes
67 void* data; // 8 bytes
68 };
69 GOOGLE_CHECK_MESSAGE_SIZE(MockExtensionSet, 24);
70
71 struct MockRepeatedPtrField {
72 void* arena; // 8 bytes
73 int current_size; // 4 bytes
74 int total_size; // 4 bytes
75 void* data; // 8 bytes
76 };
77 GOOGLE_CHECK_MESSAGE_SIZE(MockRepeatedPtrField, 24);
78
79 struct MockRepeatedField {
80 int current_size; // 4 bytes
81 int total_size; // 4 bytes
82 void* data; // 8 bytes
83 };
84 GOOGLE_CHECK_MESSAGE_SIZE(MockRepeatedField, 16);
85
TEST(GeneratedMessageTest,MockSizes)86 TEST(GeneratedMessageTest, MockSizes) {
87 // Consistency checks -- if these fail, the tests below will definitely fail.
88 GOOGLE_CHECK_EQ(sizeof(MessageLite), sizeof(MockMessageBase));
89 GOOGLE_CHECK_EQ(sizeof(Message), sizeof(MockMessageBase));
90 GOOGLE_CHECK_EQ(sizeof(internal::ZeroFieldsBase), sizeof(MockZeroFieldsBase));
91 GOOGLE_CHECK_EQ(sizeof(internal::ExtensionSet), sizeof(MockExtensionSet));
92 GOOGLE_CHECK_EQ(sizeof(RepeatedPtrField<std::string>), sizeof(MockRepeatedPtrField));
93 GOOGLE_CHECK_EQ(sizeof(RepeatedField<int>), sizeof(MockRepeatedField));
94 }
95
TEST(GeneratedMessageTest,EmptyMessageSize)96 TEST(GeneratedMessageTest, EmptyMessageSize) {
97 EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessage),
98 sizeof(MockZeroFieldsBase));
99 }
100
TEST(GeneratedMessageTest,ReservedSize)101 TEST(GeneratedMessageTest, ReservedSize) {
102 EXPECT_EQ(sizeof(protobuf_unittest::TestReservedFields),
103 sizeof(MockZeroFieldsBase));
104 }
105
TEST(GeneratedMessageTest,EmptyMessageWithExtensionsSize)106 TEST(GeneratedMessageTest, EmptyMessageWithExtensionsSize) {
107 struct MockGenerated : public MockMessageBase { // 16 bytes
108 MockExtensionSet extensions; // 24 bytes
109 int cached_size; // 4 bytes
110 // + 4 bytes of padding
111 };
112 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 48);
113 EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessageWithExtensions),
114 sizeof(MockGenerated));
115 }
116
TEST(GeneratedMessageTest,RecursiveMessageSize)117 TEST(GeneratedMessageTest, RecursiveMessageSize) {
118 struct MockGenerated : public MockMessageBase { // 16 bytes
119 int has_bits[1]; // 4 bytes
120 int cached_size; // 4 bytes
121 void* a; // 8 bytes
122 int32_t i; // 4 bytes
123 // + 4 bytes padding
124 };
125 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 40);
126 EXPECT_EQ(sizeof(protobuf_unittest::TestRecursiveMessage),
127 sizeof(MockGenerated));
128 }
129
TEST(GeneratedMessageTest,OneStringSize)130 TEST(GeneratedMessageTest, OneStringSize) {
131 struct MockGenerated : public MockMessageBase { // 16 bytes
132 int has_bits[1]; // 4 bytes
133 int cached_size; // 4 bytes
134 void* data; // 8 bytes
135 };
136 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
137 EXPECT_EQ(sizeof(protobuf_unittest::OneString), sizeof(MockGenerated));
138 }
139
TEST(GeneratedMessageTest,MoreStringSize)140 TEST(GeneratedMessageTest, MoreStringSize) {
141 struct MockGenerated : public MockMessageBase { // 16 bytes
142 int has_bits[1]; // 4 bytes
143 int cached_size; // 4 bytes
144 MockRepeatedPtrField data; // 24 bytes
145 };
146 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 48);
147 EXPECT_EQ(sizeof(protobuf_unittest::MoreString), sizeof(MockGenerated));
148 }
149
TEST(GeneratedMessageTest,Int32MessageSize)150 TEST(GeneratedMessageTest, Int32MessageSize) {
151 struct MockGenerated : public MockMessageBase { // 16 bytes
152 int has_bits[1]; // 4 bytes
153 int cached_size; // 4 bytes
154 int32_t data; // 4 bytes
155 // + 4 bytes padding
156 };
157 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
158 EXPECT_EQ(sizeof(protobuf_unittest::Int32Message), sizeof(MockGenerated));
159 }
160
TEST(GeneratedMessageTest,Int64MessageSize)161 TEST(GeneratedMessageTest, Int64MessageSize) {
162 struct MockGenerated : public MockMessageBase { // 16 bytes
163 int has_bits[1]; // 4 bytes
164 int cached_size; // 4 bytes
165 int64_t data; // 8 bytes
166 };
167 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
168 EXPECT_EQ(sizeof(protobuf_unittest::Int64Message), sizeof(MockGenerated));
169 }
170
TEST(GeneratedMessageTest,BoolMessageSize)171 TEST(GeneratedMessageTest, BoolMessageSize) {
172 struct MockGenerated : public MockMessageBase { // 16 bytes
173 int has_bits[1]; // 4 bytes
174 int cached_size; // 4 bytes
175 bool data; // 1 byte
176 // + 3 bytes padding
177 };
178 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
179 EXPECT_EQ(sizeof(protobuf_unittest::BoolMessage), sizeof(MockGenerated));
180 }
181
TEST(GeneratedMessageTest,OneofSize)182 TEST(GeneratedMessageTest, OneofSize) {
183 struct MockGenerated : public MockMessageBase { // 16 bytes
184 void* foo; // 8 bytes
185 int cached_size; // 4 bytes
186 uint32_t oneof_case[1]; // 4 bytes
187 };
188 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
189 EXPECT_EQ(sizeof(protobuf_unittest::TestOneof), sizeof(MockGenerated));
190 }
191
TEST(GeneratedMessageTest,Oneof2Size)192 TEST(GeneratedMessageTest, Oneof2Size) {
193 struct MockGenerated : public MockMessageBase { // 16 bytes
194 int has_bits[1]; // 4 bytes
195 int cached_size; // 4 bytes
196 void* baz_string; // 8 bytes
197 int32_t baz_int; // 4 bytes
198 // + 4 bytes padding
199 void* foo; // 8 bytes
200 void* bar; // 8 bytes
201 uint32_t oneof_case[2]; // 8 bytes
202 };
203 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 64);
204 EXPECT_EQ(sizeof(protobuf_unittest::TestOneof2), sizeof(MockGenerated));
205 }
206
TEST(GeneratedMessageTest,FieldOrderingsSize)207 TEST(GeneratedMessageTest, FieldOrderingsSize) {
208 struct MockGenerated : public MockMessageBase { // 16 bytes
209 int has_bits[1]; // 4 bytes
210 int cached_size; // 4 bytes
211 MockExtensionSet extensions; // 24 bytes
212 void* my_string; // 8 bytes
213 void* optional_nested_message; // 8 bytes
214 int64_t my_int; // 8 bytes
215 float my_float; // 4 bytes
216 // + 4 bytes of padding
217 };
218 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 80);
219 EXPECT_EQ(sizeof(protobuf_unittest::TestFieldOrderings), sizeof(MockGenerated));
220 }
221
TEST(GeneratedMessageTest,TestMessageSize)222 TEST(GeneratedMessageTest, TestMessageSize) {
223 // We expect the message to contain (not in this order):
224 struct MockGenerated : public MockMessageBase { // 16 bytes
225 int has_bits[1]; // 4 bytes
226 int cached_size; // 4 bytes
227 void* m4; // 8 bytes
228 int64_t m2; // 8 bytes
229 bool m1; // 1 bytes
230 bool m3; // 1 bytes
231 // + 2 bytes padding
232 int m5; // 4 bytes
233 int64_t m6; // 8 bytes
234 };
235 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 56);
236 EXPECT_EQ(sizeof(protobuf_unittest::TestMessageSize), sizeof(MockGenerated));
237 }
238
TEST(GeneratedMessageTest,PackedTypesSize)239 TEST(GeneratedMessageTest, PackedTypesSize) {
240 struct MockGenerated : public MockMessageBase { // 16 bytes
241 MockRepeatedField packed_int32; // 16 bytes
242 int packed_int32_cached_byte_size; // 4 bytes + 4 bytes padding
243 MockRepeatedField packed_int64; // 16 bytes
244 int packed_int64_cached_byte_size; // 4 bytes + 4 bytes padding
245 MockRepeatedField packed_uint32; // 16 bytes
246 int packed_uint32_cached_byte_size; // 4 bytes + 4 bytes padding
247 MockRepeatedField packed_uint64; // 16 bytes
248 int packed_uint64_cached_byte_size; // 4 bytes + 4 bytes padding
249 MockRepeatedField packed_sint32; // 16 bytes
250 int packed_sint32_cached_byte_size; // 4 bytes + 4 bytes padding
251 MockRepeatedField packed_sint64; // 16 bytes
252 int packed_sint64_cached_byte_size; // 4 bytes + 4 bytes padding
253 MockRepeatedField packed_fixed32; // 16 bytes
254 MockRepeatedField packed_fixed64; // 16 bytes
255 MockRepeatedField packed_sfixed32; // 16 bytes
256 MockRepeatedField packed_sfixed64; // 16 bytes
257 MockRepeatedField packed_float; // 16 bytes
258 MockRepeatedField packed_double; // 16 bytes
259 MockRepeatedField packed_bool; // 16 bytes
260 MockRepeatedField packed_enum; // 16 bytes
261 int packed_enum_cached_byte_size; // 4 bytes
262 int cached_size; // 4 bytes
263 };
264 GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 16 * 15 + 8 * 6 + 8);
265 EXPECT_EQ(sizeof(protobuf_unittest::TestPackedTypes), sizeof(MockGenerated));
266 }
267
268 } // namespace cpp_unittest
269 } // namespace cpp
270 } // namespace compiler
271 } // namespace protobuf
272 } // namespace google
273