• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include <cstdint>
9 #include <string>
10 
11 #include <gtest/gtest.h>
12 #include "absl/log/absl_check.h"
13 #include "google/protobuf/descriptor.h"
14 #include "google/protobuf/generated_message_bases.h"
15 #include "google/protobuf/repeated_ptr_field.h"
16 #include "google/protobuf/unittest.pb.h"
17 
18 // Must be included last.
19 #include "google/protobuf/port_def.inc"
20 
21 namespace google {
22 namespace protobuf {
23 namespace compiler {
24 namespace cpp {
25 
26 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
27 namespace cpp_unittest {
28 
29 
30 #if !defined(ABSL_CHECK_MESSAGE_SIZE)
31 #define ABSL_CHECK_MESSAGE_SIZE(t, expected)
32 #endif
33 
34 // Mock structures to lock down the size of messages in a platform-independent
35 // way.  The commented sizes only apply when build with clang x86_64.
36 struct MockMessageBase {
37   virtual ~MockMessageBase() = default;  // 8 bytes vtable
38   void* internal_metadata;               // 8 bytes
39 };
40 ABSL_CHECK_MESSAGE_SIZE(MockMessageBase, 16);
41 
42 struct MockZeroFieldsBase : public MockMessageBase {
43   int cached_size;  // 4 bytes
44   // + 4 bytes padding
45 };
46 ABSL_CHECK_MESSAGE_SIZE(MockZeroFieldsBase, 24);
47 
48 struct MockExtensionSet {
49   void* arena;       // 8 bytes
50   int16_t capacity;  // 4 bytes
51   int16_t size;      // 4 bytes
52   void* data;        // 8 bytes
53 };
54 ABSL_CHECK_MESSAGE_SIZE(MockExtensionSet, 24);
55 
56 struct MockRepeatedPtrField {
57   void* arena;       // 8 bytes
58   int current_size;  // 4 bytes
59   int total_size;    // 4 bytes
60   void* data;        // 8 bytes
61 };
62 ABSL_CHECK_MESSAGE_SIZE(MockRepeatedPtrField, 24);
63 
64 struct MockRepeatedField {
65   int current_size;  // 4 bytes
66   int total_size;    // 4 bytes
67   void* data;        // 8 bytes
68 };
69 ABSL_CHECK_MESSAGE_SIZE(MockRepeatedField, 16);
70 
TEST(GeneratedMessageTest,MockSizes)71 TEST(GeneratedMessageTest, MockSizes) {
72   // Consistency checks -- if these fail, the tests below will definitely fail.
73   ABSL_CHECK_EQ(sizeof(MessageLite), sizeof(MockMessageBase));
74   ABSL_CHECK_EQ(sizeof(Message), sizeof(MockMessageBase));
75   ABSL_CHECK_EQ(sizeof(internal::ZeroFieldsBase), sizeof(MockZeroFieldsBase));
76   ABSL_CHECK_EQ(sizeof(internal::ExtensionSet), sizeof(MockExtensionSet));
77   ABSL_CHECK_EQ(sizeof(RepeatedPtrField<std::string>),
78                 sizeof(MockRepeatedPtrField));
79   ABSL_CHECK_EQ(sizeof(RepeatedField<int>), sizeof(MockRepeatedField));
80 }
81 
TEST(GeneratedMessageTest,EmptyMessageSize)82 TEST(GeneratedMessageTest, EmptyMessageSize) {
83   EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessage),
84             sizeof(MockZeroFieldsBase));
85 }
86 
TEST(GeneratedMessageTest,ReservedSize)87 TEST(GeneratedMessageTest, ReservedSize) {
88   EXPECT_EQ(sizeof(protobuf_unittest::TestReservedFields),
89             sizeof(MockZeroFieldsBase));
90 }
91 
TEST(GeneratedMessageTest,EmptyMessageWithExtensionsSize)92 TEST(GeneratedMessageTest, EmptyMessageWithExtensionsSize) {
93   struct MockGenerated : public MockMessageBase {  // 16 bytes
94     MockExtensionSet extensions;                   // 24 bytes
95     int cached_size;                               // 4 bytes
96     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
97     // + 0-4 bytes of padding
98   };
99   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 48);
100   EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessageWithExtensions),
101             sizeof(MockGenerated));
102 }
103 
TEST(GeneratedMessageTest,RecursiveMessageSize)104 TEST(GeneratedMessageTest, RecursiveMessageSize) {
105   // TODO: remove once synthetic_pdproto lands.
106 #ifndef PROTOBUF_FORCE_SPLIT
107   struct MockGenerated : public MockMessageBase {  // 16 bytes
108     int has_bits[1];                               // 4 bytes
109     int cached_size;                               // 4 bytes
110     void* a;                                       // 8 bytes
111     int32_t i;                                     // 4 bytes
112     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
113     // + 0-4 bytes padding
114   };
115   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 40);
116 #else   // !PROTOBUF_FORCE_SPLIT
117   struct MockGenerated : public MockMessageBase {  // 16 bytes
118     int has_bits[1];                               // 4 bytes
119     int cached_size;                               // 4 bytes
120     void* split;                                   // 8 bytes
121     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
122     // + 0-4 bytes padding
123   };
124   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
125 #endif  // PROTOBUF_FORCE_SPLIT
126 
127   EXPECT_EQ(sizeof(protobuf_unittest::TestRecursiveMessage),
128             sizeof(MockGenerated));
129 }
130 
TEST(GeneratedMessageTest,OneStringSize)131 TEST(GeneratedMessageTest, OneStringSize) {
132   struct MockGenerated : public MockMessageBase {  // 16 bytes
133     int has_bits[1];                               // 4 bytes
134     int cached_size;                               // 4 bytes
135     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
136                                                    // + 0-4 bytes padding
137     void* data;                                    // 8 bytes
138   };
139   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
140   EXPECT_EQ(sizeof(protobuf_unittest::OneString), sizeof(MockGenerated));
141 }
142 
TEST(GeneratedMessageTest,MoreStringSize)143 TEST(GeneratedMessageTest, MoreStringSize) {
144   // TODO: remove once synthetic_pdproto lands.
145 #ifndef PROTOBUF_FORCE_SPLIT
146   struct MockGenerated : public MockMessageBase {  // 16 bytes
147     int cached_size;                               // 4 bytes
148     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
149                                                    // + 0-4 bytes padding
150     MockRepeatedPtrField data;                     // 24 bytes
151   };
152   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 48);
153 #else   // !PROTOBUF_FORCE_SPLIT
154   struct MockGenerated : public MockMessageBase {  // 16 bytes
155     int cached_size;                               // 4 bytes
156     void* split;                                   // 8 bytes
157     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
158                                                    // + 0-4 bytes padding
159   };
160   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
161 #endif  // PROTOBUF_FORCE_SPLIT
162   EXPECT_EQ(sizeof(protobuf_unittest::MoreString), sizeof(MockGenerated));
163 }
164 
TEST(GeneratedMessageTest,Int32MessageSize)165 TEST(GeneratedMessageTest, Int32MessageSize) {
166   struct MockGenerated : public MockMessageBase {  // 16 bytes
167     int has_bits[1];                               // 4 bytes
168     int cached_size;                               // 4 bytes
169     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
170                                                    // + 0-4 bytes padding
171     int32_t data;                                  // 4 bytes
172   };
173   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
174   EXPECT_EQ(sizeof(protobuf_unittest::Int32Message), sizeof(MockGenerated));
175 }
176 
TEST(GeneratedMessageTest,Int64MessageSize)177 TEST(GeneratedMessageTest, Int64MessageSize) {
178   struct MockGenerated : public MockMessageBase {  // 16 bytes
179     int has_bits[1];                               // 4 bytes
180     int cached_size;                               // 4 bytes
181     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
182                                                    // + 0-4 bytes padding
183     int64_t data;                                  // 8 bytes
184   };
185   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
186   EXPECT_EQ(sizeof(protobuf_unittest::Int64Message), sizeof(MockGenerated));
187 }
188 
TEST(GeneratedMessageTest,BoolMessageSize)189 TEST(GeneratedMessageTest, BoolMessageSize) {
190   struct MockGenerated : public MockMessageBase {  // 16 bytes
191     int has_bits[1];                               // 4 bytes
192     int cached_size;                               // 4 bytes
193     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
194                                                    // + 0-4 bytes padding
195     bool data;                                     // 1 byte
196     // + 3 bytes padding
197   };
198   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
199   EXPECT_EQ(sizeof(protobuf_unittest::BoolMessage), sizeof(MockGenerated));
200 }
201 
TEST(GeneratedMessageTest,OneofSize)202 TEST(GeneratedMessageTest, OneofSize) {
203   struct MockGenerated : public MockMessageBase {  // 16 bytes
204     void* foo;                                     // 8 bytes
205     int cached_size;                               // 4 bytes
206     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
207                                                    // + 0-4 bytes padding
208     uint32_t oneof_case[1];                        // 4 bytes
209   };
210   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
211   EXPECT_EQ(sizeof(protobuf_unittest::TestOneof), sizeof(MockGenerated));
212 }
213 
TEST(GeneratedMessageTest,Oneof2Size)214 TEST(GeneratedMessageTest, Oneof2Size) {
215   // TODO: remove once synthetic_pdproto lands.
216 #ifndef PROTOBUF_FORCE_SPLIT
217   struct MockGenerated : public MockMessageBase {  // 16 bytes
218     int has_bits[1];                               // 4 bytes
219     int cached_size;                               // 4 bytes
220     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
221                                                    // + 0-4 bytes padding
222     void* baz_string;                              // 8 bytes
223     int32_t baz_int;                               // 4 bytes
224                                                    // + 4 bytes padding
225     void* foo;                                     // 8 bytes
226     void* bar;                                     // 8 bytes
227     uint32_t oneof_case[2];                        // 8 bytes
228   };
229   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 64);
230 #else   // !PROTOBUF_FORCE_SPLIT
231   struct MockGenerated : public MockMessageBase {  // 16 bytes
232     int has_bits[1];                               // 4 bytes
233     int cached_size;                               // 4 bytes
234     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
235                                                    // + 0-4 bytes padding
236     void* split;                                   // 8 bytes
237     void* foo;                                     // 8 bytes
238     void* bar;                                     // 8 bytes
239     uint32_t oneof_case[2];                        // 8 bytes
240   };
241   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 56);
242 #endif  // PROTOBUF_FORCE_SPLIT
243   EXPECT_EQ(sizeof(protobuf_unittest::TestOneof2), sizeof(MockGenerated));
244 }
245 
TEST(GeneratedMessageTest,FieldOrderingsSize)246 TEST(GeneratedMessageTest, FieldOrderingsSize) {
247   // TODO: remove once synthetic_pdproto lands.
248 #ifndef PROTOBUF_FORCE_SPLIT
249   struct MockGenerated : public MockMessageBase {  // 16 bytes
250     int has_bits[1];                               // 4 bytes
251     int cached_size;                               // 4 bytes
252     MockExtensionSet extensions;                   // 24 bytes
253     void* my_string;                               // 8 bytes
254     void* optional_nested_message;                 // 8 bytes
255     int64_t my_int;                                // 8 bytes
256     float my_float;                                // 4 bytes
257     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
258     // + 0-4 bytes padding
259   };
260   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 80);
261 #else   // !PROTOBUF_FORCE_SPLIT
262   struct MockGenerated : public MockMessageBase {  // 16 bytes
263     int has_bits[1];                               // 4 bytes
264     int cached_size;                               // 4 bytes
265     MockExtensionSet extensions;                   // 24 bytes
266     void* split;                                   // 8 bytes
267     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
268     // + 0-4 bytes padding
269   };
270   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 56);
271 #endif  // PROTOBUF_FORCE_SPLIT
272   EXPECT_EQ(sizeof(protobuf_unittest::TestFieldOrderings), sizeof(MockGenerated));
273 }
274 
TEST(GeneratedMessageTest,TestMessageSize)275 TEST(GeneratedMessageTest, TestMessageSize) {
276   // We expect the message to contain (not in this order):
277   // TODO: remove once synthetic_pdproto lands.
278 #ifndef PROTOBUF_FORCE_SPLIT
279   struct MockGenerated : public MockMessageBase {  // 16 bytes
280     int has_bits[1];                               // 4 bytes
281     int cached_size;                               // 4 bytes
282     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
283                                                    // + 0-4 bytes padding
284     void* m4;                                      // 8 bytes
285     int64_t m2;                                    // 8 bytes
286     bool m1;                                       // 1 bytes
287     bool m3;                                       // 1 bytes
288                                                    // + 2 bytes padding
289     int m5;                                        // 4 bytes
290     int64_t m6;                                    // 8 bytes
291   };
292   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 56);
293 #else   // !PROTOBUF_FORCE_SPLIT
294   struct MockGenerated : public MockMessageBase {  // 16 bytes
295     int has_bits[1];                               // 4 bytes
296     int cached_size;                               // 4 bytes
297     void* split;                                   // 8 bytes
298     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
299                                                    // + 0-4 bytes padding
300   };
301   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
302 #endif  // PROTOBUF_FORCE_SPLIT
303   EXPECT_EQ(sizeof(protobuf_unittest::TestMessageSize), sizeof(MockGenerated));
304 }
305 
TEST(GeneratedMessageTest,PackedTypesSize)306 TEST(GeneratedMessageTest, PackedTypesSize) {
307   // TODO: remove once synthetic_pdproto lands.
308 #ifndef PROTOBUF_FORCE_SPLIT
309   struct MockGenerated : public MockMessageBase {  // 16 bytes
310     MockRepeatedField packed_int32;                // 16 bytes
311     int packed_int32_cached_byte_size;             // 4 bytes + 4 bytes padding
312     MockRepeatedField packed_int64;                // 16 bytes
313     int packed_int64_cached_byte_size;             // 4 bytes + 4 bytes padding
314     MockRepeatedField packed_uint32;               // 16 bytes
315     int packed_uint32_cached_byte_size;            // 4 bytes + 4 bytes padding
316     MockRepeatedField packed_uint64;               // 16 bytes
317     int packed_uint64_cached_byte_size;            // 4 bytes + 4 bytes padding
318     MockRepeatedField packed_sint32;               // 16 bytes
319     int packed_sint32_cached_byte_size;            // 4 bytes + 4 bytes padding
320     MockRepeatedField packed_sint64;               // 16 bytes
321     int packed_sint64_cached_byte_size;            // 4 bytes + 4 bytes padding
322     MockRepeatedField packed_fixed32;              // 16 bytes
323     MockRepeatedField packed_fixed64;              // 16 bytes
324     MockRepeatedField packed_sfixed32;             // 16 bytes
325     MockRepeatedField packed_sfixed64;             // 16 bytes
326     MockRepeatedField packed_float;                // 16 bytes
327     MockRepeatedField packed_double;               // 16 bytes
328     MockRepeatedField packed_bool;                 // 16 bytes
329     MockRepeatedField packed_enum;                 // 16 bytes
330     int packed_enum_cached_byte_size;              // 4 bytes
331     int cached_size;                               // 4 bytes
332     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
333     // + 0-4 bytes padding
334   };
335   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 16 * 15 + 8 * 6 + 8);
336 #else   // !PROTOBUF_FORCE_SPLIT
337   struct MockGenerated : public MockMessageBase {  // 16 bytes
338     int cached_size;                               // 4 bytes + 4 bytes padding
339     void* split;                                   // 8 bytes
340     PROTOBUF_TSAN_DECLARE_MEMBER;                  // 0-4 bytes
341     // + 0-4 bytes padding
342   };
343   ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32);
344 #endif  // PROTOBUF_FORCE_SPLIT
345   EXPECT_EQ(sizeof(protobuf_unittest::TestPackedTypes), sizeof(MockGenerated));
346 }
347 
348 }  // namespace cpp_unittest
349 }  // namespace cpp
350 }  // namespace compiler
351 }  // namespace protobuf
352 }  // namespace google
353 
354 #include "google/protobuf/port_undef.inc"
355