• 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/stubs/hash.h>
36 #include <google/protobuf/stubs/common.h>
37 #include <google/protobuf/stubs/once.h>
38 #include <google/protobuf/extension_set.h>
39 #include <google/protobuf/message_lite.h>
40 #include <google/protobuf/io/coded_stream.h>
41 #include <google/protobuf/wire_format_lite_inl.h>
42 #include <google/protobuf/repeated_field.h>
43 #include <google/protobuf/stubs/map_util.h>
44 
45 namespace google {
46 namespace protobuf {
47 namespace internal {
48 
49 namespace {
50 
real_type(FieldType type)51 inline WireFormatLite::FieldType real_type(FieldType type) {
52   GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
53   return static_cast<WireFormatLite::FieldType>(type);
54 }
55 
cpp_type(FieldType type)56 inline WireFormatLite::CppType cpp_type(FieldType type) {
57   return WireFormatLite::FieldTypeToCppType(real_type(type));
58 }
59 
is_packable(WireFormatLite::WireType type)60 inline bool is_packable(WireFormatLite::WireType type) {
61   switch (type) {
62     case WireFormatLite::WIRETYPE_VARINT:
63     case WireFormatLite::WIRETYPE_FIXED64:
64     case WireFormatLite::WIRETYPE_FIXED32:
65       return true;
66     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
67     case WireFormatLite::WIRETYPE_START_GROUP:
68     case WireFormatLite::WIRETYPE_END_GROUP:
69       return false;
70 
71     // Do not add a default statement. Let the compiler complain when someone
72     // adds a new wire type.
73   }
74   GOOGLE_LOG(FATAL) << "can't reach here.";
75   return false;
76 }
77 
78 // Registry stuff.
79 typedef hash_map<pair<const MessageLite*, int>,
80                  ExtensionInfo> ExtensionRegistry;
81 ExtensionRegistry* registry_ = NULL;
82 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
83 
DeleteRegistry()84 void DeleteRegistry() {
85   delete registry_;
86   registry_ = NULL;
87 }
88 
InitRegistry()89 void InitRegistry() {
90   registry_ = new ExtensionRegistry;
91   OnShutdown(&DeleteRegistry);
92 }
93 
94 // This function is only called at startup, so there is no need for thread-
95 // safety.
Register(const MessageLite * containing_type,int number,ExtensionInfo info)96 void Register(const MessageLite* containing_type,
97               int number, ExtensionInfo info) {
98   ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
99 
100   if (!InsertIfNotPresent(registry_, std::make_pair(containing_type, number),
101                           info)) {
102     GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
103                << containing_type->GetTypeName()
104                << "\", field number " << number << ".";
105   }
106 }
107 
FindRegisteredExtension(const MessageLite * containing_type,int number)108 const ExtensionInfo* FindRegisteredExtension(
109     const MessageLite* containing_type, int number) {
110   return (registry_ == NULL)
111              ? NULL
112              : FindOrNull(*registry_, std::make_pair(containing_type, number));
113 }
114 
115 }  // namespace
116 
~ExtensionFinder()117 ExtensionFinder::~ExtensionFinder() {}
118 
Find(int number,ExtensionInfo * output)119 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
120   const ExtensionInfo* extension =
121       FindRegisteredExtension(containing_type_, number);
122   if (extension == NULL) {
123     return false;
124   } else {
125     *output = *extension;
126     return true;
127   }
128 }
129 
RegisterExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed)130 void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
131                                      int number, FieldType type,
132                                      bool is_repeated, bool is_packed) {
133   GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
134   GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
135   GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
136   ExtensionInfo info(type, is_repeated, is_packed);
137   Register(containing_type, number, info);
138 }
139 
CallNoArgValidityFunc(const void * arg,int number)140 static bool CallNoArgValidityFunc(const void* arg, int number) {
141   // Note:  Must use C-style cast here rather than reinterpret_cast because
142   //   the C++ standard at one point did not allow casts between function and
143   //   data pointers and some compilers enforce this for C++-style casts.  No
144   //   compiler enforces it for C-style casts since lots of C-style code has
145   //   relied on these kinds of casts for a long time, despite being
146   //   technically undefined.  See:
147   //     http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
148   // Also note:  Some compilers do not allow function pointers to be "const".
149   //   Which makes sense, I suppose, because it's meaningless.
150   return ((EnumValidityFunc*)arg)(number);
151 }
152 
RegisterEnumExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,EnumValidityFunc * is_valid)153 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
154                                          int number, FieldType type,
155                                          bool is_repeated, bool is_packed,
156                                          EnumValidityFunc* is_valid) {
157   GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
158   ExtensionInfo info(type, is_repeated, is_packed);
159   info.enum_validity_check.func = CallNoArgValidityFunc;
160   // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
161   info.enum_validity_check.arg = (void*)is_valid;
162   Register(containing_type, number, info);
163 }
164 
RegisterMessageExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,const MessageLite * prototype)165 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
166                                             int number, FieldType type,
167                                             bool is_repeated, bool is_packed,
168                                             const MessageLite* prototype) {
169   GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
170         type == WireFormatLite::TYPE_GROUP);
171   ExtensionInfo info(type, is_repeated, is_packed);
172   info.message_prototype = prototype;
173   Register(containing_type, number, info);
174 }
175 
176 
177 // ===================================================================
178 // Constructors and basic methods.
179 
ExtensionSet(::google::protobuf::Arena * arena)180 ExtensionSet::ExtensionSet(::google::protobuf::Arena* arena)
181     : arena_(arena) {
182   if (arena_ != NULL) {
183     arena_->OwnDestructor(&extensions_);
184   }
185 }
186 
ExtensionSet()187 ExtensionSet::ExtensionSet() : arena_(NULL) {}
188 
~ExtensionSet()189 ExtensionSet::~ExtensionSet() {
190   // Deletes all allocated extensions.
191   if (arena_ == NULL) {
192     for (ExtensionMap::iterator iter = extensions_.begin();
193          iter != extensions_.end(); ++iter) {
194       iter->second.Free();
195     }
196   }
197 }
198 
199 // Defined in extension_set_heavy.cc.
200 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
201 //                                 const DescriptorPool* pool,
202 //                                 vector<const FieldDescriptor*>* output) const
203 
Has(int number) const204 bool ExtensionSet::Has(int number) const {
205   ExtensionMap::const_iterator iter = extensions_.find(number);
206   if (iter == extensions_.end()) return false;
207   GOOGLE_DCHECK(!iter->second.is_repeated);
208   return !iter->second.is_cleared;
209 }
210 
NumExtensions() const211 int ExtensionSet::NumExtensions() const {
212   int result = 0;
213   for (ExtensionMap::const_iterator iter = extensions_.begin();
214        iter != extensions_.end(); ++iter) {
215     if (!iter->second.is_cleared) {
216       ++result;
217     }
218   }
219   return result;
220 }
221 
ExtensionSize(int number) const222 int ExtensionSet::ExtensionSize(int number) const {
223   ExtensionMap::const_iterator iter = extensions_.find(number);
224   if (iter == extensions_.end()) return false;
225   return iter->second.GetSize();
226 }
227 
ExtensionType(int number) const228 FieldType ExtensionSet::ExtensionType(int number) const {
229   ExtensionMap::const_iterator iter = extensions_.find(number);
230   if (iter == extensions_.end()) {
231     GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
232     return 0;
233   }
234   if (iter->second.is_cleared) {
235     GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
236   }
237   return iter->second.type;
238 }
239 
ClearExtension(int number)240 void ExtensionSet::ClearExtension(int number) {
241   ExtensionMap::iterator iter = extensions_.find(number);
242   if (iter == extensions_.end()) return;
243   iter->second.Clear();
244 }
245 
246 // ===================================================================
247 // Field accessors
248 
249 namespace {
250 
251 enum Cardinality {
252   REPEATED,
253   OPTIONAL
254 };
255 
256 }  // namespace
257 
258 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                             \
259   GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL);         \
260   GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
261 
262 // -------------------------------------------------------------------
263 // Primitives
264 
265 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
266                                                                                \
267 LOWERCASE ExtensionSet::Get##CAMELCASE(int number,                             \
268                                        LOWERCASE default_value) const {        \
269   ExtensionMap::const_iterator iter = extensions_.find(number);                \
270   if (iter == extensions_.end() || iter->second.is_cleared) {                  \
271     return default_value;                                                      \
272   } else {                                                                     \
273     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE);                            \
274     return iter->second.LOWERCASE##_value;                                     \
275   }                                                                            \
276 }                                                                              \
277                                                                                \
278 void ExtensionSet::Set##CAMELCASE(int number, FieldType type,                  \
279                                   LOWERCASE value,                             \
280                                   const FieldDescriptor* descriptor) {         \
281   Extension* extension;                                                        \
282   if (MaybeNewExtension(number, descriptor, &extension)) {                     \
283     extension->type = type;                                                    \
284     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
285     extension->is_repeated = false;                                            \
286   } else {                                                                     \
287     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE);                              \
288   }                                                                            \
289   extension->is_cleared = false;                                               \
290   extension->LOWERCASE##_value = value;                                        \
291 }                                                                              \
292                                                                                \
293 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const {  \
294   ExtensionMap::const_iterator iter = extensions_.find(number);                \
295   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
296   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
297   return iter->second.repeated_##LOWERCASE##_value->Get(index);                \
298 }                                                                              \
299                                                                                \
300 void ExtensionSet::SetRepeated##CAMELCASE(                                     \
301     int number, int index, LOWERCASE value) {                                  \
302   ExtensionMap::iterator iter = extensions_.find(number);                      \
303   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
304   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
305   iter->second.repeated_##LOWERCASE##_value->Set(index, value);                \
306 }                                                                              \
307                                                                                \
308 void ExtensionSet::Add##CAMELCASE(int number, FieldType type,                  \
309                                   bool packed, LOWERCASE value,                \
310                                   const FieldDescriptor* descriptor) {         \
311   Extension* extension;                                                        \
312   if (MaybeNewExtension(number, descriptor, &extension)) {                     \
313     extension->type = type;                                                    \
314     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
315     extension->is_repeated = true;                                             \
316     extension->is_packed = packed;                                             \
317     extension->repeated_##LOWERCASE##_value =                                  \
318       Arena::CreateMessage<RepeatedField<LOWERCASE> >(arena_);                 \
319   } else {                                                                     \
320     GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE);                              \
321     GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                   \
322   }                                                                            \
323   extension->repeated_##LOWERCASE##_value->Add(value);                         \
324 }
325 
PRIMITIVE_ACCESSORS(INT32,int32,Int32)326 PRIMITIVE_ACCESSORS( INT32,  int32,  Int32)
327 PRIMITIVE_ACCESSORS( INT64,  int64,  Int64)
328 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
329 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
330 PRIMITIVE_ACCESSORS( FLOAT,  float,  Float)
331 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
332 PRIMITIVE_ACCESSORS(  BOOL,   bool,   Bool)
333 
334 #undef PRIMITIVE_ACCESSORS
335 
336 const void* ExtensionSet::GetRawRepeatedField(int number,
337                                               const void* default_value) const {
338   ExtensionMap::const_iterator iter = extensions_.find(number);
339   if (iter == extensions_.end()) {
340     return default_value;
341   }
342   // We assume that all the RepeatedField<>* pointers have the same
343   // size and alignment within the anonymous union in Extension.
344   return iter->second.repeated_int32_value;
345 }
346 
MutableRawRepeatedField(int number,FieldType field_type,bool packed,const FieldDescriptor * desc)347 void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
348                                             bool packed,
349                                             const FieldDescriptor* desc) {
350   Extension* extension;
351 
352   // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
353   // extension.
354   if (MaybeNewExtension(number, desc, &extension)) {
355     extension->is_repeated = true;
356     extension->type = field_type;
357     extension->is_packed = packed;
358 
359     switch (WireFormatLite::FieldTypeToCppType(
360         static_cast<WireFormatLite::FieldType>(field_type))) {
361       case WireFormatLite::CPPTYPE_INT32:
362         extension->repeated_int32_value =
363             Arena::CreateMessage<RepeatedField<int32> >(arena_);
364         break;
365       case WireFormatLite::CPPTYPE_INT64:
366         extension->repeated_int64_value =
367             Arena::CreateMessage<RepeatedField<int64> >(arena_);
368         break;
369       case WireFormatLite::CPPTYPE_UINT32:
370         extension->repeated_uint32_value =
371             Arena::CreateMessage<RepeatedField<uint32> >(arena_);
372         break;
373       case WireFormatLite::CPPTYPE_UINT64:
374         extension->repeated_uint64_value =
375             Arena::CreateMessage<RepeatedField<uint64> >(arena_);
376         break;
377       case WireFormatLite::CPPTYPE_DOUBLE:
378         extension->repeated_double_value =
379             Arena::CreateMessage<RepeatedField<double> >(arena_);
380         break;
381       case WireFormatLite::CPPTYPE_FLOAT:
382         extension->repeated_float_value =
383             Arena::CreateMessage<RepeatedField<float> >(arena_);
384         break;
385       case WireFormatLite::CPPTYPE_BOOL:
386         extension->repeated_bool_value =
387             Arena::CreateMessage<RepeatedField<bool> >(arena_);
388         break;
389       case WireFormatLite::CPPTYPE_ENUM:
390         extension->repeated_enum_value =
391             Arena::CreateMessage<RepeatedField<int> >(arena_);
392         break;
393       case WireFormatLite::CPPTYPE_STRING:
394         extension->repeated_string_value =
395             Arena::CreateMessage<RepeatedPtrField< ::std::string> >(arena_);
396         break;
397       case WireFormatLite::CPPTYPE_MESSAGE:
398         extension->repeated_message_value =
399             Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
400         break;
401     }
402   }
403 
404   // We assume that all the RepeatedField<>* pointers have the same
405   // size and alignment within the anonymous union in Extension.
406   return extension->repeated_int32_value;
407 }
408 
409 // Compatible version using old call signature. Does not create extensions when
410 // the don't already exist; instead, just GOOGLE_CHECK-fails.
MutableRawRepeatedField(int number)411 void* ExtensionSet::MutableRawRepeatedField(int number) {
412   ExtensionMap::iterator iter = extensions_.find(number);
413   GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
414   // We assume that all the RepeatedField<>* pointers have the same
415   // size and alignment within the anonymous union in Extension.
416   return iter->second.repeated_int32_value;
417 }
418 
419 
420 // -------------------------------------------------------------------
421 // Enums
422 
GetEnum(int number,int default_value) const423 int ExtensionSet::GetEnum(int number, int default_value) const {
424   ExtensionMap::const_iterator iter = extensions_.find(number);
425   if (iter == extensions_.end() || iter->second.is_cleared) {
426     // Not present.  Return the default value.
427     return default_value;
428   } else {
429     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
430     return iter->second.enum_value;
431   }
432 }
433 
SetEnum(int number,FieldType type,int value,const FieldDescriptor * descriptor)434 void ExtensionSet::SetEnum(int number, FieldType type, int value,
435                            const FieldDescriptor* descriptor) {
436   Extension* extension;
437   if (MaybeNewExtension(number, descriptor, &extension)) {
438     extension->type = type;
439     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
440     extension->is_repeated = false;
441   } else {
442     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
443   }
444   extension->is_cleared = false;
445   extension->enum_value = value;
446 }
447 
GetRepeatedEnum(int number,int index) const448 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
449   ExtensionMap::const_iterator iter = extensions_.find(number);
450   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
451   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
452   return iter->second.repeated_enum_value->Get(index);
453 }
454 
SetRepeatedEnum(int number,int index,int value)455 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
456   ExtensionMap::iterator iter = extensions_.find(number);
457   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
458   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
459   iter->second.repeated_enum_value->Set(index, value);
460 }
461 
AddEnum(int number,FieldType type,bool packed,int value,const FieldDescriptor * descriptor)462 void ExtensionSet::AddEnum(int number, FieldType type,
463                            bool packed, int value,
464                            const FieldDescriptor* descriptor) {
465   Extension* extension;
466   if (MaybeNewExtension(number, descriptor, &extension)) {
467     extension->type = type;
468     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
469     extension->is_repeated = true;
470     extension->is_packed = packed;
471     extension->repeated_enum_value =
472         Arena::CreateMessage<RepeatedField<int> >(arena_);
473   } else {
474     GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
475     GOOGLE_DCHECK_EQ(extension->is_packed, packed);
476   }
477   extension->repeated_enum_value->Add(value);
478 }
479 
480 // -------------------------------------------------------------------
481 // Strings
482 
GetString(int number,const string & default_value) const483 const string& ExtensionSet::GetString(int number,
484                                       const string& default_value) const {
485   ExtensionMap::const_iterator iter = extensions_.find(number);
486   if (iter == extensions_.end() || iter->second.is_cleared) {
487     // Not present.  Return the default value.
488     return default_value;
489   } else {
490     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
491     return *iter->second.string_value;
492   }
493 }
494 
MutableString(int number,FieldType type,const FieldDescriptor * descriptor)495 string* ExtensionSet::MutableString(int number, FieldType type,
496                                     const FieldDescriptor* descriptor) {
497   Extension* extension;
498   if (MaybeNewExtension(number, descriptor, &extension)) {
499     extension->type = type;
500     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
501     extension->is_repeated = false;
502     extension->string_value = Arena::Create<string>(arena_);
503   } else {
504     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
505   }
506   extension->is_cleared = false;
507   return extension->string_value;
508 }
509 
GetRepeatedString(int number,int index) const510 const string& ExtensionSet::GetRepeatedString(int number, int index) const {
511   ExtensionMap::const_iterator iter = extensions_.find(number);
512   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
513   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
514   return iter->second.repeated_string_value->Get(index);
515 }
516 
MutableRepeatedString(int number,int index)517 string* ExtensionSet::MutableRepeatedString(int number, int index) {
518   ExtensionMap::iterator iter = extensions_.find(number);
519   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
520   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
521   return iter->second.repeated_string_value->Mutable(index);
522 }
523 
AddString(int number,FieldType type,const FieldDescriptor * descriptor)524 string* ExtensionSet::AddString(int number, FieldType type,
525                                 const FieldDescriptor* descriptor) {
526   Extension* extension;
527   if (MaybeNewExtension(number, descriptor, &extension)) {
528     extension->type = type;
529     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
530     extension->is_repeated = true;
531     extension->is_packed = false;
532     extension->repeated_string_value =
533         Arena::CreateMessage<RepeatedPtrField<string> >(arena_);
534   } else {
535     GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
536   }
537   return extension->repeated_string_value->Add();
538 }
539 
540 // -------------------------------------------------------------------
541 // Messages
542 
GetMessage(int number,const MessageLite & default_value) const543 const MessageLite& ExtensionSet::GetMessage(
544     int number, const MessageLite& default_value) const {
545   ExtensionMap::const_iterator iter = extensions_.find(number);
546   if (iter == extensions_.end()) {
547     // Not present.  Return the default value.
548     return default_value;
549   } else {
550     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
551     if (iter->second.is_lazy) {
552       return iter->second.lazymessage_value->GetMessage(default_value);
553     } else {
554       return *iter->second.message_value;
555     }
556   }
557 }
558 
559 // Defined in extension_set_heavy.cc.
560 // const MessageLite& ExtensionSet::GetMessage(int number,
561 //                                             const Descriptor* message_type,
562 //                                             MessageFactory* factory) const
563 
MutableMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)564 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
565                                           const MessageLite& prototype,
566                                           const FieldDescriptor* descriptor) {
567   Extension* extension;
568   if (MaybeNewExtension(number, descriptor, &extension)) {
569     extension->type = type;
570     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
571     extension->is_repeated = false;
572     extension->is_lazy = false;
573     extension->message_value = prototype.New(arena_);
574     extension->is_cleared = false;
575     return extension->message_value;
576   } else {
577     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
578     extension->is_cleared = false;
579     if (extension->is_lazy) {
580       return extension->lazymessage_value->MutableMessage(prototype);
581     } else {
582       return extension->message_value;
583     }
584   }
585 }
586 
587 // Defined in extension_set_heavy.cc.
588 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
589 //                                           const Descriptor* message_type,
590 //                                           MessageFactory* factory)
591 
SetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)592 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
593                                        const FieldDescriptor* descriptor,
594                                        MessageLite* message) {
595   if (message == NULL) {
596     ClearExtension(number);
597     return;
598   }
599   ::google::protobuf::Arena* message_arena = message->GetArena();
600   Extension* extension;
601   if (MaybeNewExtension(number, descriptor, &extension)) {
602     extension->type = type;
603     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
604     extension->is_repeated = false;
605     extension->is_lazy = false;
606     if (message_arena == arena_) {
607       extension->message_value = message;
608     } else if (message_arena == NULL) {
609       extension->message_value = message;
610       arena_->Own(message);  // not NULL because not equal to message_arena
611     } else {
612       extension->message_value = message->New(arena_);
613       extension->message_value->CheckTypeAndMergeFrom(*message);
614     }
615   } else {
616     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
617     if (extension->is_lazy) {
618       extension->lazymessage_value->SetAllocatedMessage(message);
619     } else {
620       if (arena_ == NULL) {
621         delete extension->message_value;
622       }
623       if (message_arena == arena_) {
624         extension->message_value = message;
625       } else if (message_arena == NULL) {
626         extension->message_value = message;
627         arena_->Own(message);  // not NULL because not equal to message_arena
628       } else {
629         extension->message_value = message->New(arena_);
630         extension->message_value->CheckTypeAndMergeFrom(*message);
631       }
632     }
633   }
634   extension->is_cleared = false;
635 }
636 
UnsafeArenaSetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)637 void ExtensionSet::UnsafeArenaSetAllocatedMessage(
638     int number, FieldType type, const FieldDescriptor* descriptor,
639     MessageLite* message) {
640   if (message == NULL) {
641     ClearExtension(number);
642     return;
643   }
644   Extension* extension;
645   if (MaybeNewExtension(number, descriptor, &extension)) {
646     extension->type = type;
647     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
648     extension->is_repeated = false;
649     extension->is_lazy = false;
650     extension->message_value = message;
651   } else {
652     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
653     if (extension->is_lazy) {
654       extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message);
655     } else {
656       if (arena_ == NULL) {
657         delete extension->message_value;
658       }
659       extension->message_value = message;
660     }
661   }
662   extension->is_cleared = false;
663 }
664 
665 
ReleaseMessage(int number,const MessageLite & prototype)666 MessageLite* ExtensionSet::ReleaseMessage(int number,
667                                           const MessageLite& prototype) {
668   ExtensionMap::iterator iter = extensions_.find(number);
669   if (iter == extensions_.end()) {
670     // Not present.  Return NULL.
671     return NULL;
672   } else {
673     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
674     MessageLite* ret = NULL;
675     if (iter->second.is_lazy) {
676       ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
677       if (arena_ == NULL) {
678         delete iter->second.lazymessage_value;
679       }
680     } else {
681       if (arena_ == NULL) {
682         ret = iter->second.message_value;
683       } else {
684         // ReleaseMessage() always returns a heap-allocated message, and we are
685         // on an arena, so we need to make a copy of this message to return.
686         ret = (iter->second.message_value)->New();
687         ret->CheckTypeAndMergeFrom(*iter->second.message_value);
688       }
689     }
690     extensions_.erase(number);
691     return ret;
692   }
693 }
694 
UnsafeArenaReleaseMessage(int number,const MessageLite & prototype)695 MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
696     int number, const MessageLite& prototype) {
697   ExtensionMap::iterator iter = extensions_.find(number);
698   if (iter == extensions_.end()) {
699     // Not present.  Return NULL.
700     return NULL;
701   } else {
702     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
703     MessageLite* ret = NULL;
704     if (iter->second.is_lazy) {
705       ret =
706         iter->second.lazymessage_value->UnsafeArenaReleaseMessage(prototype);
707       if (arena_ == NULL) {
708         delete iter->second.lazymessage_value;
709       }
710     } else {
711       ret = iter->second.message_value;
712     }
713     extensions_.erase(number);
714     return ret;
715   }
716 }
717 
718 // Defined in extension_set_heavy.cc.
719 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
720 //                                           MessageFactory* factory);
721 
GetRepeatedMessage(int number,int index) const722 const MessageLite& ExtensionSet::GetRepeatedMessage(
723     int number, int index) const {
724   ExtensionMap::const_iterator iter = extensions_.find(number);
725   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
726   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
727   return iter->second.repeated_message_value->Get(index);
728 }
729 
MutableRepeatedMessage(int number,int index)730 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
731   ExtensionMap::iterator iter = extensions_.find(number);
732   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
733   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
734   return iter->second.repeated_message_value->Mutable(index);
735 }
736 
AddMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)737 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
738                                       const MessageLite& prototype,
739                                       const FieldDescriptor* descriptor) {
740   Extension* extension;
741   if (MaybeNewExtension(number, descriptor, &extension)) {
742     extension->type = type;
743     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
744     extension->is_repeated = true;
745     extension->repeated_message_value =
746         Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
747   } else {
748     GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
749   }
750 
751   // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
752   // allocate an abstract object, so we have to be tricky.
753   MessageLite* result = extension->repeated_message_value
754       ->AddFromCleared<GenericTypeHandler<MessageLite> >();
755   if (result == NULL) {
756     result = prototype.New(arena_);
757     extension->repeated_message_value->AddAllocated(result);
758   }
759   return result;
760 }
761 
762 // Defined in extension_set_heavy.cc.
763 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
764 //                                       const Descriptor* message_type,
765 //                                       MessageFactory* factory)
766 
767 #undef GOOGLE_DCHECK_TYPE
768 
RemoveLast(int number)769 void ExtensionSet::RemoveLast(int number) {
770   ExtensionMap::iterator iter = extensions_.find(number);
771   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
772 
773   Extension* extension = &iter->second;
774   GOOGLE_DCHECK(extension->is_repeated);
775 
776   switch(cpp_type(extension->type)) {
777     case WireFormatLite::CPPTYPE_INT32:
778       extension->repeated_int32_value->RemoveLast();
779       break;
780     case WireFormatLite::CPPTYPE_INT64:
781       extension->repeated_int64_value->RemoveLast();
782       break;
783     case WireFormatLite::CPPTYPE_UINT32:
784       extension->repeated_uint32_value->RemoveLast();
785       break;
786     case WireFormatLite::CPPTYPE_UINT64:
787       extension->repeated_uint64_value->RemoveLast();
788       break;
789     case WireFormatLite::CPPTYPE_FLOAT:
790       extension->repeated_float_value->RemoveLast();
791       break;
792     case WireFormatLite::CPPTYPE_DOUBLE:
793       extension->repeated_double_value->RemoveLast();
794       break;
795     case WireFormatLite::CPPTYPE_BOOL:
796       extension->repeated_bool_value->RemoveLast();
797       break;
798     case WireFormatLite::CPPTYPE_ENUM:
799       extension->repeated_enum_value->RemoveLast();
800       break;
801     case WireFormatLite::CPPTYPE_STRING:
802       extension->repeated_string_value->RemoveLast();
803       break;
804     case WireFormatLite::CPPTYPE_MESSAGE:
805       extension->repeated_message_value->RemoveLast();
806       break;
807   }
808 }
809 
ReleaseLast(int number)810 MessageLite* ExtensionSet::ReleaseLast(int number) {
811   ExtensionMap::iterator iter = extensions_.find(number);
812   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
813 
814   Extension* extension = &iter->second;
815   GOOGLE_DCHECK(extension->is_repeated);
816   GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
817   return extension->repeated_message_value->ReleaseLast();
818 }
819 
SwapElements(int number,int index1,int index2)820 void ExtensionSet::SwapElements(int number, int index1, int index2) {
821   ExtensionMap::iterator iter = extensions_.find(number);
822   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
823 
824   Extension* extension = &iter->second;
825   GOOGLE_DCHECK(extension->is_repeated);
826 
827   switch(cpp_type(extension->type)) {
828     case WireFormatLite::CPPTYPE_INT32:
829       extension->repeated_int32_value->SwapElements(index1, index2);
830       break;
831     case WireFormatLite::CPPTYPE_INT64:
832       extension->repeated_int64_value->SwapElements(index1, index2);
833       break;
834     case WireFormatLite::CPPTYPE_UINT32:
835       extension->repeated_uint32_value->SwapElements(index1, index2);
836       break;
837     case WireFormatLite::CPPTYPE_UINT64:
838       extension->repeated_uint64_value->SwapElements(index1, index2);
839       break;
840     case WireFormatLite::CPPTYPE_FLOAT:
841       extension->repeated_float_value->SwapElements(index1, index2);
842       break;
843     case WireFormatLite::CPPTYPE_DOUBLE:
844       extension->repeated_double_value->SwapElements(index1, index2);
845       break;
846     case WireFormatLite::CPPTYPE_BOOL:
847       extension->repeated_bool_value->SwapElements(index1, index2);
848       break;
849     case WireFormatLite::CPPTYPE_ENUM:
850       extension->repeated_enum_value->SwapElements(index1, index2);
851       break;
852     case WireFormatLite::CPPTYPE_STRING:
853       extension->repeated_string_value->SwapElements(index1, index2);
854       break;
855     case WireFormatLite::CPPTYPE_MESSAGE:
856       extension->repeated_message_value->SwapElements(index1, index2);
857       break;
858   }
859 }
860 
861 // ===================================================================
862 
Clear()863 void ExtensionSet::Clear() {
864   for (ExtensionMap::iterator iter = extensions_.begin();
865        iter != extensions_.end(); ++iter) {
866     iter->second.Clear();
867   }
868 }
869 
MergeFrom(const ExtensionSet & other)870 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
871   for (ExtensionMap::const_iterator iter = other.extensions_.begin();
872        iter != other.extensions_.end(); ++iter) {
873     const Extension& other_extension = iter->second;
874     InternalExtensionMergeFrom(iter->first, other_extension);
875   }
876 }
877 
InternalExtensionMergeFrom(int number,const Extension & other_extension)878 void ExtensionSet::InternalExtensionMergeFrom(
879   int number, const Extension& other_extension) {
880   if (other_extension.is_repeated) {
881     Extension* extension;
882     bool is_new = MaybeNewExtension(number, other_extension.descriptor,
883                                     &extension);
884     if (is_new) {
885       // Extension did not already exist in set.
886       extension->type = other_extension.type;
887       extension->is_packed = other_extension.is_packed;
888       extension->is_repeated = true;
889     } else {
890       GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
891       GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
892       GOOGLE_DCHECK(extension->is_repeated);
893     }
894 
895     switch (cpp_type(other_extension.type)) {
896 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)                    \
897       case WireFormatLite::CPPTYPE_##UPPERCASE:                             \
898         if (is_new) {                                                       \
899           extension->repeated_##LOWERCASE##_value =                         \
900             Arena::CreateMessage<REPEATED_TYPE >(arena_);                   \
901         }                                                                   \
902         extension->repeated_##LOWERCASE##_value->MergeFrom(                 \
903           *other_extension.repeated_##LOWERCASE##_value);                   \
904         break;
905 
906       HANDLE_TYPE(  INT32,   int32, RepeatedField   <  int32>);
907       HANDLE_TYPE(  INT64,   int64, RepeatedField   <  int64>);
908       HANDLE_TYPE( UINT32,  uint32, RepeatedField   < uint32>);
909       HANDLE_TYPE( UINT64,  uint64, RepeatedField   < uint64>);
910       HANDLE_TYPE(  FLOAT,   float, RepeatedField   <  float>);
911       HANDLE_TYPE( DOUBLE,  double, RepeatedField   < double>);
912       HANDLE_TYPE(   BOOL,    bool, RepeatedField   <   bool>);
913       HANDLE_TYPE(   ENUM,    enum, RepeatedField   <    int>);
914       HANDLE_TYPE( STRING,  string, RepeatedPtrField< string>);
915 #undef HANDLE_TYPE
916 
917       case WireFormatLite::CPPTYPE_MESSAGE:
918         if (is_new) {
919           extension->repeated_message_value =
920               Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
921         }
922         // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
923         // it would attempt to allocate new objects.
924         RepeatedPtrField<MessageLite>* other_repeated_message =
925             other_extension.repeated_message_value;
926         for (int i = 0; i < other_repeated_message->size(); i++) {
927           const MessageLite& other_message = other_repeated_message->Get(i);
928           MessageLite* target = extension->repeated_message_value
929                    ->AddFromCleared<GenericTypeHandler<MessageLite> >();
930           if (target == NULL) {
931             target = other_message.New(arena_);
932             extension->repeated_message_value->AddAllocated(target);
933           }
934           target->CheckTypeAndMergeFrom(other_message);
935         }
936         break;
937     }
938   } else {
939     if (!other_extension.is_cleared) {
940       switch (cpp_type(other_extension.type)) {
941 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)                       \
942         case WireFormatLite::CPPTYPE_##UPPERCASE:                          \
943           Set##CAMELCASE(number, other_extension.type,                     \
944                          other_extension.LOWERCASE##_value,                \
945                          other_extension.descriptor);                      \
946           break;
947 
948         HANDLE_TYPE( INT32,  int32,  Int32);
949         HANDLE_TYPE( INT64,  int64,  Int64);
950         HANDLE_TYPE(UINT32, uint32, UInt32);
951         HANDLE_TYPE(UINT64, uint64, UInt64);
952         HANDLE_TYPE( FLOAT,  float,  Float);
953         HANDLE_TYPE(DOUBLE, double, Double);
954         HANDLE_TYPE(  BOOL,   bool,   Bool);
955         HANDLE_TYPE(  ENUM,   enum,   Enum);
956 #undef HANDLE_TYPE
957         case WireFormatLite::CPPTYPE_STRING:
958           SetString(number, other_extension.type,
959                     *other_extension.string_value,
960                     other_extension.descriptor);
961           break;
962         case WireFormatLite::CPPTYPE_MESSAGE: {
963           Extension* extension;
964           bool is_new = MaybeNewExtension(number,
965                                           other_extension.descriptor,
966                                           &extension);
967           if (is_new) {
968             extension->type = other_extension.type;
969             extension->is_packed = other_extension.is_packed;
970             extension->is_repeated = false;
971             if (other_extension.is_lazy) {
972               extension->is_lazy = true;
973               extension->lazymessage_value =
974                   other_extension.lazymessage_value->New(arena_);
975               extension->lazymessage_value->MergeFrom(
976                   *other_extension.lazymessage_value);
977             } else {
978               extension->is_lazy = false;
979               extension->message_value =
980                   other_extension.message_value->New(arena_);
981               extension->message_value->CheckTypeAndMergeFrom(
982                   *other_extension.message_value);
983             }
984           } else {
985             GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
986             GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
987             GOOGLE_DCHECK(!extension->is_repeated);
988             if (other_extension.is_lazy) {
989               if (extension->is_lazy) {
990                 extension->lazymessage_value->MergeFrom(
991                     *other_extension.lazymessage_value);
992               } else {
993                 extension->message_value->CheckTypeAndMergeFrom(
994                     other_extension.lazymessage_value->GetMessage(
995                         *extension->message_value));
996               }
997             } else {
998               if (extension->is_lazy) {
999                 extension->lazymessage_value->MutableMessage(
1000                     *other_extension.message_value)->CheckTypeAndMergeFrom(
1001                         *other_extension.message_value);
1002               } else {
1003                 extension->message_value->CheckTypeAndMergeFrom(
1004                     *other_extension.message_value);
1005               }
1006             }
1007           }
1008           extension->is_cleared = false;
1009           break;
1010         }
1011       }
1012     }
1013   }
1014 }
1015 
Swap(ExtensionSet * x)1016 void ExtensionSet::Swap(ExtensionSet* x) {
1017   if (GetArenaNoVirtual() == x->GetArenaNoVirtual()) {
1018     extensions_.swap(x->extensions_);
1019   } else {
1020     // TODO(cfallin, rohananil): We maybe able to optimize a case where we are
1021     // swapping from heap to arena-allocated extension set, by just Own()'ing
1022     // the extensions.
1023     ExtensionSet extension_set;
1024     extension_set.MergeFrom(*x);
1025     x->Clear();
1026     x->MergeFrom(*this);
1027     Clear();
1028     MergeFrom(extension_set);
1029   }
1030 }
1031 
SwapExtension(ExtensionSet * other,int number)1032 void ExtensionSet::SwapExtension(ExtensionSet* other,
1033                                  int number) {
1034   if (this == other) return;
1035   ExtensionMap::iterator this_iter = extensions_.find(number);
1036   ExtensionMap::iterator other_iter = other->extensions_.find(number);
1037 
1038   if (this_iter == extensions_.end() &&
1039       other_iter == other->extensions_.end()) {
1040     return;
1041   }
1042 
1043   if (this_iter != extensions_.end() &&
1044       other_iter != other->extensions_.end()) {
1045     if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1046       using std::swap;
1047       swap(this_iter->second, other_iter->second);
1048     } else {
1049       // TODO(cfallin, rohananil): We could further optimize these cases,
1050       // especially avoid creation of ExtensionSet, and move MergeFrom logic
1051       // into Extensions itself (which takes arena as an argument).
1052       // We do it this way to reuse the copy-across-arenas logic already
1053       // implemented in ExtensionSet's MergeFrom.
1054       ExtensionSet temp;
1055       temp.InternalExtensionMergeFrom(number, other_iter->second);
1056       ExtensionMap::iterator temp_iter = temp.extensions_.find(number);
1057       other_iter->second.Clear();
1058       other->InternalExtensionMergeFrom(number, this_iter->second);
1059       this_iter->second.Clear();
1060       InternalExtensionMergeFrom(number, temp_iter->second);
1061     }
1062     return;
1063   }
1064 
1065   if (this_iter == extensions_.end()) {
1066     if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1067       extensions_.insert(std::make_pair(number, other_iter->second));
1068     } else {
1069       InternalExtensionMergeFrom(number, other_iter->second);
1070     }
1071     other->extensions_.erase(number);
1072     return;
1073   }
1074 
1075   if (other_iter == other->extensions_.end()) {
1076     if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) {
1077       other->extensions_.insert(std::make_pair(number, this_iter->second));
1078     } else {
1079       other->InternalExtensionMergeFrom(number, this_iter->second);
1080     }
1081     extensions_.erase(number);
1082     return;
1083   }
1084 }
1085 
IsInitialized() const1086 bool ExtensionSet::IsInitialized() const {
1087   // Extensions are never required.  However, we need to check that all
1088   // embedded messages are initialized.
1089   for (ExtensionMap::const_iterator iter = extensions_.begin();
1090        iter != extensions_.end(); ++iter) {
1091     const Extension& extension = iter->second;
1092     if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
1093       if (extension.is_repeated) {
1094         for (int i = 0; i < extension.repeated_message_value->size(); i++) {
1095           if (!extension.repeated_message_value->Get(i).IsInitialized()) {
1096             return false;
1097           }
1098         }
1099       } else {
1100         if (!extension.is_cleared) {
1101           if (extension.is_lazy) {
1102             if (!extension.lazymessage_value->IsInitialized()) return false;
1103           } else {
1104             if (!extension.message_value->IsInitialized()) return false;
1105           }
1106         }
1107       }
1108     }
1109   }
1110 
1111   return true;
1112 }
1113 
FindExtensionInfoFromTag(uint32 tag,ExtensionFinder * extension_finder,int * field_number,ExtensionInfo * extension,bool * was_packed_on_wire)1114 bool ExtensionSet::FindExtensionInfoFromTag(
1115     uint32 tag, ExtensionFinder* extension_finder, int* field_number,
1116     ExtensionInfo* extension, bool* was_packed_on_wire) {
1117   *field_number = WireFormatLite::GetTagFieldNumber(tag);
1118   WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
1119   return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
1120                                           extension_finder, extension,
1121                                           was_packed_on_wire);
1122 }
1123 
FindExtensionInfoFromFieldNumber(int wire_type,int field_number,ExtensionFinder * extension_finder,ExtensionInfo * extension,bool * was_packed_on_wire)1124 bool ExtensionSet::FindExtensionInfoFromFieldNumber(
1125     int wire_type, int field_number, ExtensionFinder* extension_finder,
1126     ExtensionInfo* extension, bool* was_packed_on_wire) {
1127   if (!extension_finder->Find(field_number, extension)) {
1128     return false;
1129   }
1130 
1131   WireFormatLite::WireType expected_wire_type =
1132       WireFormatLite::WireTypeForFieldType(real_type(extension->type));
1133 
1134   // Check if this is a packed field.
1135   *was_packed_on_wire = false;
1136   if (extension->is_repeated &&
1137       wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
1138       is_packable(expected_wire_type)) {
1139     *was_packed_on_wire = true;
1140     return true;
1141   }
1142   // Otherwise the wire type must match.
1143   return expected_wire_type == wire_type;
1144 }
1145 
ParseField(uint32 tag,io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)1146 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1147                               ExtensionFinder* extension_finder,
1148                               FieldSkipper* field_skipper) {
1149   int number;
1150   bool was_packed_on_wire;
1151   ExtensionInfo extension;
1152   if (!FindExtensionInfoFromTag(
1153       tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
1154     return field_skipper->SkipField(input, tag);
1155   } else {
1156     return ParseFieldWithExtensionInfo(
1157         number, was_packed_on_wire, extension, input, field_skipper);
1158   }
1159 }
1160 
ParseFieldWithExtensionInfo(int number,bool was_packed_on_wire,const ExtensionInfo & extension,io::CodedInputStream * input,FieldSkipper * field_skipper)1161 bool ExtensionSet::ParseFieldWithExtensionInfo(
1162     int number, bool was_packed_on_wire, const ExtensionInfo& extension,
1163     io::CodedInputStream* input,
1164     FieldSkipper* field_skipper) {
1165   // Explicitly not read extension.is_packed, instead check whether the field
1166   // was encoded in packed form on the wire.
1167   if (was_packed_on_wire) {
1168     uint32 size;
1169     if (!input->ReadVarint32(&size)) return false;
1170     io::CodedInputStream::Limit limit = input->PushLimit(size);
1171 
1172     switch (extension.type) {
1173 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)        \
1174       case WireFormatLite::TYPE_##UPPERCASE:                                   \
1175         while (input->BytesUntilLimit() > 0) {                                 \
1176           CPP_LOWERCASE value;                                                 \
1177           if (!WireFormatLite::ReadPrimitive<                                  \
1178                   CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(            \
1179                 input, &value)) return false;                                  \
1180           Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
1181                              extension.is_packed, value,                       \
1182                              extension.descriptor);                            \
1183         }                                                                      \
1184         break
1185 
1186       HANDLE_TYPE(   INT32,  Int32,   int32);
1187       HANDLE_TYPE(   INT64,  Int64,   int64);
1188       HANDLE_TYPE(  UINT32, UInt32,  uint32);
1189       HANDLE_TYPE(  UINT64, UInt64,  uint64);
1190       HANDLE_TYPE(  SINT32,  Int32,   int32);
1191       HANDLE_TYPE(  SINT64,  Int64,   int64);
1192       HANDLE_TYPE( FIXED32, UInt32,  uint32);
1193       HANDLE_TYPE( FIXED64, UInt64,  uint64);
1194       HANDLE_TYPE(SFIXED32,  Int32,   int32);
1195       HANDLE_TYPE(SFIXED64,  Int64,   int64);
1196       HANDLE_TYPE(   FLOAT,  Float,   float);
1197       HANDLE_TYPE(  DOUBLE, Double,  double);
1198       HANDLE_TYPE(    BOOL,   Bool,    bool);
1199 #undef HANDLE_TYPE
1200 
1201       case WireFormatLite::TYPE_ENUM:
1202         while (input->BytesUntilLimit() > 0) {
1203           int value;
1204           if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1205                   input, &value)) return false;
1206           if (extension.enum_validity_check.func(
1207                   extension.enum_validity_check.arg, value)) {
1208             AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
1209                     value, extension.descriptor);
1210           } else {
1211             // Invalid value.  Treat as unknown.
1212             field_skipper->SkipUnknownEnum(number, value);
1213           }
1214         }
1215         break;
1216 
1217       case WireFormatLite::TYPE_STRING:
1218       case WireFormatLite::TYPE_BYTES:
1219       case WireFormatLite::TYPE_GROUP:
1220       case WireFormatLite::TYPE_MESSAGE:
1221         GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1222         break;
1223     }
1224 
1225     input->PopLimit(limit);
1226   } else {
1227     switch (extension.type) {
1228 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                   \
1229       case WireFormatLite::TYPE_##UPPERCASE: {                                 \
1230         CPP_LOWERCASE value;                                                   \
1231         if (!WireFormatLite::ReadPrimitive<                                    \
1232                 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(              \
1233                input, &value)) return false;                                   \
1234         if (extension.is_repeated) {                                           \
1235           Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
1236                              extension.is_packed, value,                       \
1237                              extension.descriptor);                            \
1238         } else {                                                               \
1239           Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
1240                              extension.descriptor);                            \
1241         }                                                                      \
1242       } break
1243 
1244       HANDLE_TYPE(   INT32,  Int32,   int32);
1245       HANDLE_TYPE(   INT64,  Int64,   int64);
1246       HANDLE_TYPE(  UINT32, UInt32,  uint32);
1247       HANDLE_TYPE(  UINT64, UInt64,  uint64);
1248       HANDLE_TYPE(  SINT32,  Int32,   int32);
1249       HANDLE_TYPE(  SINT64,  Int64,   int64);
1250       HANDLE_TYPE( FIXED32, UInt32,  uint32);
1251       HANDLE_TYPE( FIXED64, UInt64,  uint64);
1252       HANDLE_TYPE(SFIXED32,  Int32,   int32);
1253       HANDLE_TYPE(SFIXED64,  Int64,   int64);
1254       HANDLE_TYPE(   FLOAT,  Float,   float);
1255       HANDLE_TYPE(  DOUBLE, Double,  double);
1256       HANDLE_TYPE(    BOOL,   Bool,    bool);
1257 #undef HANDLE_TYPE
1258 
1259       case WireFormatLite::TYPE_ENUM: {
1260         int value;
1261         if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1262                 input, &value)) return false;
1263 
1264         if (!extension.enum_validity_check.func(
1265                 extension.enum_validity_check.arg, value)) {
1266           // Invalid value.  Treat as unknown.
1267           field_skipper->SkipUnknownEnum(number, value);
1268         } else if (extension.is_repeated) {
1269           AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
1270                   extension.descriptor);
1271         } else {
1272           SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1273                   extension.descriptor);
1274         }
1275         break;
1276       }
1277 
1278       case WireFormatLite::TYPE_STRING:  {
1279         string* value = extension.is_repeated ?
1280           AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
1281           MutableString(number, WireFormatLite::TYPE_STRING,
1282                         extension.descriptor);
1283         if (!WireFormatLite::ReadString(input, value)) return false;
1284         break;
1285       }
1286 
1287       case WireFormatLite::TYPE_BYTES:  {
1288         string* value = extension.is_repeated ?
1289           AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1290           MutableString(number, WireFormatLite::TYPE_BYTES,
1291                         extension.descriptor);
1292         if (!WireFormatLite::ReadBytes(input, value)) return false;
1293         break;
1294       }
1295 
1296       case WireFormatLite::TYPE_GROUP: {
1297         MessageLite* value = extension.is_repeated ?
1298             AddMessage(number, WireFormatLite::TYPE_GROUP,
1299                        *extension.message_prototype, extension.descriptor) :
1300             MutableMessage(number, WireFormatLite::TYPE_GROUP,
1301                            *extension.message_prototype, extension.descriptor);
1302         if (!WireFormatLite::ReadGroup(number, input, value)) return false;
1303         break;
1304       }
1305 
1306       case WireFormatLite::TYPE_MESSAGE: {
1307         MessageLite* value = extension.is_repeated ?
1308             AddMessage(number, WireFormatLite::TYPE_MESSAGE,
1309                        *extension.message_prototype, extension.descriptor) :
1310             MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
1311                            *extension.message_prototype, extension.descriptor);
1312         if (!WireFormatLite::ReadMessage(input, value)) return false;
1313         break;
1314       }
1315     }
1316   }
1317 
1318   return true;
1319 }
1320 
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type)1321 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1322                               const MessageLite* containing_type) {
1323   FieldSkipper skipper;
1324   GeneratedExtensionFinder finder(containing_type);
1325   return ParseField(tag, input, &finder, &skipper);
1326 }
1327 
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type,io::CodedOutputStream * unknown_fields)1328 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1329                               const MessageLite* containing_type,
1330                               io::CodedOutputStream* unknown_fields) {
1331   CodedOutputStreamFieldSkipper skipper(unknown_fields);
1332   GeneratedExtensionFinder finder(containing_type);
1333   return ParseField(tag, input, &finder, &skipper);
1334 }
1335 
1336 // Defined in extension_set_heavy.cc.
1337 // bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1338 //                               const MessageLite* containing_type,
1339 //                               UnknownFieldSet* unknown_fields)
1340 
1341 // Defined in extension_set_heavy.cc.
1342 // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1343 //                                    const MessageLite* containing_type,
1344 //                                    UnknownFieldSet* unknown_fields);
1345 
SerializeWithCachedSizes(int start_field_number,int end_field_number,io::CodedOutputStream * output) const1346 void ExtensionSet::SerializeWithCachedSizes(
1347     int start_field_number, int end_field_number,
1348     io::CodedOutputStream* output) const {
1349   ExtensionMap::const_iterator iter;
1350   for (iter = extensions_.lower_bound(start_field_number);
1351        iter != extensions_.end() && iter->first < end_field_number;
1352        ++iter) {
1353     iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1354   }
1355 }
1356 
ByteSize() const1357 int ExtensionSet::ByteSize() const {
1358   int total_size = 0;
1359 
1360   for (ExtensionMap::const_iterator iter = extensions_.begin();
1361        iter != extensions_.end(); ++iter) {
1362     total_size += iter->second.ByteSize(iter->first);
1363   }
1364 
1365   return total_size;
1366 }
1367 
1368 // Defined in extension_set_heavy.cc.
1369 // int ExtensionSet::SpaceUsedExcludingSelf() const
1370 
MaybeNewExtension(int number,const FieldDescriptor * descriptor,Extension ** result)1371 bool ExtensionSet::MaybeNewExtension(int number,
1372                                      const FieldDescriptor* descriptor,
1373                                      Extension** result) {
1374   pair<ExtensionMap::iterator, bool> insert_result =
1375       extensions_.insert(std::make_pair(number, Extension()));
1376   *result = &insert_result.first->second;
1377   (*result)->descriptor = descriptor;
1378   return insert_result.second;
1379 }
1380 
1381 // ===================================================================
1382 // Methods of ExtensionSet::Extension
1383 
Clear()1384 void ExtensionSet::Extension::Clear() {
1385   if (is_repeated) {
1386     switch (cpp_type(type)) {
1387 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1388       case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1389         repeated_##LOWERCASE##_value->Clear();                     \
1390         break
1391 
1392       HANDLE_TYPE(  INT32,   int32);
1393       HANDLE_TYPE(  INT64,   int64);
1394       HANDLE_TYPE( UINT32,  uint32);
1395       HANDLE_TYPE( UINT64,  uint64);
1396       HANDLE_TYPE(  FLOAT,   float);
1397       HANDLE_TYPE( DOUBLE,  double);
1398       HANDLE_TYPE(   BOOL,    bool);
1399       HANDLE_TYPE(   ENUM,    enum);
1400       HANDLE_TYPE( STRING,  string);
1401       HANDLE_TYPE(MESSAGE, message);
1402 #undef HANDLE_TYPE
1403     }
1404   } else {
1405     if (!is_cleared) {
1406       switch (cpp_type(type)) {
1407         case WireFormatLite::CPPTYPE_STRING:
1408           string_value->clear();
1409           break;
1410         case WireFormatLite::CPPTYPE_MESSAGE:
1411           if (is_lazy) {
1412             lazymessage_value->Clear();
1413           } else {
1414             message_value->Clear();
1415           }
1416           break;
1417         default:
1418           // No need to do anything.  Get*() will return the default value
1419           // as long as is_cleared is true and Set*() will overwrite the
1420           // previous value.
1421           break;
1422       }
1423 
1424       is_cleared = true;
1425     }
1426   }
1427 }
1428 
SerializeFieldWithCachedSizes(int number,io::CodedOutputStream * output) const1429 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1430     int number,
1431     io::CodedOutputStream* output) const {
1432   if (is_repeated) {
1433     if (is_packed) {
1434       if (cached_size == 0) return;
1435 
1436       WireFormatLite::WriteTag(number,
1437           WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1438       output->WriteVarint32(cached_size);
1439 
1440       switch (real_type(type)) {
1441 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1442         case WireFormatLite::TYPE_##UPPERCASE:                              \
1443           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1444             WireFormatLite::Write##CAMELCASE##NoTag(                        \
1445               repeated_##LOWERCASE##_value->Get(i), output);                \
1446           }                                                                 \
1447           break
1448 
1449         HANDLE_TYPE(   INT32,    Int32,   int32);
1450         HANDLE_TYPE(   INT64,    Int64,   int64);
1451         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1452         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1453         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1454         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1455         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1456         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1457         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1458         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1459         HANDLE_TYPE(   FLOAT,    Float,   float);
1460         HANDLE_TYPE(  DOUBLE,   Double,  double);
1461         HANDLE_TYPE(    BOOL,     Bool,    bool);
1462         HANDLE_TYPE(    ENUM,     Enum,    enum);
1463 #undef HANDLE_TYPE
1464 
1465         case WireFormatLite::TYPE_STRING:
1466         case WireFormatLite::TYPE_BYTES:
1467         case WireFormatLite::TYPE_GROUP:
1468         case WireFormatLite::TYPE_MESSAGE:
1469           GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1470           break;
1471       }
1472     } else {
1473       switch (real_type(type)) {
1474 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1475         case WireFormatLite::TYPE_##UPPERCASE:                              \
1476           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1477             WireFormatLite::Write##CAMELCASE(number,                        \
1478               repeated_##LOWERCASE##_value->Get(i), output);                \
1479           }                                                                 \
1480           break
1481 
1482         HANDLE_TYPE(   INT32,    Int32,   int32);
1483         HANDLE_TYPE(   INT64,    Int64,   int64);
1484         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1485         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1486         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1487         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1488         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1489         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1490         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1491         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1492         HANDLE_TYPE(   FLOAT,    Float,   float);
1493         HANDLE_TYPE(  DOUBLE,   Double,  double);
1494         HANDLE_TYPE(    BOOL,     Bool,    bool);
1495         HANDLE_TYPE(  STRING,   String,  string);
1496         HANDLE_TYPE(   BYTES,    Bytes,  string);
1497         HANDLE_TYPE(    ENUM,     Enum,    enum);
1498         HANDLE_TYPE(   GROUP,    Group, message);
1499         HANDLE_TYPE( MESSAGE,  Message, message);
1500 #undef HANDLE_TYPE
1501       }
1502     }
1503   } else if (!is_cleared) {
1504     switch (real_type(type)) {
1505 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
1506       case WireFormatLite::TYPE_##UPPERCASE:                     \
1507         WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1508         break
1509 
1510       HANDLE_TYPE(   INT32,    Int32,    int32_value);
1511       HANDLE_TYPE(   INT64,    Int64,    int64_value);
1512       HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1513       HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1514       HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1515       HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1516       HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
1517       HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
1518       HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
1519       HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
1520       HANDLE_TYPE(   FLOAT,    Float,    float_value);
1521       HANDLE_TYPE(  DOUBLE,   Double,   double_value);
1522       HANDLE_TYPE(    BOOL,     Bool,     bool_value);
1523       HANDLE_TYPE(  STRING,   String,  *string_value);
1524       HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1525       HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1526       HANDLE_TYPE(   GROUP,    Group, *message_value);
1527 #undef HANDLE_TYPE
1528       case WireFormatLite::TYPE_MESSAGE:
1529         if (is_lazy) {
1530           lazymessage_value->WriteMessage(number, output);
1531         } else {
1532           WireFormatLite::WriteMessage(number, *message_value, output);
1533         }
1534         break;
1535     }
1536   }
1537 }
1538 
ByteSize(int number) const1539 int ExtensionSet::Extension::ByteSize(int number) const {
1540   int result = 0;
1541 
1542   if (is_repeated) {
1543     if (is_packed) {
1544       switch (real_type(type)) {
1545 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1546         case WireFormatLite::TYPE_##UPPERCASE:                              \
1547           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1548             result += WireFormatLite::CAMELCASE##Size(                      \
1549               repeated_##LOWERCASE##_value->Get(i));                        \
1550           }                                                                 \
1551           break
1552 
1553         HANDLE_TYPE(   INT32,    Int32,   int32);
1554         HANDLE_TYPE(   INT64,    Int64,   int64);
1555         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1556         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1557         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1558         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1559         HANDLE_TYPE(    ENUM,     Enum,    enum);
1560 #undef HANDLE_TYPE
1561 
1562         // Stuff with fixed size.
1563 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1564         case WireFormatLite::TYPE_##UPPERCASE:                              \
1565           result += WireFormatLite::k##CAMELCASE##Size *                    \
1566                     repeated_##LOWERCASE##_value->size();                   \
1567           break
1568         HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1569         HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1570         HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1571         HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1572         HANDLE_TYPE(   FLOAT,    Float,  float);
1573         HANDLE_TYPE(  DOUBLE,   Double, double);
1574         HANDLE_TYPE(    BOOL,     Bool,   bool);
1575 #undef HANDLE_TYPE
1576 
1577         case WireFormatLite::TYPE_STRING:
1578         case WireFormatLite::TYPE_BYTES:
1579         case WireFormatLite::TYPE_GROUP:
1580         case WireFormatLite::TYPE_MESSAGE:
1581           GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1582           break;
1583       }
1584 
1585       cached_size = result;
1586       if (result > 0) {
1587         result += io::CodedOutputStream::VarintSize32(result);
1588         result += io::CodedOutputStream::VarintSize32(
1589             WireFormatLite::MakeTag(number,
1590                 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1591       }
1592     } else {
1593       int tag_size = WireFormatLite::TagSize(number, real_type(type));
1594 
1595       switch (real_type(type)) {
1596 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1597         case WireFormatLite::TYPE_##UPPERCASE:                              \
1598           result += tag_size * repeated_##LOWERCASE##_value->size();        \
1599           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1600             result += WireFormatLite::CAMELCASE##Size(                      \
1601               repeated_##LOWERCASE##_value->Get(i));                        \
1602           }                                                                 \
1603           break
1604 
1605         HANDLE_TYPE(   INT32,    Int32,   int32);
1606         HANDLE_TYPE(   INT64,    Int64,   int64);
1607         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1608         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1609         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1610         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1611         HANDLE_TYPE(  STRING,   String,  string);
1612         HANDLE_TYPE(   BYTES,    Bytes,  string);
1613         HANDLE_TYPE(    ENUM,     Enum,    enum);
1614         HANDLE_TYPE(   GROUP,    Group, message);
1615         HANDLE_TYPE( MESSAGE,  Message, message);
1616 #undef HANDLE_TYPE
1617 
1618         // Stuff with fixed size.
1619 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1620         case WireFormatLite::TYPE_##UPPERCASE:                              \
1621           result += (tag_size + WireFormatLite::k##CAMELCASE##Size) *       \
1622                     repeated_##LOWERCASE##_value->size();                   \
1623           break
1624         HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1625         HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1626         HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1627         HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1628         HANDLE_TYPE(   FLOAT,    Float,  float);
1629         HANDLE_TYPE(  DOUBLE,   Double, double);
1630         HANDLE_TYPE(    BOOL,     Bool,   bool);
1631 #undef HANDLE_TYPE
1632       }
1633     }
1634   } else if (!is_cleared) {
1635     result += WireFormatLite::TagSize(number, real_type(type));
1636     switch (real_type(type)) {
1637 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                      \
1638       case WireFormatLite::TYPE_##UPPERCASE:                              \
1639         result += WireFormatLite::CAMELCASE##Size(LOWERCASE);             \
1640         break
1641 
1642       HANDLE_TYPE(   INT32,    Int32,    int32_value);
1643       HANDLE_TYPE(   INT64,    Int64,    int64_value);
1644       HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1645       HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1646       HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1647       HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1648       HANDLE_TYPE(  STRING,   String,  *string_value);
1649       HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1650       HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1651       HANDLE_TYPE(   GROUP,    Group, *message_value);
1652 #undef HANDLE_TYPE
1653       case WireFormatLite::TYPE_MESSAGE: {
1654         if (is_lazy) {
1655           int size = lazymessage_value->ByteSize();
1656           result += io::CodedOutputStream::VarintSize32(size) + size;
1657         } else {
1658           result += WireFormatLite::MessageSize(*message_value);
1659         }
1660         break;
1661       }
1662 
1663       // Stuff with fixed size.
1664 #define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
1665       case WireFormatLite::TYPE_##UPPERCASE:                              \
1666         result += WireFormatLite::k##CAMELCASE##Size;                     \
1667         break
1668       HANDLE_TYPE( FIXED32,  Fixed32);
1669       HANDLE_TYPE( FIXED64,  Fixed64);
1670       HANDLE_TYPE(SFIXED32, SFixed32);
1671       HANDLE_TYPE(SFIXED64, SFixed64);
1672       HANDLE_TYPE(   FLOAT,    Float);
1673       HANDLE_TYPE(  DOUBLE,   Double);
1674       HANDLE_TYPE(    BOOL,     Bool);
1675 #undef HANDLE_TYPE
1676     }
1677   }
1678 
1679   return result;
1680 }
1681 
GetSize() const1682 int ExtensionSet::Extension::GetSize() const {
1683   GOOGLE_DCHECK(is_repeated);
1684   switch (cpp_type(type)) {
1685 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                        \
1686     case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1687       return repeated_##LOWERCASE##_value->size()
1688 
1689     HANDLE_TYPE(  INT32,   int32);
1690     HANDLE_TYPE(  INT64,   int64);
1691     HANDLE_TYPE( UINT32,  uint32);
1692     HANDLE_TYPE( UINT64,  uint64);
1693     HANDLE_TYPE(  FLOAT,   float);
1694     HANDLE_TYPE( DOUBLE,  double);
1695     HANDLE_TYPE(   BOOL,    bool);
1696     HANDLE_TYPE(   ENUM,    enum);
1697     HANDLE_TYPE( STRING,  string);
1698     HANDLE_TYPE(MESSAGE, message);
1699 #undef HANDLE_TYPE
1700   }
1701 
1702   GOOGLE_LOG(FATAL) << "Can't get here.";
1703   return 0;
1704 }
1705 
1706 // This function deletes all allocated objects. This function should be only
1707 // called if the Extension was created with an arena.
Free()1708 void ExtensionSet::Extension::Free() {
1709   if (is_repeated) {
1710     switch (cpp_type(type)) {
1711 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1712       case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1713         delete repeated_##LOWERCASE##_value;                       \
1714         break
1715 
1716       HANDLE_TYPE(  INT32,   int32);
1717       HANDLE_TYPE(  INT64,   int64);
1718       HANDLE_TYPE( UINT32,  uint32);
1719       HANDLE_TYPE( UINT64,  uint64);
1720       HANDLE_TYPE(  FLOAT,   float);
1721       HANDLE_TYPE( DOUBLE,  double);
1722       HANDLE_TYPE(   BOOL,    bool);
1723       HANDLE_TYPE(   ENUM,    enum);
1724       HANDLE_TYPE( STRING,  string);
1725       HANDLE_TYPE(MESSAGE, message);
1726 #undef HANDLE_TYPE
1727     }
1728   } else {
1729     switch (cpp_type(type)) {
1730       case WireFormatLite::CPPTYPE_STRING:
1731         delete string_value;
1732         break;
1733       case WireFormatLite::CPPTYPE_MESSAGE:
1734         if (is_lazy) {
1735           delete lazymessage_value;
1736         } else {
1737           delete message_value;
1738         }
1739         break;
1740       default:
1741         break;
1742     }
1743   }
1744 }
1745 
1746 // Defined in extension_set_heavy.cc.
1747 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1748 
1749 // ==================================================================
1750 // Default repeated field instances for iterator-compatible accessors
1751 
1752 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_primitive_generic_type_traits_once_init_);
1753 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_string_type_traits_once_init_);
1754 GOOGLE_PROTOBUF_DECLARE_ONCE(repeated_message_generic_type_traits_once_init_);
1755 
InitializeDefaultRepeatedFields()1756 void RepeatedPrimitiveGenericTypeTraits::InitializeDefaultRepeatedFields() {
1757   default_repeated_field_int32_ = new RepeatedField<int32>;
1758   default_repeated_field_int64_ = new RepeatedField<int64>;
1759   default_repeated_field_uint32_ = new RepeatedField<uint32>;
1760   default_repeated_field_uint64_ = new RepeatedField<uint64>;
1761   default_repeated_field_double_ = new RepeatedField<double>;
1762   default_repeated_field_float_ = new RepeatedField<float>;
1763   default_repeated_field_bool_ = new RepeatedField<bool>;
1764   OnShutdown(&DestroyDefaultRepeatedFields);
1765 }
1766 
DestroyDefaultRepeatedFields()1767 void RepeatedPrimitiveGenericTypeTraits::DestroyDefaultRepeatedFields() {
1768   delete default_repeated_field_int32_;
1769   delete default_repeated_field_int64_;
1770   delete default_repeated_field_uint32_;
1771   delete default_repeated_field_uint64_;
1772   delete default_repeated_field_double_;
1773   delete default_repeated_field_float_;
1774   delete default_repeated_field_bool_;
1775 }
1776 
InitializeDefaultRepeatedFields()1777 void RepeatedStringTypeTraits::InitializeDefaultRepeatedFields() {
1778   default_repeated_field_ = new RepeatedFieldType;
1779   OnShutdown(&DestroyDefaultRepeatedFields);
1780 }
1781 
DestroyDefaultRepeatedFields()1782 void RepeatedStringTypeTraits::DestroyDefaultRepeatedFields() {
1783   delete default_repeated_field_;
1784 }
1785 
InitializeDefaultRepeatedFields()1786 void RepeatedMessageGenericTypeTraits::InitializeDefaultRepeatedFields() {
1787   default_repeated_field_ = new RepeatedFieldType;
1788   OnShutdown(&DestroyDefaultRepeatedFields);
1789 }
1790 
DestroyDefaultRepeatedFields()1791 void RepeatedMessageGenericTypeTraits::DestroyDefaultRepeatedFields() {
1792   delete default_repeated_field_;
1793 }
1794 
1795 const RepeatedField<int32>*
1796 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ = NULL;
1797 const RepeatedField<int64>*
1798 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ = NULL;
1799 const RepeatedField<uint32>*
1800 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ = NULL;
1801 const RepeatedField<uint64>*
1802 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ = NULL;
1803 const RepeatedField<double>*
1804 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ = NULL;
1805 const RepeatedField<float>*
1806 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ = NULL;
1807 const RepeatedField<bool>*
1808 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ = NULL;
1809 const RepeatedStringTypeTraits::RepeatedFieldType*
1810 RepeatedStringTypeTraits::default_repeated_field_ = NULL;
1811 const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
1812 RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
1813 
1814 }  // namespace internal
1815 }  // namespace protobuf
1816 }  // namespace google
1817