PageRenderTime 137ms CodeModel.GetById 12ms app.highlight 115ms RepoModel.GetById 2ms app.codeStats 0ms

/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/extension_set.cc

http://github.com/tomahawk-player/tomahawk
C++ | 1464 lines | 1170 code | 162 blank | 132 comment | 186 complexity | abfd54309523c64cda04e50283266534 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1// Protocol Buffers - Google's data interchange format
   2// Copyright 2008 Google Inc.  All rights reserved.
   3// http://code.google.com/p/protobuf/
   4//
   5// Redistribution and use in source and binary forms, with or without
   6// modification, are permitted provided that the following conditions are
   7// met:
   8//
   9//     * Redistributions of source code must retain the above copyright
  10// notice, this list of conditions and the following disclaimer.
  11//     * Redistributions in binary form must reproduce the above
  12// copyright notice, this list of conditions and the following disclaimer
  13// in the documentation and/or other materials provided with the
  14// distribution.
  15//     * Neither the name of Google Inc. nor the names of its
  16// contributors may be used to endorse or promote products derived from
  17// this software without specific prior written permission.
  18//
  19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30
  31// Author: kenton@google.com (Kenton Varda)
  32//  Based on original Protocol Buffers design by
  33//  Sanjay Ghemawat, Jeff Dean, and others.
  34
  35#include <google/protobuf/stubs/hash.h>
  36#include <google/protobuf/stubs/common.h>
  37#include <google/protobuf/stubs/once.h>
  38#include <google/protobuf/extension_set.h>
  39#include <google/protobuf/message_lite.h>
  40#include <google/protobuf/io/coded_stream.h>
  41#include <google/protobuf/io/zero_copy_stream_impl.h>
  42#include <google/protobuf/wire_format_lite_inl.h>
  43#include <google/protobuf/repeated_field.h>
  44#include <google/protobuf/stubs/map-util.h>
  45
  46namespace google {
  47namespace protobuf {
  48namespace internal {
  49
  50namespace {
  51
  52inline WireFormatLite::FieldType real_type(FieldType type) {
  53  GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
  54  return static_cast<WireFormatLite::FieldType>(type);
  55}
  56
  57inline WireFormatLite::CppType cpp_type(FieldType type) {
  58  return WireFormatLite::FieldTypeToCppType(real_type(type));
  59}
  60
  61// Registry stuff.
  62typedef hash_map<pair<const MessageLite*, int>,
  63                 ExtensionInfo> ExtensionRegistry;
  64ExtensionRegistry* registry_ = NULL;
  65GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
  66
  67void DeleteRegistry() {
  68  delete registry_;
  69  registry_ = NULL;
  70}
  71
  72void InitRegistry() {
  73  registry_ = new ExtensionRegistry;
  74  internal::OnShutdown(&DeleteRegistry);
  75}
  76
  77// This function is only called at startup, so there is no need for thread-
  78// safety.
  79void Register(const MessageLite* containing_type,
  80              int number, ExtensionInfo info) {
  81  ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
  82
  83  if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
  84                          info)) {
  85    GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
  86               << containing_type->GetTypeName()
  87               << "\", field number " << number << ".";
  88  }
  89}
  90
  91const ExtensionInfo* FindRegisteredExtension(
  92    const MessageLite* containing_type, int number) {
  93  return (registry_ == NULL) ? NULL :
  94         FindOrNull(*registry_, make_pair(containing_type, number));
  95}
  96
  97}  // namespace
  98
  99ExtensionFinder::~ExtensionFinder() {}
 100
 101bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
 102  const ExtensionInfo* extension =
 103      FindRegisteredExtension(containing_type_, number);
 104  if (extension == NULL) {
 105    return false;
 106  } else {
 107    *output = *extension;
 108    return true;
 109  }
 110}
 111
 112void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
 113                                     int number, FieldType type,
 114                                     bool is_repeated, bool is_packed) {
 115  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
 116  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
 117  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
 118  ExtensionInfo info(type, is_repeated, is_packed);
 119  Register(containing_type, number, info);
 120}
 121
 122static bool CallNoArgValidityFunc(const void* arg, int number) {
 123  // Note:  Must use C-style cast here rather than reinterpret_cast because
 124  //   the C++ standard at one point did not allow casts between function and
 125  //   data pointers and some compilers enforce this for C++-style casts.  No
 126  //   compiler enforces it for C-style casts since lots of C-style code has
 127  //   relied on these kinds of casts for a long time, despite being
 128  //   technically undefined.  See:
 129  //     http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
 130  // Also note:  Some compilers do not allow function pointers to be "const".
 131  //   Which makes sense, I suppose, because it's meaningless.
 132  return ((EnumValidityFunc*)arg)(number);
 133}
 134
 135void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
 136                                         int number, FieldType type,
 137                                         bool is_repeated, bool is_packed,
 138                                         EnumValidityFunc* is_valid) {
 139  GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
 140  ExtensionInfo info(type, is_repeated, is_packed);
 141  info.enum_validity_check.func = CallNoArgValidityFunc;
 142  // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
 143  info.enum_validity_check.arg = (void*)is_valid;
 144  Register(containing_type, number, info);
 145}
 146
 147void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
 148                                            int number, FieldType type,
 149                                            bool is_repeated, bool is_packed,
 150                                            const MessageLite* prototype) {
 151  GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
 152        type == WireFormatLite::TYPE_GROUP);
 153  ExtensionInfo info(type, is_repeated, is_packed);
 154  info.message_prototype = prototype;
 155  Register(containing_type, number, info);
 156}
 157
 158
 159// ===================================================================
 160// Constructors and basic methods.
 161
 162ExtensionSet::ExtensionSet() {}
 163
 164ExtensionSet::~ExtensionSet() {
 165  for (map<int, Extension>::iterator iter = extensions_.begin();
 166       iter != extensions_.end(); ++iter) {
 167    iter->second.Free();
 168  }
 169}
 170
 171// Defined in extension_set_heavy.cc.
 172// void ExtensionSet::AppendToList(const Descriptor* containing_type,
 173//                                 const DescriptorPool* pool,
 174//                                 vector<const FieldDescriptor*>* output) const
 175
 176bool ExtensionSet::Has(int number) const {
 177  map<int, Extension>::const_iterator iter = extensions_.find(number);
 178  if (iter == extensions_.end()) return false;
 179  GOOGLE_DCHECK(!iter->second.is_repeated);
 180  return !iter->second.is_cleared;
 181}
 182
 183int ExtensionSet::ExtensionSize(int number) const {
 184  map<int, Extension>::const_iterator iter = extensions_.find(number);
 185  if (iter == extensions_.end()) return false;
 186  return iter->second.GetSize();
 187}
 188
 189FieldType ExtensionSet::ExtensionType(int number) const {
 190  map<int, Extension>::const_iterator iter = extensions_.find(number);
 191  if (iter == extensions_.end()) {
 192    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
 193    return 0;
 194  }
 195  if (iter->second.is_cleared) {
 196    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
 197  }
 198  return iter->second.type;
 199}
 200
 201void ExtensionSet::ClearExtension(int number) {
 202  map<int, Extension>::iterator iter = extensions_.find(number);
 203  if (iter == extensions_.end()) return;
 204  iter->second.Clear();
 205}
 206
 207// ===================================================================
 208// Field accessors
 209
 210namespace {
 211
 212enum Cardinality {
 213  REPEATED,
 214  OPTIONAL
 215};
 216
 217}  // namespace
 218
 219#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                             \
 220  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL);         \
 221  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
 222
 223// -------------------------------------------------------------------
 224// Primitives
 225
 226#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
 227                                                                               \
 228LOWERCASE ExtensionSet::Get##CAMELCASE(int number,                             \
 229                                       LOWERCASE default_value) const {        \
 230  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
 231  if (iter == extensions_.end() || iter->second.is_cleared) {                  \
 232    return default_value;                                                      \
 233  } else {                                                                     \
 234    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE);                            \
 235    return iter->second.LOWERCASE##_value;                                     \
 236  }                                                                            \
 237}                                                                              \
 238                                                                               \
 239void ExtensionSet::Set##CAMELCASE(int number, FieldType type,                  \
 240                                  LOWERCASE value,                             \
 241                                  const FieldDescriptor* descriptor) {         \
 242  Extension* extension;                                                        \
 243  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
 244    extension->type = type;                                                    \
 245    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
 246    extension->is_repeated = false;                                            \
 247  } else {                                                                     \
 248    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE);                              \
 249  }                                                                            \
 250  extension->is_cleared = false;                                               \
 251  extension->LOWERCASE##_value = value;                                        \
 252}                                                                              \
 253                                                                               \
 254LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const {  \
 255  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
 256  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
 257  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
 258  return iter->second.repeated_##LOWERCASE##_value->Get(index);                \
 259}                                                                              \
 260                                                                               \
 261void ExtensionSet::SetRepeated##CAMELCASE(                                     \
 262    int number, int index, LOWERCASE value) {                                  \
 263  map<int, Extension>::iterator iter = extensions_.find(number);               \
 264  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
 265  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
 266  iter->second.repeated_##LOWERCASE##_value->Set(index, value);                \
 267}                                                                              \
 268                                                                               \
 269void ExtensionSet::Add##CAMELCASE(int number, FieldType type,                  \
 270                                  bool packed, LOWERCASE value,                \
 271                                  const FieldDescriptor* descriptor) {         \
 272  Extension* extension;                                                        \
 273  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
 274    extension->type = type;                                                    \
 275    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
 276    extension->is_repeated = true;                                             \
 277    extension->is_packed = packed;                                             \
 278    extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>();  \
 279  } else {                                                                     \
 280    GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE);                              \
 281    GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                   \
 282  }                                                                            \
 283  extension->repeated_##LOWERCASE##_value->Add(value);                         \
 284}
 285
 286PRIMITIVE_ACCESSORS( INT32,  int32,  Int32)
 287PRIMITIVE_ACCESSORS( INT64,  int64,  Int64)
 288PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
 289PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
 290PRIMITIVE_ACCESSORS( FLOAT,  float,  Float)
 291PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
 292PRIMITIVE_ACCESSORS(  BOOL,   bool,   Bool)
 293
 294#undef PRIMITIVE_ACCESSORS
 295
 296// -------------------------------------------------------------------
 297// Enums
 298
 299int ExtensionSet::GetEnum(int number, int default_value) const {
 300  map<int, Extension>::const_iterator iter = extensions_.find(number);
 301  if (iter == extensions_.end() || iter->second.is_cleared) {
 302    // Not present.  Return the default value.
 303    return default_value;
 304  } else {
 305    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
 306    return iter->second.enum_value;
 307  }
 308}
 309
 310void ExtensionSet::SetEnum(int number, FieldType type, int value,
 311                           const FieldDescriptor* descriptor) {
 312  Extension* extension;
 313  if (MaybeNewExtension(number, descriptor, &extension)) {
 314    extension->type = type;
 315    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
 316    extension->is_repeated = false;
 317  } else {
 318    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
 319  }
 320  extension->is_cleared = false;
 321  extension->enum_value = value;
 322}
 323
 324int ExtensionSet::GetRepeatedEnum(int number, int index) const {
 325  map<int, Extension>::const_iterator iter = extensions_.find(number);
 326  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 327  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
 328  return iter->second.repeated_enum_value->Get(index);
 329}
 330
 331void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
 332  map<int, Extension>::iterator iter = extensions_.find(number);
 333  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 334  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
 335  iter->second.repeated_enum_value->Set(index, value);
 336}
 337
 338void ExtensionSet::AddEnum(int number, FieldType type,
 339                           bool packed, int value,
 340                           const FieldDescriptor* descriptor) {
 341  Extension* extension;
 342  if (MaybeNewExtension(number, descriptor, &extension)) {
 343    extension->type = type;
 344    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
 345    extension->is_repeated = true;
 346    extension->is_packed = packed;
 347    extension->repeated_enum_value = new RepeatedField<int>();
 348  } else {
 349    GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
 350    GOOGLE_DCHECK_EQ(extension->is_packed, packed);
 351  }
 352  extension->repeated_enum_value->Add(value);
 353}
 354
 355// -------------------------------------------------------------------
 356// Strings
 357
 358const string& ExtensionSet::GetString(int number,
 359                                      const string& default_value) const {
 360  map<int, Extension>::const_iterator iter = extensions_.find(number);
 361  if (iter == extensions_.end() || iter->second.is_cleared) {
 362    // Not present.  Return the default value.
 363    return default_value;
 364  } else {
 365    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
 366    return *iter->second.string_value;
 367  }
 368}
 369
 370string* ExtensionSet::MutableString(int number, FieldType type,
 371                                    const FieldDescriptor* descriptor) {
 372  Extension* extension;
 373  if (MaybeNewExtension(number, descriptor, &extension)) {
 374    extension->type = type;
 375    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
 376    extension->is_repeated = false;
 377    extension->string_value = new string;
 378  } else {
 379    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
 380  }
 381  extension->is_cleared = false;
 382  return extension->string_value;
 383}
 384
 385const string& ExtensionSet::GetRepeatedString(int number, int index) const {
 386  map<int, Extension>::const_iterator iter = extensions_.find(number);
 387  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 388  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
 389  return iter->second.repeated_string_value->Get(index);
 390}
 391
 392string* ExtensionSet::MutableRepeatedString(int number, int index) {
 393  map<int, Extension>::iterator iter = extensions_.find(number);
 394  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 395  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
 396  return iter->second.repeated_string_value->Mutable(index);
 397}
 398
 399string* ExtensionSet::AddString(int number, FieldType type,
 400                                const FieldDescriptor* descriptor) {
 401  Extension* extension;
 402  if (MaybeNewExtension(number, descriptor, &extension)) {
 403    extension->type = type;
 404    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
 405    extension->is_repeated = true;
 406    extension->is_packed = false;
 407    extension->repeated_string_value = new RepeatedPtrField<string>();
 408  } else {
 409    GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
 410  }
 411  return extension->repeated_string_value->Add();
 412}
 413
 414// -------------------------------------------------------------------
 415// Messages
 416
 417const MessageLite& ExtensionSet::GetMessage(
 418    int number, const MessageLite& default_value) const {
 419  map<int, Extension>::const_iterator iter = extensions_.find(number);
 420  if (iter == extensions_.end()) {
 421    // Not present.  Return the default value.
 422    return default_value;
 423  } else {
 424    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
 425    return *iter->second.message_value;
 426  }
 427}
 428
 429// Defined in extension_set_heavy.cc.
 430// const MessageLite& ExtensionSet::GetMessage(int number,
 431//                                             const Descriptor* message_type,
 432//                                             MessageFactory* factory) const
 433
 434MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
 435                                          const MessageLite& prototype,
 436                                          const FieldDescriptor* descriptor) {
 437  Extension* extension;
 438  if (MaybeNewExtension(number, descriptor, &extension)) {
 439    extension->type = type;
 440    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
 441    extension->is_repeated = false;
 442    extension->message_value = prototype.New();
 443  } else {
 444    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
 445  }
 446  extension->is_cleared = false;
 447  return extension->message_value;
 448}
 449
 450// Defined in extension_set_heavy.cc.
 451// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
 452//                                           const Descriptor* message_type,
 453//                                           MessageFactory* factory)
 454
 455const MessageLite& ExtensionSet::GetRepeatedMessage(
 456    int number, int index) const {
 457  map<int, Extension>::const_iterator iter = extensions_.find(number);
 458  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 459  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
 460  return iter->second.repeated_message_value->Get(index);
 461}
 462
 463MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
 464  map<int, Extension>::iterator iter = extensions_.find(number);
 465  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 466  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
 467  return iter->second.repeated_message_value->Mutable(index);
 468}
 469
 470MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
 471                                      const MessageLite& prototype,
 472                                      const FieldDescriptor* descriptor) {
 473  Extension* extension;
 474  if (MaybeNewExtension(number, descriptor, &extension)) {
 475    extension->type = type;
 476    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
 477    extension->is_repeated = true;
 478    extension->repeated_message_value =
 479      new RepeatedPtrField<MessageLite>();
 480  } else {
 481    GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
 482  }
 483
 484  // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
 485  // allocate an abstract object, so we have to be tricky.
 486  MessageLite* result = extension->repeated_message_value
 487      ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
 488  if (result == NULL) {
 489    result = prototype.New();
 490    extension->repeated_message_value->AddAllocated(result);
 491  }
 492  return result;
 493}
 494
 495// Defined in extension_set_heavy.cc.
 496// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
 497//                                       const Descriptor* message_type,
 498//                                       MessageFactory* factory)
 499
 500#undef GOOGLE_DCHECK_TYPE
 501
 502void ExtensionSet::RemoveLast(int number) {
 503  map<int, Extension>::iterator iter = extensions_.find(number);
 504  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 505
 506  Extension* extension = &iter->second;
 507  GOOGLE_DCHECK(extension->is_repeated);
 508
 509  switch(cpp_type(extension->type)) {
 510    case WireFormatLite::CPPTYPE_INT32:
 511      extension->repeated_int32_value->RemoveLast();
 512      break;
 513    case WireFormatLite::CPPTYPE_INT64:
 514      extension->repeated_int64_value->RemoveLast();
 515      break;
 516    case WireFormatLite::CPPTYPE_UINT32:
 517      extension->repeated_uint32_value->RemoveLast();
 518      break;
 519    case WireFormatLite::CPPTYPE_UINT64:
 520      extension->repeated_uint64_value->RemoveLast();
 521      break;
 522    case WireFormatLite::CPPTYPE_FLOAT:
 523      extension->repeated_float_value->RemoveLast();
 524      break;
 525    case WireFormatLite::CPPTYPE_DOUBLE:
 526      extension->repeated_double_value->RemoveLast();
 527      break;
 528    case WireFormatLite::CPPTYPE_BOOL:
 529      extension->repeated_bool_value->RemoveLast();
 530      break;
 531    case WireFormatLite::CPPTYPE_ENUM:
 532      extension->repeated_enum_value->RemoveLast();
 533      break;
 534    case WireFormatLite::CPPTYPE_STRING:
 535      extension->repeated_string_value->RemoveLast();
 536      break;
 537    case WireFormatLite::CPPTYPE_MESSAGE:
 538      extension->repeated_message_value->RemoveLast();
 539      break;
 540  }
 541}
 542
 543void ExtensionSet::SwapElements(int number, int index1, int index2) {
 544  map<int, Extension>::iterator iter = extensions_.find(number);
 545  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
 546
 547  Extension* extension = &iter->second;
 548  GOOGLE_DCHECK(extension->is_repeated);
 549
 550  switch(cpp_type(extension->type)) {
 551    case WireFormatLite::CPPTYPE_INT32:
 552      extension->repeated_int32_value->SwapElements(index1, index2);
 553      break;
 554    case WireFormatLite::CPPTYPE_INT64:
 555      extension->repeated_int64_value->SwapElements(index1, index2);
 556      break;
 557    case WireFormatLite::CPPTYPE_UINT32:
 558      extension->repeated_uint32_value->SwapElements(index1, index2);
 559      break;
 560    case WireFormatLite::CPPTYPE_UINT64:
 561      extension->repeated_uint64_value->SwapElements(index1, index2);
 562      break;
 563    case WireFormatLite::CPPTYPE_FLOAT:
 564      extension->repeated_float_value->SwapElements(index1, index2);
 565      break;
 566    case WireFormatLite::CPPTYPE_DOUBLE:
 567      extension->repeated_double_value->SwapElements(index1, index2);
 568      break;
 569    case WireFormatLite::CPPTYPE_BOOL:
 570      extension->repeated_bool_value->SwapElements(index1, index2);
 571      break;
 572    case WireFormatLite::CPPTYPE_ENUM:
 573      extension->repeated_enum_value->SwapElements(index1, index2);
 574      break;
 575    case WireFormatLite::CPPTYPE_STRING:
 576      extension->repeated_string_value->SwapElements(index1, index2);
 577      break;
 578    case WireFormatLite::CPPTYPE_MESSAGE:
 579      extension->repeated_message_value->SwapElements(index1, index2);
 580      break;
 581  }
 582}
 583
 584// ===================================================================
 585
 586void ExtensionSet::Clear() {
 587  for (map<int, Extension>::iterator iter = extensions_.begin();
 588       iter != extensions_.end(); ++iter) {
 589    iter->second.Clear();
 590  }
 591}
 592
 593void ExtensionSet::MergeFrom(const ExtensionSet& other) {
 594  for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
 595       iter != other.extensions_.end(); ++iter) {
 596    const Extension& other_extension = iter->second;
 597
 598    if (other_extension.is_repeated) {
 599      Extension* extension;
 600      bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
 601                                      &extension);
 602      if (is_new) {
 603        // Extension did not already exist in set.
 604        extension->type = other_extension.type;
 605        extension->is_repeated = true;
 606      } else {
 607        GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
 608        GOOGLE_DCHECK(extension->is_repeated);
 609      }
 610
 611      switch (cpp_type(other_extension.type)) {
 612#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)             \
 613        case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
 614          if (is_new) {                                              \
 615            extension->repeated_##LOWERCASE##_value =                \
 616              new REPEATED_TYPE;                                     \
 617          }                                                          \
 618          extension->repeated_##LOWERCASE##_value->MergeFrom(        \
 619            *other_extension.repeated_##LOWERCASE##_value);          \
 620          break;
 621
 622        HANDLE_TYPE(  INT32,   int32, RepeatedField   <  int32>);
 623        HANDLE_TYPE(  INT64,   int64, RepeatedField   <  int64>);
 624        HANDLE_TYPE( UINT32,  uint32, RepeatedField   < uint32>);
 625        HANDLE_TYPE( UINT64,  uint64, RepeatedField   < uint64>);
 626        HANDLE_TYPE(  FLOAT,   float, RepeatedField   <  float>);
 627        HANDLE_TYPE( DOUBLE,  double, RepeatedField   < double>);
 628        HANDLE_TYPE(   BOOL,    bool, RepeatedField   <   bool>);
 629        HANDLE_TYPE(   ENUM,    enum, RepeatedField   <    int>);
 630        HANDLE_TYPE( STRING,  string, RepeatedPtrField< string>);
 631#undef HANDLE_TYPE
 632
 633        case WireFormatLite::CPPTYPE_MESSAGE:
 634          if (is_new) {
 635            extension->repeated_message_value =
 636              new RepeatedPtrField<MessageLite>();
 637          }
 638          // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
 639          // it would attempt to allocate new objects.
 640          RepeatedPtrField<MessageLite>* other_repeated_message =
 641              other_extension.repeated_message_value;
 642          for (int i = 0; i < other_repeated_message->size(); i++) {
 643            const MessageLite& other_message = other_repeated_message->Get(i);
 644            MessageLite* target = extension->repeated_message_value
 645                     ->AddFromCleared<GenericTypeHandler<MessageLite> >();
 646            if (target == NULL) {
 647              target = other_message.New();
 648              extension->repeated_message_value->AddAllocated(target);
 649            }
 650            target->CheckTypeAndMergeFrom(other_message);
 651          }
 652          break;
 653      }
 654    } else {
 655      if (!other_extension.is_cleared) {
 656        switch (cpp_type(other_extension.type)) {
 657#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)                         \
 658          case WireFormatLite::CPPTYPE_##UPPERCASE:                          \
 659            Set##CAMELCASE(iter->first, other_extension.type,                \
 660                           other_extension.LOWERCASE##_value,                \
 661                           other_extension.descriptor);                      \
 662            break;
 663
 664          HANDLE_TYPE( INT32,  int32,  Int32);
 665          HANDLE_TYPE( INT64,  int64,  Int64);
 666          HANDLE_TYPE(UINT32, uint32, UInt32);
 667          HANDLE_TYPE(UINT64, uint64, UInt64);
 668          HANDLE_TYPE( FLOAT,  float,  Float);
 669          HANDLE_TYPE(DOUBLE, double, Double);
 670          HANDLE_TYPE(  BOOL,   bool,   Bool);
 671          HANDLE_TYPE(  ENUM,   enum,   Enum);
 672#undef HANDLE_TYPE
 673          case WireFormatLite::CPPTYPE_STRING:
 674            SetString(iter->first, other_extension.type,
 675                      *other_extension.string_value,
 676                      other_extension.descriptor);
 677            break;
 678          case WireFormatLite::CPPTYPE_MESSAGE:
 679            MutableMessage(iter->first, other_extension.type,
 680                           *other_extension.message_value,
 681                           other_extension.descriptor)
 682              ->CheckTypeAndMergeFrom(*other_extension.message_value);
 683            break;
 684        }
 685      }
 686    }
 687  }
 688}
 689
 690void ExtensionSet::Swap(ExtensionSet* x) {
 691  extensions_.swap(x->extensions_);
 692}
 693
 694bool ExtensionSet::IsInitialized() const {
 695  // Extensions are never required.  However, we need to check that all
 696  // embedded messages are initialized.
 697  for (map<int, Extension>::const_iterator iter = extensions_.begin();
 698       iter != extensions_.end(); ++iter) {
 699    const Extension& extension = iter->second;
 700    if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
 701      if (extension.is_repeated) {
 702        for (int i = 0; i < extension.repeated_message_value->size(); i++) {
 703          if (!extension.repeated_message_value->Get(i).IsInitialized()) {
 704            return false;
 705          }
 706        }
 707      } else {
 708        if (!extension.is_cleared) {
 709          if (!extension.message_value->IsInitialized()) return false;
 710        }
 711      }
 712    }
 713  }
 714
 715  return true;
 716}
 717
 718bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
 719                              ExtensionFinder* extension_finder,
 720                              FieldSkipper* field_skipper) {
 721  int number = WireFormatLite::GetTagFieldNumber(tag);
 722  WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
 723
 724  ExtensionInfo extension;
 725  bool is_unknown;
 726  if (!extension_finder->Find(number, &extension)) {
 727    is_unknown = true;
 728  } else if (extension.is_packed) {
 729    is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
 730  } else {
 731    WireFormatLite::WireType expected_wire_type =
 732        WireFormatLite::WireTypeForFieldType(real_type(extension.type));
 733    is_unknown = (wire_type != expected_wire_type);
 734  }
 735
 736  if (is_unknown) {
 737    field_skipper->SkipField(input, tag);
 738  } else if (extension.is_packed) {
 739    uint32 size;
 740    if (!input->ReadVarint32(&size)) return false;
 741    io::CodedInputStream::Limit limit = input->PushLimit(size);
 742
 743    switch (extension.type) {
 744#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)        \
 745      case WireFormatLite::TYPE_##UPPERCASE:                                   \
 746        while (input->BytesUntilLimit() > 0) {                                 \
 747          CPP_LOWERCASE value;                                                 \
 748          if (!WireFormatLite::ReadPrimitive<                                  \
 749                  CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(            \
 750                input, &value)) return false;                                  \
 751          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
 752                             true, value, extension.descriptor);               \
 753        }                                                                      \
 754        break
 755
 756      HANDLE_TYPE(   INT32,  Int32,   int32);
 757      HANDLE_TYPE(   INT64,  Int64,   int64);
 758      HANDLE_TYPE(  UINT32, UInt32,  uint32);
 759      HANDLE_TYPE(  UINT64, UInt64,  uint64);
 760      HANDLE_TYPE(  SINT32,  Int32,   int32);
 761      HANDLE_TYPE(  SINT64,  Int64,   int64);
 762      HANDLE_TYPE( FIXED32, UInt32,  uint32);
 763      HANDLE_TYPE( FIXED64, UInt64,  uint64);
 764      HANDLE_TYPE(SFIXED32,  Int32,   int32);
 765      HANDLE_TYPE(SFIXED64,  Int64,   int64);
 766      HANDLE_TYPE(   FLOAT,  Float,   float);
 767      HANDLE_TYPE(  DOUBLE, Double,  double);
 768      HANDLE_TYPE(    BOOL,   Bool,    bool);
 769#undef HANDLE_TYPE
 770
 771      case WireFormatLite::TYPE_ENUM:
 772        while (input->BytesUntilLimit() > 0) {
 773          int value;
 774          if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
 775                  input, &value)) return false;
 776          if (extension.enum_validity_check.func(
 777                  extension.enum_validity_check.arg, value)) {
 778            AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
 779                    extension.descriptor);
 780          }
 781        }
 782        break;
 783
 784      case WireFormatLite::TYPE_STRING:
 785      case WireFormatLite::TYPE_BYTES:
 786      case WireFormatLite::TYPE_GROUP:
 787      case WireFormatLite::TYPE_MESSAGE:
 788        GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
 789        break;
 790    }
 791
 792    input->PopLimit(limit);
 793  } else {
 794    switch (extension.type) {
 795#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                   \
 796      case WireFormatLite::TYPE_##UPPERCASE: {                                 \
 797        CPP_LOWERCASE value;                                                   \
 798        if (!WireFormatLite::ReadPrimitive<                                    \
 799                CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(              \
 800               input, &value)) return false;                                   \
 801        if (extension.is_repeated) {                                          \
 802          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
 803                             false, value, extension.descriptor);              \
 804        } else {                                                               \
 805          Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
 806                             extension.descriptor);                            \
 807        }                                                                      \
 808      } break
 809
 810      HANDLE_TYPE(   INT32,  Int32,   int32);
 811      HANDLE_TYPE(   INT64,  Int64,   int64);
 812      HANDLE_TYPE(  UINT32, UInt32,  uint32);
 813      HANDLE_TYPE(  UINT64, UInt64,  uint64);
 814      HANDLE_TYPE(  SINT32,  Int32,   int32);
 815      HANDLE_TYPE(  SINT64,  Int64,   int64);
 816      HANDLE_TYPE( FIXED32, UInt32,  uint32);
 817      HANDLE_TYPE( FIXED64, UInt64,  uint64);
 818      HANDLE_TYPE(SFIXED32,  Int32,   int32);
 819      HANDLE_TYPE(SFIXED64,  Int64,   int64);
 820      HANDLE_TYPE(   FLOAT,  Float,   float);
 821      HANDLE_TYPE(  DOUBLE, Double,  double);
 822      HANDLE_TYPE(    BOOL,   Bool,    bool);
 823#undef HANDLE_TYPE
 824
 825      case WireFormatLite::TYPE_ENUM: {
 826        int value;
 827        if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
 828                input, &value)) return false;
 829
 830        if (!extension.enum_validity_check.func(
 831                extension.enum_validity_check.arg, value)) {
 832          // Invalid value.  Treat as unknown.
 833          field_skipper->SkipUnknownEnum(number, value);
 834        } else if (extension.is_repeated) {
 835          AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
 836                  extension.descriptor);
 837        } else {
 838          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
 839                  extension.descriptor);
 840        }
 841        break;
 842      }
 843
 844      case WireFormatLite::TYPE_STRING:  {
 845        string* value = extension.is_repeated ?
 846          AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
 847          MutableString(number, WireFormatLite::TYPE_STRING,
 848                        extension.descriptor);
 849        if (!WireFormatLite::ReadString(input, value)) return false;
 850        break;
 851      }
 852
 853      case WireFormatLite::TYPE_BYTES:  {
 854        string* value = extension.is_repeated ?
 855          AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
 856          MutableString(number, WireFormatLite::TYPE_STRING,
 857                        extension.descriptor);
 858        if (!WireFormatLite::ReadBytes(input, value)) return false;
 859        break;
 860      }
 861
 862      case WireFormatLite::TYPE_GROUP: {
 863        MessageLite* value = extension.is_repeated ?
 864            AddMessage(number, WireFormatLite::TYPE_GROUP,
 865                       *extension.message_prototype, extension.descriptor) :
 866            MutableMessage(number, WireFormatLite::TYPE_GROUP,
 867                           *extension.message_prototype, extension.descriptor);
 868        if (!WireFormatLite::ReadGroup(number, input, value)) return false;
 869        break;
 870      }
 871
 872      case WireFormatLite::TYPE_MESSAGE: {
 873        MessageLite* value = extension.is_repeated ?
 874            AddMessage(number, WireFormatLite::TYPE_MESSAGE,
 875                       *extension.message_prototype, extension.descriptor) :
 876            MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
 877                           *extension.message_prototype, extension.descriptor);
 878        if (!WireFormatLite::ReadMessage(input, value)) return false;
 879        break;
 880      }
 881    }
 882  }
 883
 884  return true;
 885}
 886
 887bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
 888                              const MessageLite* containing_type) {
 889  FieldSkipper skipper;
 890  GeneratedExtensionFinder finder(containing_type);
 891  return ParseField(tag, input, &finder, &skipper);
 892}
 893
 894// Defined in extension_set_heavy.cc.
 895// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
 896//                               const MessageLite* containing_type,
 897//                               UnknownFieldSet* unknown_fields)
 898
 899bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
 900                                   ExtensionFinder* extension_finder,
 901                                   FieldSkipper* field_skipper) {
 902  while (true) {
 903    uint32 tag = input->ReadTag();
 904    switch (tag) {
 905      case 0:
 906        return true;
 907      case WireFormatLite::kMessageSetItemStartTag:
 908        if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
 909          return false;
 910        }
 911        break;
 912      default:
 913        if (!ParseField(tag, input, extension_finder, field_skipper)) {
 914          return false;
 915        }
 916        break;
 917    }
 918  }
 919}
 920
 921bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
 922                                   const MessageLite* containing_type) {
 923  FieldSkipper skipper;
 924  GeneratedExtensionFinder finder(containing_type);
 925  return ParseMessageSet(input, &finder, &skipper);
 926}
 927
 928// Defined in extension_set_heavy.cc.
 929// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
 930//                                    const MessageLite* containing_type,
 931//                                    UnknownFieldSet* unknown_fields);
 932
 933bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
 934                                       ExtensionFinder* extension_finder,
 935                                       FieldSkipper* field_skipper) {
 936  // TODO(kenton):  It would be nice to share code between this and
 937  // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
 938  // differences would be hard to factor out.
 939
 940  // This method parses a group which should contain two fields:
 941  //   required int32 type_id = 2;
 942  //   required data message = 3;
 943
 944  // Once we see a type_id, we'll construct a fake tag for this extension
 945  // which is the tag it would have had under the proto2 extensions wire
 946  // format.
 947  uint32 fake_tag = 0;
 948
 949  // If we see message data before the type_id, we'll append it to this so
 950  // we can parse it later.  This will probably never happen in practice,
 951  // as no MessageSet encoder I know of writes the message before the type ID.
 952  // But, it's technically valid so we should allow it.
 953  // TODO(kenton):  Use a Cord instead?  Do I care?
 954  string message_data;
 955
 956  while (true) {
 957    uint32 tag = input->ReadTag();
 958    if (tag == 0) return false;
 959
 960    switch (tag) {
 961      case WireFormatLite::kMessageSetTypeIdTag: {
 962        uint32 type_id;
 963        if (!input->ReadVarint32(&type_id)) return false;
 964        fake_tag = WireFormatLite::MakeTag(type_id,
 965            WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
 966
 967        if (!message_data.empty()) {
 968          // We saw some message data before the type_id.  Have to parse it
 969          // now.
 970          io::CodedInputStream sub_input(
 971              reinterpret_cast<const uint8*>(message_data.data()),
 972              message_data.size());
 973          if (!ParseField(fake_tag, &sub_input,
 974                          extension_finder, field_skipper)) {
 975            return false;
 976          }
 977          message_data.clear();
 978        }
 979
 980        break;
 981      }
 982
 983      case WireFormatLite::kMessageSetMessageTag: {
 984        if (fake_tag == 0) {
 985          // We haven't seen a type_id yet.  Append this data to message_data.
 986          string temp;
 987          uint32 length;
 988          if (!input->ReadVarint32(&length)) return false;
 989          if (!input->ReadString(&temp, length)) return false;
 990          message_data.append(temp);
 991        } else {
 992          // Already saw type_id, so we can parse this directly.
 993          if (!ParseField(fake_tag, input,
 994                          extension_finder, field_skipper)) {
 995            return false;
 996          }
 997        }
 998
 999        break;
1000      }
1001
1002      case WireFormatLite::kMessageSetItemEndTag: {
1003        return true;
1004      }
1005
1006      default: {
1007        if (!field_skipper->SkipField(input, tag)) return false;
1008      }
1009    }
1010  }
1011}
1012
1013void ExtensionSet::SerializeWithCachedSizes(
1014    int start_field_number, int end_field_number,
1015    io::CodedOutputStream* output) const {
1016  map<int, Extension>::const_iterator iter;
1017  for (iter = extensions_.lower_bound(start_field_number);
1018       iter != extensions_.end() && iter->first < end_field_number;
1019       ++iter) {
1020    iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1021  }
1022}
1023
1024void ExtensionSet::SerializeMessageSetWithCachedSizes(
1025    io::CodedOutputStream* output) const {
1026  map<int, Extension>::const_iterator iter;
1027  for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
1028    iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
1029  }
1030}
1031
1032int ExtensionSet::ByteSize() const {
1033  int total_size = 0;
1034
1035  for (map<int, Extension>::const_iterator iter = extensions_.begin();
1036       iter != extensions_.end(); ++iter) {
1037    total_size += iter->second.ByteSize(iter->first);
1038  }
1039
1040  return total_size;
1041}
1042
1043int ExtensionSet::MessageSetByteSize() const {
1044  int total_size = 0;
1045
1046  for (map<int, Extension>::const_iterator iter = extensions_.begin();
1047       iter != extensions_.end(); ++iter) {
1048    total_size += iter->second.MessageSetItemByteSize(iter->first);
1049  }
1050
1051  return total_size;
1052}
1053
1054// Defined in extension_set_heavy.cc.
1055// int ExtensionSet::SpaceUsedExcludingSelf() const
1056
1057bool ExtensionSet::MaybeNewExtension(int number,
1058                                     const FieldDescriptor* descriptor,
1059                                     Extension** result) {
1060  pair<map<int, Extension>::iterator, bool> insert_result =
1061      extensions_.insert(make_pair(number, Extension()));
1062  *result = &insert_result.first->second;
1063  (*result)->descriptor = descriptor;
1064  return insert_result.second;
1065}
1066
1067// ===================================================================
1068// Methods of ExtensionSet::Extension
1069
1070void ExtensionSet::Extension::Clear() {
1071  if (is_repeated) {
1072    switch (cpp_type(type)) {
1073#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1074      case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1075        repeated_##LOWERCASE##_value->Clear();                     \
1076        break
1077
1078      HANDLE_TYPE(  INT32,   int32);
1079      HANDLE_TYPE(  INT64,   int64);
1080      HANDLE_TYPE( UINT32,  uint32);
1081      HANDLE_TYPE( UINT64,  uint64);
1082      HANDLE_TYPE(  FLOAT,   float);
1083      HANDLE_TYPE( DOUBLE,  double);
1084      HANDLE_TYPE(   BOOL,    bool);
1085      HANDLE_TYPE(   ENUM,    enum);
1086      HANDLE_TYPE( STRING,  string);
1087      HANDLE_TYPE(MESSAGE, message);
1088#undef HANDLE_TYPE
1089    }
1090  } else {
1091    if (!is_cleared) {
1092      switch (cpp_type(type)) {
1093        case WireFormatLite::CPPTYPE_STRING:
1094          string_value->clear();
1095          break;
1096        case WireFormatLite::CPPTYPE_MESSAGE:
1097          message_value->Clear();
1098          break;
1099        default:
1100          // No need to do anything.  Get*() will return the default value
1101          // as long as is_cleared is true and Set*() will overwrite the
1102          // previous value.
1103          break;
1104      }
1105
1106      is_cleared = true;
1107    }
1108  }
1109}
1110
1111void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1112    int number,
1113    io::CodedOutputStream* output) const {
1114  if (is_repeated) {
1115    if (is_packed) {
1116      if (cached_size == 0) return;
1117
1118      WireFormatLite::WriteTag(number,
1119          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1120      output->WriteVarint32(cached_size);
1121
1122      switch (real_type(type)) {
1123#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1124        case WireFormatLite::TYPE_##UPPERCASE:                              \
1125          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1126            WireFormatLite::Write##CAMELCASE##NoTag(                        \
1127              repeated_##LOWERCASE##_value->Get(i), output);                \
1128          }                                                                 \
1129          break
1130
1131        HANDLE_TYPE(   INT32,    Int32,   int32);
1132        HANDLE_TYPE(   INT64,    Int64,   int64);
1133        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1134        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1135        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1136        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1137        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1138        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1139        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1140        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1141        HANDLE_TYPE(   FLOAT,    Float,   float);
1142        HANDLE_TYPE(  DOUBLE,   Double,  double);
1143        HANDLE_TYPE(    BOOL,     Bool,    bool);
1144        HANDLE_TYPE(    ENUM,     Enum,    enum);
1145#undef HANDLE_TYPE
1146
1147        case WireFormatLite::TYPE_STRING:
1148        case WireFormatLite::TYPE_BYTES:
1149        case WireFormatLite::TYPE_GROUP:
1150        case WireFormatLite::TYPE_MESSAGE:
1151          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1152          break;
1153      }
1154    } else {
1155      switch (real_type(type)) {
1156#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1157        case WireFormatLite::TYPE_##UPPERCASE:                              \
1158          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1159            WireFormatLite::Write##CAMELCASE(number,                        \
1160              repeated_##LOWERCASE##_value->Get(i), output);                \
1161          }                                                                 \
1162          break
1163
1164        HANDLE_TYPE(   INT32,    Int32,   int32);
1165        HANDLE_TYPE(   INT64,    Int64,   int64);
1166        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1167        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1168        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1169        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1170        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1171        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1172        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1173        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1174        HANDLE_TYPE(   FLOAT,    Float,   float);
1175        HANDLE_TYPE(  DOUBLE,   Double,  double);
1176        HANDLE_TYPE(    BOOL,     Bool,    bool);
1177        HANDLE_TYPE(  STRING,   String,  string);
1178        HANDLE_TYPE(   BYTES,    Bytes,  string);
1179        HANDLE_TYPE(    ENUM,     Enum,    enum);
1180        HANDLE_TYPE(   GROUP,    Group, message);
1181        HANDLE_TYPE( MESSAGE,  Message, message);
1182#undef HANDLE_TYPE
1183      }
1184    }
1185  } else if (!is_cleared) {
1186    switch (real_type(type)) {
1187#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
1188      case WireFormatLite::TYPE_##UPPERCASE:                     \
1189        WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1190        break
1191
1192      HANDLE_TYPE(   INT32,    Int32,    int32_value);
1193      HANDLE_TYPE(   INT64,    Int64,    int64_value);
1194      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1195      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1196      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1197      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1198      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
1199      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
1200      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
1201      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
1202      HANDLE_TYPE(   FLOAT,    Float,    float_value);
1203      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
1204      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
1205      HANDLE_TYPE(  STRING,   String,  *string_value);
1206      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1207      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1208      HANDLE_TYPE(   GROUP,    Group, *message_value);
1209      HANDLE_TYPE( MESSAGE,  Message, *message_value);
1210#undef HANDLE_TYPE
1211    }
1212  }
1213}
1214
1215void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
1216    int number,
1217    io::CodedOutputStream* out

Large files files are truncated, but you can click here to view the full file