• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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