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 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/extension_set.h>
36
37 #include <tuple>
38 #include <unordered_map>
39 #include <utility>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/extension_set_inl.h>
42 #include <google/protobuf/parse_context.h>
43 #include <google/protobuf/io/coded_stream.h>
44 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
45 #include <google/protobuf/message_lite.h>
46 #include <google/protobuf/metadata_lite.h>
47 #include <google/protobuf/repeated_field.h>
48 #include <google/protobuf/stubs/map_util.h>
49 #include <google/protobuf/stubs/hash.h>
50
51 #include <google/protobuf/port_def.inc>
52
53 namespace google {
54 namespace protobuf {
55 namespace internal {
56
57 namespace {
58
real_type(FieldType type)59 inline WireFormatLite::FieldType real_type(FieldType type) {
60 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
61 return static_cast<WireFormatLite::FieldType>(type);
62 }
63
cpp_type(FieldType type)64 inline WireFormatLite::CppType cpp_type(FieldType type) {
65 return WireFormatLite::FieldTypeToCppType(real_type(type));
66 }
67
is_packable(WireFormatLite::WireType type)68 inline bool is_packable(WireFormatLite::WireType type) {
69 switch (type) {
70 case WireFormatLite::WIRETYPE_VARINT:
71 case WireFormatLite::WIRETYPE_FIXED64:
72 case WireFormatLite::WIRETYPE_FIXED32:
73 return true;
74 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
75 case WireFormatLite::WIRETYPE_START_GROUP:
76 case WireFormatLite::WIRETYPE_END_GROUP:
77 return false;
78
79 // Do not add a default statement. Let the compiler complain when someone
80 // adds a new wire type.
81 }
82 GOOGLE_LOG(FATAL) << "can't reach here.";
83 return false;
84 }
85
86 // Registry stuff.
87 struct ExtensionHasher {
operator ()google::protobuf::internal::__anon293ef5e10111::ExtensionHasher88 std::size_t operator()(const std::pair<const MessageLite*, int>& p) const {
89 return std::hash<const MessageLite*>{}(p.first) ^
90 std::hash<int>{}(p.second);
91 }
92 };
93
94 typedef std::unordered_map<std::pair<const MessageLite*, int>, ExtensionInfo,
95 ExtensionHasher>
96 ExtensionRegistry;
97
98 static const ExtensionRegistry* global_registry = nullptr;
99
100 // This function is only called at startup, so there is no need for thread-
101 // safety.
Register(const MessageLite * containing_type,int number,ExtensionInfo info)102 void Register(const MessageLite* containing_type, int number,
103 ExtensionInfo info) {
104 static auto local_static_registry = OnShutdownDelete(new ExtensionRegistry);
105 global_registry = local_static_registry;
106 if (!InsertIfNotPresent(local_static_registry,
107 std::make_pair(containing_type, number), info)) {
108 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
109 << containing_type->GetTypeName() << "\", field number "
110 << number << ".";
111 }
112 }
113
FindRegisteredExtension(const MessageLite * containing_type,int number)114 const ExtensionInfo* FindRegisteredExtension(const MessageLite* containing_type,
115 int number) {
116 return global_registry == nullptr
117 ? nullptr
118 : FindOrNull(*global_registry,
119 std::make_pair(containing_type, number));
120 }
121
122 } // namespace
123
~ExtensionFinder()124 ExtensionFinder::~ExtensionFinder() {}
125
Find(int number,ExtensionInfo * output)126 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
127 const ExtensionInfo* extension =
128 FindRegisteredExtension(containing_type_, number);
129 if (extension == NULL) {
130 return false;
131 } else {
132 *output = *extension;
133 return true;
134 }
135 }
136
RegisterExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed)137 void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
138 int number, FieldType type,
139 bool is_repeated, bool is_packed) {
140 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
141 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
142 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
143 ExtensionInfo info(type, is_repeated, is_packed);
144 Register(containing_type, number, info);
145 }
146
CallNoArgValidityFunc(const void * arg,int number)147 static bool CallNoArgValidityFunc(const void* arg, int number) {
148 // Note: Must use C-style cast here rather than reinterpret_cast because
149 // the C++ standard at one point did not allow casts between function and
150 // data pointers and some compilers enforce this for C++-style casts. No
151 // compiler enforces it for C-style casts since lots of C-style code has
152 // relied on these kinds of casts for a long time, despite being
153 // technically undefined. See:
154 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
155 // Also note: Some compilers do not allow function pointers to be "const".
156 // Which makes sense, I suppose, because it's meaningless.
157 return ((EnumValidityFunc*)arg)(number);
158 }
159
RegisterEnumExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,EnumValidityFunc * is_valid)160 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
161 int number, FieldType type,
162 bool is_repeated, bool is_packed,
163 EnumValidityFunc* is_valid) {
164 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
165 ExtensionInfo info(type, is_repeated, is_packed);
166 info.enum_validity_check.func = CallNoArgValidityFunc;
167 // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
168 info.enum_validity_check.arg = (void*)is_valid;
169 Register(containing_type, number, info);
170 }
171
RegisterMessageExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,const MessageLite * prototype)172 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
173 int number, FieldType type,
174 bool is_repeated, bool is_packed,
175 const MessageLite* prototype) {
176 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
177 type == WireFormatLite::TYPE_GROUP);
178 ExtensionInfo info(type, is_repeated, is_packed);
179 info.message_info = {prototype};
180 Register(containing_type, number, info);
181 }
182
183
184 // ===================================================================
185 // Constructors and basic methods.
186
ExtensionSet(Arena * arena)187 ExtensionSet::ExtensionSet(Arena* arena)
188 : arena_(arena),
189 flat_capacity_(0),
190 flat_size_(0),
191 map_{flat_capacity_ == 0
192 ? NULL
193 : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
194
ExtensionSet()195 ExtensionSet::ExtensionSet()
196 : arena_(NULL),
197 flat_capacity_(0),
198 flat_size_(0),
199 map_{flat_capacity_ == 0
200 ? NULL
201 : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
202
~ExtensionSet()203 ExtensionSet::~ExtensionSet() {
204 // Deletes all allocated extensions.
205 if (arena_ == NULL) {
206 ForEach([](int /* number */, Extension& ext) { ext.Free(); });
207 if (PROTOBUF_PREDICT_FALSE(is_large())) {
208 delete map_.large;
209 } else {
210 DeleteFlatMap(map_.flat, flat_capacity_);
211 }
212 }
213 }
214
DeleteFlatMap(const ExtensionSet::KeyValue * flat,uint16 flat_capacity)215 void ExtensionSet::DeleteFlatMap(const ExtensionSet::KeyValue* flat,
216 uint16 flat_capacity) {
217 #ifdef __cpp_sized_deallocation
218 // Arena::CreateArray already requires a trivially destructible type, but
219 // ensure this constraint is not violated in the future.
220 static_assert(std::is_trivially_destructible<KeyValue>::value,
221 "CreateArray requires a trivially destructible type");
222 // A const-cast is needed, but this is safe as we are about to deallocate the
223 // array.
224 ::operator delete[](const_cast<ExtensionSet::KeyValue*>(flat),
225 sizeof(*flat) * flat_capacity);
226 #else // !__cpp_sized_deallocation
227 delete[] flat;
228 #endif // !__cpp_sized_deallocation
229 }
230
231 // Defined in extension_set_heavy.cc.
232 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
233 // const DescriptorPool* pool,
234 // vector<const FieldDescriptor*>* output) const
235
Has(int number) const236 bool ExtensionSet::Has(int number) const {
237 const Extension* ext = FindOrNull(number);
238 if (ext == NULL) return false;
239 GOOGLE_DCHECK(!ext->is_repeated);
240 return !ext->is_cleared;
241 }
242
NumExtensions() const243 int ExtensionSet::NumExtensions() const {
244 int result = 0;
245 ForEach([&result](int /* number */, const Extension& ext) {
246 if (!ext.is_cleared) {
247 ++result;
248 }
249 });
250 return result;
251 }
252
ExtensionSize(int number) const253 int ExtensionSet::ExtensionSize(int number) const {
254 const Extension* ext = FindOrNull(number);
255 return ext == NULL ? 0 : ext->GetSize();
256 }
257
ExtensionType(int number) const258 FieldType ExtensionSet::ExtensionType(int number) const {
259 const Extension* ext = FindOrNull(number);
260 if (ext == NULL) {
261 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
262 return 0;
263 }
264 if (ext->is_cleared) {
265 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
266 }
267 return ext->type;
268 }
269
ClearExtension(int number)270 void ExtensionSet::ClearExtension(int number) {
271 Extension* ext = FindOrNull(number);
272 if (ext == NULL) return;
273 ext->Clear();
274 }
275
276 // ===================================================================
277 // Field accessors
278
279 namespace {
280
281 enum { REPEATED_FIELD, OPTIONAL_FIELD };
282
283 } // namespace
284
285 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
286 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED_FIELD : OPTIONAL_FIELD, LABEL); \
287 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
288
289 // -------------------------------------------------------------------
290 // Primitives
291
292 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
293 \
294 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, LOWERCASE default_value) \
295 const { \
296 const Extension* extension = FindOrNull(number); \
297 if (extension == NULL || extension->is_cleared) { \
298 return default_value; \
299 } else { \
300 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \
301 return extension->LOWERCASE##_value; \
302 } \
303 } \
304 \
305 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
306 LOWERCASE value, \
307 const FieldDescriptor* descriptor) { \
308 Extension* extension; \
309 if (MaybeNewExtension(number, descriptor, &extension)) { \
310 extension->type = type; \
311 GOOGLE_DCHECK_EQ(cpp_type(extension->type), \
312 WireFormatLite::CPPTYPE_##UPPERCASE); \
313 extension->is_repeated = false; \
314 } else { \
315 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE); \
316 } \
317 extension->is_cleared = false; \
318 extension->LOWERCASE##_value = value; \
319 } \
320 \
321 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) \
322 const { \
323 const Extension* extension = FindOrNull(number); \
324 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty)."; \
325 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \
326 return extension->repeated_##LOWERCASE##_value->Get(index); \
327 } \
328 \
329 void ExtensionSet::SetRepeated##CAMELCASE(int number, int index, \
330 LOWERCASE value) { \
331 Extension* extension = FindOrNull(number); \
332 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty)."; \
333 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \
334 extension->repeated_##LOWERCASE##_value->Set(index, value); \
335 } \
336 \
337 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, bool packed, \
338 LOWERCASE value, \
339 const FieldDescriptor* descriptor) { \
340 Extension* extension; \
341 if (MaybeNewExtension(number, descriptor, &extension)) { \
342 extension->type = type; \
343 GOOGLE_DCHECK_EQ(cpp_type(extension->type), \
344 WireFormatLite::CPPTYPE_##UPPERCASE); \
345 extension->is_repeated = true; \
346 extension->is_packed = packed; \
347 extension->repeated_##LOWERCASE##_value = \
348 Arena::CreateMessage<RepeatedField<LOWERCASE>>(arena_); \
349 } else { \
350 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE); \
351 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
352 } \
353 extension->repeated_##LOWERCASE##_value->Add(value); \
354 }
355
PRIMITIVE_ACCESSORS(INT32,int32,Int32)356 PRIMITIVE_ACCESSORS(INT32, int32, Int32)
357 PRIMITIVE_ACCESSORS(INT64, int64, Int64)
358 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
359 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
360 PRIMITIVE_ACCESSORS(FLOAT, float, Float)
361 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
362 PRIMITIVE_ACCESSORS(BOOL, bool, Bool)
363
364 #undef PRIMITIVE_ACCESSORS
365
366 const void* ExtensionSet::GetRawRepeatedField(int number,
367 const void* default_value) const {
368 const Extension* extension = FindOrNull(number);
369 if (extension == NULL) {
370 return default_value;
371 }
372 // We assume that all the RepeatedField<>* pointers have the same
373 // size and alignment within the anonymous union in Extension.
374 return extension->repeated_int32_value;
375 }
376
MutableRawRepeatedField(int number,FieldType field_type,bool packed,const FieldDescriptor * desc)377 void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
378 bool packed,
379 const FieldDescriptor* desc) {
380 Extension* extension;
381
382 // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
383 // extension.
384 if (MaybeNewExtension(number, desc, &extension)) {
385 extension->is_repeated = true;
386 extension->type = field_type;
387 extension->is_packed = packed;
388
389 switch (WireFormatLite::FieldTypeToCppType(
390 static_cast<WireFormatLite::FieldType>(field_type))) {
391 case WireFormatLite::CPPTYPE_INT32:
392 extension->repeated_int32_value =
393 Arena::CreateMessage<RepeatedField<int32>>(arena_);
394 break;
395 case WireFormatLite::CPPTYPE_INT64:
396 extension->repeated_int64_value =
397 Arena::CreateMessage<RepeatedField<int64>>(arena_);
398 break;
399 case WireFormatLite::CPPTYPE_UINT32:
400 extension->repeated_uint32_value =
401 Arena::CreateMessage<RepeatedField<uint32>>(arena_);
402 break;
403 case WireFormatLite::CPPTYPE_UINT64:
404 extension->repeated_uint64_value =
405 Arena::CreateMessage<RepeatedField<uint64>>(arena_);
406 break;
407 case WireFormatLite::CPPTYPE_DOUBLE:
408 extension->repeated_double_value =
409 Arena::CreateMessage<RepeatedField<double>>(arena_);
410 break;
411 case WireFormatLite::CPPTYPE_FLOAT:
412 extension->repeated_float_value =
413 Arena::CreateMessage<RepeatedField<float>>(arena_);
414 break;
415 case WireFormatLite::CPPTYPE_BOOL:
416 extension->repeated_bool_value =
417 Arena::CreateMessage<RepeatedField<bool>>(arena_);
418 break;
419 case WireFormatLite::CPPTYPE_ENUM:
420 extension->repeated_enum_value =
421 Arena::CreateMessage<RepeatedField<int>>(arena_);
422 break;
423 case WireFormatLite::CPPTYPE_STRING:
424 extension->repeated_string_value =
425 Arena::CreateMessage<RepeatedPtrField<std::string>>(arena_);
426 break;
427 case WireFormatLite::CPPTYPE_MESSAGE:
428 extension->repeated_message_value =
429 Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_);
430 break;
431 }
432 }
433
434 // We assume that all the RepeatedField<>* pointers have the same
435 // size and alignment within the anonymous union in Extension.
436 return extension->repeated_int32_value;
437 }
438
439 // Compatible version using old call signature. Does not create extensions when
440 // the don't already exist; instead, just GOOGLE_CHECK-fails.
MutableRawRepeatedField(int number)441 void* ExtensionSet::MutableRawRepeatedField(int number) {
442 Extension* extension = FindOrNull(number);
443 GOOGLE_CHECK(extension != NULL) << "Extension not found.";
444 // We assume that all the RepeatedField<>* pointers have the same
445 // size and alignment within the anonymous union in Extension.
446 return extension->repeated_int32_value;
447 }
448
449 // -------------------------------------------------------------------
450 // Enums
451
GetEnum(int number,int default_value) const452 int ExtensionSet::GetEnum(int number, int default_value) const {
453 const Extension* extension = FindOrNull(number);
454 if (extension == NULL || extension->is_cleared) {
455 // Not present. Return the default value.
456 return default_value;
457 } else {
458 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM);
459 return extension->enum_value;
460 }
461 }
462
SetEnum(int number,FieldType type,int value,const FieldDescriptor * descriptor)463 void ExtensionSet::SetEnum(int number, FieldType type, int value,
464 const FieldDescriptor* descriptor) {
465 Extension* extension;
466 if (MaybeNewExtension(number, descriptor, &extension)) {
467 extension->type = type;
468 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
469 extension->is_repeated = false;
470 } else {
471 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM);
472 }
473 extension->is_cleared = false;
474 extension->enum_value = value;
475 }
476
GetRepeatedEnum(int number,int index) const477 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
478 const Extension* extension = FindOrNull(number);
479 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
480 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM);
481 return extension->repeated_enum_value->Get(index);
482 }
483
SetRepeatedEnum(int number,int index,int value)484 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
485 Extension* extension = FindOrNull(number);
486 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
487 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM);
488 extension->repeated_enum_value->Set(index, value);
489 }
490
AddEnum(int number,FieldType type,bool packed,int value,const FieldDescriptor * descriptor)491 void ExtensionSet::AddEnum(int number, FieldType type, bool packed, int value,
492 const FieldDescriptor* descriptor) {
493 Extension* extension;
494 if (MaybeNewExtension(number, descriptor, &extension)) {
495 extension->type = type;
496 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
497 extension->is_repeated = true;
498 extension->is_packed = packed;
499 extension->repeated_enum_value =
500 Arena::CreateMessage<RepeatedField<int>>(arena_);
501 } else {
502 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM);
503 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
504 }
505 extension->repeated_enum_value->Add(value);
506 }
507
508 // -------------------------------------------------------------------
509 // Strings
510
GetString(int number,const std::string & default_value) const511 const std::string& ExtensionSet::GetString(
512 int number, const std::string& default_value) const {
513 const Extension* extension = FindOrNull(number);
514 if (extension == NULL || extension->is_cleared) {
515 // Not present. Return the default value.
516 return default_value;
517 } else {
518 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, STRING);
519 return *extension->string_value;
520 }
521 }
522
MutableString(int number,FieldType type,const FieldDescriptor * descriptor)523 std::string* ExtensionSet::MutableString(int number, FieldType type,
524 const FieldDescriptor* descriptor) {
525 Extension* extension;
526 if (MaybeNewExtension(number, descriptor, &extension)) {
527 extension->type = type;
528 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
529 extension->is_repeated = false;
530 extension->string_value = Arena::Create<std::string>(arena_);
531 } else {
532 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, STRING);
533 }
534 extension->is_cleared = false;
535 return extension->string_value;
536 }
537
GetRepeatedString(int number,int index) const538 const std::string& ExtensionSet::GetRepeatedString(int number,
539 int index) const {
540 const Extension* extension = FindOrNull(number);
541 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
542 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING);
543 return extension->repeated_string_value->Get(index);
544 }
545
MutableRepeatedString(int number,int index)546 std::string* ExtensionSet::MutableRepeatedString(int number, int index) {
547 Extension* extension = FindOrNull(number);
548 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
549 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING);
550 return extension->repeated_string_value->Mutable(index);
551 }
552
AddString(int number,FieldType type,const FieldDescriptor * descriptor)553 std::string* ExtensionSet::AddString(int number, FieldType type,
554 const FieldDescriptor* descriptor) {
555 Extension* extension;
556 if (MaybeNewExtension(number, descriptor, &extension)) {
557 extension->type = type;
558 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
559 extension->is_repeated = true;
560 extension->is_packed = false;
561 extension->repeated_string_value =
562 Arena::CreateMessage<RepeatedPtrField<std::string>>(arena_);
563 } else {
564 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING);
565 }
566 return extension->repeated_string_value->Add();
567 }
568
569 // -------------------------------------------------------------------
570 // Messages
571
GetMessage(int number,const MessageLite & default_value) const572 const MessageLite& ExtensionSet::GetMessage(
573 int number, const MessageLite& default_value) const {
574 const Extension* extension = FindOrNull(number);
575 if (extension == NULL) {
576 // Not present. Return the default value.
577 return default_value;
578 } else {
579 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
580 if (extension->is_lazy) {
581 return extension->lazymessage_value->GetMessage(default_value);
582 } else {
583 return *extension->message_value;
584 }
585 }
586 }
587
588 // Defined in extension_set_heavy.cc.
589 // const MessageLite& ExtensionSet::GetMessage(int number,
590 // const Descriptor* message_type,
591 // MessageFactory* factory) const
592
MutableMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)593 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
594 const MessageLite& prototype,
595 const FieldDescriptor* descriptor) {
596 Extension* extension;
597 if (MaybeNewExtension(number, descriptor, &extension)) {
598 extension->type = type;
599 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
600 extension->is_repeated = false;
601 extension->is_lazy = false;
602 extension->message_value = prototype.New(arena_);
603 extension->is_cleared = false;
604 return extension->message_value;
605 } else {
606 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
607 extension->is_cleared = false;
608 if (extension->is_lazy) {
609 return extension->lazymessage_value->MutableMessage(prototype);
610 } else {
611 return extension->message_value;
612 }
613 }
614 }
615
616 // Defined in extension_set_heavy.cc.
617 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
618 // const Descriptor* message_type,
619 // MessageFactory* factory)
620
SetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)621 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
622 const FieldDescriptor* descriptor,
623 MessageLite* message) {
624 if (message == NULL) {
625 ClearExtension(number);
626 return;
627 }
628 Arena* message_arena = message->GetArena();
629 Extension* extension;
630 if (MaybeNewExtension(number, descriptor, &extension)) {
631 extension->type = type;
632 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
633 extension->is_repeated = false;
634 extension->is_lazy = false;
635 if (message_arena == arena_) {
636 extension->message_value = message;
637 } else if (message_arena == NULL) {
638 extension->message_value = message;
639 arena_->Own(message); // not NULL because not equal to message_arena
640 } else {
641 extension->message_value = message->New(arena_);
642 extension->message_value->CheckTypeAndMergeFrom(*message);
643 }
644 } else {
645 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
646 if (extension->is_lazy) {
647 extension->lazymessage_value->SetAllocatedMessage(message);
648 } else {
649 if (arena_ == NULL) {
650 delete extension->message_value;
651 }
652 if (message_arena == arena_) {
653 extension->message_value = message;
654 } else if (message_arena == NULL) {
655 extension->message_value = message;
656 arena_->Own(message); // not NULL because not equal to message_arena
657 } else {
658 extension->message_value = message->New(arena_);
659 extension->message_value->CheckTypeAndMergeFrom(*message);
660 }
661 }
662 }
663 extension->is_cleared = false;
664 }
665
UnsafeArenaSetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)666 void ExtensionSet::UnsafeArenaSetAllocatedMessage(
667 int number, FieldType type, const FieldDescriptor* descriptor,
668 MessageLite* message) {
669 if (message == NULL) {
670 ClearExtension(number);
671 return;
672 }
673 Extension* extension;
674 if (MaybeNewExtension(number, descriptor, &extension)) {
675 extension->type = type;
676 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
677 extension->is_repeated = false;
678 extension->is_lazy = false;
679 extension->message_value = message;
680 } else {
681 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
682 if (extension->is_lazy) {
683 extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message);
684 } else {
685 if (arena_ == NULL) {
686 delete extension->message_value;
687 }
688 extension->message_value = message;
689 }
690 }
691 extension->is_cleared = false;
692 }
693
ReleaseMessage(int number,const MessageLite & prototype)694 MessageLite* ExtensionSet::ReleaseMessage(int number,
695 const MessageLite& prototype) {
696 Extension* extension = FindOrNull(number);
697 if (extension == NULL) {
698 // Not present. Return NULL.
699 return NULL;
700 } else {
701 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
702 MessageLite* ret = NULL;
703 if (extension->is_lazy) {
704 ret = extension->lazymessage_value->ReleaseMessage(prototype);
705 if (arena_ == NULL) {
706 delete extension->lazymessage_value;
707 }
708 } else {
709 if (arena_ == NULL) {
710 ret = extension->message_value;
711 } else {
712 // ReleaseMessage() always returns a heap-allocated message, and we are
713 // on an arena, so we need to make a copy of this message to return.
714 ret = extension->message_value->New();
715 ret->CheckTypeAndMergeFrom(*extension->message_value);
716 }
717 }
718 Erase(number);
719 return ret;
720 }
721 }
722
UnsafeArenaReleaseMessage(int number,const MessageLite & prototype)723 MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
724 int number, const MessageLite& prototype) {
725 Extension* extension = FindOrNull(number);
726 if (extension == NULL) {
727 // Not present. Return NULL.
728 return NULL;
729 } else {
730 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
731 MessageLite* ret = NULL;
732 if (extension->is_lazy) {
733 ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(prototype);
734 if (arena_ == NULL) {
735 delete extension->lazymessage_value;
736 }
737 } else {
738 ret = extension->message_value;
739 }
740 Erase(number);
741 return ret;
742 }
743 }
744
745 // Defined in extension_set_heavy.cc.
746 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
747 // MessageFactory* factory);
748
GetRepeatedMessage(int number,int index) const749 const MessageLite& ExtensionSet::GetRepeatedMessage(int number,
750 int index) const {
751 const Extension* extension = FindOrNull(number);
752 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
753 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE);
754 return extension->repeated_message_value->Get(index);
755 }
756
MutableRepeatedMessage(int number,int index)757 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
758 Extension* extension = FindOrNull(number);
759 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
760 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE);
761 return extension->repeated_message_value->Mutable(index);
762 }
763
AddMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)764 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
765 const MessageLite& prototype,
766 const FieldDescriptor* descriptor) {
767 Extension* extension;
768 if (MaybeNewExtension(number, descriptor, &extension)) {
769 extension->type = type;
770 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
771 extension->is_repeated = true;
772 extension->repeated_message_value =
773 Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_);
774 } else {
775 GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE);
776 }
777
778 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
779 // allocate an abstract object, so we have to be tricky.
780 MessageLite* result = reinterpret_cast<internal::RepeatedPtrFieldBase*>(
781 extension->repeated_message_value)
782 ->AddFromCleared<GenericTypeHandler<MessageLite>>();
783 if (result == NULL) {
784 result = prototype.New(arena_);
785 extension->repeated_message_value->AddAllocated(result);
786 }
787 return result;
788 }
789
790 // Defined in extension_set_heavy.cc.
791 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
792 // const Descriptor* message_type,
793 // MessageFactory* factory)
794
795 #undef GOOGLE_DCHECK_TYPE
796
RemoveLast(int number)797 void ExtensionSet::RemoveLast(int number) {
798 Extension* extension = FindOrNull(number);
799 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
800 GOOGLE_DCHECK(extension->is_repeated);
801
802 switch (cpp_type(extension->type)) {
803 case WireFormatLite::CPPTYPE_INT32:
804 extension->repeated_int32_value->RemoveLast();
805 break;
806 case WireFormatLite::CPPTYPE_INT64:
807 extension->repeated_int64_value->RemoveLast();
808 break;
809 case WireFormatLite::CPPTYPE_UINT32:
810 extension->repeated_uint32_value->RemoveLast();
811 break;
812 case WireFormatLite::CPPTYPE_UINT64:
813 extension->repeated_uint64_value->RemoveLast();
814 break;
815 case WireFormatLite::CPPTYPE_FLOAT:
816 extension->repeated_float_value->RemoveLast();
817 break;
818 case WireFormatLite::CPPTYPE_DOUBLE:
819 extension->repeated_double_value->RemoveLast();
820 break;
821 case WireFormatLite::CPPTYPE_BOOL:
822 extension->repeated_bool_value->RemoveLast();
823 break;
824 case WireFormatLite::CPPTYPE_ENUM:
825 extension->repeated_enum_value->RemoveLast();
826 break;
827 case WireFormatLite::CPPTYPE_STRING:
828 extension->repeated_string_value->RemoveLast();
829 break;
830 case WireFormatLite::CPPTYPE_MESSAGE:
831 extension->repeated_message_value->RemoveLast();
832 break;
833 }
834 }
835
ReleaseLast(int number)836 MessageLite* ExtensionSet::ReleaseLast(int number) {
837 Extension* extension = FindOrNull(number);
838 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
839 GOOGLE_DCHECK(extension->is_repeated);
840 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
841 return extension->repeated_message_value->ReleaseLast();
842 }
843
SwapElements(int number,int index1,int index2)844 void ExtensionSet::SwapElements(int number, int index1, int index2) {
845 Extension* extension = FindOrNull(number);
846 GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
847 GOOGLE_DCHECK(extension->is_repeated);
848
849 switch (cpp_type(extension->type)) {
850 case WireFormatLite::CPPTYPE_INT32:
851 extension->repeated_int32_value->SwapElements(index1, index2);
852 break;
853 case WireFormatLite::CPPTYPE_INT64:
854 extension->repeated_int64_value->SwapElements(index1, index2);
855 break;
856 case WireFormatLite::CPPTYPE_UINT32:
857 extension->repeated_uint32_value->SwapElements(index1, index2);
858 break;
859 case WireFormatLite::CPPTYPE_UINT64:
860 extension->repeated_uint64_value->SwapElements(index1, index2);
861 break;
862 case WireFormatLite::CPPTYPE_FLOAT:
863 extension->repeated_float_value->SwapElements(index1, index2);
864 break;
865 case WireFormatLite::CPPTYPE_DOUBLE:
866 extension->repeated_double_value->SwapElements(index1, index2);
867 break;
868 case WireFormatLite::CPPTYPE_BOOL:
869 extension->repeated_bool_value->SwapElements(index1, index2);
870 break;
871 case WireFormatLite::CPPTYPE_ENUM:
872 extension->repeated_enum_value->SwapElements(index1, index2);
873 break;
874 case WireFormatLite::CPPTYPE_STRING:
875 extension->repeated_string_value->SwapElements(index1, index2);
876 break;
877 case WireFormatLite::CPPTYPE_MESSAGE:
878 extension->repeated_message_value->SwapElements(index1, index2);
879 break;
880 }
881 }
882
883 // ===================================================================
884
Clear()885 void ExtensionSet::Clear() {
886 ForEach([](int /* number */, Extension& ext) { ext.Clear(); });
887 }
888
889 namespace {
890 // Computes the size of a std::set_union without constructing the union.
891 template <typename ItX, typename ItY>
SizeOfUnion(ItX it_xs,ItX end_xs,ItY it_ys,ItY end_ys)892 size_t SizeOfUnion(ItX it_xs, ItX end_xs, ItY it_ys, ItY end_ys) {
893 size_t result = 0;
894 while (it_xs != end_xs && it_ys != end_ys) {
895 ++result;
896 if (it_xs->first < it_ys->first) {
897 ++it_xs;
898 } else if (it_xs->first == it_ys->first) {
899 ++it_xs;
900 ++it_ys;
901 } else {
902 ++it_ys;
903 }
904 }
905 result += std::distance(it_xs, end_xs);
906 result += std::distance(it_ys, end_ys);
907 return result;
908 }
909 } // namespace
910
MergeFrom(const ExtensionSet & other)911 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
912 if (PROTOBUF_PREDICT_TRUE(!is_large())) {
913 if (PROTOBUF_PREDICT_TRUE(!other.is_large())) {
914 GrowCapacity(SizeOfUnion(flat_begin(), flat_end(), other.flat_begin(),
915 other.flat_end()));
916 } else {
917 GrowCapacity(SizeOfUnion(flat_begin(), flat_end(),
918 other.map_.large->begin(),
919 other.map_.large->end()));
920 }
921 }
922 other.ForEach([this](int number, const Extension& ext) {
923 this->InternalExtensionMergeFrom(number, ext);
924 });
925 }
926
InternalExtensionMergeFrom(int number,const Extension & other_extension)927 void ExtensionSet::InternalExtensionMergeFrom(
928 int number, const Extension& other_extension) {
929 if (other_extension.is_repeated) {
930 Extension* extension;
931 bool is_new =
932 MaybeNewExtension(number, other_extension.descriptor, &extension);
933 if (is_new) {
934 // Extension did not already exist in set.
935 extension->type = other_extension.type;
936 extension->is_packed = other_extension.is_packed;
937 extension->is_repeated = true;
938 } else {
939 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
940 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
941 GOOGLE_DCHECK(extension->is_repeated);
942 }
943
944 switch (cpp_type(other_extension.type)) {
945 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
946 case WireFormatLite::CPPTYPE_##UPPERCASE: \
947 if (is_new) { \
948 extension->repeated_##LOWERCASE##_value = \
949 Arena::CreateMessage<REPEATED_TYPE>(arena_); \
950 } \
951 extension->repeated_##LOWERCASE##_value->MergeFrom( \
952 *other_extension.repeated_##LOWERCASE##_value); \
953 break;
954
955 HANDLE_TYPE(INT32, int32, RepeatedField<int32>);
956 HANDLE_TYPE(INT64, int64, RepeatedField<int64>);
957 HANDLE_TYPE(UINT32, uint32, RepeatedField<uint32>);
958 HANDLE_TYPE(UINT64, uint64, RepeatedField<uint64>);
959 HANDLE_TYPE(FLOAT, float, RepeatedField<float>);
960 HANDLE_TYPE(DOUBLE, double, RepeatedField<double>);
961 HANDLE_TYPE(BOOL, bool, RepeatedField<bool>);
962 HANDLE_TYPE(ENUM, enum, RepeatedField<int>);
963 HANDLE_TYPE(STRING, string, RepeatedPtrField<std::string>);
964 #undef HANDLE_TYPE
965
966 case WireFormatLite::CPPTYPE_MESSAGE:
967 if (is_new) {
968 extension->repeated_message_value =
969 Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_);
970 }
971 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
972 // it would attempt to allocate new objects.
973 RepeatedPtrField<MessageLite>* other_repeated_message =
974 other_extension.repeated_message_value;
975 for (int i = 0; i < other_repeated_message->size(); i++) {
976 const MessageLite& other_message = other_repeated_message->Get(i);
977 MessageLite* target =
978 reinterpret_cast<internal::RepeatedPtrFieldBase*>(
979 extension->repeated_message_value)
980 ->AddFromCleared<GenericTypeHandler<MessageLite>>();
981 if (target == NULL) {
982 target = other_message.New(arena_);
983 extension->repeated_message_value->AddAllocated(target);
984 }
985 target->CheckTypeAndMergeFrom(other_message);
986 }
987 break;
988 }
989 } else {
990 if (!other_extension.is_cleared) {
991 switch (cpp_type(other_extension.type)) {
992 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
993 case WireFormatLite::CPPTYPE_##UPPERCASE: \
994 Set##CAMELCASE(number, other_extension.type, \
995 other_extension.LOWERCASE##_value, \
996 other_extension.descriptor); \
997 break;
998
999 HANDLE_TYPE(INT32, int32, Int32);
1000 HANDLE_TYPE(INT64, int64, Int64);
1001 HANDLE_TYPE(UINT32, uint32, UInt32);
1002 HANDLE_TYPE(UINT64, uint64, UInt64);
1003 HANDLE_TYPE(FLOAT, float, Float);
1004 HANDLE_TYPE(DOUBLE, double, Double);
1005 HANDLE_TYPE(BOOL, bool, Bool);
1006 HANDLE_TYPE(ENUM, enum, Enum);
1007 #undef HANDLE_TYPE
1008 case WireFormatLite::CPPTYPE_STRING:
1009 SetString(number, other_extension.type, *other_extension.string_value,
1010 other_extension.descriptor);
1011 break;
1012 case WireFormatLite::CPPTYPE_MESSAGE: {
1013 Extension* extension;
1014 bool is_new =
1015 MaybeNewExtension(number, other_extension.descriptor, &extension);
1016 if (is_new) {
1017 extension->type = other_extension.type;
1018 extension->is_packed = other_extension.is_packed;
1019 extension->is_repeated = false;
1020 if (other_extension.is_lazy) {
1021 extension->is_lazy = true;
1022 extension->lazymessage_value =
1023 other_extension.lazymessage_value->New(arena_);
1024 extension->lazymessage_value->MergeFrom(
1025 *other_extension.lazymessage_value);
1026 } else {
1027 extension->is_lazy = false;
1028 extension->message_value =
1029 other_extension.message_value->New(arena_);
1030 extension->message_value->CheckTypeAndMergeFrom(
1031 *other_extension.message_value);
1032 }
1033 } else {
1034 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
1035 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
1036 GOOGLE_DCHECK(!extension->is_repeated);
1037 if (other_extension.is_lazy) {
1038 if (extension->is_lazy) {
1039 extension->lazymessage_value->MergeFrom(
1040 *other_extension.lazymessage_value);
1041 } else {
1042 extension->message_value->CheckTypeAndMergeFrom(
1043 other_extension.lazymessage_value->GetMessage(
1044 *extension->message_value));
1045 }
1046 } else {
1047 if (extension->is_lazy) {
1048 extension->lazymessage_value
1049 ->MutableMessage(*other_extension.message_value)
1050 ->CheckTypeAndMergeFrom(*other_extension.message_value);
1051 } else {
1052 extension->message_value->CheckTypeAndMergeFrom(
1053 *other_extension.message_value);
1054 }
1055 }
1056 }
1057 extension->is_cleared = false;
1058 break;
1059 }
1060 }
1061 }
1062 }
1063 }
1064
Swap(ExtensionSet * x)1065 void ExtensionSet::Swap(ExtensionSet* x) {
1066 if (GetArena() == x->GetArena()) {
1067 using std::swap;
1068 swap(flat_capacity_, x->flat_capacity_);
1069 swap(flat_size_, x->flat_size_);
1070 swap(map_, x->map_);
1071 } else {
1072 // TODO(cfallin, rohananil): We maybe able to optimize a case where we are
1073 // swapping from heap to arena-allocated extension set, by just Own()'ing
1074 // the extensions.
1075 ExtensionSet extension_set;
1076 extension_set.MergeFrom(*x);
1077 x->Clear();
1078 x->MergeFrom(*this);
1079 Clear();
1080 MergeFrom(extension_set);
1081 }
1082 }
1083
SwapExtension(ExtensionSet * other,int number)1084 void ExtensionSet::SwapExtension(ExtensionSet* other, int number) {
1085 if (this == other) return;
1086 Extension* this_ext = FindOrNull(number);
1087 Extension* other_ext = other->FindOrNull(number);
1088
1089 if (this_ext == NULL && other_ext == NULL) {
1090 return;
1091 }
1092
1093 if (this_ext != NULL && other_ext != NULL) {
1094 if (GetArena() == other->GetArena()) {
1095 using std::swap;
1096 swap(*this_ext, *other_ext);
1097 } else {
1098 // TODO(cfallin, rohananil): We could further optimize these cases,
1099 // especially avoid creation of ExtensionSet, and move MergeFrom logic
1100 // into Extensions itself (which takes arena as an argument).
1101 // We do it this way to reuse the copy-across-arenas logic already
1102 // implemented in ExtensionSet's MergeFrom.
1103 ExtensionSet temp;
1104 temp.InternalExtensionMergeFrom(number, *other_ext);
1105 Extension* temp_ext = temp.FindOrNull(number);
1106 other_ext->Clear();
1107 other->InternalExtensionMergeFrom(number, *this_ext);
1108 this_ext->Clear();
1109 InternalExtensionMergeFrom(number, *temp_ext);
1110 }
1111 return;
1112 }
1113
1114 if (this_ext == NULL) {
1115 if (GetArena() == other->GetArena()) {
1116 *Insert(number).first = *other_ext;
1117 } else {
1118 InternalExtensionMergeFrom(number, *other_ext);
1119 }
1120 other->Erase(number);
1121 return;
1122 }
1123
1124 if (other_ext == NULL) {
1125 if (GetArena() == other->GetArena()) {
1126 *other->Insert(number).first = *this_ext;
1127 } else {
1128 other->InternalExtensionMergeFrom(number, *this_ext);
1129 }
1130 Erase(number);
1131 return;
1132 }
1133 }
1134
IsInitialized() const1135 bool ExtensionSet::IsInitialized() const {
1136 // Extensions are never required. However, we need to check that all
1137 // embedded messages are initialized.
1138 if (PROTOBUF_PREDICT_FALSE(is_large())) {
1139 for (const auto& kv : *map_.large) {
1140 if (!kv.second.IsInitialized()) return false;
1141 }
1142 return true;
1143 }
1144 for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) {
1145 if (!it->second.IsInitialized()) return false;
1146 }
1147 return true;
1148 }
1149
FindExtensionInfoFromTag(uint32 tag,ExtensionFinder * extension_finder,int * field_number,ExtensionInfo * extension,bool * was_packed_on_wire)1150 bool ExtensionSet::FindExtensionInfoFromTag(uint32 tag,
1151 ExtensionFinder* extension_finder,
1152 int* field_number,
1153 ExtensionInfo* extension,
1154 bool* was_packed_on_wire) {
1155 *field_number = WireFormatLite::GetTagFieldNumber(tag);
1156 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
1157 return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
1158 extension_finder, extension,
1159 was_packed_on_wire);
1160 }
1161
FindExtensionInfoFromFieldNumber(int wire_type,int field_number,ExtensionFinder * extension_finder,ExtensionInfo * extension,bool * was_packed_on_wire)1162 bool ExtensionSet::FindExtensionInfoFromFieldNumber(
1163 int wire_type, int field_number, ExtensionFinder* extension_finder,
1164 ExtensionInfo* extension, bool* was_packed_on_wire) {
1165 if (!extension_finder->Find(field_number, extension)) {
1166 return false;
1167 }
1168
1169 WireFormatLite::WireType expected_wire_type =
1170 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
1171
1172 // Check if this is a packed field.
1173 *was_packed_on_wire = false;
1174 if (extension->is_repeated &&
1175 wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
1176 is_packable(expected_wire_type)) {
1177 *was_packed_on_wire = true;
1178 return true;
1179 }
1180 // Otherwise the wire type must match.
1181 return expected_wire_type == wire_type;
1182 }
1183
ParseField(uint32 tag,io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)1184 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1185 ExtensionFinder* extension_finder,
1186 FieldSkipper* field_skipper) {
1187 int number;
1188 bool was_packed_on_wire;
1189 ExtensionInfo extension;
1190 if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension,
1191 &was_packed_on_wire)) {
1192 return field_skipper->SkipField(input, tag);
1193 } else {
1194 return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension,
1195 input, field_skipper);
1196 }
1197 }
1198
ParseField(uint64 tag,const char * ptr,const MessageLite * containing_type,internal::InternalMetadata * metadata,internal::ParseContext * ctx)1199 const char* ExtensionSet::ParseField(uint64 tag, const char* ptr,
1200 const MessageLite* containing_type,
1201 internal::InternalMetadata* metadata,
1202 internal::ParseContext* ctx) {
1203 GeneratedExtensionFinder finder(containing_type);
1204 int number = tag >> 3;
1205 bool was_packed_on_wire;
1206 ExtensionInfo extension;
1207 if (!FindExtensionInfoFromFieldNumber(tag & 7, number, &finder, &extension,
1208 &was_packed_on_wire)) {
1209 return UnknownFieldParse(
1210 tag, metadata->mutable_unknown_fields<std::string>(), ptr, ctx);
1211 }
1212 return ParseFieldWithExtensionInfo<std::string>(
1213 number, was_packed_on_wire, extension, metadata, ptr, ctx);
1214 }
1215
ParseMessageSetItem(const char * ptr,const MessageLite * containing_type,internal::InternalMetadata * metadata,internal::ParseContext * ctx)1216 const char* ExtensionSet::ParseMessageSetItem(
1217 const char* ptr, const MessageLite* containing_type,
1218 internal::InternalMetadata* metadata, internal::ParseContext* ctx) {
1219 return ParseMessageSetItemTmpl<MessageLite, std::string>(ptr, containing_type,
1220 metadata, ctx);
1221 }
1222
ParseFieldWithExtensionInfo(int number,bool was_packed_on_wire,const ExtensionInfo & extension,io::CodedInputStream * input,FieldSkipper * field_skipper)1223 bool ExtensionSet::ParseFieldWithExtensionInfo(int number,
1224 bool was_packed_on_wire,
1225 const ExtensionInfo& extension,
1226 io::CodedInputStream* input,
1227 FieldSkipper* field_skipper) {
1228 // Explicitly not read extension.is_packed, instead check whether the field
1229 // was encoded in packed form on the wire.
1230 if (was_packed_on_wire) {
1231 uint32 size;
1232 if (!input->ReadVarint32(&size)) return false;
1233 io::CodedInputStream::Limit limit = input->PushLimit(size);
1234
1235 switch (extension.type) {
1236 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
1237 case WireFormatLite::TYPE_##UPPERCASE: \
1238 while (input->BytesUntilLimit() > 0) { \
1239 CPP_LOWERCASE value; \
1240 if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE, \
1241 WireFormatLite::TYPE_##UPPERCASE>( \
1242 input, &value)) \
1243 return false; \
1244 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
1245 extension.is_packed, value, extension.descriptor); \
1246 } \
1247 break
1248
1249 HANDLE_TYPE(INT32, Int32, int32);
1250 HANDLE_TYPE(INT64, Int64, int64);
1251 HANDLE_TYPE(UINT32, UInt32, uint32);
1252 HANDLE_TYPE(UINT64, UInt64, uint64);
1253 HANDLE_TYPE(SINT32, Int32, int32);
1254 HANDLE_TYPE(SINT64, Int64, int64);
1255 HANDLE_TYPE(FIXED32, UInt32, uint32);
1256 HANDLE_TYPE(FIXED64, UInt64, uint64);
1257 HANDLE_TYPE(SFIXED32, Int32, int32);
1258 HANDLE_TYPE(SFIXED64, Int64, int64);
1259 HANDLE_TYPE(FLOAT, Float, float);
1260 HANDLE_TYPE(DOUBLE, Double, double);
1261 HANDLE_TYPE(BOOL, Bool, bool);
1262 #undef HANDLE_TYPE
1263
1264 case WireFormatLite::TYPE_ENUM:
1265 while (input->BytesUntilLimit() > 0) {
1266 int value;
1267 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1268 input, &value))
1269 return false;
1270 if (extension.enum_validity_check.func(
1271 extension.enum_validity_check.arg, value)) {
1272 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
1273 value, extension.descriptor);
1274 } else {
1275 // Invalid value. Treat as unknown.
1276 field_skipper->SkipUnknownEnum(number, value);
1277 }
1278 }
1279 break;
1280
1281 case WireFormatLite::TYPE_STRING:
1282 case WireFormatLite::TYPE_BYTES:
1283 case WireFormatLite::TYPE_GROUP:
1284 case WireFormatLite::TYPE_MESSAGE:
1285 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1286 break;
1287 }
1288
1289 input->PopLimit(limit);
1290 } else {
1291 switch (extension.type) {
1292 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
1293 case WireFormatLite::TYPE_##UPPERCASE: { \
1294 CPP_LOWERCASE value; \
1295 if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE, \
1296 WireFormatLite::TYPE_##UPPERCASE>( \
1297 input, &value)) \
1298 return false; \
1299 if (extension.is_repeated) { \
1300 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
1301 extension.is_packed, value, extension.descriptor); \
1302 } else { \
1303 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
1304 extension.descriptor); \
1305 } \
1306 } break
1307
1308 HANDLE_TYPE(INT32, Int32, int32);
1309 HANDLE_TYPE(INT64, Int64, int64);
1310 HANDLE_TYPE(UINT32, UInt32, uint32);
1311 HANDLE_TYPE(UINT64, UInt64, uint64);
1312 HANDLE_TYPE(SINT32, Int32, int32);
1313 HANDLE_TYPE(SINT64, Int64, int64);
1314 HANDLE_TYPE(FIXED32, UInt32, uint32);
1315 HANDLE_TYPE(FIXED64, UInt64, uint64);
1316 HANDLE_TYPE(SFIXED32, Int32, int32);
1317 HANDLE_TYPE(SFIXED64, Int64, int64);
1318 HANDLE_TYPE(FLOAT, Float, float);
1319 HANDLE_TYPE(DOUBLE, Double, double);
1320 HANDLE_TYPE(BOOL, Bool, bool);
1321 #undef HANDLE_TYPE
1322
1323 case WireFormatLite::TYPE_ENUM: {
1324 int value;
1325 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1326 input, &value))
1327 return false;
1328
1329 if (!extension.enum_validity_check.func(
1330 extension.enum_validity_check.arg, value)) {
1331 // Invalid value. Treat as unknown.
1332 field_skipper->SkipUnknownEnum(number, value);
1333 } else if (extension.is_repeated) {
1334 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
1335 extension.descriptor);
1336 } else {
1337 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1338 extension.descriptor);
1339 }
1340 break;
1341 }
1342
1343 case WireFormatLite::TYPE_STRING: {
1344 std::string* value =
1345 extension.is_repeated
1346 ? AddString(number, WireFormatLite::TYPE_STRING,
1347 extension.descriptor)
1348 : MutableString(number, WireFormatLite::TYPE_STRING,
1349 extension.descriptor);
1350 if (!WireFormatLite::ReadString(input, value)) return false;
1351 break;
1352 }
1353
1354 case WireFormatLite::TYPE_BYTES: {
1355 std::string* value =
1356 extension.is_repeated
1357 ? AddString(number, WireFormatLite::TYPE_BYTES,
1358 extension.descriptor)
1359 : MutableString(number, WireFormatLite::TYPE_BYTES,
1360 extension.descriptor);
1361 if (!WireFormatLite::ReadBytes(input, value)) return false;
1362 break;
1363 }
1364
1365 case WireFormatLite::TYPE_GROUP: {
1366 MessageLite* value =
1367 extension.is_repeated
1368 ? AddMessage(number, WireFormatLite::TYPE_GROUP,
1369 *extension.message_info.prototype,
1370 extension.descriptor)
1371 : MutableMessage(number, WireFormatLite::TYPE_GROUP,
1372 *extension.message_info.prototype,
1373 extension.descriptor);
1374 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
1375 break;
1376 }
1377
1378 case WireFormatLite::TYPE_MESSAGE: {
1379 MessageLite* value =
1380 extension.is_repeated
1381 ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
1382 *extension.message_info.prototype,
1383 extension.descriptor)
1384 : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
1385 *extension.message_info.prototype,
1386 extension.descriptor);
1387 if (!WireFormatLite::ReadMessage(input, value)) return false;
1388 break;
1389 }
1390 }
1391 }
1392
1393 return true;
1394 }
1395
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type)1396 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1397 const MessageLite* containing_type) {
1398 FieldSkipper skipper;
1399 GeneratedExtensionFinder finder(containing_type);
1400 return ParseField(tag, input, &finder, &skipper);
1401 }
1402
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type,io::CodedOutputStream * unknown_fields)1403 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1404 const MessageLite* containing_type,
1405 io::CodedOutputStream* unknown_fields) {
1406 CodedOutputStreamFieldSkipper skipper(unknown_fields);
1407 GeneratedExtensionFinder finder(containing_type);
1408 return ParseField(tag, input, &finder, &skipper);
1409 }
1410
ParseMessageSetLite(io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)1411 bool ExtensionSet::ParseMessageSetLite(io::CodedInputStream* input,
1412 ExtensionFinder* extension_finder,
1413 FieldSkipper* field_skipper) {
1414 while (true) {
1415 const uint32 tag = input->ReadTag();
1416 switch (tag) {
1417 case 0:
1418 return true;
1419 case WireFormatLite::kMessageSetItemStartTag:
1420 if (!ParseMessageSetItemLite(input, extension_finder, field_skipper)) {
1421 return false;
1422 }
1423 break;
1424 default:
1425 if (!ParseField(tag, input, extension_finder, field_skipper)) {
1426 return false;
1427 }
1428 break;
1429 }
1430 }
1431 }
1432
ParseMessageSetItemLite(io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)1433 bool ExtensionSet::ParseMessageSetItemLite(io::CodedInputStream* input,
1434 ExtensionFinder* extension_finder,
1435 FieldSkipper* field_skipper) {
1436 struct MSLite {
1437 bool ParseField(int type_id, io::CodedInputStream* input) {
1438 return me->ParseField(
1439 WireFormatLite::WIRETYPE_LENGTH_DELIMITED + 8 * type_id, input,
1440 extension_finder, field_skipper);
1441 }
1442
1443 bool SkipField(uint32 tag, io::CodedInputStream* input) {
1444 return field_skipper->SkipField(input, tag);
1445 }
1446
1447 ExtensionSet* me;
1448 ExtensionFinder* extension_finder;
1449 FieldSkipper* field_skipper;
1450 };
1451
1452 return ParseMessageSetItemImpl(input,
1453 MSLite{this, extension_finder, field_skipper});
1454 }
1455
ParseMessageSet(io::CodedInputStream * input,const MessageLite * containing_type,std::string * unknown_fields)1456 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1457 const MessageLite* containing_type,
1458 std::string* unknown_fields) {
1459 io::StringOutputStream zcis(unknown_fields);
1460 io::CodedOutputStream output(&zcis);
1461 CodedOutputStreamFieldSkipper skipper(&output);
1462 GeneratedExtensionFinder finder(containing_type);
1463 return ParseMessageSetLite(input, &finder, &skipper);
1464 }
1465
_InternalSerialize(int start_field_number,int end_field_number,uint8 * target,io::EpsCopyOutputStream * stream) const1466 uint8* ExtensionSet::_InternalSerialize(int start_field_number,
1467 int end_field_number, uint8* target,
1468 io::EpsCopyOutputStream* stream) const {
1469 if (PROTOBUF_PREDICT_FALSE(is_large())) {
1470 const auto& end = map_.large->end();
1471 for (auto it = map_.large->lower_bound(start_field_number);
1472 it != end && it->first < end_field_number; ++it) {
1473 target = it->second.InternalSerializeFieldWithCachedSizesToArray(
1474 it->first, target, stream);
1475 }
1476 return target;
1477 }
1478 const KeyValue* end = flat_end();
1479 for (const KeyValue* it = std::lower_bound(
1480 flat_begin(), end, start_field_number, KeyValue::FirstComparator());
1481 it != end && it->first < end_field_number; ++it) {
1482 target = it->second.InternalSerializeFieldWithCachedSizesToArray(
1483 it->first, target, stream);
1484 }
1485 return target;
1486 }
1487
InternalSerializeMessageSetWithCachedSizesToArray(uint8 * target,io::EpsCopyOutputStream * stream) const1488 uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
1489 uint8* target, io::EpsCopyOutputStream* stream) const {
1490 ForEach([&target, stream](int number, const Extension& ext) {
1491 target = ext.InternalSerializeMessageSetItemWithCachedSizesToArray(
1492 number, target, stream);
1493 });
1494 return target;
1495 }
1496
ByteSize() const1497 size_t ExtensionSet::ByteSize() const {
1498 size_t total_size = 0;
1499 ForEach([&total_size](int number, const Extension& ext) {
1500 total_size += ext.ByteSize(number);
1501 });
1502 return total_size;
1503 }
1504
1505 // Defined in extension_set_heavy.cc.
1506 // int ExtensionSet::SpaceUsedExcludingSelf() const
1507
MaybeNewExtension(int number,const FieldDescriptor * descriptor,Extension ** result)1508 bool ExtensionSet::MaybeNewExtension(int number,
1509 const FieldDescriptor* descriptor,
1510 Extension** result) {
1511 bool extension_is_new = false;
1512 std::tie(*result, extension_is_new) = Insert(number);
1513 (*result)->descriptor = descriptor;
1514 return extension_is_new;
1515 }
1516
1517 // ===================================================================
1518 // Methods of ExtensionSet::Extension
1519
Clear()1520 void ExtensionSet::Extension::Clear() {
1521 if (is_repeated) {
1522 switch (cpp_type(type)) {
1523 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1524 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1525 repeated_##LOWERCASE##_value->Clear(); \
1526 break
1527
1528 HANDLE_TYPE(INT32, int32);
1529 HANDLE_TYPE(INT64, int64);
1530 HANDLE_TYPE(UINT32, uint32);
1531 HANDLE_TYPE(UINT64, uint64);
1532 HANDLE_TYPE(FLOAT, float);
1533 HANDLE_TYPE(DOUBLE, double);
1534 HANDLE_TYPE(BOOL, bool);
1535 HANDLE_TYPE(ENUM, enum);
1536 HANDLE_TYPE(STRING, string);
1537 HANDLE_TYPE(MESSAGE, message);
1538 #undef HANDLE_TYPE
1539 }
1540 } else {
1541 if (!is_cleared) {
1542 switch (cpp_type(type)) {
1543 case WireFormatLite::CPPTYPE_STRING:
1544 string_value->clear();
1545 break;
1546 case WireFormatLite::CPPTYPE_MESSAGE:
1547 if (is_lazy) {
1548 lazymessage_value->Clear();
1549 } else {
1550 message_value->Clear();
1551 }
1552 break;
1553 default:
1554 // No need to do anything. Get*() will return the default value
1555 // as long as is_cleared is true and Set*() will overwrite the
1556 // previous value.
1557 break;
1558 }
1559
1560 is_cleared = true;
1561 }
1562 }
1563 }
1564
ByteSize(int number) const1565 size_t ExtensionSet::Extension::ByteSize(int number) const {
1566 size_t result = 0;
1567
1568 if (is_repeated) {
1569 if (is_packed) {
1570 switch (real_type(type)) {
1571 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1572 case WireFormatLite::TYPE_##UPPERCASE: \
1573 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1574 result += WireFormatLite::CAMELCASE##Size( \
1575 repeated_##LOWERCASE##_value->Get(i)); \
1576 } \
1577 break
1578
1579 HANDLE_TYPE(INT32, Int32, int32);
1580 HANDLE_TYPE(INT64, Int64, int64);
1581 HANDLE_TYPE(UINT32, UInt32, uint32);
1582 HANDLE_TYPE(UINT64, UInt64, uint64);
1583 HANDLE_TYPE(SINT32, SInt32, int32);
1584 HANDLE_TYPE(SINT64, SInt64, int64);
1585 HANDLE_TYPE(ENUM, Enum, enum);
1586 #undef HANDLE_TYPE
1587
1588 // Stuff with fixed size.
1589 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1590 case WireFormatLite::TYPE_##UPPERCASE: \
1591 result += WireFormatLite::k##CAMELCASE##Size * \
1592 FromIntSize(repeated_##LOWERCASE##_value->size()); \
1593 break
1594 HANDLE_TYPE(FIXED32, Fixed32, uint32);
1595 HANDLE_TYPE(FIXED64, Fixed64, uint64);
1596 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1597 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1598 HANDLE_TYPE(FLOAT, Float, float);
1599 HANDLE_TYPE(DOUBLE, Double, double);
1600 HANDLE_TYPE(BOOL, Bool, bool);
1601 #undef HANDLE_TYPE
1602
1603 case WireFormatLite::TYPE_STRING:
1604 case WireFormatLite::TYPE_BYTES:
1605 case WireFormatLite::TYPE_GROUP:
1606 case WireFormatLite::TYPE_MESSAGE:
1607 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1608 break;
1609 }
1610
1611 cached_size = ToCachedSize(result);
1612 if (result > 0) {
1613 result += io::CodedOutputStream::VarintSize32(result);
1614 result += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
1615 number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1616 }
1617 } else {
1618 size_t tag_size = WireFormatLite::TagSize(number, real_type(type));
1619
1620 switch (real_type(type)) {
1621 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1622 case WireFormatLite::TYPE_##UPPERCASE: \
1623 result += tag_size * FromIntSize(repeated_##LOWERCASE##_value->size()); \
1624 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1625 result += WireFormatLite::CAMELCASE##Size( \
1626 repeated_##LOWERCASE##_value->Get(i)); \
1627 } \
1628 break
1629
1630 HANDLE_TYPE(INT32, Int32, int32);
1631 HANDLE_TYPE(INT64, Int64, int64);
1632 HANDLE_TYPE(UINT32, UInt32, uint32);
1633 HANDLE_TYPE(UINT64, UInt64, uint64);
1634 HANDLE_TYPE(SINT32, SInt32, int32);
1635 HANDLE_TYPE(SINT64, SInt64, int64);
1636 HANDLE_TYPE(STRING, String, string);
1637 HANDLE_TYPE(BYTES, Bytes, string);
1638 HANDLE_TYPE(ENUM, Enum, enum);
1639 HANDLE_TYPE(GROUP, Group, message);
1640 HANDLE_TYPE(MESSAGE, Message, message);
1641 #undef HANDLE_TYPE
1642
1643 // Stuff with fixed size.
1644 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1645 case WireFormatLite::TYPE_##UPPERCASE: \
1646 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
1647 FromIntSize(repeated_##LOWERCASE##_value->size()); \
1648 break
1649 HANDLE_TYPE(FIXED32, Fixed32, uint32);
1650 HANDLE_TYPE(FIXED64, Fixed64, uint64);
1651 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1652 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1653 HANDLE_TYPE(FLOAT, Float, float);
1654 HANDLE_TYPE(DOUBLE, Double, double);
1655 HANDLE_TYPE(BOOL, Bool, bool);
1656 #undef HANDLE_TYPE
1657 }
1658 }
1659 } else if (!is_cleared) {
1660 result += WireFormatLite::TagSize(number, real_type(type));
1661 switch (real_type(type)) {
1662 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1663 case WireFormatLite::TYPE_##UPPERCASE: \
1664 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
1665 break
1666
1667 HANDLE_TYPE(INT32, Int32, int32_value);
1668 HANDLE_TYPE(INT64, Int64, int64_value);
1669 HANDLE_TYPE(UINT32, UInt32, uint32_value);
1670 HANDLE_TYPE(UINT64, UInt64, uint64_value);
1671 HANDLE_TYPE(SINT32, SInt32, int32_value);
1672 HANDLE_TYPE(SINT64, SInt64, int64_value);
1673 HANDLE_TYPE(STRING, String, *string_value);
1674 HANDLE_TYPE(BYTES, Bytes, *string_value);
1675 HANDLE_TYPE(ENUM, Enum, enum_value);
1676 HANDLE_TYPE(GROUP, Group, *message_value);
1677 #undef HANDLE_TYPE
1678 case WireFormatLite::TYPE_MESSAGE: {
1679 if (is_lazy) {
1680 size_t size = lazymessage_value->ByteSizeLong();
1681 result += io::CodedOutputStream::VarintSize32(size) + size;
1682 } else {
1683 result += WireFormatLite::MessageSize(*message_value);
1684 }
1685 break;
1686 }
1687
1688 // Stuff with fixed size.
1689 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
1690 case WireFormatLite::TYPE_##UPPERCASE: \
1691 result += WireFormatLite::k##CAMELCASE##Size; \
1692 break
1693 HANDLE_TYPE(FIXED32, Fixed32);
1694 HANDLE_TYPE(FIXED64, Fixed64);
1695 HANDLE_TYPE(SFIXED32, SFixed32);
1696 HANDLE_TYPE(SFIXED64, SFixed64);
1697 HANDLE_TYPE(FLOAT, Float);
1698 HANDLE_TYPE(DOUBLE, Double);
1699 HANDLE_TYPE(BOOL, Bool);
1700 #undef HANDLE_TYPE
1701 }
1702 }
1703
1704 return result;
1705 }
1706
GetSize() const1707 int ExtensionSet::Extension::GetSize() const {
1708 GOOGLE_DCHECK(is_repeated);
1709 switch (cpp_type(type)) {
1710 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1711 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1712 return repeated_##LOWERCASE##_value->size()
1713
1714 HANDLE_TYPE(INT32, int32);
1715 HANDLE_TYPE(INT64, int64);
1716 HANDLE_TYPE(UINT32, uint32);
1717 HANDLE_TYPE(UINT64, uint64);
1718 HANDLE_TYPE(FLOAT, float);
1719 HANDLE_TYPE(DOUBLE, double);
1720 HANDLE_TYPE(BOOL, bool);
1721 HANDLE_TYPE(ENUM, enum);
1722 HANDLE_TYPE(STRING, string);
1723 HANDLE_TYPE(MESSAGE, message);
1724 #undef HANDLE_TYPE
1725 }
1726
1727 GOOGLE_LOG(FATAL) << "Can't get here.";
1728 return 0;
1729 }
1730
1731 // This function deletes all allocated objects. This function should be only
1732 // called if the Extension was created with an arena.
Free()1733 void ExtensionSet::Extension::Free() {
1734 if (is_repeated) {
1735 switch (cpp_type(type)) {
1736 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1737 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1738 delete repeated_##LOWERCASE##_value; \
1739 break
1740
1741 HANDLE_TYPE(INT32, int32);
1742 HANDLE_TYPE(INT64, int64);
1743 HANDLE_TYPE(UINT32, uint32);
1744 HANDLE_TYPE(UINT64, uint64);
1745 HANDLE_TYPE(FLOAT, float);
1746 HANDLE_TYPE(DOUBLE, double);
1747 HANDLE_TYPE(BOOL, bool);
1748 HANDLE_TYPE(ENUM, enum);
1749 HANDLE_TYPE(STRING, string);
1750 HANDLE_TYPE(MESSAGE, message);
1751 #undef HANDLE_TYPE
1752 }
1753 } else {
1754 switch (cpp_type(type)) {
1755 case WireFormatLite::CPPTYPE_STRING:
1756 delete string_value;
1757 break;
1758 case WireFormatLite::CPPTYPE_MESSAGE:
1759 if (is_lazy) {
1760 delete lazymessage_value;
1761 } else {
1762 delete message_value;
1763 }
1764 break;
1765 default:
1766 break;
1767 }
1768 }
1769 }
1770
1771 // Defined in extension_set_heavy.cc.
1772 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1773
IsInitialized() const1774 bool ExtensionSet::Extension::IsInitialized() const {
1775 if (cpp_type(type) == WireFormatLite::CPPTYPE_MESSAGE) {
1776 if (is_repeated) {
1777 for (int i = 0; i < repeated_message_value->size(); i++) {
1778 if (!repeated_message_value->Get(i).IsInitialized()) {
1779 return false;
1780 }
1781 }
1782 } else {
1783 if (!is_cleared) {
1784 if (is_lazy) {
1785 if (!lazymessage_value->IsInitialized()) return false;
1786 } else {
1787 if (!message_value->IsInitialized()) return false;
1788 }
1789 }
1790 }
1791 }
1792 return true;
1793 }
1794
1795 // Dummy key method to avoid weak vtable.
UnusedKeyMethod()1796 void ExtensionSet::LazyMessageExtension::UnusedKeyMethod() {}
1797
FindOrNull(int key) const1798 const ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) const {
1799 if (PROTOBUF_PREDICT_FALSE(is_large())) {
1800 return FindOrNullInLargeMap(key);
1801 }
1802 const KeyValue* end = flat_end();
1803 const KeyValue* it =
1804 std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1805 if (it != end && it->first == key) {
1806 return &it->second;
1807 }
1808 return NULL;
1809 }
1810
FindOrNullInLargeMap(int key) const1811 const ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap(
1812 int key) const {
1813 assert(is_large());
1814 LargeMap::const_iterator it = map_.large->find(key);
1815 if (it != map_.large->end()) {
1816 return &it->second;
1817 }
1818 return NULL;
1819 }
1820
FindOrNull(int key)1821 ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) {
1822 if (PROTOBUF_PREDICT_FALSE(is_large())) {
1823 return FindOrNullInLargeMap(key);
1824 }
1825 KeyValue* end = flat_end();
1826 KeyValue* it =
1827 std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1828 if (it != end && it->first == key) {
1829 return &it->second;
1830 }
1831 return NULL;
1832 }
1833
FindOrNullInLargeMap(int key)1834 ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap(int key) {
1835 assert(is_large());
1836 LargeMap::iterator it = map_.large->find(key);
1837 if (it != map_.large->end()) {
1838 return &it->second;
1839 }
1840 return NULL;
1841 }
1842
Insert(int key)1843 std::pair<ExtensionSet::Extension*, bool> ExtensionSet::Insert(int key) {
1844 if (PROTOBUF_PREDICT_FALSE(is_large())) {
1845 auto maybe = map_.large->insert({key, Extension()});
1846 return {&maybe.first->second, maybe.second};
1847 }
1848 KeyValue* end = flat_end();
1849 KeyValue* it =
1850 std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1851 if (it != end && it->first == key) {
1852 return {&it->second, false};
1853 }
1854 if (flat_size_ < flat_capacity_) {
1855 std::copy_backward(it, end, end + 1);
1856 ++flat_size_;
1857 it->first = key;
1858 it->second = Extension();
1859 return {&it->second, true};
1860 }
1861 GrowCapacity(flat_size_ + 1);
1862 return Insert(key);
1863 }
1864
GrowCapacity(size_t minimum_new_capacity)1865 void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) {
1866 if (PROTOBUF_PREDICT_FALSE(is_large())) {
1867 return; // LargeMap does not have a "reserve" method.
1868 }
1869 if (flat_capacity_ >= minimum_new_capacity) {
1870 return;
1871 }
1872
1873 const auto old_flat_capacity = flat_capacity_;
1874
1875 do {
1876 flat_capacity_ = flat_capacity_ == 0 ? 1 : flat_capacity_ * 4;
1877 } while (flat_capacity_ < minimum_new_capacity);
1878
1879 const KeyValue* begin = flat_begin();
1880 const KeyValue* end = flat_end();
1881 if (flat_capacity_ > kMaximumFlatCapacity) {
1882 // Switch to LargeMap
1883 map_.large = Arena::Create<LargeMap>(arena_);
1884 LargeMap::iterator hint = map_.large->begin();
1885 for (const KeyValue* it = begin; it != end; ++it) {
1886 hint = map_.large->insert(hint, {it->first, it->second});
1887 }
1888 flat_size_ = 0;
1889 } else {
1890 map_.flat = Arena::CreateArray<KeyValue>(arena_, flat_capacity_);
1891 std::copy(begin, end, map_.flat);
1892 }
1893 if (arena_ == nullptr) {
1894 DeleteFlatMap(begin, old_flat_capacity);
1895 }
1896 }
1897
1898 // static
1899 constexpr uint16 ExtensionSet::kMaximumFlatCapacity;
1900
Erase(int key)1901 void ExtensionSet::Erase(int key) {
1902 if (PROTOBUF_PREDICT_FALSE(is_large())) {
1903 map_.large->erase(key);
1904 return;
1905 }
1906 KeyValue* end = flat_end();
1907 KeyValue* it =
1908 std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1909 if (it != end && it->first == key) {
1910 std::copy(it + 1, end, it);
1911 --flat_size_;
1912 }
1913 }
1914
1915 // ==================================================================
1916 // Default repeated field instances for iterator-compatible accessors
1917
default_instance()1918 const RepeatedPrimitiveDefaults* RepeatedPrimitiveDefaults::default_instance() {
1919 static auto instance = OnShutdownDelete(new RepeatedPrimitiveDefaults);
1920 return instance;
1921 }
1922
1923 const RepeatedStringTypeTraits::RepeatedFieldType*
GetDefaultRepeatedField()1924 RepeatedStringTypeTraits::GetDefaultRepeatedField() {
1925 static auto instance = OnShutdownDelete(new RepeatedFieldType);
1926 return instance;
1927 }
1928
InternalSerializeFieldWithCachedSizesToArray(int number,uint8 * target,io::EpsCopyOutputStream * stream) const1929 uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
1930 int number, uint8* target, io::EpsCopyOutputStream* stream) const {
1931 if (is_repeated) {
1932 if (is_packed) {
1933 if (cached_size == 0) return target;
1934
1935 target = stream->EnsureSpace(target);
1936 target = WireFormatLite::WriteTagToArray(
1937 number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
1938 target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
1939
1940 switch (real_type(type)) {
1941 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1942 case WireFormatLite::TYPE_##UPPERCASE: \
1943 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1944 target = stream->EnsureSpace(target); \
1945 target = WireFormatLite::Write##CAMELCASE##NoTagToArray( \
1946 repeated_##LOWERCASE##_value->Get(i), target); \
1947 } \
1948 break
1949
1950 HANDLE_TYPE(INT32, Int32, int32);
1951 HANDLE_TYPE(INT64, Int64, int64);
1952 HANDLE_TYPE(UINT32, UInt32, uint32);
1953 HANDLE_TYPE(UINT64, UInt64, uint64);
1954 HANDLE_TYPE(SINT32, SInt32, int32);
1955 HANDLE_TYPE(SINT64, SInt64, int64);
1956 HANDLE_TYPE(FIXED32, Fixed32, uint32);
1957 HANDLE_TYPE(FIXED64, Fixed64, uint64);
1958 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1959 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1960 HANDLE_TYPE(FLOAT, Float, float);
1961 HANDLE_TYPE(DOUBLE, Double, double);
1962 HANDLE_TYPE(BOOL, Bool, bool);
1963 HANDLE_TYPE(ENUM, Enum, enum);
1964 #undef HANDLE_TYPE
1965
1966 case WireFormatLite::TYPE_STRING:
1967 case WireFormatLite::TYPE_BYTES:
1968 case WireFormatLite::TYPE_GROUP:
1969 case WireFormatLite::TYPE_MESSAGE:
1970 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1971 break;
1972 }
1973 } else {
1974 switch (real_type(type)) {
1975 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1976 case WireFormatLite::TYPE_##UPPERCASE: \
1977 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1978 target = stream->EnsureSpace(target); \
1979 target = WireFormatLite::Write##CAMELCASE##ToArray( \
1980 number, repeated_##LOWERCASE##_value->Get(i), target); \
1981 } \
1982 break
1983
1984 HANDLE_TYPE(INT32, Int32, int32);
1985 HANDLE_TYPE(INT64, Int64, int64);
1986 HANDLE_TYPE(UINT32, UInt32, uint32);
1987 HANDLE_TYPE(UINT64, UInt64, uint64);
1988 HANDLE_TYPE(SINT32, SInt32, int32);
1989 HANDLE_TYPE(SINT64, SInt64, int64);
1990 HANDLE_TYPE(FIXED32, Fixed32, uint32);
1991 HANDLE_TYPE(FIXED64, Fixed64, uint64);
1992 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1993 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1994 HANDLE_TYPE(FLOAT, Float, float);
1995 HANDLE_TYPE(DOUBLE, Double, double);
1996 HANDLE_TYPE(BOOL, Bool, bool);
1997 HANDLE_TYPE(ENUM, Enum, enum);
1998 #undef HANDLE_TYPE
1999 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
2000 case WireFormatLite::TYPE_##UPPERCASE: \
2001 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
2002 target = stream->EnsureSpace(target); \
2003 target = stream->WriteString( \
2004 number, repeated_##LOWERCASE##_value->Get(i), target); \
2005 } \
2006 break
2007 HANDLE_TYPE(STRING, String, string);
2008 HANDLE_TYPE(BYTES, Bytes, string);
2009 #undef HANDLE_TYPE
2010 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
2011 case WireFormatLite::TYPE_##UPPERCASE: \
2012 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
2013 target = stream->EnsureSpace(target); \
2014 target = WireFormatLite::InternalWrite##CAMELCASE( \
2015 number, repeated_##LOWERCASE##_value->Get(i), target, stream); \
2016 } \
2017 break
2018
2019 HANDLE_TYPE(GROUP, Group, message);
2020 HANDLE_TYPE(MESSAGE, Message, message);
2021 #undef HANDLE_TYPE
2022 }
2023 }
2024 } else if (!is_cleared) {
2025 switch (real_type(type)) {
2026 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
2027 case WireFormatLite::TYPE_##UPPERCASE: \
2028 target = stream->EnsureSpace(target); \
2029 target = WireFormatLite::Write##CAMELCASE##ToArray(number, VALUE, target); \
2030 break
2031
2032 HANDLE_TYPE(INT32, Int32, int32_value);
2033 HANDLE_TYPE(INT64, Int64, int64_value);
2034 HANDLE_TYPE(UINT32, UInt32, uint32_value);
2035 HANDLE_TYPE(UINT64, UInt64, uint64_value);
2036 HANDLE_TYPE(SINT32, SInt32, int32_value);
2037 HANDLE_TYPE(SINT64, SInt64, int64_value);
2038 HANDLE_TYPE(FIXED32, Fixed32, uint32_value);
2039 HANDLE_TYPE(FIXED64, Fixed64, uint64_value);
2040 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
2041 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
2042 HANDLE_TYPE(FLOAT, Float, float_value);
2043 HANDLE_TYPE(DOUBLE, Double, double_value);
2044 HANDLE_TYPE(BOOL, Bool, bool_value);
2045 HANDLE_TYPE(ENUM, Enum, enum_value);
2046 #undef HANDLE_TYPE
2047 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
2048 case WireFormatLite::TYPE_##UPPERCASE: \
2049 target = stream->EnsureSpace(target); \
2050 target = stream->WriteString(number, VALUE, target); \
2051 break
2052 HANDLE_TYPE(STRING, String, *string_value);
2053 HANDLE_TYPE(BYTES, Bytes, *string_value);
2054 #undef HANDLE_TYPE
2055 case WireFormatLite::TYPE_GROUP:
2056 target = stream->EnsureSpace(target);
2057 target = WireFormatLite::InternalWriteGroup(number, *message_value,
2058 target, stream);
2059 break;
2060 case WireFormatLite::TYPE_MESSAGE:
2061 if (is_lazy) {
2062 target =
2063 lazymessage_value->WriteMessageToArray(number, target, stream);
2064 } else {
2065 target = stream->EnsureSpace(target);
2066 target = WireFormatLite::InternalWriteMessage(number, *message_value,
2067 target, stream);
2068 }
2069 break;
2070 }
2071 }
2072 return target;
2073 }
2074
2075 uint8*
InternalSerializeMessageSetItemWithCachedSizesToArray(int number,uint8 * target,io::EpsCopyOutputStream * stream) const2076 ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
2077 int number, uint8* target, io::EpsCopyOutputStream* stream) const {
2078 if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
2079 // Not a valid MessageSet extension, but serialize it the normal way.
2080 GOOGLE_LOG(WARNING) << "Invalid message set extension.";
2081 return InternalSerializeFieldWithCachedSizesToArray(number, target, stream);
2082 }
2083
2084 if (is_cleared) return target;
2085
2086 target = stream->EnsureSpace(target);
2087 // Start group.
2088 target = io::CodedOutputStream::WriteTagToArray(
2089 WireFormatLite::kMessageSetItemStartTag, target);
2090 // Write type ID.
2091 target = WireFormatLite::WriteUInt32ToArray(
2092 WireFormatLite::kMessageSetTypeIdNumber, number, target);
2093 // Write message.
2094 if (is_lazy) {
2095 target = lazymessage_value->WriteMessageToArray(
2096 WireFormatLite::kMessageSetMessageNumber, target, stream);
2097 } else {
2098 target = WireFormatLite::InternalWriteMessage(
2099 WireFormatLite::kMessageSetMessageNumber, *message_value, target,
2100 stream);
2101 }
2102 // End group.
2103 target = stream->EnsureSpace(target);
2104 target = io::CodedOutputStream::WriteTagToArray(
2105 WireFormatLite::kMessageSetItemEndTag, target);
2106 return target;
2107 }
2108
MessageSetItemByteSize(int number) const2109 size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
2110 if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
2111 // Not a valid MessageSet extension, but compute the byte size for it the
2112 // normal way.
2113 return ByteSize(number);
2114 }
2115
2116 if (is_cleared) return 0;
2117
2118 size_t our_size = WireFormatLite::kMessageSetItemTagsSize;
2119
2120 // type_id
2121 our_size += io::CodedOutputStream::VarintSize32(number);
2122
2123 // message
2124 size_t message_size = 0;
2125 if (is_lazy) {
2126 message_size = lazymessage_value->ByteSizeLong();
2127 } else {
2128 message_size = message_value->ByteSizeLong();
2129 }
2130
2131 our_size += io::CodedOutputStream::VarintSize32(message_size);
2132 our_size += message_size;
2133
2134 return our_size;
2135 }
2136
MessageSetByteSize() const2137 size_t ExtensionSet::MessageSetByteSize() const {
2138 size_t total_size = 0;
2139 ForEach([&total_size](int number, const Extension& ext) {
2140 total_size += ext.MessageSetItemByteSize(number);
2141 });
2142 return total_size;
2143 }
2144
2145 } // namespace internal
2146 } // namespace protobuf
2147 } // namespace google
2148