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