• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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/io/zero_copy_stream_impl.h>
42 #include <google/protobuf/wire_format_lite_inl.h>
43 #include <google/protobuf/repeated_field.h>
44 #include <google/protobuf/stubs/map-util.h>
45 
46 namespace google {
47 namespace protobuf {
48 namespace internal {
49 
50 namespace {
51 
real_type(FieldType type)52 inline WireFormatLite::FieldType real_type(FieldType type) {
53   GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
54   return static_cast<WireFormatLite::FieldType>(type);
55 }
56 
cpp_type(FieldType type)57 inline WireFormatLite::CppType cpp_type(FieldType type) {
58   return WireFormatLite::FieldTypeToCppType(real_type(type));
59 }
60 
61 // Registry stuff.
62 typedef hash_map<pair<const MessageLite*, int>,
63                  ExtensionInfo> ExtensionRegistry;
64 ExtensionRegistry* registry_ = NULL;
65 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
66 
DeleteRegistry()67 void DeleteRegistry() {
68   delete registry_;
69   registry_ = NULL;
70 }
71 
InitRegistry()72 void InitRegistry() {
73   registry_ = new ExtensionRegistry;
74   internal::OnShutdown(&DeleteRegistry);
75 }
76 
77 // This function is only called at startup, so there is no need for thread-
78 // safety.
Register(const MessageLite * containing_type,int number,ExtensionInfo info)79 void Register(const MessageLite* containing_type,
80               int number, ExtensionInfo info) {
81   ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
82 
83   if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
84                           info)) {
85     GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
86                << containing_type->GetTypeName()
87                << "\", field number " << number << ".";
88   }
89 }
90 
FindRegisteredExtension(const MessageLite * containing_type,int number)91 const ExtensionInfo* FindRegisteredExtension(
92     const MessageLite* containing_type, int number) {
93   return (registry_ == NULL) ? NULL :
94          FindOrNull(*registry_, make_pair(containing_type, number));
95 }
96 
97 }  // namespace
98 
~ExtensionFinder()99 ExtensionFinder::~ExtensionFinder() {}
100 
Find(int number,ExtensionInfo * output)101 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
102   const ExtensionInfo* extension =
103       FindRegisteredExtension(containing_type_, number);
104   if (extension == NULL) {
105     return false;
106   } else {
107     *output = *extension;
108     return true;
109   }
110 }
111 
RegisterExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed)112 void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
113                                      int number, FieldType type,
114                                      bool is_repeated, bool is_packed) {
115   GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
116   GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
117   GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
118   ExtensionInfo info(type, is_repeated, is_packed);
119   Register(containing_type, number, info);
120 }
121 
CallNoArgValidityFunc(const void * arg,int number)122 static bool CallNoArgValidityFunc(const void* arg, int number) {
123   // Note:  Must use C-style cast here rather than reinterpret_cast because
124   //   the C++ standard at one point did not allow casts between function and
125   //   data pointers and some compilers enforce this for C++-style casts.  No
126   //   compiler enforces it for C-style casts since lots of C-style code has
127   //   relied on these kinds of casts for a long time, despite being
128   //   technically undefined.  See:
129   //     http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
130   // Also note:  Some compilers do not allow function pointers to be "const".
131   //   Which makes sense, I suppose, because it's meaningless.
132   return ((EnumValidityFunc*)arg)(number);
133 }
134 
RegisterEnumExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,EnumValidityFunc * is_valid)135 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
136                                          int number, FieldType type,
137                                          bool is_repeated, bool is_packed,
138                                          EnumValidityFunc* is_valid) {
139   GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
140   ExtensionInfo info(type, is_repeated, is_packed);
141   info.enum_validity_check.func = CallNoArgValidityFunc;
142   // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
143   info.enum_validity_check.arg = (void*)is_valid;
144   Register(containing_type, number, info);
145 }
146 
RegisterMessageExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,const MessageLite * prototype)147 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
148                                             int number, FieldType type,
149                                             bool is_repeated, bool is_packed,
150                                             const MessageLite* prototype) {
151   GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
152         type == WireFormatLite::TYPE_GROUP);
153   ExtensionInfo info(type, is_repeated, is_packed);
154   info.message_prototype = prototype;
155   Register(containing_type, number, info);
156 }
157 
158 
159 // ===================================================================
160 // Constructors and basic methods.
161 
ExtensionSet()162 ExtensionSet::ExtensionSet() {}
163 
~ExtensionSet()164 ExtensionSet::~ExtensionSet() {
165   for (map<int, Extension>::iterator iter = extensions_.begin();
166        iter != extensions_.end(); ++iter) {
167     iter->second.Free();
168   }
169 }
170 
171 // Defined in extension_set_heavy.cc.
172 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
173 //                                 const DescriptorPool* pool,
174 //                                 vector<const FieldDescriptor*>* output) const
175 
Has(int number) const176 bool ExtensionSet::Has(int number) const {
177   map<int, Extension>::const_iterator iter = extensions_.find(number);
178   if (iter == extensions_.end()) return false;
179   GOOGLE_DCHECK(!iter->second.is_repeated);
180   return !iter->second.is_cleared;
181 }
182 
ExtensionSize(int number) const183 int ExtensionSet::ExtensionSize(int number) const {
184   map<int, Extension>::const_iterator iter = extensions_.find(number);
185   if (iter == extensions_.end()) return false;
186   return iter->second.GetSize();
187 }
188 
ClearExtension(int number)189 void ExtensionSet::ClearExtension(int number) {
190   map<int, Extension>::iterator iter = extensions_.find(number);
191   if (iter == extensions_.end()) return;
192   iter->second.Clear();
193 }
194 
195 // ===================================================================
196 // Field accessors
197 
198 namespace {
199 
200 enum Cardinality {
201   REPEATED,
202   OPTIONAL
203 };
204 
205 }  // namespace
206 
207 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                             \
208   GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL);         \
209   GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
210 
211 // -------------------------------------------------------------------
212 // Primitives
213 
214 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
215                                                                                \
216 LOWERCASE ExtensionSet::Get##CAMELCASE(int number,                             \
217                                        LOWERCASE default_value) const {        \
218   map<int, Extension>::const_iterator iter = extensions_.find(number);         \
219   if (iter == extensions_.end() || iter->second.is_cleared) {                  \
220     return default_value;                                                      \
221   } else {                                                                     \
222     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE);                            \
223     return iter->second.LOWERCASE##_value;                                     \
224   }                                                                            \
225 }                                                                              \
226                                                                                \
227 void ExtensionSet::Set##CAMELCASE(int number, FieldType type,                  \
228                                   LOWERCASE value,                             \
229                                   const FieldDescriptor* descriptor) {         \
230   Extension* extension;                                                        \
231   if (MaybeNewExtension(number, descriptor, &extension)) {                     \
232     extension->type = type;                                                    \
233     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
234     extension->is_repeated = false;                                            \
235   } else {                                                                     \
236     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE);                              \
237   }                                                                            \
238   extension->is_cleared = false;                                               \
239   extension->LOWERCASE##_value = value;                                        \
240 }                                                                              \
241                                                                                \
242 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const {  \
243   map<int, Extension>::const_iterator iter = extensions_.find(number);         \
244   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
245   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
246   return iter->second.repeated_##LOWERCASE##_value->Get(index);                \
247 }                                                                              \
248                                                                                \
249 void ExtensionSet::SetRepeated##CAMELCASE(                                     \
250     int number, int index, LOWERCASE value) {                                  \
251   map<int, Extension>::iterator iter = extensions_.find(number);               \
252   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
253   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
254   iter->second.repeated_##LOWERCASE##_value->Set(index, value);                \
255 }                                                                              \
256                                                                                \
257 void ExtensionSet::Add##CAMELCASE(int number, FieldType type,                  \
258                                   bool packed, LOWERCASE value,                \
259                                   const FieldDescriptor* descriptor) {         \
260   Extension* extension;                                                        \
261   if (MaybeNewExtension(number, descriptor, &extension)) {                     \
262     extension->type = type;                                                    \
263     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
264     extension->is_repeated = true;                                             \
265     extension->is_packed = packed;                                             \
266     extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>();  \
267   } else {                                                                     \
268     GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE);                              \
269     GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                   \
270   }                                                                            \
271   extension->repeated_##LOWERCASE##_value->Add(value);                         \
272 }
273 
PRIMITIVE_ACCESSORS(INT32,int32,Int32)274 PRIMITIVE_ACCESSORS( INT32,  int32,  Int32)
275 PRIMITIVE_ACCESSORS( INT64,  int64,  Int64)
276 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
277 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
278 PRIMITIVE_ACCESSORS( FLOAT,  float,  Float)
279 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
280 PRIMITIVE_ACCESSORS(  BOOL,   bool,   Bool)
281 
282 #undef PRIMITIVE_ACCESSORS
283 
284 // -------------------------------------------------------------------
285 // Enums
286 
287 int ExtensionSet::GetEnum(int number, int default_value) const {
288   map<int, Extension>::const_iterator iter = extensions_.find(number);
289   if (iter == extensions_.end() || iter->second.is_cleared) {
290     // Not present.  Return the default value.
291     return default_value;
292   } else {
293     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
294     return iter->second.enum_value;
295   }
296 }
297 
SetEnum(int number,FieldType type,int value,const FieldDescriptor * descriptor)298 void ExtensionSet::SetEnum(int number, FieldType type, int value,
299                            const FieldDescriptor* descriptor) {
300   Extension* extension;
301   if (MaybeNewExtension(number, descriptor, &extension)) {
302     extension->type = type;
303     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
304     extension->is_repeated = false;
305   } else {
306     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
307   }
308   extension->is_cleared = false;
309   extension->enum_value = value;
310 }
311 
GetRepeatedEnum(int number,int index) const312 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
313   map<int, Extension>::const_iterator iter = extensions_.find(number);
314   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
315   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
316   return iter->second.repeated_enum_value->Get(index);
317 }
318 
SetRepeatedEnum(int number,int index,int value)319 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
320   map<int, Extension>::iterator iter = extensions_.find(number);
321   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
322   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
323   iter->second.repeated_enum_value->Set(index, value);
324 }
325 
AddEnum(int number,FieldType type,bool packed,int value,const FieldDescriptor * descriptor)326 void ExtensionSet::AddEnum(int number, FieldType type,
327                            bool packed, int value,
328                            const FieldDescriptor* descriptor) {
329   Extension* extension;
330   if (MaybeNewExtension(number, descriptor, &extension)) {
331     extension->type = type;
332     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
333     extension->is_repeated = true;
334     extension->is_packed = packed;
335     extension->repeated_enum_value = new RepeatedField<int>();
336   } else {
337     GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
338     GOOGLE_DCHECK_EQ(extension->is_packed, packed);
339   }
340   extension->repeated_enum_value->Add(value);
341 }
342 
343 // -------------------------------------------------------------------
344 // Strings
345 
GetString(int number,const string & default_value) const346 const string& ExtensionSet::GetString(int number,
347                                       const string& default_value) const {
348   map<int, Extension>::const_iterator iter = extensions_.find(number);
349   if (iter == extensions_.end() || iter->second.is_cleared) {
350     // Not present.  Return the default value.
351     return default_value;
352   } else {
353     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
354     return *iter->second.string_value;
355   }
356 }
357 
MutableString(int number,FieldType type,const FieldDescriptor * descriptor)358 string* ExtensionSet::MutableString(int number, FieldType type,
359                                     const FieldDescriptor* descriptor) {
360   Extension* extension;
361   if (MaybeNewExtension(number, descriptor, &extension)) {
362     extension->type = type;
363     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
364     extension->is_repeated = false;
365     extension->string_value = new string;
366   } else {
367     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
368   }
369   extension->is_cleared = false;
370   return extension->string_value;
371 }
372 
GetRepeatedString(int number,int index) const373 const string& ExtensionSet::GetRepeatedString(int number, int index) const {
374   map<int, Extension>::const_iterator iter = extensions_.find(number);
375   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
376   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
377   return iter->second.repeated_string_value->Get(index);
378 }
379 
MutableRepeatedString(int number,int index)380 string* ExtensionSet::MutableRepeatedString(int number, int index) {
381   map<int, Extension>::iterator iter = extensions_.find(number);
382   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
383   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
384   return iter->second.repeated_string_value->Mutable(index);
385 }
386 
AddString(int number,FieldType type,const FieldDescriptor * descriptor)387 string* ExtensionSet::AddString(int number, FieldType type,
388                                 const FieldDescriptor* descriptor) {
389   Extension* extension;
390   if (MaybeNewExtension(number, descriptor, &extension)) {
391     extension->type = type;
392     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
393     extension->is_repeated = true;
394     extension->is_packed = false;
395     extension->repeated_string_value = new RepeatedPtrField<string>();
396   } else {
397     GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
398   }
399   return extension->repeated_string_value->Add();
400 }
401 
402 // -------------------------------------------------------------------
403 // Messages
404 
GetMessage(int number,const MessageLite & default_value) const405 const MessageLite& ExtensionSet::GetMessage(
406     int number, const MessageLite& default_value) const {
407   map<int, Extension>::const_iterator iter = extensions_.find(number);
408   if (iter == extensions_.end()) {
409     // Not present.  Return the default value.
410     return default_value;
411   } else {
412     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
413     return *iter->second.message_value;
414   }
415 }
416 
417 // Defined in extension_set_heavy.cc.
418 // const MessageLite& ExtensionSet::GetMessage(int number,
419 //                                             const Descriptor* message_type,
420 //                                             MessageFactory* factory) const
421 
MutableMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)422 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
423                                           const MessageLite& prototype,
424                                           const FieldDescriptor* descriptor) {
425   Extension* extension;
426   if (MaybeNewExtension(number, descriptor, &extension)) {
427     extension->type = type;
428     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
429     extension->is_repeated = false;
430     extension->message_value = prototype.New();
431   } else {
432     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
433   }
434   extension->is_cleared = false;
435   return extension->message_value;
436 }
437 
438 // Defined in extension_set_heavy.cc.
439 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
440 //                                           const Descriptor* message_type,
441 //                                           MessageFactory* factory)
442 
GetRepeatedMessage(int number,int index) const443 const MessageLite& ExtensionSet::GetRepeatedMessage(
444     int number, int index) const {
445   map<int, Extension>::const_iterator iter = extensions_.find(number);
446   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
447   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
448   return iter->second.repeated_message_value->Get(index);
449 }
450 
MutableRepeatedMessage(int number,int index)451 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
452   map<int, Extension>::iterator iter = extensions_.find(number);
453   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
454   GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
455   return iter->second.repeated_message_value->Mutable(index);
456 }
457 
AddMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)458 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
459                                       const MessageLite& prototype,
460                                       const FieldDescriptor* descriptor) {
461   Extension* extension;
462   if (MaybeNewExtension(number, descriptor, &extension)) {
463     extension->type = type;
464     GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
465     extension->is_repeated = true;
466     extension->repeated_message_value =
467       new RepeatedPtrField<MessageLite>();
468   } else {
469     GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
470   }
471 
472   // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
473   // allocate an abstract object, so we have to be tricky.
474   MessageLite* result = extension->repeated_message_value
475       ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
476   if (result == NULL) {
477     result = prototype.New();
478     extension->repeated_message_value->AddAllocated(result);
479   }
480   return result;
481 }
482 
483 // Defined in extension_set_heavy.cc.
484 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
485 //                                       const Descriptor* message_type,
486 //                                       MessageFactory* factory)
487 
488 #undef GOOGLE_DCHECK_TYPE
489 
RemoveLast(int number)490 void ExtensionSet::RemoveLast(int number) {
491   map<int, Extension>::iterator iter = extensions_.find(number);
492   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
493 
494   Extension* extension = &iter->second;
495   GOOGLE_DCHECK(extension->is_repeated);
496 
497   switch(cpp_type(extension->type)) {
498     case WireFormatLite::CPPTYPE_INT32:
499       extension->repeated_int32_value->RemoveLast();
500       break;
501     case WireFormatLite::CPPTYPE_INT64:
502       extension->repeated_int64_value->RemoveLast();
503       break;
504     case WireFormatLite::CPPTYPE_UINT32:
505       extension->repeated_uint32_value->RemoveLast();
506       break;
507     case WireFormatLite::CPPTYPE_UINT64:
508       extension->repeated_uint64_value->RemoveLast();
509       break;
510     case WireFormatLite::CPPTYPE_FLOAT:
511       extension->repeated_float_value->RemoveLast();
512       break;
513     case WireFormatLite::CPPTYPE_DOUBLE:
514       extension->repeated_double_value->RemoveLast();
515       break;
516     case WireFormatLite::CPPTYPE_BOOL:
517       extension->repeated_bool_value->RemoveLast();
518       break;
519     case WireFormatLite::CPPTYPE_ENUM:
520       extension->repeated_enum_value->RemoveLast();
521       break;
522     case WireFormatLite::CPPTYPE_STRING:
523       extension->repeated_string_value->RemoveLast();
524       break;
525     case WireFormatLite::CPPTYPE_MESSAGE:
526       extension->repeated_message_value->RemoveLast();
527       break;
528   }
529 }
530 
SwapElements(int number,int index1,int index2)531 void ExtensionSet::SwapElements(int number, int index1, int index2) {
532   map<int, Extension>::iterator iter = extensions_.find(number);
533   GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
534 
535   Extension* extension = &iter->second;
536   GOOGLE_DCHECK(extension->is_repeated);
537 
538   switch(cpp_type(extension->type)) {
539     case WireFormatLite::CPPTYPE_INT32:
540       extension->repeated_int32_value->SwapElements(index1, index2);
541       break;
542     case WireFormatLite::CPPTYPE_INT64:
543       extension->repeated_int64_value->SwapElements(index1, index2);
544       break;
545     case WireFormatLite::CPPTYPE_UINT32:
546       extension->repeated_uint32_value->SwapElements(index1, index2);
547       break;
548     case WireFormatLite::CPPTYPE_UINT64:
549       extension->repeated_uint64_value->SwapElements(index1, index2);
550       break;
551     case WireFormatLite::CPPTYPE_FLOAT:
552       extension->repeated_float_value->SwapElements(index1, index2);
553       break;
554     case WireFormatLite::CPPTYPE_DOUBLE:
555       extension->repeated_double_value->SwapElements(index1, index2);
556       break;
557     case WireFormatLite::CPPTYPE_BOOL:
558       extension->repeated_bool_value->SwapElements(index1, index2);
559       break;
560     case WireFormatLite::CPPTYPE_ENUM:
561       extension->repeated_enum_value->SwapElements(index1, index2);
562       break;
563     case WireFormatLite::CPPTYPE_STRING:
564       extension->repeated_string_value->SwapElements(index1, index2);
565       break;
566     case WireFormatLite::CPPTYPE_MESSAGE:
567       extension->repeated_message_value->SwapElements(index1, index2);
568       break;
569   }
570 }
571 
572 // ===================================================================
573 
Clear()574 void ExtensionSet::Clear() {
575   for (map<int, Extension>::iterator iter = extensions_.begin();
576        iter != extensions_.end(); ++iter) {
577     iter->second.Clear();
578   }
579 }
580 
MergeFrom(const ExtensionSet & other)581 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
582   for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
583        iter != other.extensions_.end(); ++iter) {
584     const Extension& other_extension = iter->second;
585 
586     if (other_extension.is_repeated) {
587       Extension* extension;
588       bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
589                                       &extension);
590       if (is_new) {
591         // Extension did not already exist in set.
592         extension->type = other_extension.type;
593         extension->is_repeated = true;
594       } else {
595         GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
596         GOOGLE_DCHECK(extension->is_repeated);
597       }
598 
599       switch (cpp_type(other_extension.type)) {
600 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)             \
601         case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
602           if (is_new) {                                              \
603             extension->repeated_##LOWERCASE##_value =                \
604               new REPEATED_TYPE;                                     \
605           }                                                          \
606           extension->repeated_##LOWERCASE##_value->MergeFrom(        \
607             *other_extension.repeated_##LOWERCASE##_value);          \
608           break;
609 
610         HANDLE_TYPE(  INT32,   int32, RepeatedField   <  int32>);
611         HANDLE_TYPE(  INT64,   int64, RepeatedField   <  int64>);
612         HANDLE_TYPE( UINT32,  uint32, RepeatedField   < uint32>);
613         HANDLE_TYPE( UINT64,  uint64, RepeatedField   < uint64>);
614         HANDLE_TYPE(  FLOAT,   float, RepeatedField   <  float>);
615         HANDLE_TYPE( DOUBLE,  double, RepeatedField   < double>);
616         HANDLE_TYPE(   BOOL,    bool, RepeatedField   <   bool>);
617         HANDLE_TYPE(   ENUM,    enum, RepeatedField   <    int>);
618         HANDLE_TYPE( STRING,  string, RepeatedPtrField< string>);
619 #undef HANDLE_TYPE
620 
621         case WireFormatLite::CPPTYPE_MESSAGE:
622           if (is_new) {
623             extension->repeated_message_value =
624               new RepeatedPtrField<MessageLite>();
625           }
626           // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
627           // it would attempt to allocate new objects.
628           RepeatedPtrField<MessageLite>* other_repeated_message =
629               other_extension.repeated_message_value;
630           for (int i = 0; i < other_repeated_message->size(); i++) {
631             const MessageLite& other_message = other_repeated_message->Get(i);
632             MessageLite* target = extension->repeated_message_value
633                      ->AddFromCleared<GenericTypeHandler<MessageLite> >();
634             if (target == NULL) {
635               target = other_message.New();
636               extension->repeated_message_value->AddAllocated(target);
637             }
638             target->CheckTypeAndMergeFrom(other_message);
639           }
640           break;
641       }
642     } else {
643       if (!other_extension.is_cleared) {
644         switch (cpp_type(other_extension.type)) {
645 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)                         \
646           case WireFormatLite::CPPTYPE_##UPPERCASE:                          \
647             Set##CAMELCASE(iter->first, other_extension.type,                \
648                            other_extension.LOWERCASE##_value,                \
649                            other_extension.descriptor);                      \
650             break;
651 
652           HANDLE_TYPE( INT32,  int32,  Int32);
653           HANDLE_TYPE( INT64,  int64,  Int64);
654           HANDLE_TYPE(UINT32, uint32, UInt32);
655           HANDLE_TYPE(UINT64, uint64, UInt64);
656           HANDLE_TYPE( FLOAT,  float,  Float);
657           HANDLE_TYPE(DOUBLE, double, Double);
658           HANDLE_TYPE(  BOOL,   bool,   Bool);
659           HANDLE_TYPE(  ENUM,   enum,   Enum);
660 #undef HANDLE_TYPE
661           case WireFormatLite::CPPTYPE_STRING:
662             SetString(iter->first, other_extension.type,
663                       *other_extension.string_value,
664                       other_extension.descriptor);
665             break;
666           case WireFormatLite::CPPTYPE_MESSAGE:
667             MutableMessage(iter->first, other_extension.type,
668                            *other_extension.message_value,
669                            other_extension.descriptor)
670               ->CheckTypeAndMergeFrom(*other_extension.message_value);
671             break;
672         }
673       }
674     }
675   }
676 }
677 
Swap(ExtensionSet * x)678 void ExtensionSet::Swap(ExtensionSet* x) {
679   extensions_.swap(x->extensions_);
680 }
681 
IsInitialized() const682 bool ExtensionSet::IsInitialized() const {
683   // Extensions are never required.  However, we need to check that all
684   // embedded messages are initialized.
685   for (map<int, Extension>::const_iterator iter = extensions_.begin();
686        iter != extensions_.end(); ++iter) {
687     const Extension& extension = iter->second;
688     if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
689       if (extension.is_repeated) {
690         for (int i = 0; i < extension.repeated_message_value->size(); i++) {
691           if (!extension.repeated_message_value->Get(i).IsInitialized()) {
692             return false;
693           }
694         }
695       } else {
696         if (!extension.is_cleared) {
697           if (!extension.message_value->IsInitialized()) return false;
698         }
699       }
700     }
701   }
702 
703   return true;
704 }
705 
ParseField(uint32 tag,io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)706 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
707                               ExtensionFinder* extension_finder,
708                               FieldSkipper* field_skipper) {
709   int number = WireFormatLite::GetTagFieldNumber(tag);
710   WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
711 
712   ExtensionInfo extension;
713   bool is_unknown;
714   if (!extension_finder->Find(number, &extension)) {
715     is_unknown = true;
716   } else if (extension.is_packed) {
717     is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
718   } else {
719     WireFormatLite::WireType expected_wire_type =
720         WireFormatLite::WireTypeForFieldType(real_type(extension.type));
721     is_unknown = (wire_type != expected_wire_type);
722   }
723 
724   if (is_unknown) {
725     field_skipper->SkipField(input, tag);
726   } else if (extension.is_packed) {
727     uint32 size;
728     if (!input->ReadVarint32(&size)) return false;
729     io::CodedInputStream::Limit limit = input->PushLimit(size);
730 
731     switch (extension.type) {
732 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)        \
733       case WireFormatLite::TYPE_##UPPERCASE:                                   \
734         while (input->BytesUntilLimit() > 0) {                                 \
735           CPP_LOWERCASE value;                                                 \
736           if (!WireFormatLite::ReadPrimitive<                                  \
737                   CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(            \
738                 input, &value)) return false;                                  \
739           Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
740                              true, value, extension.descriptor);               \
741         }                                                                      \
742         break
743 
744       HANDLE_TYPE(   INT32,  Int32,   int32);
745       HANDLE_TYPE(   INT64,  Int64,   int64);
746       HANDLE_TYPE(  UINT32, UInt32,  uint32);
747       HANDLE_TYPE(  UINT64, UInt64,  uint64);
748       HANDLE_TYPE(  SINT32,  Int32,   int32);
749       HANDLE_TYPE(  SINT64,  Int64,   int64);
750       HANDLE_TYPE( FIXED32, UInt32,  uint32);
751       HANDLE_TYPE( FIXED64, UInt64,  uint64);
752       HANDLE_TYPE(SFIXED32,  Int32,   int32);
753       HANDLE_TYPE(SFIXED64,  Int64,   int64);
754       HANDLE_TYPE(   FLOAT,  Float,   float);
755       HANDLE_TYPE(  DOUBLE, Double,  double);
756       HANDLE_TYPE(    BOOL,   Bool,    bool);
757 #undef HANDLE_TYPE
758 
759       case WireFormatLite::TYPE_ENUM:
760         while (input->BytesUntilLimit() > 0) {
761           int value;
762           if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
763                   input, &value)) return false;
764           if (extension.enum_validity_check.func(
765                   extension.enum_validity_check.arg, value)) {
766             AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
767                     extension.descriptor);
768           }
769         }
770         break;
771 
772       case WireFormatLite::TYPE_STRING:
773       case WireFormatLite::TYPE_BYTES:
774       case WireFormatLite::TYPE_GROUP:
775       case WireFormatLite::TYPE_MESSAGE:
776         GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
777         break;
778     }
779 
780     input->PopLimit(limit);
781   } else {
782     switch (extension.type) {
783 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                   \
784       case WireFormatLite::TYPE_##UPPERCASE: {                                 \
785         CPP_LOWERCASE value;                                                   \
786         if (!WireFormatLite::ReadPrimitive<                                    \
787                 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(              \
788                input, &value)) return false;                                   \
789         if (extension.is_repeated) {                                          \
790           Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
791                              false, value, extension.descriptor);              \
792         } else {                                                               \
793           Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
794                              extension.descriptor);                            \
795         }                                                                      \
796       } break
797 
798       HANDLE_TYPE(   INT32,  Int32,   int32);
799       HANDLE_TYPE(   INT64,  Int64,   int64);
800       HANDLE_TYPE(  UINT32, UInt32,  uint32);
801       HANDLE_TYPE(  UINT64, UInt64,  uint64);
802       HANDLE_TYPE(  SINT32,  Int32,   int32);
803       HANDLE_TYPE(  SINT64,  Int64,   int64);
804       HANDLE_TYPE( FIXED32, UInt32,  uint32);
805       HANDLE_TYPE( FIXED64, UInt64,  uint64);
806       HANDLE_TYPE(SFIXED32,  Int32,   int32);
807       HANDLE_TYPE(SFIXED64,  Int64,   int64);
808       HANDLE_TYPE(   FLOAT,  Float,   float);
809       HANDLE_TYPE(  DOUBLE, Double,  double);
810       HANDLE_TYPE(    BOOL,   Bool,    bool);
811 #undef HANDLE_TYPE
812 
813       case WireFormatLite::TYPE_ENUM: {
814         int value;
815         if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
816                 input, &value)) return false;
817 
818         if (!extension.enum_validity_check.func(
819                 extension.enum_validity_check.arg, value)) {
820           // Invalid value.  Treat as unknown.
821           field_skipper->SkipUnknownEnum(number, value);
822         } else if (extension.is_repeated) {
823           AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
824                   extension.descriptor);
825         } else {
826           SetEnum(number, WireFormatLite::TYPE_ENUM, value,
827                   extension.descriptor);
828         }
829         break;
830       }
831 
832       case WireFormatLite::TYPE_STRING:  {
833         string* value = extension.is_repeated ?
834           AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
835           MutableString(number, WireFormatLite::TYPE_STRING,
836                         extension.descriptor);
837         if (!WireFormatLite::ReadString(input, value)) return false;
838         break;
839       }
840 
841       case WireFormatLite::TYPE_BYTES:  {
842         string* value = extension.is_repeated ?
843           AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
844           MutableString(number, WireFormatLite::TYPE_STRING,
845                         extension.descriptor);
846         if (!WireFormatLite::ReadBytes(input, value)) return false;
847         break;
848       }
849 
850       case WireFormatLite::TYPE_GROUP: {
851         MessageLite* value = extension.is_repeated ?
852             AddMessage(number, WireFormatLite::TYPE_GROUP,
853                        *extension.message_prototype, extension.descriptor) :
854             MutableMessage(number, WireFormatLite::TYPE_GROUP,
855                            *extension.message_prototype, extension.descriptor);
856         if (!WireFormatLite::ReadGroup(number, input, value)) return false;
857         break;
858       }
859 
860       case WireFormatLite::TYPE_MESSAGE: {
861         MessageLite* value = extension.is_repeated ?
862             AddMessage(number, WireFormatLite::TYPE_MESSAGE,
863                        *extension.message_prototype, extension.descriptor) :
864             MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
865                            *extension.message_prototype, extension.descriptor);
866         if (!WireFormatLite::ReadMessage(input, value)) return false;
867         break;
868       }
869     }
870   }
871 
872   return true;
873 }
874 
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type)875 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
876                               const MessageLite* containing_type) {
877   FieldSkipper skipper;
878   GeneratedExtensionFinder finder(containing_type);
879   return ParseField(tag, input, &finder, &skipper);
880 }
881 
882 // Defined in extension_set_heavy.cc.
883 // bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
884 //                               const MessageLite* containing_type,
885 //                               UnknownFieldSet* unknown_fields)
886 
ParseMessageSet(io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)887 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
888                                    ExtensionFinder* extension_finder,
889                                    FieldSkipper* field_skipper) {
890   while (true) {
891     uint32 tag = input->ReadTag();
892     switch (tag) {
893       case 0:
894         return true;
895       case WireFormatLite::kMessageSetItemStartTag:
896         if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
897           return false;
898         }
899         break;
900       default:
901         if (!ParseField(tag, input, extension_finder, field_skipper)) {
902           return false;
903         }
904         break;
905     }
906   }
907 }
908 
ParseMessageSet(io::CodedInputStream * input,const MessageLite * containing_type)909 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
910                                    const MessageLite* containing_type) {
911   FieldSkipper skipper;
912   GeneratedExtensionFinder finder(containing_type);
913   return ParseMessageSet(input, &finder, &skipper);
914 }
915 
916 // Defined in extension_set_heavy.cc.
917 // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
918 //                                    const MessageLite* containing_type,
919 //                                    UnknownFieldSet* unknown_fields);
920 
ParseMessageSetItem(io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)921 bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
922                                        ExtensionFinder* extension_finder,
923                                        FieldSkipper* field_skipper) {
924   // TODO(kenton):  It would be nice to share code between this and
925   // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
926   // differences would be hard to factor out.
927 
928   // This method parses a group which should contain two fields:
929   //   required int32 type_id = 2;
930   //   required data message = 3;
931 
932   // Once we see a type_id, we'll construct a fake tag for this extension
933   // which is the tag it would have had under the proto2 extensions wire
934   // format.
935   uint32 fake_tag = 0;
936 
937   // If we see message data before the type_id, we'll append it to this so
938   // we can parse it later.  This will probably never happen in practice,
939   // as no MessageSet encoder I know of writes the message before the type ID.
940   // But, it's technically valid so we should allow it.
941   // TODO(kenton):  Use a Cord instead?  Do I care?
942   string message_data;
943 
944   while (true) {
945     uint32 tag = input->ReadTag();
946     if (tag == 0) return false;
947 
948     switch (tag) {
949       case WireFormatLite::kMessageSetTypeIdTag: {
950         uint32 type_id;
951         if (!input->ReadVarint32(&type_id)) return false;
952         fake_tag = WireFormatLite::MakeTag(type_id,
953             WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
954 
955         if (!message_data.empty()) {
956           // We saw some message data before the type_id.  Have to parse it
957           // now.
958           io::CodedInputStream sub_input(
959               reinterpret_cast<const uint8*>(message_data.data()),
960               message_data.size());
961           if (!ParseField(fake_tag, &sub_input,
962                           extension_finder, field_skipper)) {
963             return false;
964           }
965           message_data.clear();
966         }
967 
968         break;
969       }
970 
971       case WireFormatLite::kMessageSetMessageTag: {
972         if (fake_tag == 0) {
973           // We haven't seen a type_id yet.  Append this data to message_data.
974           string temp;
975           uint32 length;
976           if (!input->ReadVarint32(&length)) return false;
977           if (!input->ReadString(&temp, length)) return false;
978           message_data.append(temp);
979         } else {
980           // Already saw type_id, so we can parse this directly.
981           if (!ParseField(fake_tag, input,
982                           extension_finder, field_skipper)) {
983             return false;
984           }
985         }
986 
987         break;
988       }
989 
990       case WireFormatLite::kMessageSetItemEndTag: {
991         return true;
992       }
993 
994       default: {
995         if (!field_skipper->SkipField(input, tag)) return false;
996       }
997     }
998   }
999 }
1000 
SerializeWithCachedSizes(int start_field_number,int end_field_number,io::CodedOutputStream * output) const1001 void ExtensionSet::SerializeWithCachedSizes(
1002     int start_field_number, int end_field_number,
1003     io::CodedOutputStream* output) const {
1004   map<int, Extension>::const_iterator iter;
1005   for (iter = extensions_.lower_bound(start_field_number);
1006        iter != extensions_.end() && iter->first < end_field_number;
1007        ++iter) {
1008     iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1009   }
1010 }
1011 
SerializeMessageSetWithCachedSizes(io::CodedOutputStream * output) const1012 void ExtensionSet::SerializeMessageSetWithCachedSizes(
1013     io::CodedOutputStream* output) const {
1014   map<int, Extension>::const_iterator iter;
1015   for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
1016     iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
1017   }
1018 }
1019 
ByteSize() const1020 int ExtensionSet::ByteSize() const {
1021   int total_size = 0;
1022 
1023   for (map<int, Extension>::const_iterator iter = extensions_.begin();
1024        iter != extensions_.end(); ++iter) {
1025     total_size += iter->second.ByteSize(iter->first);
1026   }
1027 
1028   return total_size;
1029 }
1030 
MessageSetByteSize() const1031 int ExtensionSet::MessageSetByteSize() const {
1032   int total_size = 0;
1033 
1034   for (map<int, Extension>::const_iterator iter = extensions_.begin();
1035        iter != extensions_.end(); ++iter) {
1036     total_size += iter->second.MessageSetItemByteSize(iter->first);
1037   }
1038 
1039   return total_size;
1040 }
1041 
1042 // Defined in extension_set_heavy.cc.
1043 // int ExtensionSet::SpaceUsedExcludingSelf() const
1044 
MaybeNewExtension(int number,const FieldDescriptor * descriptor,Extension ** result)1045 bool ExtensionSet::MaybeNewExtension(int number,
1046                                      const FieldDescriptor* descriptor,
1047                                      Extension** result) {
1048   pair<map<int, Extension>::iterator, bool> insert_result =
1049       extensions_.insert(make_pair(number, Extension()));
1050   *result = &insert_result.first->second;
1051   (*result)->descriptor = descriptor;
1052   return insert_result.second;
1053 }
1054 
1055 // ===================================================================
1056 // Methods of ExtensionSet::Extension
1057 
Clear()1058 void ExtensionSet::Extension::Clear() {
1059   if (is_repeated) {
1060     switch (cpp_type(type)) {
1061 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1062       case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1063         repeated_##LOWERCASE##_value->Clear();                     \
1064         break
1065 
1066       HANDLE_TYPE(  INT32,   int32);
1067       HANDLE_TYPE(  INT64,   int64);
1068       HANDLE_TYPE( UINT32,  uint32);
1069       HANDLE_TYPE( UINT64,  uint64);
1070       HANDLE_TYPE(  FLOAT,   float);
1071       HANDLE_TYPE( DOUBLE,  double);
1072       HANDLE_TYPE(   BOOL,    bool);
1073       HANDLE_TYPE(   ENUM,    enum);
1074       HANDLE_TYPE( STRING,  string);
1075       HANDLE_TYPE(MESSAGE, message);
1076 #undef HANDLE_TYPE
1077     }
1078   } else {
1079     if (!is_cleared) {
1080       switch (cpp_type(type)) {
1081         case WireFormatLite::CPPTYPE_STRING:
1082           string_value->clear();
1083           break;
1084         case WireFormatLite::CPPTYPE_MESSAGE:
1085           message_value->Clear();
1086           break;
1087         default:
1088           // No need to do anything.  Get*() will return the default value
1089           // as long as is_cleared is true and Set*() will overwrite the
1090           // previous value.
1091           break;
1092       }
1093 
1094       is_cleared = true;
1095     }
1096   }
1097 }
1098 
SerializeFieldWithCachedSizes(int number,io::CodedOutputStream * output) const1099 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1100     int number,
1101     io::CodedOutputStream* output) const {
1102   if (is_repeated) {
1103     if (is_packed) {
1104       if (cached_size == 0) return;
1105 
1106       WireFormatLite::WriteTag(number,
1107           WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1108       output->WriteVarint32(cached_size);
1109 
1110       switch (real_type(type)) {
1111 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1112         case WireFormatLite::TYPE_##UPPERCASE:                              \
1113           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1114             WireFormatLite::Write##CAMELCASE##NoTag(                        \
1115               repeated_##LOWERCASE##_value->Get(i), output);                \
1116           }                                                                 \
1117           break
1118 
1119         HANDLE_TYPE(   INT32,    Int32,   int32);
1120         HANDLE_TYPE(   INT64,    Int64,   int64);
1121         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1122         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1123         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1124         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1125         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1126         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1127         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1128         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1129         HANDLE_TYPE(   FLOAT,    Float,   float);
1130         HANDLE_TYPE(  DOUBLE,   Double,  double);
1131         HANDLE_TYPE(    BOOL,     Bool,    bool);
1132         HANDLE_TYPE(    ENUM,     Enum,    enum);
1133 #undef HANDLE_TYPE
1134 
1135         case WireFormatLite::TYPE_STRING:
1136         case WireFormatLite::TYPE_BYTES:
1137         case WireFormatLite::TYPE_GROUP:
1138         case WireFormatLite::TYPE_MESSAGE:
1139           GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1140           break;
1141       }
1142     } else {
1143       switch (real_type(type)) {
1144 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1145         case WireFormatLite::TYPE_##UPPERCASE:                              \
1146           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1147             WireFormatLite::Write##CAMELCASE(number,                        \
1148               repeated_##LOWERCASE##_value->Get(i), output);                \
1149           }                                                                 \
1150           break
1151 
1152         HANDLE_TYPE(   INT32,    Int32,   int32);
1153         HANDLE_TYPE(   INT64,    Int64,   int64);
1154         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1155         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1156         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1157         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1158         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1159         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1160         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1161         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1162         HANDLE_TYPE(   FLOAT,    Float,   float);
1163         HANDLE_TYPE(  DOUBLE,   Double,  double);
1164         HANDLE_TYPE(    BOOL,     Bool,    bool);
1165         HANDLE_TYPE(  STRING,   String,  string);
1166         HANDLE_TYPE(   BYTES,    Bytes,  string);
1167         HANDLE_TYPE(    ENUM,     Enum,    enum);
1168         HANDLE_TYPE(   GROUP,    Group, message);
1169         HANDLE_TYPE( MESSAGE,  Message, message);
1170 #undef HANDLE_TYPE
1171       }
1172     }
1173   } else if (!is_cleared) {
1174     switch (real_type(type)) {
1175 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
1176       case WireFormatLite::TYPE_##UPPERCASE:                     \
1177         WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1178         break
1179 
1180       HANDLE_TYPE(   INT32,    Int32,    int32_value);
1181       HANDLE_TYPE(   INT64,    Int64,    int64_value);
1182       HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1183       HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1184       HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1185       HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1186       HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
1187       HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
1188       HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
1189       HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
1190       HANDLE_TYPE(   FLOAT,    Float,    float_value);
1191       HANDLE_TYPE(  DOUBLE,   Double,   double_value);
1192       HANDLE_TYPE(    BOOL,     Bool,     bool_value);
1193       HANDLE_TYPE(  STRING,   String,  *string_value);
1194       HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1195       HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1196       HANDLE_TYPE(   GROUP,    Group, *message_value);
1197       HANDLE_TYPE( MESSAGE,  Message, *message_value);
1198 #undef HANDLE_TYPE
1199     }
1200   }
1201 }
1202 
SerializeMessageSetItemWithCachedSizes(int number,io::CodedOutputStream * output) const1203 void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
1204     int number,
1205     io::CodedOutputStream* output) const {
1206   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1207     // Not a valid MessageSet extension, but serialize it the normal way.
1208     SerializeFieldWithCachedSizes(number, output);
1209     return;
1210   }
1211 
1212   if (is_cleared) return;
1213 
1214   // Start group.
1215   output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
1216 
1217   // Write type ID.
1218   WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
1219                               number,
1220                               output);
1221   // Write message.
1222   WireFormatLite::WriteMessageMaybeToArray(
1223       WireFormatLite::kMessageSetMessageNumber,
1224       *message_value,
1225       output);
1226 
1227   // End group.
1228   output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
1229 }
1230 
ByteSize(int number) const1231 int ExtensionSet::Extension::ByteSize(int number) const {
1232   int result = 0;
1233 
1234   if (is_repeated) {
1235     if (is_packed) {
1236       switch (real_type(type)) {
1237 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1238         case WireFormatLite::TYPE_##UPPERCASE:                              \
1239           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1240             result += WireFormatLite::CAMELCASE##Size(                      \
1241               repeated_##LOWERCASE##_value->Get(i));                        \
1242           }                                                                 \
1243           break
1244 
1245         HANDLE_TYPE(   INT32,    Int32,   int32);
1246         HANDLE_TYPE(   INT64,    Int64,   int64);
1247         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1248         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1249         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1250         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1251         HANDLE_TYPE(    ENUM,     Enum,    enum);
1252 #undef HANDLE_TYPE
1253 
1254         // Stuff with fixed size.
1255 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1256         case WireFormatLite::TYPE_##UPPERCASE:                              \
1257           result += WireFormatLite::k##CAMELCASE##Size *                    \
1258                     repeated_##LOWERCASE##_value->size();                   \
1259           break
1260         HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1261         HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1262         HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1263         HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1264         HANDLE_TYPE(   FLOAT,    Float,  float);
1265         HANDLE_TYPE(  DOUBLE,   Double, double);
1266         HANDLE_TYPE(    BOOL,     Bool,   bool);
1267 #undef HANDLE_TYPE
1268 
1269         case WireFormatLite::TYPE_STRING:
1270         case WireFormatLite::TYPE_BYTES:
1271         case WireFormatLite::TYPE_GROUP:
1272         case WireFormatLite::TYPE_MESSAGE:
1273           GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1274           break;
1275       }
1276 
1277       cached_size = result;
1278       if (result > 0) {
1279         result += io::CodedOutputStream::VarintSize32(result);
1280         result += io::CodedOutputStream::VarintSize32(
1281             WireFormatLite::MakeTag(number,
1282                 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1283       }
1284     } else {
1285       int tag_size = WireFormatLite::TagSize(number, real_type(type));
1286 
1287       switch (real_type(type)) {
1288 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1289         case WireFormatLite::TYPE_##UPPERCASE:                              \
1290           result += tag_size * repeated_##LOWERCASE##_value->size();        \
1291           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1292             result += WireFormatLite::CAMELCASE##Size(                      \
1293               repeated_##LOWERCASE##_value->Get(i));                        \
1294           }                                                                 \
1295           break
1296 
1297         HANDLE_TYPE(   INT32,    Int32,   int32);
1298         HANDLE_TYPE(   INT64,    Int64,   int64);
1299         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1300         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1301         HANDLE_TYPE(  SINT32,   SInt32,   int32);
1302         HANDLE_TYPE(  SINT64,   SInt64,   int64);
1303         HANDLE_TYPE(  STRING,   String,  string);
1304         HANDLE_TYPE(   BYTES,    Bytes,  string);
1305         HANDLE_TYPE(    ENUM,     Enum,    enum);
1306         HANDLE_TYPE(   GROUP,    Group, message);
1307         HANDLE_TYPE( MESSAGE,  Message, message);
1308 #undef HANDLE_TYPE
1309 
1310         // Stuff with fixed size.
1311 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1312         case WireFormatLite::TYPE_##UPPERCASE:                              \
1313           result += (tag_size + WireFormatLite::k##CAMELCASE##Size) *       \
1314                     repeated_##LOWERCASE##_value->size();                   \
1315           break
1316         HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1317         HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1318         HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1319         HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1320         HANDLE_TYPE(   FLOAT,    Float,  float);
1321         HANDLE_TYPE(  DOUBLE,   Double, double);
1322         HANDLE_TYPE(    BOOL,     Bool,   bool);
1323 #undef HANDLE_TYPE
1324       }
1325     }
1326   } else if (!is_cleared) {
1327     result += WireFormatLite::TagSize(number, real_type(type));
1328     switch (real_type(type)) {
1329 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                      \
1330       case WireFormatLite::TYPE_##UPPERCASE:                              \
1331         result += WireFormatLite::CAMELCASE##Size(LOWERCASE);             \
1332         break
1333 
1334       HANDLE_TYPE(   INT32,    Int32,    int32_value);
1335       HANDLE_TYPE(   INT64,    Int64,    int64_value);
1336       HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1337       HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1338       HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1339       HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1340       HANDLE_TYPE(  STRING,   String,  *string_value);
1341       HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1342       HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1343       HANDLE_TYPE(   GROUP,    Group, *message_value);
1344       HANDLE_TYPE( MESSAGE,  Message, *message_value);
1345 #undef HANDLE_TYPE
1346 
1347       // Stuff with fixed size.
1348 #define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
1349       case WireFormatLite::TYPE_##UPPERCASE:                              \
1350         result += WireFormatLite::k##CAMELCASE##Size;                     \
1351         break
1352       HANDLE_TYPE( FIXED32,  Fixed32);
1353       HANDLE_TYPE( FIXED64,  Fixed64);
1354       HANDLE_TYPE(SFIXED32, SFixed32);
1355       HANDLE_TYPE(SFIXED64, SFixed64);
1356       HANDLE_TYPE(   FLOAT,    Float);
1357       HANDLE_TYPE(  DOUBLE,   Double);
1358       HANDLE_TYPE(    BOOL,     Bool);
1359 #undef HANDLE_TYPE
1360     }
1361   }
1362 
1363   return result;
1364 }
1365 
MessageSetItemByteSize(int number) const1366 int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
1367   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1368     // Not a valid MessageSet extension, but compute the byte size for it the
1369     // normal way.
1370     return ByteSize(number);
1371   }
1372 
1373   if (is_cleared) return 0;
1374 
1375   int our_size = WireFormatLite::kMessageSetItemTagsSize;
1376 
1377   // type_id
1378   our_size += io::CodedOutputStream::VarintSize32(number);
1379 
1380   // message
1381   int message_size = message_value->ByteSize();
1382 
1383   our_size += io::CodedOutputStream::VarintSize32(message_size);
1384   our_size += message_size;
1385 
1386   return our_size;
1387 }
1388 
GetSize() const1389 int ExtensionSet::Extension::GetSize() const {
1390   GOOGLE_DCHECK(is_repeated);
1391   switch (cpp_type(type)) {
1392 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                        \
1393     case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1394       return repeated_##LOWERCASE##_value->size()
1395 
1396     HANDLE_TYPE(  INT32,   int32);
1397     HANDLE_TYPE(  INT64,   int64);
1398     HANDLE_TYPE( UINT32,  uint32);
1399     HANDLE_TYPE( UINT64,  uint64);
1400     HANDLE_TYPE(  FLOAT,   float);
1401     HANDLE_TYPE( DOUBLE,  double);
1402     HANDLE_TYPE(   BOOL,    bool);
1403     HANDLE_TYPE(   ENUM,    enum);
1404     HANDLE_TYPE( STRING,  string);
1405     HANDLE_TYPE(MESSAGE, message);
1406 #undef HANDLE_TYPE
1407   }
1408 
1409   GOOGLE_LOG(FATAL) << "Can't get here.";
1410   return 0;
1411 }
1412 
Free()1413 void ExtensionSet::Extension::Free() {
1414   if (is_repeated) {
1415     switch (cpp_type(type)) {
1416 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1417       case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1418         delete repeated_##LOWERCASE##_value;                       \
1419         break
1420 
1421       HANDLE_TYPE(  INT32,   int32);
1422       HANDLE_TYPE(  INT64,   int64);
1423       HANDLE_TYPE( UINT32,  uint32);
1424       HANDLE_TYPE( UINT64,  uint64);
1425       HANDLE_TYPE(  FLOAT,   float);
1426       HANDLE_TYPE( DOUBLE,  double);
1427       HANDLE_TYPE(   BOOL,    bool);
1428       HANDLE_TYPE(   ENUM,    enum);
1429       HANDLE_TYPE( STRING,  string);
1430       HANDLE_TYPE(MESSAGE, message);
1431 #undef HANDLE_TYPE
1432     }
1433   } else {
1434     switch (cpp_type(type)) {
1435       case WireFormatLite::CPPTYPE_STRING:
1436         delete string_value;
1437         break;
1438       case WireFormatLite::CPPTYPE_MESSAGE:
1439         delete message_value;
1440         break;
1441       default:
1442         break;
1443     }
1444   }
1445 }
1446 
1447 // Defined in extension_set_heavy.cc.
1448 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1449 
1450 }  // namespace internal
1451 }  // namespace protobuf
1452 }  // namespace google
1453