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