15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/hash.h>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/once.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/extension_set.h>
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/message_lite.h>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/coded_stream.h>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/wire_format_lite_inl.h>
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/repeated_field.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/map-util.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline WireFormatLite::FieldType real_type(FieldType type) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<WireFormatLite::FieldType>(type);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline WireFormatLite::CppType cpp_type(FieldType type) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return WireFormatLite::FieldTypeToCppType(real_type(type));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Registry stuff.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef hash_map<pair<const MessageLite*, int>,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ExtensionInfo> ExtensionRegistry;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionRegistry* registry_ = NULL;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteRegistry() {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete registry_;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registry_ = NULL;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitRegistry() {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registry_ = new ExtensionRegistry;
74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  OnShutdown(&DeleteRegistry);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This function is only called at startup, so there is no need for thread-
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// safety.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Register(const MessageLite* containing_type,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int number, ExtensionInfo info) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          info)) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << containing_type->GetTypeName()
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "\", field number " << number << ".";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ExtensionInfo* FindRegisteredExtension(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MessageLite* containing_type, int number) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (registry_ == NULL) ? NULL :
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         FindOrNull(*registry_, make_pair(containing_type, number));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionFinder::~ExtensionFinder() {}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ExtensionInfo* extension =
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FindRegisteredExtension(containing_type_, number);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension == NULL) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *output = *extension;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int number, FieldType type,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     bool is_repeated, bool is_packed) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionInfo info(type, is_repeated, is_packed);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Register(containing_type, number, info);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool CallNoArgValidityFunc(const void* arg, int number) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note:  Must use C-style cast here rather than reinterpret_cast because
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   the C++ standard at one point did not allow casts between function and
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   data pointers and some compilers enforce this for C++-style casts.  No
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   compiler enforces it for C-style casts since lots of C-style code has
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   relied on these kinds of casts for a long time, despite being
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   technically undefined.  See:
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Also note:  Some compilers do not allow function pointers to be "const".
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   Which makes sense, I suppose, because it's meaningless.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ((EnumValidityFunc*)arg)(number);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int number, FieldType type,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         bool is_repeated, bool is_packed,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         EnumValidityFunc* is_valid) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionInfo info(type, is_repeated, is_packed);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.enum_validity_check.func = CallNoArgValidityFunc;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.enum_validity_check.arg = (void*)is_valid;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Register(containing_type, number, info);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int number, FieldType type,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            bool is_repeated, bool is_packed,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const MessageLite* prototype) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        type == WireFormatLite::TYPE_GROUP);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionInfo info(type, is_repeated, is_packed);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.message_prototype = prototype;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Register(containing_type, number, info);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructors and basic methods.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::ExtensionSet() {}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionSet::~ExtensionSet() {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (map<int, Extension>::iterator iter = extensions_.begin();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second.Free();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void ExtensionSet::AppendToList(const Descriptor* containing_type,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                 const DescriptorPool* pool,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                 vector<const FieldDescriptor*>* output) const
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::Has(int number) const {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end()) return false;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK(!iter->second.is_repeated);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !iter->second.is_cleared;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
183ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochint ExtensionSet::NumExtensions() const {
184ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  int result = 0;
185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (map<int, Extension>::const_iterator iter = extensions_.begin();
186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       iter != extensions_.end(); ++iter) {
187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (!iter->second.is_cleared) {
188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ++result;
189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return result;
192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionSet::ExtensionSize(int number) const {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end()) return false;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.GetSize();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FieldType ExtensionSet::ExtensionType(int number) const {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end()) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter->second.is_cleared) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.type;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::ClearExtension(int number) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::iterator iter = extensions_.find(number);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end()) return;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter->second.Clear();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Field accessors
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum Cardinality {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  REPEATED,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OPTIONAL
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                             \
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL);         \
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Primitives
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                               \
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LOWERCASE ExtensionSet::Get##CAMELCASE(int number,                             \
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       LOWERCASE default_value) const {        \
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end() || iter->second.is_cleared) {                  \
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return default_value;                                                      \
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {                                                                     \
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE);                            \
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return iter->second.LOWERCASE##_value;                                     \
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }                                                                            \
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}                                                                              \
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                               \
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Set##CAMELCASE(int number, FieldType type,                  \
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  LOWERCASE value,                             \
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const FieldDescriptor* descriptor) {         \
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;                                                        \
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;                                                    \
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = false;                                            \
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {                                                                     \
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE);                              \
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }                                                                            \
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->is_cleared = false;                                               \
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->LOWERCASE##_value = value;                                        \
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}                                                                              \
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                               \
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const {  \
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.repeated_##LOWERCASE##_value->Get(index);                \
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}                                                                              \
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                               \
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::SetRepeated##CAMELCASE(                                     \
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int number, int index, LOWERCASE value) {                                  \
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::iterator iter = extensions_.find(number);               \
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter->second.repeated_##LOWERCASE##_value->Set(index, value);                \
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}                                                                              \
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                               \
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Add##CAMELCASE(int number, FieldType type,                  \
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  bool packed, LOWERCASE value,                \
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const FieldDescriptor* descriptor) {         \
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;                                                        \
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;                                                    \
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = true;                                             \
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_packed = packed;                                             \
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>();  \
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {                                                                     \
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE);                              \
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                   \
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }                                                                            \
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->repeated_##LOWERCASE##_value->Add(value);                         \
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIMITIVE_ACCESSORS( INT32,  int32,  Int32)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIMITIVE_ACCESSORS( INT64,  int64,  Int64)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIMITIVE_ACCESSORS( FLOAT,  float,  Float)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRIMITIVE_ACCESSORS(  BOOL,   bool,   Bool)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef PRIMITIVE_ACCESSORS
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
307ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid* ExtensionSet::MutableRawRepeatedField(int number) {
308ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // We assume that all the RepeatedField<>* pointers have the same
309ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // size and alignment within the anonymous union in Extension.
310ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  map<int, Extension>::const_iterator iter = extensions_.find(number);
311ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_CHECK(iter != extensions_.end()) << "no extension numbered " << number;
312ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return iter->second.repeated_int32_value;
313ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
314ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enums
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionSet::GetEnum(int number, int default_value) const {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end() || iter->second.is_cleared) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not present.  Return the default value.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return default_value;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return iter->second.enum_value;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::SetEnum(int number, FieldType type, int value,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* descriptor) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = false;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->is_cleared = false;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->enum_value = value;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionSet::GetRepeatedEnum(int number, int index) const {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.repeated_enum_value->Get(index);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::iterator iter = extensions_.find(number);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter->second.repeated_enum_value->Set(index, value);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::AddEnum(int number, FieldType type,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool packed, int value,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const FieldDescriptor* descriptor) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = true;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_packed = packed;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->repeated_enum_value = new RepeatedField<int>();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(extension->is_packed, packed);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->repeated_enum_value->Add(value);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Strings
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const string& ExtensionSet::GetString(int number,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const string& default_value) const {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end() || iter->second.is_cleared) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not present.  Return the default value.
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return default_value;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *iter->second.string_value;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string* ExtensionSet::MutableString(int number, FieldType type,
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const FieldDescriptor* descriptor) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = false;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->string_value = new string;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension->is_cleared = false;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension->string_value;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const string& ExtensionSet::GetRepeatedString(int number, int index) const {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.repeated_string_value->Get(index);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string* ExtensionSet::MutableRepeatedString(int number, int index) {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::iterator iter = extensions_.find(number);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.repeated_string_value->Mutable(index);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string* ExtensionSet::AddString(int number, FieldType type,
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const FieldDescriptor* descriptor) {
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = true;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_packed = false;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->repeated_string_value = new RepeatedPtrField<string>();
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return extension->repeated_string_value->Add();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Messages
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MessageLite& ExtensionSet::GetMessage(
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int number, const MessageLite& default_value) const {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (iter == extensions_.end()) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not present.  Return the default value.
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return default_value;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
444ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (iter->second.is_lazy) {
445ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return iter->second.lazymessage_value->GetMessage(default_value);
446ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return *iter->second.message_value;
448ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// const MessageLite& ExtensionSet::GetMessage(int number,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                             const Descriptor* message_type,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                             MessageFactory* factory) const
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const MessageLite& prototype,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const FieldDescriptor* descriptor) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = false;
465ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extension->is_lazy = false;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->message_value = prototype.New();
467ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extension->is_cleared = false;
468ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return extension->message_value;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
471ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extension->is_cleared = false;
472ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (extension->is_lazy) {
473ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return extension->lazymessage_value->MutableMessage(prototype);
474ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
475ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      return extension->message_value;
476ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                           const Descriptor* message_type,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                           MessageFactory* factory)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ExtensionSet::SetAllocatedMessage(int number, FieldType type,
486ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                       const FieldDescriptor* descriptor,
487ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                       MessageLite* message) {
488ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (message == NULL) {
489ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ClearExtension(number);
490ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return;
491ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
492ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  Extension* extension;
493ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (MaybeNewExtension(number, descriptor, &extension)) {
494ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extension->type = type;
495ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
496ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extension->is_repeated = false;
497ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extension->is_lazy = false;
498ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extension->message_value = message;
499ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
500ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
501ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (extension->is_lazy) {
502ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      extension->lazymessage_value->SetAllocatedMessage(message);
503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      delete extension->message_value;
505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      extension->message_value = message;
506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
507ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
508ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  extension->is_cleared = false;
509ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
510ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
511ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochMessageLite* ExtensionSet::ReleaseMessage(int number,
512ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                          const MessageLite& prototype) {
513ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  map<int, Extension>::iterator iter = extensions_.find(number);
514ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (iter == extensions_.end()) {
515ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // Not present.  Return NULL.
516ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return NULL;
517ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
518ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
519ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    MessageLite* ret = NULL;
520ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (iter->second.is_lazy) {
521ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
522ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      delete iter->second.lazymessage_value;
523ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
524ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ret = iter->second.message_value;
525ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
526ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    extensions_.erase(number);
527ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return ret;
528ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
529ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
530ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
531ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Defined in extension_set_heavy.cc.
532ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
533ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//                                           MessageFactory* factory);
534ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MessageLite& ExtensionSet::GetRepeatedMessage(
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int number, int index) const {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter = extensions_.find(number);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.repeated_message_value->Get(index);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::iterator iter = extensions_.find(number);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter->second.repeated_message_value->Mutable(index);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const MessageLite& prototype,
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const FieldDescriptor* descriptor) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (MaybeNewExtension(number, descriptor, &extension)) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->type = type;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->is_repeated = true;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->repeated_message_value =
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new RepeatedPtrField<MessageLite>();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allocate an abstract object, so we have to be tricky.
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageLite* result = extension->repeated_message_value
567ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ->AddFromCleared<GenericTypeHandler<MessageLite> >();
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (result == NULL) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = prototype.New();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension->repeated_message_value->AddAllocated(result);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                       const Descriptor* message_type,
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                       MessageFactory* factory)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef GOOGLE_DCHECK_TYPE
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::RemoveLast(int number) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::iterator iter = extensions_.find(number);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension = &iter->second;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK(extension->is_repeated);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch(cpp_type(extension->type)) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_INT32:
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_int32_value->RemoveLast();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_INT64:
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_int64_value->RemoveLast();
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_UINT32:
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_uint32_value->RemoveLast();
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_UINT64:
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_uint64_value->RemoveLast();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_FLOAT:
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_float_value->RemoveLast();
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_DOUBLE:
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_double_value->RemoveLast();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_BOOL:
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_bool_value->RemoveLast();
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_ENUM:
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_enum_value->RemoveLast();
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_STRING:
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_string_value->RemoveLast();
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_MESSAGE:
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_message_value->RemoveLast();
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
623ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochMessageLite* ExtensionSet::ReleaseLast(int number) {
624ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  map<int, Extension>::iterator iter = extensions_.find(number);
625ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
626ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
627ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  Extension* extension = &iter->second;
628ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_DCHECK(extension->is_repeated);
629ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
630ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return extension->repeated_message_value->ReleaseLast();
631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
632ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::SwapElements(int number, int index1, int index2) {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::iterator iter = extensions_.find(number);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Extension* extension = &iter->second;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK(extension->is_repeated);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch(cpp_type(extension->type)) {
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_INT32:
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_int32_value->SwapElements(index1, index2);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_INT64:
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_int64_value->SwapElements(index1, index2);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_UINT32:
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_uint32_value->SwapElements(index1, index2);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_UINT64:
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_uint64_value->SwapElements(index1, index2);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_FLOAT:
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_float_value->SwapElements(index1, index2);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_DOUBLE:
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_double_value->SwapElements(index1, index2);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_BOOL:
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_bool_value->SwapElements(index1, index2);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_ENUM:
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_enum_value->SwapElements(index1, index2);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_STRING:
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_string_value->SwapElements(index1, index2);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_MESSAGE:
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension->repeated_message_value->SwapElements(index1, index2);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Clear() {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (map<int, Extension>::iterator iter = extensions_.begin();
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second.Clear();
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::MergeFrom(const ExtensionSet& other) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != other.extensions_.end(); ++iter) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension& other_extension = iter->second;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (other_extension.is_repeated) {
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Extension* extension;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &extension);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_new) {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Extension did not already exist in set.
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extension->type = other_extension.type;
695ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        extension->is_packed = other_extension.is_packed;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extension->is_repeated = true;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
699ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GOOGLE_DCHECK(extension->is_repeated);
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (cpp_type(other_extension.type)) {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)             \
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (is_new) {                                              \
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            extension->repeated_##LOWERCASE##_value =                \
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              new REPEATED_TYPE;                                     \
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }                                                          \
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extension->repeated_##LOWERCASE##_value->MergeFrom(        \
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            *other_extension.repeated_##LOWERCASE##_value);          \
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  INT32,   int32, RepeatedField   <  int32>);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  INT64,   int64, RepeatedField   <  int64>);
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( UINT32,  uint32, RepeatedField   < uint32>);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( UINT64,  uint64, RepeatedField   < uint64>);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  FLOAT,   float, RepeatedField   <  float>);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( DOUBLE,  double, RepeatedField   < double>);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   BOOL,    bool, RepeatedField   <   bool>);
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   ENUM,    enum, RepeatedField   <    int>);
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( STRING,  string, RepeatedPtrField< string>);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::CPPTYPE_MESSAGE:
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (is_new) {
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            extension->repeated_message_value =
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              new RepeatedPtrField<MessageLite>();
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // it would attempt to allocate new objects.
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          RepeatedPtrField<MessageLite>* other_repeated_message =
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              other_extension.repeated_message_value;
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          for (int i = 0; i < other_repeated_message->size(); i++) {
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const MessageLite& other_message = other_repeated_message->Get(i);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            MessageLite* target = extension->repeated_message_value
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ->AddFromCleared<GenericTypeHandler<MessageLite> >();
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (target == NULL) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              target = other_message.New();
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              extension->repeated_message_value->AddAllocated(target);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            target->CheckTypeAndMergeFrom(other_message);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!other_extension.is_cleared) {
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        switch (cpp_type(other_extension.type)) {
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)                         \
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case WireFormatLite::CPPTYPE_##UPPERCASE:                          \
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Set##CAMELCASE(iter->first, other_extension.type,                \
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           other_extension.LOWERCASE##_value,                \
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           other_extension.descriptor);                      \
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE( INT32,  int32,  Int32);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE( INT64,  int64,  Int64);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE(UINT32, uint32, UInt32);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE(UINT64, uint64, UInt64);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE( FLOAT,  float,  Float);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE(DOUBLE, double, Double);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE(  BOOL,   bool,   Bool);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HANDLE_TYPE(  ENUM,   enum,   Enum);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          case WireFormatLite::CPPTYPE_STRING:
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SetString(iter->first, other_extension.type,
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      *other_extension.string_value,
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      other_extension.descriptor);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
770ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          case WireFormatLite::CPPTYPE_MESSAGE: {
771ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            Extension* extension;
772ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            bool is_new = MaybeNewExtension(iter->first,
773ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                            other_extension.descriptor,
774ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                                            &extension);
775ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            if (is_new) {
776ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              extension->type = other_extension.type;
777ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              extension->is_packed = other_extension.is_packed;
778ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              extension->is_repeated = false;
779ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              if (other_extension.is_lazy) {
780ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                extension->is_lazy = true;
781ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                extension->lazymessage_value =
782ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                    other_extension.lazymessage_value->New();
783ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                extension->lazymessage_value->MergeFrom(
784ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                    *other_extension.lazymessage_value);
785ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              } else {
786ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                extension->is_lazy = false;
787ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                extension->message_value =
788ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                    other_extension.message_value->New();
789ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                extension->message_value->CheckTypeAndMergeFrom(
790ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                    *other_extension.message_value);
791ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              }
792ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            } else {
793ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
794ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
795ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              GOOGLE_DCHECK(!extension->is_repeated);
796ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              if (other_extension.is_lazy) {
797ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                if (extension->is_lazy) {
798ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                  extension->lazymessage_value->MergeFrom(
799ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      *other_extension.lazymessage_value);
800ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                } else {
801ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                  extension->message_value->CheckTypeAndMergeFrom(
802ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      other_extension.lazymessage_value->GetMessage(
803ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                          *extension->message_value));
804ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                }
805ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              } else {
806ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                if (extension->is_lazy) {
807ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                  extension->lazymessage_value->MutableMessage(
808ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      *other_extension.message_value)->CheckTypeAndMergeFrom(
809ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                          *other_extension.message_value);
810ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                } else {
811ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                  extension->message_value->CheckTypeAndMergeFrom(
812ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                      *other_extension.message_value);
813ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                }
814ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              }
815ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            }
816ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            extension->is_cleared = false;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            break;
818ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          }
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Swap(ExtensionSet* x) {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions_.swap(x->extensions_);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::IsInitialized() const {
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extensions are never required.  However, we need to check that all
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // embedded messages are initialized.
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (map<int, Extension>::const_iterator iter = extensions_.begin();
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Extension& extension = iter->second;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (extension.is_repeated) {
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int i = 0; i < extension.repeated_message_value->size(); i++) {
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (!extension.repeated_message_value->Get(i).IsInitialized()) {
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return false;
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!extension.is_cleared) {
844ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          if (extension.is_lazy) {
845ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            if (!extension.lazymessage_value->IsInitialized()) return false;
846ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          } else {
847ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            if (!extension.message_value->IsInitialized()) return false;
848ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
857ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool ExtensionSet::FindExtensionInfoFromTag(
858ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    uint32 tag, ExtensionFinder* extension_finder,
859ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int* field_number, ExtensionInfo* extension) {
860ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  *field_number = WireFormatLite::GetTagFieldNumber(tag);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_unknown;
864ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!extension_finder->Find(*field_number, extension)) {
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_unknown = true;
866ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else if (extension->is_packed) {
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WireFormatLite::WireType expected_wire_type =
870ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        WireFormatLite::WireTypeForFieldType(real_type(extension->type));
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_unknown = (wire_type != expected_wire_type);
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
873ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return !is_unknown;
874ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
875ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
876ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
877ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                              ExtensionFinder* extension_finder,
878ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                              FieldSkipper* field_skipper) {
879ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  int number;
880ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ExtensionInfo extension;
881ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension)) {
882ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return field_skipper->SkipField(input, tag);
883ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
884ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return ParseFieldWithExtensionInfo(number, extension, input, field_skipper);
885ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
886ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
888ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool ExtensionSet::ParseFieldWithExtensionInfo(
889ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int number, const ExtensionInfo& extension,
890ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    io::CodedInputStream* input,
891ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    FieldSkipper* field_skipper) {
892ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (extension.is_packed) {
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 size;
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!input->ReadVarint32(&size)) return false;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedInputStream::Limit limit = input->PushLimit(size);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (extension.type) {
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)        \
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_##UPPERCASE:                                   \
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (input->BytesUntilLimit() > 0) {                                 \
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          CPP_LOWERCASE value;                                                 \
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (!WireFormatLite::ReadPrimitive<                                  \
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(            \
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                input, &value)) return false;                                  \
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             true, value, extension.descriptor);               \
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }                                                                      \
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT32,  Int32,   int32);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT64,  Int64,   int64);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT32, UInt32,  uint32);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT64, UInt64,  uint64);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT32,  Int32,   int32);
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT64,  Int64,   int64);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED32, UInt32,  uint32);
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED64, UInt64,  uint64);
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED32,  Int32,   int32);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED64,  Int64,   int64);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   FLOAT,  Float,   float);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  DOUBLE, Double,  double);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(    BOOL,   Bool,    bool);
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_ENUM:
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        while (input->BytesUntilLimit() > 0) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int value;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  input, &value)) return false;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (extension.enum_validity_check.func(
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  extension.enum_validity_check.arg, value)) {
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    extension.descriptor);
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_STRING:
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_BYTES:
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_GROUP:
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_MESSAGE:
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    input->PopLimit(limit);
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (extension.type) {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                   \
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_##UPPERCASE: {                                 \
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CPP_LOWERCASE value;                                                   \
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WireFormatLite::ReadPrimitive<                                    \
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(              \
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               input, &value)) return false;                                   \
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (extension.is_repeated) {                                          \
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             false, value, extension.descriptor);              \
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {                                                               \
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             extension.descriptor);                            \
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }                                                                      \
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } break
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT32,  Int32,   int32);
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT64,  Int64,   int64);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT32, UInt32,  uint32);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT64, UInt64,  uint64);
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT32,  Int32,   int32);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT64,  Int64,   int64);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED32, UInt32,  uint32);
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED64, UInt64,  uint64);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED32,  Int32,   int32);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED64,  Int64,   int64);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   FLOAT,  Float,   float);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  DOUBLE, Double,  double);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(    BOOL,   Bool,    bool);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_ENUM: {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int value;
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                input, &value)) return false;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!extension.enum_validity_check.func(
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                extension.enum_validity_check.arg, value)) {
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Invalid value.  Treat as unknown.
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          field_skipper->SkipUnknownEnum(number, value);
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else if (extension.is_repeated) {
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  extension.descriptor);
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  extension.descriptor);
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_STRING:  {
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        string* value = extension.is_repeated ?
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          MutableString(number, WireFormatLite::TYPE_STRING,
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        extension.descriptor);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WireFormatLite::ReadString(input, value)) return false;
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_BYTES:  {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        string* value = extension.is_repeated ?
1009ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1010ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          MutableString(number, WireFormatLite::TYPE_BYTES,
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        extension.descriptor);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WireFormatLite::ReadBytes(input, value)) return false;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_GROUP: {
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MessageLite* value = extension.is_repeated ?
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AddMessage(number, WireFormatLite::TYPE_GROUP,
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       *extension.message_prototype, extension.descriptor) :
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            MutableMessage(number, WireFormatLite::TYPE_GROUP,
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           *extension.message_prototype, extension.descriptor);
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WireFormatLite::ReadGroup(number, input, value)) return false;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_MESSAGE: {
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        MessageLite* value = extension.is_repeated ?
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AddMessage(number, WireFormatLite::TYPE_MESSAGE,
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       *extension.message_prototype, extension.descriptor) :
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           *extension.message_prototype, extension.descriptor);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!WireFormatLite::ReadMessage(input, value)) return false;
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const MessageLite* containing_type,
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              UnknownFieldSet* unknown_fields) {
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FieldSkipper skipper(unknown_fields);
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GeneratedExtensionFinder finder(containing_type);
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ParseField(tag, input, &finder, &skipper);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                    const Message* containing_type,
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                    UnknownFieldSet* unknown_fields)
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                         const Message* containing_type,
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                                         UnknownFieldSet* unknown_fields);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::SerializeWithCachedSizes(
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int start_field_number, int end_field_number,
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream* output) const {
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<int, Extension>::const_iterator iter;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (iter = extensions_.lower_bound(start_field_number);
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end() && iter->first < end_field_number;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++iter) {
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->second.SerializeFieldWithCachedSizes(iter->first, output);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionSet::ByteSize() const {
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int total_size = 0;
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (map<int, Extension>::const_iterator iter = extensions_.begin();
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != extensions_.end(); ++iter) {
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_size += iter->second.ByteSize(iter->first);
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return total_size;
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int ExtensionSet::SpaceUsedExcludingSelf() const
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionSet::MaybeNewExtension(int number,
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const FieldDescriptor* descriptor,
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     Extension** result) {
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pair<map<int, Extension>::iterator, bool> insert_result =
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions_.insert(make_pair(number, Extension()));
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = &insert_result.first->second;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (*result)->descriptor = descriptor;
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return insert_result.second;
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Methods of ExtensionSet::Extension
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Extension::Clear() {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_repeated) {
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (cpp_type(type)) {
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        repeated_##LOWERCASE##_value->Clear();                     \
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  INT32,   int32);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  INT64,   int64);
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( UINT32,  uint32);
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( UINT64,  uint64);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  FLOAT,   float);
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( DOUBLE,  double);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   BOOL,    bool);
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   ENUM,    enum);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( STRING,  string);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(MESSAGE, message);
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_cleared) {
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (cpp_type(type)) {
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::CPPTYPE_STRING:
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          string_value->clear();
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::CPPTYPE_MESSAGE:
1124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          if (is_lazy) {
1125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            lazymessage_value->Clear();
1126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          } else {
1127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            message_value->Clear();
1128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          }
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // No need to do anything.  Get*() will return the default value
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // as long as is_cleared is true and Set*() will overwrite the
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // previous value.
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_cleared = true;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int number,
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io::CodedOutputStream* output) const {
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_repeated) {
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_packed) {
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (cached_size == 0) return;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WireFormatLite::WriteTag(number,
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output->WriteVarint32(cached_size);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (real_type(type)) {
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_##UPPERCASE:                              \
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            WireFormatLite::Write##CAMELCASE##NoTag(                        \
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              repeated_##LOWERCASE##_value->Get(i), output);                \
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }                                                                 \
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT32,    Int32,   int32);
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT64,    Int64,   int64);
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT32,   SInt32,   int32);
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT64,   SInt64,   int64);
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   FLOAT,    Float,   float);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  DOUBLE,   Double,  double);
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    BOOL,     Bool,    bool);
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    ENUM,     Enum,    enum);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_STRING:
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_BYTES:
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_GROUP:
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_MESSAGE:
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (real_type(type)) {
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_##UPPERCASE:                              \
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            WireFormatLite::Write##CAMELCASE(number,                        \
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              repeated_##LOWERCASE##_value->Get(i), output);                \
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }                                                                 \
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT32,    Int32,   int32);
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT64,    Int64,   int64);
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT32,   SInt32,   int32);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT64,   SInt64,   int64);
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   FLOAT,    Float,   float);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  DOUBLE,   Double,  double);
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    BOOL,     Bool,    bool);
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  STRING,   String,  string);
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   BYTES,    Bytes,  string);
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    ENUM,     Enum,    enum);
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   GROUP,    Group, message);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( MESSAGE,  Message, message);
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!is_cleared) {
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (real_type(type)) {
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_##UPPERCASE:                     \
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT32,    Int32,    int32_value);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT64,    Int64,    int64_value);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   FLOAT,    Float,    float_value);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  STRING,   String,  *string_value);
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   GROUP,    Group, *message_value);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
1241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      case WireFormatLite::TYPE_MESSAGE:
1242ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        if (is_lazy) {
1243ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          lazymessage_value->WriteMessage(number, output);
1244ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        } else {
1245ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          WireFormatLite::WriteMessage(number, *message_value, output);
1246ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        }
1247ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        break;
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionSet::Extension::ByteSize(int number) const {
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = 0;
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_repeated) {
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_packed) {
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (real_type(type)) {
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_##UPPERCASE:                              \
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            result += WireFormatLite::CAMELCASE##Size(                      \
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              repeated_##LOWERCASE##_value->Get(i));                        \
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }                                                                 \
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT32,    Int32,   int32);
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT64,    Int64,   int64);
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT32,   SInt32,   int32);
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT64,   SInt64,   int64);
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    ENUM,     Enum,    enum);
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Stuff with fixed size.
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_##UPPERCASE:                              \
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          result += WireFormatLite::k##CAMELCASE##Size *                    \
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    repeated_##LOWERCASE##_value->size();                   \
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED32,  Fixed32, uint32);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED64,  Fixed64, uint64);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED32, SFixed32,  int32);
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED64, SFixed64,  int64);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   FLOAT,    Float,  float);
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  DOUBLE,   Double, double);
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    BOOL,     Bool,   bool);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_STRING:
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_BYTES:
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_GROUP:
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_MESSAGE:
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cached_size = result;
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (result > 0) {
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result += io::CodedOutputStream::VarintSize32(result);
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result += io::CodedOutputStream::VarintSize32(
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            WireFormatLite::MakeTag(number,
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int tag_size = WireFormatLite::TagSize(number, real_type(type));
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switch (real_type(type)) {
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_##UPPERCASE:                              \
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          result += tag_size * repeated_##LOWERCASE##_value->size();        \
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            result += WireFormatLite::CAMELCASE##Size(                      \
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              repeated_##LOWERCASE##_value->Get(i));                        \
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }                                                                 \
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT32,    Int32,   int32);
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   INT64,    Int64,   int64);
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT32,   SInt32,   int32);
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  SINT64,   SInt64,   int64);
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  STRING,   String,  string);
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   BYTES,    Bytes,  string);
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    ENUM,     Enum,    enum);
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   GROUP,    Group, message);
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( MESSAGE,  Message, message);
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Stuff with fixed size.
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case WireFormatLite::TYPE_##UPPERCASE:                              \
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          result += (tag_size + WireFormatLite::k##CAMELCASE##Size) *       \
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    repeated_##LOWERCASE##_value->size();                   \
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED32,  Fixed32, uint32);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE( FIXED64,  Fixed64, uint64);
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED32, SFixed32,  int32);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(SFIXED64, SFixed64,  int64);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(   FLOAT,    Float,  float);
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(  DOUBLE,   Double, double);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HANDLE_TYPE(    BOOL,     Bool,   bool);
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (!is_cleared) {
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result += WireFormatLite::TagSize(number, real_type(type));
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (real_type(type)) {
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                      \
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_##UPPERCASE:                              \
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result += WireFormatLite::CAMELCASE##Size(LOWERCASE);             \
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT32,    Int32,    int32_value);
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   INT64,    Int64,    int64_value);
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  STRING,   String,  *string_value);
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   GROUP,    Group, *message_value);
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
1366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      case WireFormatLite::TYPE_MESSAGE: {
1367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        if (is_lazy) {
1368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          int size = lazymessage_value->ByteSize();
1369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          result += io::CodedOutputStream::VarintSize32(size) + size;
1370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        } else {
1371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          result += WireFormatLite::MessageSize(*message_value);
1372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        }
1373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        break;
1374ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      }
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Stuff with fixed size.
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::TYPE_##UPPERCASE:                              \
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result += WireFormatLite::k##CAMELCASE##Size;                     \
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED32,  Fixed32);
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( FIXED64,  Fixed64);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED32, SFixed32);
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(SFIXED64, SFixed64);
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   FLOAT,    Float);
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  DOUBLE,   Double);
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(    BOOL,     Bool);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionSet::Extension::GetSize() const {
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_DCHECK(is_repeated);
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (cpp_type(type)) {
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                        \
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return repeated_##LOWERCASE##_value->size()
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE(  INT32,   int32);
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE(  INT64,   int64);
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE( UINT32,  uint32);
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE( UINT64,  uint64);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE(  FLOAT,   float);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE( DOUBLE,  double);
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE(   BOOL,    bool);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE(   ENUM,    enum);
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE( STRING,  string);
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HANDLE_TYPE(MESSAGE, message);
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GOOGLE_LOG(FATAL) << "Can't get here.";
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionSet::Extension::Free() {
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_repeated) {
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (cpp_type(type)) {
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delete repeated_##LOWERCASE##_value;                       \
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  INT32,   int32);
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  INT64,   int64);
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( UINT32,  uint32);
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( UINT64,  uint64);
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(  FLOAT,   float);
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( DOUBLE,  double);
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   BOOL,    bool);
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(   ENUM,    enum);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE( STRING,  string);
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HANDLE_TYPE(MESSAGE, message);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef HANDLE_TYPE
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (cpp_type(type)) {
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::CPPTYPE_STRING:
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delete string_value;
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case WireFormatLite::CPPTYPE_MESSAGE:
1445ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        if (is_lazy) {
1446ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          delete lazymessage_value;
1447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        } else {
1448ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          delete message_value;
1449ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        }
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defined in extension_set_heavy.cc.
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
1463