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