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 // Contains methods defined in extension_set.h which cannot be part of the
36 // lite library because they use descriptors or reflection.
37 
38 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
39 #include <google/protobuf/descriptor.h>
40 #include <google/protobuf/extension_set.h>
41 #include <google/protobuf/message.h>
42 #include <google/protobuf/repeated_field.h>
43 #include <google/protobuf/wire_format.h>
44 #include <google/protobuf/wire_format_lite_inl.h>
45 
46 namespace google {
47 
48 namespace protobuf {
49 namespace internal {
50 
51 // A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
52 class MessageSetFieldSkipper
53     : public UnknownFieldSetFieldSkipper {
54  public:
MessageSetFieldSkipper(UnknownFieldSet * unknown_fields)55   explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
56       : UnknownFieldSetFieldSkipper(unknown_fields) {}
~MessageSetFieldSkipper()57   virtual ~MessageSetFieldSkipper() {}
58 
59   virtual bool SkipMessageSetField(io::CodedInputStream* input,
60                                    int field_number);
61 };
SkipMessageSetField(io::CodedInputStream * input,int field_number)62 bool MessageSetFieldSkipper::SkipMessageSetField(
63     io::CodedInputStream* input, int field_number) {
64   uint32 length;
65   if (!input->ReadVarint32(&length)) return false;
66   if (unknown_fields_ == NULL) {
67     return input->Skip(length);
68   } else {
69     return input->ReadString(
70         unknown_fields_->AddLengthDelimited(field_number), length);
71   }
72 }
73 
74 
75 // Implementation of ExtensionFinder which finds extensions in a given
76 // DescriptorPool, using the given MessageFactory to construct sub-objects.
77 // This class is implemented in extension_set_heavy.cc.
78 class DescriptorPoolExtensionFinder : public ExtensionFinder {
79  public:
DescriptorPoolExtensionFinder(const DescriptorPool * pool,MessageFactory * factory,const Descriptor * containing_type)80   DescriptorPoolExtensionFinder(const DescriptorPool* pool,
81                                 MessageFactory* factory,
82                                 const Descriptor* containing_type)
83       : pool_(pool), factory_(factory), containing_type_(containing_type) {}
~DescriptorPoolExtensionFinder()84   virtual ~DescriptorPoolExtensionFinder() {}
85 
86   virtual bool Find(int number, ExtensionInfo* output);
87 
88  private:
89   const DescriptorPool* pool_;
90   MessageFactory* factory_;
91   const Descriptor* containing_type_;
92 };
93 
AppendToList(const Descriptor * containing_type,const DescriptorPool * pool,std::vector<const FieldDescriptor * > * output) const94 void ExtensionSet::AppendToList(
95     const Descriptor* containing_type,
96     const DescriptorPool* pool,
97     std::vector<const FieldDescriptor*>* output) const {
98   for (ExtensionMap::const_iterator iter = extensions_.begin();
99        iter != extensions_.end(); ++iter) {
100     bool has = false;
101     if (iter->second.is_repeated) {
102       has = iter->second.GetSize() > 0;
103     } else {
104       has = !iter->second.is_cleared;
105     }
106 
107     if (has) {
108       // TODO(kenton): Looking up each field by number is somewhat unfortunate.
109       //   Is there a better way?  The problem is that descriptors are lazily-
110       //   initialized, so they might not even be constructed until
111       //   AppendToList() is called.
112 
113       if (iter->second.descriptor == NULL) {
114         output->push_back(pool->FindExtensionByNumber(
115             containing_type, iter->first));
116       } else {
117         output->push_back(iter->second.descriptor);
118       }
119     }
120   }
121 }
122 
real_type(FieldType type)123 inline FieldDescriptor::Type real_type(FieldType type) {
124   GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
125   return static_cast<FieldDescriptor::Type>(type);
126 }
127 
cpp_type(FieldType type)128 inline FieldDescriptor::CppType cpp_type(FieldType type) {
129   return FieldDescriptor::TypeToCppType(
130       static_cast<FieldDescriptor::Type>(type));
131 }
132 
field_type(FieldType type)133 inline WireFormatLite::FieldType field_type(FieldType type) {
134   GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
135   return static_cast<WireFormatLite::FieldType>(type);
136 }
137 
138 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                            \
139   GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED     \
140                                   : FieldDescriptor::LABEL_OPTIONAL,      \
141             FieldDescriptor::LABEL_##LABEL);                              \
142   GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
143 
GetMessage(int number,const Descriptor * message_type,MessageFactory * factory) const144 const MessageLite& ExtensionSet::GetMessage(int number,
145                                             const Descriptor* message_type,
146                                             MessageFactory* factory) const {
147   ExtensionMap::const_iterator iter = extensions_.find(number);
148   if (iter == extensions_.end() || iter->second.is_cleared) {
149     // Not present.  Return the default value.
150     return *factory->GetPrototype(message_type);
151   } else {
152     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
153     if (iter->second.is_lazy) {
154       return iter->second.lazymessage_value->GetMessage(
155           *factory->GetPrototype(message_type));
156     } else {
157       return *iter->second.message_value;
158     }
159   }
160 }
161 
MutableMessage(const FieldDescriptor * descriptor,MessageFactory * factory)162 MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
163                                           MessageFactory* factory) {
164   Extension* extension;
165   if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
166     extension->type = descriptor->type();
167     GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
168     extension->is_repeated = false;
169     extension->is_packed = false;
170     const MessageLite* prototype =
171         factory->GetPrototype(descriptor->message_type());
172     extension->is_lazy = false;
173     extension->message_value = prototype->New(arena_);
174     extension->is_cleared = false;
175     return extension->message_value;
176   } else {
177     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
178     extension->is_cleared = false;
179     if (extension->is_lazy) {
180       return extension->lazymessage_value->MutableMessage(
181           *factory->GetPrototype(descriptor->message_type()));
182     } else {
183       return extension->message_value;
184     }
185   }
186 }
187 
ReleaseMessage(const FieldDescriptor * descriptor,MessageFactory * factory)188 MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
189                                           MessageFactory* factory) {
190   ExtensionMap::iterator iter = extensions_.find(descriptor->number());
191   if (iter == extensions_.end()) {
192     // Not present.  Return NULL.
193     return NULL;
194   } else {
195     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
196     MessageLite* ret = NULL;
197     if (iter->second.is_lazy) {
198       ret = iter->second.lazymessage_value->ReleaseMessage(
199           *factory->GetPrototype(descriptor->message_type()));
200       if (arena_ == NULL) {
201         delete iter->second.lazymessage_value;
202       }
203     } else {
204       if (arena_ != NULL) {
205         ret = (iter->second.message_value)->New();
206         ret->CheckTypeAndMergeFrom(*(iter->second.message_value));
207       } else {
208         ret = iter->second.message_value;
209       }
210     }
211     extensions_.erase(descriptor->number());
212     return ret;
213   }
214 }
215 
UnsafeArenaReleaseMessage(const FieldDescriptor * descriptor,MessageFactory * factory)216 MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
217     const FieldDescriptor* descriptor, MessageFactory* factory) {
218   ExtensionMap::iterator iter = extensions_.find(descriptor->number());
219   if (iter == extensions_.end()) {
220     // Not present.  Return NULL.
221     return NULL;
222   } else {
223     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
224     MessageLite* ret = NULL;
225     if (iter->second.is_lazy) {
226       ret = iter->second.lazymessage_value->UnsafeArenaReleaseMessage(
227           *factory->GetPrototype(descriptor->message_type()));
228       if (arena_ == NULL) {
229         delete iter->second.lazymessage_value;
230       }
231     } else {
232       ret = iter->second.message_value;
233     }
234     extensions_.erase(descriptor->number());
235     return ret;
236   }
237 }
238 
MaybeNewRepeatedExtension(const FieldDescriptor * descriptor)239 ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(const FieldDescriptor* descriptor) {
240   Extension* extension;
241   if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
242     extension->type = descriptor->type();
243     GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
244     extension->is_repeated = true;
245     extension->repeated_message_value =
246         ::google::protobuf::Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_);
247   } else {
248     GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
249   }
250   return extension;
251 }
252 
AddMessage(const FieldDescriptor * descriptor,MessageFactory * factory)253 MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
254                                       MessageFactory* factory) {
255   Extension* extension = MaybeNewRepeatedExtension(descriptor);
256 
257   // RepeatedPtrField<Message> does not know how to Add() since it cannot
258   // allocate an abstract object, so we have to be tricky.
259   MessageLite* result = extension->repeated_message_value
260       ->AddFromCleared<GenericTypeHandler<MessageLite> >();
261   if (result == NULL) {
262     const MessageLite* prototype;
263     if (extension->repeated_message_value->size() == 0) {
264       prototype = factory->GetPrototype(descriptor->message_type());
265       GOOGLE_CHECK(prototype != NULL);
266     } else {
267       prototype = &extension->repeated_message_value->Get(0);
268     }
269     result = prototype->New(arena_);
270     extension->repeated_message_value->AddAllocated(result);
271   }
272   return result;
273 }
274 
AddAllocatedMessage(const FieldDescriptor * descriptor,MessageLite * new_entry)275 void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor,
276                                        MessageLite* new_entry) {
277   Extension* extension = MaybeNewRepeatedExtension(descriptor);
278 
279   extension->repeated_message_value->AddAllocated(new_entry);
280 }
281 
ValidateEnumUsingDescriptor(const void * arg,int number)282 static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
283   return reinterpret_cast<const EnumDescriptor*>(arg)
284       ->FindValueByNumber(number) != NULL;
285 }
286 
Find(int number,ExtensionInfo * output)287 bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
288   const FieldDescriptor* extension =
289       pool_->FindExtensionByNumber(containing_type_, number);
290   if (extension == NULL) {
291     return false;
292   } else {
293     output->type = extension->type();
294     output->is_repeated = extension->is_repeated();
295     output->is_packed = extension->options().packed();
296     output->descriptor = extension;
297     if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
298       output->message_prototype =
299           factory_->GetPrototype(extension->message_type());
300       GOOGLE_CHECK(output->message_prototype != NULL)
301           << "Extension factory's GetPrototype() returned NULL for extension: "
302           << extension->full_name();
303     } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
304       output->enum_validity_check.func = ValidateEnumUsingDescriptor;
305       output->enum_validity_check.arg = extension->enum_type();
306     }
307 
308     return true;
309   }
310 }
311 
ParseField(uint32 tag,io::CodedInputStream * input,const Message * containing_type,UnknownFieldSet * unknown_fields)312 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
313                               const Message* containing_type,
314                               UnknownFieldSet* unknown_fields) {
315   UnknownFieldSetFieldSkipper skipper(unknown_fields);
316   if (input->GetExtensionPool() == NULL) {
317     GeneratedExtensionFinder finder(containing_type);
318     return ParseField(tag, input, &finder, &skipper);
319   } else {
320     DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
321                                          input->GetExtensionFactory(),
322                                          containing_type->GetDescriptor());
323     return ParseField(tag, input, &finder, &skipper);
324   }
325 }
326 
ParseMessageSet(io::CodedInputStream * input,const Message * containing_type,UnknownFieldSet * unknown_fields)327 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
328                                    const Message* containing_type,
329                                    UnknownFieldSet* unknown_fields) {
330   MessageSetFieldSkipper skipper(unknown_fields);
331   if (input->GetExtensionPool() == NULL) {
332     GeneratedExtensionFinder finder(containing_type);
333     return ParseMessageSet(input, &finder, &skipper);
334   } else {
335     DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
336                                          input->GetExtensionFactory(),
337                                          containing_type->GetDescriptor());
338     return ParseMessageSet(input, &finder, &skipper);
339   }
340 }
341 
SpaceUsedExcludingSelf() const342 int ExtensionSet::SpaceUsedExcludingSelf() const {
343   int total_size =
344       extensions_.size() * sizeof(ExtensionMap::value_type);
345   for (ExtensionMap::const_iterator iter = extensions_.begin(),
346        end = extensions_.end();
347        iter != end;
348        ++iter) {
349     total_size += iter->second.SpaceUsedExcludingSelf();
350   }
351   return total_size;
352 }
353 
RepeatedMessage_SpaceUsedExcludingSelf(RepeatedPtrFieldBase * field)354 inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
355     RepeatedPtrFieldBase* field) {
356   return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
357 }
358 
SpaceUsedExcludingSelf() const359 int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
360   int total_size = 0;
361   if (is_repeated) {
362     switch (cpp_type(type)) {
363 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
364       case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
365         total_size += sizeof(*repeated_##LOWERCASE##_value) +      \
366             repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
367         break
368 
369       HANDLE_TYPE(  INT32,   int32);
370       HANDLE_TYPE(  INT64,   int64);
371       HANDLE_TYPE( UINT32,  uint32);
372       HANDLE_TYPE( UINT64,  uint64);
373       HANDLE_TYPE(  FLOAT,   float);
374       HANDLE_TYPE( DOUBLE,  double);
375       HANDLE_TYPE(   BOOL,    bool);
376       HANDLE_TYPE(   ENUM,    enum);
377       HANDLE_TYPE( STRING,  string);
378 #undef HANDLE_TYPE
379 
380       case FieldDescriptor::CPPTYPE_MESSAGE:
381         // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
382         // but MessageLite has no SpaceUsed(), so we must directly call
383         // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
384         // handler.
385         total_size += sizeof(*repeated_message_value) +
386             RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
387         break;
388     }
389   } else {
390     switch (cpp_type(type)) {
391       case FieldDescriptor::CPPTYPE_STRING:
392         total_size += sizeof(*string_value) +
393                       StringSpaceUsedExcludingSelf(*string_value);
394         break;
395       case FieldDescriptor::CPPTYPE_MESSAGE:
396         if (is_lazy) {
397           total_size += lazymessage_value->SpaceUsed();
398         } else {
399           total_size += down_cast<Message*>(message_value)->SpaceUsed();
400         }
401         break;
402       default:
403         // No extra storage costs for primitive types.
404         break;
405     }
406   }
407   return total_size;
408 }
409 
410 // The Serialize*ToArray methods are only needed in the heavy library, as
411 // the lite library only generates SerializeWithCachedSizes.
SerializeWithCachedSizesToArray(int start_field_number,int end_field_number,uint8 * target) const412 uint8* ExtensionSet::SerializeWithCachedSizesToArray(int start_field_number,
413                                                      int end_field_number,
414                                                      uint8* target) const {
415   return InternalSerializeWithCachedSizesToArray(
416       start_field_number, end_field_number, false, target);
417 }
418 
SerializeMessageSetWithCachedSizesToArray(uint8 * target) const419 uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
420     uint8* target) const {
421   return InternalSerializeMessageSetWithCachedSizesToArray(false, target);
422 }
423 
InternalSerializeWithCachedSizesToArray(int start_field_number,int end_field_number,bool deterministic,uint8 * target) const424 uint8* ExtensionSet::InternalSerializeWithCachedSizesToArray(
425     int start_field_number, int end_field_number,
426     bool deterministic, uint8* target) const {
427   ExtensionMap::const_iterator iter;
428   for (iter = extensions_.lower_bound(start_field_number);
429        iter != extensions_.end() && iter->first < end_field_number;
430        ++iter) {
431     target = iter->second.InternalSerializeFieldWithCachedSizesToArray(
432         iter->first, deterministic, target);
433   }
434   return target;
435 }
436 
InternalSerializeMessageSetWithCachedSizesToArray(bool deterministic,uint8 * target) const437 uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
438     bool deterministic, uint8* target) const {
439   ExtensionMap::const_iterator iter;
440   for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
441     target = iter->second.InternalSerializeMessageSetItemWithCachedSizesToArray(
442         iter->first, deterministic, target);
443   }
444   return target;
445 }
446 
InternalSerializeFieldWithCachedSizesToArray(int number,bool deterministic,uint8 * target) const447 uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
448     int number, bool deterministic, uint8* target) const {
449   if (is_repeated) {
450     if (is_packed) {
451       if (cached_size == 0) return target;
452 
453       target = WireFormatLite::WriteTagToArray(number,
454           WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
455       target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
456 
457       switch (real_type(type)) {
458 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
459         case FieldDescriptor::TYPE_##UPPERCASE:                             \
460           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
461             target = WireFormatLite::Write##CAMELCASE##NoTagToArray(        \
462               repeated_##LOWERCASE##_value->Get(i), target);                \
463           }                                                                 \
464           break
465 
466         HANDLE_TYPE(   INT32,    Int32,   int32);
467         HANDLE_TYPE(   INT64,    Int64,   int64);
468         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
469         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
470         HANDLE_TYPE(  SINT32,   SInt32,   int32);
471         HANDLE_TYPE(  SINT64,   SInt64,   int64);
472         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
473         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
474         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
475         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
476         HANDLE_TYPE(   FLOAT,    Float,   float);
477         HANDLE_TYPE(  DOUBLE,   Double,  double);
478         HANDLE_TYPE(    BOOL,     Bool,    bool);
479         HANDLE_TYPE(    ENUM,     Enum,    enum);
480 #undef HANDLE_TYPE
481 
482         case WireFormatLite::TYPE_STRING:
483         case WireFormatLite::TYPE_BYTES:
484         case WireFormatLite::TYPE_GROUP:
485         case WireFormatLite::TYPE_MESSAGE:
486           GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
487           break;
488       }
489     } else {
490       switch (real_type(type)) {
491 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
492         case FieldDescriptor::TYPE_##UPPERCASE:                             \
493           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
494             target = WireFormatLite::Write##CAMELCASE##ToArray(number,      \
495               repeated_##LOWERCASE##_value->Get(i), target);                \
496           }                                                                 \
497           break
498 
499         HANDLE_TYPE(   INT32,    Int32,   int32);
500         HANDLE_TYPE(   INT64,    Int64,   int64);
501         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
502         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
503         HANDLE_TYPE(  SINT32,   SInt32,   int32);
504         HANDLE_TYPE(  SINT64,   SInt64,   int64);
505         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
506         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
507         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
508         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
509         HANDLE_TYPE(   FLOAT,    Float,   float);
510         HANDLE_TYPE(  DOUBLE,   Double,  double);
511         HANDLE_TYPE(    BOOL,     Bool,    bool);
512         HANDLE_TYPE(  STRING,   String,  string);
513         HANDLE_TYPE(   BYTES,    Bytes,  string);
514         HANDLE_TYPE(    ENUM,     Enum,    enum);
515 #undef HANDLE_TYPE
516 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
517         case FieldDescriptor::TYPE_##UPPERCASE:                             \
518           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
519             target = WireFormatLite::InternalWrite##CAMELCASE##ToArray(     \
520                       number, repeated_##LOWERCASE##_value->Get(i),         \
521                       deterministic, target);                               \
522           }                                                                 \
523           break
524 
525         HANDLE_TYPE(   GROUP,    Group, message);
526         HANDLE_TYPE( MESSAGE,  Message, message);
527 #undef HANDLE_TYPE
528       }
529     }
530   } else if (!is_cleared) {
531     switch (real_type(type)) {
532 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
533       case FieldDescriptor::TYPE_##UPPERCASE:                    \
534         target = WireFormatLite::Write##CAMELCASE##ToArray(      \
535             number, VALUE, target); \
536         break
537 
538       HANDLE_TYPE(   INT32,    Int32,    int32_value);
539       HANDLE_TYPE(   INT64,    Int64,    int64_value);
540       HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
541       HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
542       HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
543       HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
544       HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
545       HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
546       HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
547       HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
548       HANDLE_TYPE(   FLOAT,    Float,    float_value);
549       HANDLE_TYPE(  DOUBLE,   Double,   double_value);
550       HANDLE_TYPE(    BOOL,     Bool,     bool_value);
551       HANDLE_TYPE(  STRING,   String,  *string_value);
552       HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
553       HANDLE_TYPE(    ENUM,     Enum,     enum_value);
554       HANDLE_TYPE(   GROUP,    Group, *message_value);
555 #undef HANDLE_TYPE
556       case FieldDescriptor::TYPE_MESSAGE:
557         if (is_lazy) {
558           target = lazymessage_value->InternalWriteMessageToArray(
559               number, deterministic, target);
560         } else {
561           target = WireFormatLite::InternalWriteMessageToArray(
562               number, *message_value, deterministic, target);
563         }
564         break;
565     }
566   }
567   return target;
568 }
569 
570 uint8*
InternalSerializeMessageSetItemWithCachedSizesToArray(int number,bool deterministic,uint8 * target) const571 ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
572     int number, bool deterministic, uint8* target) const {
573   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
574     // Not a valid MessageSet extension, but serialize it the normal way.
575     GOOGLE_LOG(WARNING) << "Invalid message set extension.";
576     return InternalSerializeFieldWithCachedSizesToArray(number, deterministic,
577                                                         target);
578   }
579 
580   if (is_cleared) return target;
581 
582   // Start group.
583   target = io::CodedOutputStream::WriteTagToArray(
584       WireFormatLite::kMessageSetItemStartTag, target);
585   // Write type ID.
586   target = WireFormatLite::WriteUInt32ToArray(
587       WireFormatLite::kMessageSetTypeIdNumber, number, target);
588   // Write message.
589   if (is_lazy) {
590     target = lazymessage_value->WriteMessageToArray(
591         WireFormatLite::kMessageSetMessageNumber, target);
592   } else {
593     target = WireFormatLite::WriteMessageToArray(
594         WireFormatLite::kMessageSetMessageNumber, *message_value, target);
595   }
596   // End group.
597   target = io::CodedOutputStream::WriteTagToArray(
598       WireFormatLite::kMessageSetItemEndTag, target);
599   return target;
600 }
601 
602 
ParseFieldMaybeLazily(int wire_type,int field_number,io::CodedInputStream * input,ExtensionFinder * extension_finder,MessageSetFieldSkipper * field_skipper)603 bool ExtensionSet::ParseFieldMaybeLazily(
604     int wire_type, int field_number, io::CodedInputStream* input,
605     ExtensionFinder* extension_finder,
606     MessageSetFieldSkipper* field_skipper) {
607   return ParseField(WireFormatLite::MakeTag(
608       field_number, static_cast<WireFormatLite::WireType>(wire_type)),
609                     input, extension_finder, field_skipper);
610 }
611 
ParseMessageSet(io::CodedInputStream * input,ExtensionFinder * extension_finder,MessageSetFieldSkipper * field_skipper)612 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
613                                    ExtensionFinder* extension_finder,
614                                    MessageSetFieldSkipper* field_skipper) {
615   while (true) {
616     const uint32 tag = input->ReadTag();
617     switch (tag) {
618       case 0:
619         return true;
620       case WireFormatLite::kMessageSetItemStartTag:
621         if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
622           return false;
623         }
624         break;
625       default:
626         if (!ParseField(tag, input, extension_finder, field_skipper)) {
627           return false;
628         }
629         break;
630     }
631   }
632 }
633 
ParseMessageSet(io::CodedInputStream * input,const MessageLite * containing_type)634 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
635                                    const MessageLite* containing_type) {
636   MessageSetFieldSkipper skipper(NULL);
637   GeneratedExtensionFinder finder(containing_type);
638   return ParseMessageSet(input, &finder, &skipper);
639 }
640 
ParseMessageSetItem(io::CodedInputStream * input,ExtensionFinder * extension_finder,MessageSetFieldSkipper * field_skipper)641 bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
642                                        ExtensionFinder* extension_finder,
643                                        MessageSetFieldSkipper* field_skipper) {
644   // TODO(kenton):  It would be nice to share code between this and
645   // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
646   // differences would be hard to factor out.
647 
648   // This method parses a group which should contain two fields:
649   //   required int32 type_id = 2;
650   //   required data message = 3;
651 
652   uint32 last_type_id = 0;
653 
654   // If we see message data before the type_id, we'll append it to this so
655   // we can parse it later.
656   string message_data;
657 
658   while (true) {
659     const uint32 tag = input->ReadTag();
660     if (tag == 0) return false;
661 
662     switch (tag) {
663       case WireFormatLite::kMessageSetTypeIdTag: {
664         uint32 type_id;
665         if (!input->ReadVarint32(&type_id)) return false;
666         last_type_id = type_id;
667 
668         if (!message_data.empty()) {
669           // We saw some message data before the type_id.  Have to parse it
670           // now.
671           io::CodedInputStream sub_input(
672               reinterpret_cast<const uint8*>(message_data.data()),
673               message_data.size());
674           if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
675                                      last_type_id, &sub_input,
676                                      extension_finder, field_skipper)) {
677             return false;
678           }
679           message_data.clear();
680         }
681 
682         break;
683       }
684 
685       case WireFormatLite::kMessageSetMessageTag: {
686         if (last_type_id == 0) {
687           // We haven't seen a type_id yet.  Append this data to message_data.
688           string temp;
689           uint32 length;
690           if (!input->ReadVarint32(&length)) return false;
691           if (!input->ReadString(&temp, length)) return false;
692           io::StringOutputStream output_stream(&message_data);
693           io::CodedOutputStream coded_output(&output_stream);
694           coded_output.WriteVarint32(length);
695           coded_output.WriteString(temp);
696         } else {
697           // Already saw type_id, so we can parse this directly.
698           if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
699                                      last_type_id, input,
700                                      extension_finder, field_skipper)) {
701             return false;
702           }
703         }
704 
705         break;
706       }
707 
708       case WireFormatLite::kMessageSetItemEndTag: {
709         return true;
710       }
711 
712       default: {
713         if (!field_skipper->SkipField(input, tag)) return false;
714       }
715     }
716   }
717 }
718 
SerializeMessageSetItemWithCachedSizes(int number,io::CodedOutputStream * output) const719 void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
720     int number,
721     io::CodedOutputStream* output) const {
722   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
723     // Not a valid MessageSet extension, but serialize it the normal way.
724     SerializeFieldWithCachedSizes(number, output);
725     return;
726   }
727 
728   if (is_cleared) return;
729 
730   // Start group.
731   output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
732 
733   // Write type ID.
734   WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
735                               number,
736                               output);
737   // Write message.
738   if (is_lazy) {
739     lazymessage_value->WriteMessage(
740         WireFormatLite::kMessageSetMessageNumber, output);
741   } else {
742     WireFormatLite::WriteMessageMaybeToArray(
743         WireFormatLite::kMessageSetMessageNumber,
744         *message_value,
745         output);
746   }
747 
748   // End group.
749   output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
750 }
751 
MessageSetItemByteSize(int number) const752 int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
753   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
754     // Not a valid MessageSet extension, but compute the byte size for it the
755     // normal way.
756     return ByteSize(number);
757   }
758 
759   if (is_cleared) return 0;
760 
761   int our_size = WireFormatLite::kMessageSetItemTagsSize;
762 
763   // type_id
764   our_size += io::CodedOutputStream::VarintSize32(number);
765 
766   // message
767   int message_size = 0;
768   if (is_lazy) {
769     message_size = lazymessage_value->ByteSize();
770   } else {
771     message_size = message_value->ByteSize();
772   }
773 
774   our_size += io::CodedOutputStream::VarintSize32(message_size);
775   our_size += message_size;
776 
777   return our_size;
778 }
779 
SerializeMessageSetWithCachedSizes(io::CodedOutputStream * output) const780 void ExtensionSet::SerializeMessageSetWithCachedSizes(
781     io::CodedOutputStream* output) const {
782   for (ExtensionMap::const_iterator iter = extensions_.begin();
783        iter != extensions_.end(); ++iter) {
784     iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
785   }
786 }
787 
MessageSetByteSize() const788 int ExtensionSet::MessageSetByteSize() const {
789   int total_size = 0;
790 
791   for (ExtensionMap::const_iterator iter = extensions_.begin();
792        iter != extensions_.end(); ++iter) {
793     total_size += iter->second.MessageSetItemByteSize(iter->first);
794   }
795 
796   return total_size;
797 }
798 
799 }  // namespace internal
800 }  // namespace protobuf
801 }  // namespace google
802