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