1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format
2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc.  All rights reserved.
3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/
4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without
6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are
7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met:
8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions of source code must retain the above copyright
10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer.
11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Redistributions in binary form must reproduce the above
12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer
13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the
14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution.
15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//     * Neither the name of Google Inc. nor the names of its
16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from
17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission.
18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda)
32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Based on original Protocol Buffers design by
33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//  Sanjay Ghemawat, Jeff Dean, and others.
34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville//
35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Contains methods defined in extension_set.h which cannot be part of the
36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// lite library because they use descriptors or reflection.
37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/extension_set.h>
39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h>
40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/message.h>
41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/repeated_field.h>
42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/wire_format.h>
43d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/wire_format_lite_inl.h>
44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google {
46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf {
47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace internal {
48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
49d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Implementation of ExtensionFinder which finds extensions in a given
50d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// DescriptorPool, using the given MessageFactory to construct sub-objects.
51d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// This class is implemented in extension_set_heavy.cc.
52d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleclass DescriptorPoolExtensionFinder : public ExtensionFinder {
53d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville public:
54d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  DescriptorPoolExtensionFinder(const DescriptorPool* pool,
55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                MessageFactory* factory,
56d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                const Descriptor* containing_type)
57d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      : pool_(pool), factory_(factory), containing_type_(containing_type) {}
58d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  virtual ~DescriptorPoolExtensionFinder() {}
59d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
60d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  virtual bool Find(int number, ExtensionInfo* output);
61d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
62d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville private:
63d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  const DescriptorPool* pool_;
64d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  MessageFactory* factory_;
65d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  const Descriptor* containing_type_;
66d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville};
67d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ExtensionSet::AppendToList(const Descriptor* containing_type,
69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                const DescriptorPool* pool,
70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                vector<const FieldDescriptor*>* output) const {
71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (map<int, Extension>::const_iterator iter = extensions_.begin();
72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       iter != extensions_.end(); ++iter) {
73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    bool has = false;
74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (iter->second.is_repeated) {
75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      has = iter->second.GetSize() > 0;
76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      has = !iter->second.is_cleared;
78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (has) {
81d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      // TODO(kenton): Looking up each field by number is somewhat unfortunate.
82d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      //   Is there a better way?  The problem is that descriptors are lazily-
83d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      //   initialized, so they might not even be constructed until
84d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      //   AppendToList() is called.
85d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
86d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (iter->second.descriptor == NULL) {
87d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        output->push_back(pool->FindExtensionByNumber(
88d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville            containing_type, iter->first));
89d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      } else {
90d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        output->push_back(iter->second.descriptor);
91d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
96d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleinline FieldDescriptor::Type real_type(FieldType type) {
97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
98d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return static_cast<FieldDescriptor::Type>(type);
99d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline FieldDescriptor::CppType cpp_type(FieldType type) {
102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return FieldDescriptor::TypeToCppType(
103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      static_cast<FieldDescriptor::Type>(type));
104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                            \
107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED     \
108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                  : FieldDescriptor::LABEL_OPTIONAL,      \
109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            FieldDescriptor::LABEL_##LABEL);                              \
110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst MessageLite& ExtensionSet::GetMessage(int number,
113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                            const Descriptor* message_type,
114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                            MessageFactory* factory) const {
115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  map<int, Extension>::const_iterator iter = extensions_.find(number);
116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (iter == extensions_.end() || iter->second.is_cleared) {
117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    // Not present.  Return the default value.
118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return *factory->GetPrototype(message_type);
119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    return *iter->second.message_value;
122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
125d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleMessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                          MessageFactory* factory) {
127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Extension* extension;
128d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
129d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    extension->type = descriptor->type();
130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension->is_repeated = false;
132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension->is_packed = false;
133d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    const MessageLite* prototype =
134d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        factory->GetPrototype(descriptor->message_type());
135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GOOGLE_CHECK(prototype != NULL);
136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension->message_value = prototype->New();
137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  extension->is_cleared = false;
141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return extension->message_value;
142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
144d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleMessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                      MessageFactory* factory) {
146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  Extension* extension;
147d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
148d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    extension->type = descriptor->type();
149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension->is_repeated = true;
151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension->repeated_message_value =
152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      new RepeatedPtrField<MessageLite>();
153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // RepeatedPtrField<Message> does not know how to Add() since it cannot
158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  // allocate an abstract object, so we have to be tricky.
159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  MessageLite* result = extension->repeated_message_value
160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (result == NULL) {
162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    const MessageLite* prototype;
163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    if (extension->repeated_message_value->size() == 0) {
164d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      prototype = factory->GetPrototype(descriptor->message_type());
165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      GOOGLE_CHECK(prototype != NULL);
166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    } else {
167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      prototype = &extension->repeated_message_value->Get(0);
168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    result = prototype->New();
170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    extension->repeated_message_value->AddAllocated(result);
171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return result;
173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
175d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestatic bool ValidateEnumUsingDescriptor(const void* arg, int number) {
176d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return reinterpret_cast<const EnumDescriptor*>(arg)
177d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      ->FindValueByNumber(number) != NULL;
178d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
179d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
180d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillebool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
181d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  const FieldDescriptor* extension =
182d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      pool_->FindExtensionByNumber(containing_type_, number);
183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (extension == NULL) {
184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return false;
185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  } else {
186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    output->type = extension->type();
187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    output->is_repeated = extension->is_repeated();
188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    output->is_packed = extension->options().packed();
189d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    output->descriptor = extension;
190d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
191d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      output->message_prototype =
192d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          factory_->GetPrototype(extension->message_type());
193d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      GOOGLE_CHECK(output->message_prototype != NULL)
194d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          << "Extension factory's GetPrototype() returned NULL for extension: "
195d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          << extension->full_name();
196d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
197d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      output->enum_validity_check.func = ValidateEnumUsingDescriptor;
198d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      output->enum_validity_check.arg = extension->enum_type();
199d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
200d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
201d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return true;
202d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
203d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
204d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
206d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                              const Message* containing_type,
207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                              UnknownFieldSet* unknown_fields) {
208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownFieldSetFieldSkipper skipper(unknown_fields);
209d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (input->GetExtensionPool() == NULL) {
210d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    GeneratedExtensionFinder finder(containing_type);
211d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return ParseField(tag, input, &finder, &skipper);
212d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  } else {
213d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
214d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                         input->GetExtensionFactory(),
215d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                         containing_type->GetDescriptor());
216d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return ParseField(tag, input, &finder, &skipper);
217d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
221d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                   const Message* containing_type,
222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                                   UnknownFieldSet* unknown_fields) {
223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  UnknownFieldSetFieldSkipper skipper(unknown_fields);
224d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (input->GetExtensionPool() == NULL) {
225d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    GeneratedExtensionFinder finder(containing_type);
226d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return ParseMessageSet(input, &finder, &skipper);
227d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  } else {
228d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
229d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                         input->GetExtensionFactory(),
230d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                         containing_type->GetDescriptor());
231d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return ParseMessageSet(input, &finder, &skipper);
232d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint ExtensionSet::SpaceUsedExcludingSelf() const {
236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int total_size =
237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      extensions_.size() * sizeof(map<int, Extension>::value_type);
238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  for (map<int, Extension>::const_iterator iter = extensions_.begin(),
239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       end = extensions_.end();
240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       iter != end;
241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville       ++iter) {
242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    total_size += iter->second.SpaceUsedExcludingSelf();
243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return total_size;
245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    RepeatedPtrFieldBase* field) {
249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  int total_size = 0;
254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  if (is_repeated) {
255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    switch (cpp_type(type)) {
256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
257d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        total_size += sizeof(*repeated_##LOWERCASE##_value) +      \
259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break
261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE(  INT32,   int32);
263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE(  INT64,   int64);
264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE( UINT32,  uint32);
265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE( UINT64,  uint64);
266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE(  FLOAT,   float);
267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE( DOUBLE,  double);
268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE(   BOOL,    bool);
269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE(   ENUM,    enum);
270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      HANDLE_TYPE( STRING,  string);
271d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#undef HANDLE_TYPE
272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
273d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      case FieldDescriptor::CPPTYPE_MESSAGE:
274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // but MessageLite has no SpaceUsed(), so we must directly call
276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // handler.
278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        total_size += sizeof(*repeated_message_value) +
279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville            RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break;
281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  } else {
283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    switch (cpp_type(type)) {
284d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      case FieldDescriptor::CPPTYPE_STRING:
285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        total_size += sizeof(*string_value) +
286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville                      StringSpaceUsedExcludingSelf(*string_value);
287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break;
288d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      case FieldDescriptor::CPPTYPE_MESSAGE:
289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        total_size += down_cast<Message*>(message_value)->SpaceUsed();
290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break;
291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville      default:
292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        // No extra storage costs for primitive types.
293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville        break;
294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville    }
295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  }
296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville  return total_size;
297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}
298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville
299d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// The Serialize*ToArray methods are only needed in the heavy library, as
300d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// the lite library only generates SerializeWithCachedSizes.
301d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleuint8* ExtensionSet::SerializeWithCachedSizesToArray(
302d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    int start_field_number, int end_field_number,
303d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    uint8* target) const {
304d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  map<int, Extension>::const_iterator iter;
305d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (iter = extensions_.lower_bound(start_field_number);
306d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville       iter != extensions_.end() && iter->first < end_field_number;
307d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville       ++iter) {
308d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
309d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                                                               target);
310d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
311d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return target;
312d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
313d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
314d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleuint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
315d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    uint8* target) const {
316d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  map<int, Extension>::const_iterator iter;
317d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
318d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
319d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        iter->first, target);
320d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
321d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return target;
322d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
323d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
324d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleuint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
325d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    int number, uint8* target) const {
326d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (is_repeated) {
327d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    if (is_packed) {
328d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      if (cached_size == 0) return target;
329d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
330d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      target = WireFormatLite::WriteTagToArray(number,
331d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
332d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
333d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
334d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      switch (real_type(type)) {
335d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
336d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        case FieldDescriptor::TYPE_##UPPERCASE:                             \
337d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
338d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville            target = WireFormatLite::Write##CAMELCASE##NoTagToArray(        \
339d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville              repeated_##LOWERCASE##_value->Get(i), target);                \
340d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          }                                                                 \
341d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          break
342d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
343d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   INT32,    Int32,   int32);
344d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   INT64,    Int64,   int64);
345d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
346d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
347d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  SINT32,   SInt32,   int32);
348d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  SINT64,   SInt64,   int64);
349d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
350d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
351d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
352d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
353d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   FLOAT,    Float,   float);
354d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  DOUBLE,   Double,  double);
355d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(    BOOL,     Bool,    bool);
356d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(    ENUM,     Enum,    enum);
357d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#undef HANDLE_TYPE
358d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
359d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        case WireFormatLite::TYPE_STRING:
360d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        case WireFormatLite::TYPE_BYTES:
361d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        case WireFormatLite::TYPE_GROUP:
362d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        case WireFormatLite::TYPE_MESSAGE:
363d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
364d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          break;
365d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
366d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    } else {
367d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      switch (real_type(type)) {
368d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
369d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        case FieldDescriptor::TYPE_##UPPERCASE:                             \
370d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
371d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville            target = WireFormatLite::Write##CAMELCASE##ToArray(number,      \
372d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville              repeated_##LOWERCASE##_value->Get(i), target);                \
373d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          }                                                                 \
374d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville          break
375d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
376d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   INT32,    Int32,   int32);
377d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   INT64,    Int64,   int64);
378d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
379d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
380d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  SINT32,   SInt32,   int32);
381d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  SINT64,   SInt64,   int64);
382d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
383d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
384d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
385d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
386d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   FLOAT,    Float,   float);
387d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  DOUBLE,   Double,  double);
388d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(    BOOL,     Bool,    bool);
389d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(  STRING,   String,  string);
390d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   BYTES,    Bytes,  string);
391d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(    ENUM,     Enum,    enum);
392d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE(   GROUP,    Group, message);
393d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        HANDLE_TYPE( MESSAGE,  Message, message);
394d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#undef HANDLE_TYPE
395d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      }
396d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
397d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  } else if (!is_cleared) {
398d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    switch (real_type(type)) {
399d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
400d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      case FieldDescriptor::TYPE_##UPPERCASE:                    \
401d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        target = WireFormatLite::Write##CAMELCASE##ToArray(      \
402d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville            number, VALUE, target); \
403d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville        break
404d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
405d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(   INT32,    Int32,    int32_value);
406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(   INT64,    Int64,    int64_value);
407d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
408d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
409d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
410d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
411d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
412d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
413d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
414d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
415d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(   FLOAT,    Float,    float_value);
416d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
417d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
418d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(  STRING,   String,  *string_value);
419d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
420d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
421d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE(   GROUP,    Group, *message_value);
422d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      HANDLE_TYPE( MESSAGE,  Message, *message_value);
423d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#undef HANDLE_TYPE
424d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    }
425d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
426d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return target;
427d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
428d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
429d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleuint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
430d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    int number,
431d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    uint8* target) const {
432d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
433d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    // Not a valid MessageSet extension, but serialize it the normal way.
434d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    GOOGLE_LOG(WARNING) << "Invalid message set extension.";
435d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return SerializeFieldWithCachedSizesToArray(number, target);
436d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
437d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
438d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  if (is_cleared) return target;
439d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
440d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Start group.
441d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  target = io::CodedOutputStream::WriteTagToArray(
442d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      WireFormatLite::kMessageSetItemStartTag, target);
443d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Write type ID.
444d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  target = WireFormatLite::WriteUInt32ToArray(
445d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      WireFormatLite::kMessageSetTypeIdNumber, number, target);
446d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // Write message.
447d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  target = WireFormatLite::WriteMessageToArray(
448d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      WireFormatLite::kMessageSetMessageNumber, *message_value, target);
449d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  // End group.
450d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  target = io::CodedOutputStream::WriteTagToArray(
451d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      WireFormatLite::kMessageSetItemEndTag, target);
452d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  return target;
453d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
454d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace internal
456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace protobuf
457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}  // namespace google
458