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
189void ExtensionSet::ClearExtension(int number) {
190  map<int, Extension>::iterator iter = extensions_.find(number);
191  if (iter == extensions_.end()) return;
192  iter->second.Clear();
193}
194
195// ===================================================================
196// Field accessors
197
198namespace {
199
200enum Cardinality {
201  REPEATED,
202  OPTIONAL
203};
204
205}  // namespace
206
207#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                             \
208  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL);         \
209  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
210
211// -------------------------------------------------------------------
212// Primitives
213
214#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
215                                                                               \
216LOWERCASE ExtensionSet::Get##CAMELCASE(int number,                             \
217                                       LOWERCASE default_value) const {        \
218  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
219  if (iter == extensions_.end() || iter->second.is_cleared) {                  \
220    return default_value;                                                      \
221  } else {                                                                     \
222    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE);                            \
223    return iter->second.LOWERCASE##_value;                                     \
224  }                                                                            \
225}                                                                              \
226                                                                               \
227void ExtensionSet::Set##CAMELCASE(int number, FieldType type,                  \
228                                  LOWERCASE value,                             \
229                                  const FieldDescriptor* descriptor) {         \
230  Extension* extension;                                                        \
231  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
232    extension->type = type;                                                    \
233    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
234    extension->is_repeated = false;                                            \
235  } else {                                                                     \
236    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE);                              \
237  }                                                                            \
238  extension->is_cleared = false;                                               \
239  extension->LOWERCASE##_value = value;                                        \
240}                                                                              \
241                                                                               \
242LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const {  \
243  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
244  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
245  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
246  return iter->second.repeated_##LOWERCASE##_value->Get(index);                \
247}                                                                              \
248                                                                               \
249void ExtensionSet::SetRepeated##CAMELCASE(                                     \
250    int number, int index, LOWERCASE value) {                                  \
251  map<int, Extension>::iterator iter = extensions_.find(number);               \
252  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
253  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE);                              \
254  iter->second.repeated_##LOWERCASE##_value->Set(index, value);                \
255}                                                                              \
256                                                                               \
257void ExtensionSet::Add##CAMELCASE(int number, FieldType type,                  \
258                                  bool packed, LOWERCASE value,                \
259                                  const FieldDescriptor* descriptor) {         \
260  Extension* extension;                                                        \
261  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
262    extension->type = type;                                                    \
263    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
264    extension->is_repeated = true;                                             \
265    extension->is_packed = packed;                                             \
266    extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>();  \
267  } else {                                                                     \
268    GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE);                              \
269    GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                   \
270  }                                                                            \
271  extension->repeated_##LOWERCASE##_value->Add(value);                         \
272}
273
274PRIMITIVE_ACCESSORS( INT32,  int32,  Int32)
275PRIMITIVE_ACCESSORS( INT64,  int64,  Int64)
276PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
277PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
278PRIMITIVE_ACCESSORS( FLOAT,  float,  Float)
279PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
280PRIMITIVE_ACCESSORS(  BOOL,   bool,   Bool)
281
282#undef PRIMITIVE_ACCESSORS
283
284// -------------------------------------------------------------------
285// Enums
286
287int ExtensionSet::GetEnum(int number, int default_value) const {
288  map<int, Extension>::const_iterator iter = extensions_.find(number);
289  if (iter == extensions_.end() || iter->second.is_cleared) {
290    // Not present.  Return the default value.
291    return default_value;
292  } else {
293    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
294    return iter->second.enum_value;
295  }
296}
297
298void ExtensionSet::SetEnum(int number, FieldType type, int value,
299                           const FieldDescriptor* descriptor) {
300  Extension* extension;
301  if (MaybeNewExtension(number, descriptor, &extension)) {
302    extension->type = type;
303    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
304    extension->is_repeated = false;
305  } else {
306    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
307  }
308  extension->is_cleared = false;
309  extension->enum_value = value;
310}
311
312int ExtensionSet::GetRepeatedEnum(int number, int index) const {
313  map<int, Extension>::const_iterator iter = extensions_.find(number);
314  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
315  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
316  return iter->second.repeated_enum_value->Get(index);
317}
318
319void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
320  map<int, Extension>::iterator iter = extensions_.find(number);
321  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
322  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
323  iter->second.repeated_enum_value->Set(index, value);
324}
325
326void ExtensionSet::AddEnum(int number, FieldType type,
327                           bool packed, int value,
328                           const FieldDescriptor* descriptor) {
329  Extension* extension;
330  if (MaybeNewExtension(number, descriptor, &extension)) {
331    extension->type = type;
332    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
333    extension->is_repeated = true;
334    extension->is_packed = packed;
335    extension->repeated_enum_value = new RepeatedField<int>();
336  } else {
337    GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
338    GOOGLE_DCHECK_EQ(extension->is_packed, packed);
339  }
340  extension->repeated_enum_value->Add(value);
341}
342
343// -------------------------------------------------------------------
344// Strings
345
346const string& ExtensionSet::GetString(int number,
347                                      const string& default_value) const {
348  map<int, Extension>::const_iterator iter = extensions_.find(number);
349  if (iter == extensions_.end() || iter->second.is_cleared) {
350    // Not present.  Return the default value.
351    return default_value;
352  } else {
353    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
354    return *iter->second.string_value;
355  }
356}
357
358string* ExtensionSet::MutableString(int number, FieldType type,
359                                    const FieldDescriptor* descriptor) {
360  Extension* extension;
361  if (MaybeNewExtension(number, descriptor, &extension)) {
362    extension->type = type;
363    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
364    extension->is_repeated = false;
365    extension->string_value = new string;
366  } else {
367    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
368  }
369  extension->is_cleared = false;
370  return extension->string_value;
371}
372
373const string& ExtensionSet::GetRepeatedString(int number, int index) const {
374  map<int, Extension>::const_iterator iter = extensions_.find(number);
375  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
376  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
377  return iter->second.repeated_string_value->Get(index);
378}
379
380string* ExtensionSet::MutableRepeatedString(int number, int index) {
381  map<int, Extension>::iterator iter = extensions_.find(number);
382  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
383  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
384  return iter->second.repeated_string_value->Mutable(index);
385}
386
387string* ExtensionSet::AddString(int number, FieldType type,
388                                const FieldDescriptor* descriptor) {
389  Extension* extension;
390  if (MaybeNewExtension(number, descriptor, &extension)) {
391    extension->type = type;
392    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
393    extension->is_repeated = true;
394    extension->is_packed = false;
395    extension->repeated_string_value = new RepeatedPtrField<string>();
396  } else {
397    GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
398  }
399  return extension->repeated_string_value->Add();
400}
401
402// -------------------------------------------------------------------
403// Messages
404
405const MessageLite& ExtensionSet::GetMessage(
406    int number, const MessageLite& default_value) const {
407  map<int, Extension>::const_iterator iter = extensions_.find(number);
408  if (iter == extensions_.end()) {
409    // Not present.  Return the default value.
410    return default_value;
411  } else {
412    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
413    return *iter->second.message_value;
414  }
415}
416
417// Defined in extension_set_heavy.cc.
418// const MessageLite& ExtensionSet::GetMessage(int number,
419//                                             const Descriptor* message_type,
420//                                             MessageFactory* factory) const
421
422MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
423                                          const MessageLite& prototype,
424                                          const FieldDescriptor* descriptor) {
425  Extension* extension;
426  if (MaybeNewExtension(number, descriptor, &extension)) {
427    extension->type = type;
428    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
429    extension->is_repeated = false;
430    extension->message_value = prototype.New();
431  } else {
432    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
433  }
434  extension->is_cleared = false;
435  return extension->message_value;
436}
437
438// Defined in extension_set_heavy.cc.
439// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
440//                                           const Descriptor* message_type,
441//                                           MessageFactory* factory)
442
443const MessageLite& ExtensionSet::GetRepeatedMessage(
444    int number, int index) const {
445  map<int, Extension>::const_iterator iter = extensions_.find(number);
446  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
447  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
448  return iter->second.repeated_message_value->Get(index);
449}
450
451MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
452  map<int, Extension>::iterator iter = extensions_.find(number);
453  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
454  GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
455  return iter->second.repeated_message_value->Mutable(index);
456}
457
458MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
459                                      const MessageLite& prototype,
460                                      const FieldDescriptor* descriptor) {
461  Extension* extension;
462  if (MaybeNewExtension(number, descriptor, &extension)) {
463    extension->type = type;
464    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
465    extension->is_repeated = true;
466    extension->repeated_message_value =
467      new RepeatedPtrField<MessageLite>();
468  } else {
469    GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
470  }
471
472  // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
473  // allocate an abstract object, so we have to be tricky.
474  MessageLite* result = extension->repeated_message_value
475      ->AddFromCleared<internal::GenericTypeHandler<MessageLite> >();
476  if (result == NULL) {
477    result = prototype.New();
478    extension->repeated_message_value->AddAllocated(result);
479  }
480  return result;
481}
482
483// Defined in extension_set_heavy.cc.
484// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
485//                                       const Descriptor* message_type,
486//                                       MessageFactory* factory)
487
488#undef GOOGLE_DCHECK_TYPE
489
490void ExtensionSet::RemoveLast(int number) {
491  map<int, Extension>::iterator iter = extensions_.find(number);
492  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
493
494  Extension* extension = &iter->second;
495  GOOGLE_DCHECK(extension->is_repeated);
496
497  switch(cpp_type(extension->type)) {
498    case WireFormatLite::CPPTYPE_INT32:
499      extension->repeated_int32_value->RemoveLast();
500      break;
501    case WireFormatLite::CPPTYPE_INT64:
502      extension->repeated_int64_value->RemoveLast();
503      break;
504    case WireFormatLite::CPPTYPE_UINT32:
505      extension->repeated_uint32_value->RemoveLast();
506      break;
507    case WireFormatLite::CPPTYPE_UINT64:
508      extension->repeated_uint64_value->RemoveLast();
509      break;
510    case WireFormatLite::CPPTYPE_FLOAT:
511      extension->repeated_float_value->RemoveLast();
512      break;
513    case WireFormatLite::CPPTYPE_DOUBLE:
514      extension->repeated_double_value->RemoveLast();
515      break;
516    case WireFormatLite::CPPTYPE_BOOL:
517      extension->repeated_bool_value->RemoveLast();
518      break;
519    case WireFormatLite::CPPTYPE_ENUM:
520      extension->repeated_enum_value->RemoveLast();
521      break;
522    case WireFormatLite::CPPTYPE_STRING:
523      extension->repeated_string_value->RemoveLast();
524      break;
525    case WireFormatLite::CPPTYPE_MESSAGE:
526      extension->repeated_message_value->RemoveLast();
527      break;
528  }
529}
530
531void ExtensionSet::SwapElements(int number, int index1, int index2) {
532  map<int, Extension>::iterator iter = extensions_.find(number);
533  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
534
535  Extension* extension = &iter->second;
536  GOOGLE_DCHECK(extension->is_repeated);
537
538  switch(cpp_type(extension->type)) {
539    case WireFormatLite::CPPTYPE_INT32:
540      extension->repeated_int32_value->SwapElements(index1, index2);
541      break;
542    case WireFormatLite::CPPTYPE_INT64:
543      extension->repeated_int64_value->SwapElements(index1, index2);
544      break;
545    case WireFormatLite::CPPTYPE_UINT32:
546      extension->repeated_uint32_value->SwapElements(index1, index2);
547      break;
548    case WireFormatLite::CPPTYPE_UINT64:
549      extension->repeated_uint64_value->SwapElements(index1, index2);
550      break;
551    case WireFormatLite::CPPTYPE_FLOAT:
552      extension->repeated_float_value->SwapElements(index1, index2);
553      break;
554    case WireFormatLite::CPPTYPE_DOUBLE:
555      extension->repeated_double_value->SwapElements(index1, index2);
556      break;
557    case WireFormatLite::CPPTYPE_BOOL:
558      extension->repeated_bool_value->SwapElements(index1, index2);
559      break;
560    case WireFormatLite::CPPTYPE_ENUM:
561      extension->repeated_enum_value->SwapElements(index1, index2);
562      break;
563    case WireFormatLite::CPPTYPE_STRING:
564      extension->repeated_string_value->SwapElements(index1, index2);
565      break;
566    case WireFormatLite::CPPTYPE_MESSAGE:
567      extension->repeated_message_value->SwapElements(index1, index2);
568      break;
569  }
570}
571
572// ===================================================================
573
574void ExtensionSet::Clear() {
575  for (map<int, Extension>::iterator iter = extensions_.begin();
576       iter != extensions_.end(); ++iter) {
577    iter->second.Clear();
578  }
579}
580
581void ExtensionSet::MergeFrom(const ExtensionSet& other) {
582  for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
583       iter != other.extensions_.end(); ++iter) {
584    const Extension& other_extension = iter->second;
585
586    if (other_extension.is_repeated) {
587      Extension* extension;
588      bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
589                                      &extension);
590      if (is_new) {
591        // Extension did not already exist in set.
592        extension->type = other_extension.type;
593        extension->is_repeated = true;
594      } else {
595        GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
596        GOOGLE_DCHECK(extension->is_repeated);
597      }
598
599      switch (cpp_type(other_extension.type)) {
600#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)             \
601        case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
602          if (is_new) {                                              \
603            extension->repeated_##LOWERCASE##_value =                \
604              new REPEATED_TYPE;                                     \
605          }                                                          \
606          extension->repeated_##LOWERCASE##_value->MergeFrom(        \
607            *other_extension.repeated_##LOWERCASE##_value);          \
608          break;
609
610        HANDLE_TYPE(  INT32,   int32, RepeatedField   <  int32>);
611        HANDLE_TYPE(  INT64,   int64, RepeatedField   <  int64>);
612        HANDLE_TYPE( UINT32,  uint32, RepeatedField   < uint32>);
613        HANDLE_TYPE( UINT64,  uint64, RepeatedField   < uint64>);
614        HANDLE_TYPE(  FLOAT,   float, RepeatedField   <  float>);
615        HANDLE_TYPE( DOUBLE,  double, RepeatedField   < double>);
616        HANDLE_TYPE(   BOOL,    bool, RepeatedField   <   bool>);
617        HANDLE_TYPE(   ENUM,    enum, RepeatedField   <    int>);
618        HANDLE_TYPE( STRING,  string, RepeatedPtrField< string>);
619#undef HANDLE_TYPE
620
621        case WireFormatLite::CPPTYPE_MESSAGE:
622          if (is_new) {
623            extension->repeated_message_value =
624              new RepeatedPtrField<MessageLite>();
625          }
626          // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
627          // it would attempt to allocate new objects.
628          RepeatedPtrField<MessageLite>* other_repeated_message =
629              other_extension.repeated_message_value;
630          for (int i = 0; i < other_repeated_message->size(); i++) {
631            const MessageLite& other_message = other_repeated_message->Get(i);
632            MessageLite* target = extension->repeated_message_value
633                     ->AddFromCleared<GenericTypeHandler<MessageLite> >();
634            if (target == NULL) {
635              target = other_message.New();
636              extension->repeated_message_value->AddAllocated(target);
637            }
638            target->CheckTypeAndMergeFrom(other_message);
639          }
640          break;
641      }
642    } else {
643      if (!other_extension.is_cleared) {
644        switch (cpp_type(other_extension.type)) {
645#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)                         \
646          case WireFormatLite::CPPTYPE_##UPPERCASE:                          \
647            Set##CAMELCASE(iter->first, other_extension.type,                \
648                           other_extension.LOWERCASE##_value,                \
649                           other_extension.descriptor);                      \
650            break;
651
652          HANDLE_TYPE( INT32,  int32,  Int32);
653          HANDLE_TYPE( INT64,  int64,  Int64);
654          HANDLE_TYPE(UINT32, uint32, UInt32);
655          HANDLE_TYPE(UINT64, uint64, UInt64);
656          HANDLE_TYPE( FLOAT,  float,  Float);
657          HANDLE_TYPE(DOUBLE, double, Double);
658          HANDLE_TYPE(  BOOL,   bool,   Bool);
659          HANDLE_TYPE(  ENUM,   enum,   Enum);
660#undef HANDLE_TYPE
661          case WireFormatLite::CPPTYPE_STRING:
662            SetString(iter->first, other_extension.type,
663                      *other_extension.string_value,
664                      other_extension.descriptor);
665            break;
666          case WireFormatLite::CPPTYPE_MESSAGE:
667            MutableMessage(iter->first, other_extension.type,
668                           *other_extension.message_value,
669                           other_extension.descriptor)
670              ->CheckTypeAndMergeFrom(*other_extension.message_value);
671            break;
672        }
673      }
674    }
675  }
676}
677
678void ExtensionSet::Swap(ExtensionSet* x) {
679  extensions_.swap(x->extensions_);
680}
681
682bool ExtensionSet::IsInitialized() const {
683  // Extensions are never required.  However, we need to check that all
684  // embedded messages are initialized.
685  for (map<int, Extension>::const_iterator iter = extensions_.begin();
686       iter != extensions_.end(); ++iter) {
687    const Extension& extension = iter->second;
688    if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
689      if (extension.is_repeated) {
690        for (int i = 0; i < extension.repeated_message_value->size(); i++) {
691          if (!extension.repeated_message_value->Get(i).IsInitialized()) {
692            return false;
693          }
694        }
695      } else {
696        if (!extension.is_cleared) {
697          if (!extension.message_value->IsInitialized()) return false;
698        }
699      }
700    }
701  }
702
703  return true;
704}
705
706bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
707                              ExtensionFinder* extension_finder,
708                              FieldSkipper* field_skipper) {
709  int number = WireFormatLite::GetTagFieldNumber(tag);
710  WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
711
712  ExtensionInfo extension;
713  bool is_unknown;
714  if (!extension_finder->Find(number, &extension)) {
715    is_unknown = true;
716  } else if (extension.is_packed) {
717    is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
718  } else {
719    WireFormatLite::WireType expected_wire_type =
720        WireFormatLite::WireTypeForFieldType(real_type(extension.type));
721    is_unknown = (wire_type != expected_wire_type);
722  }
723
724  if (is_unknown) {
725    field_skipper->SkipField(input, tag);
726  } else if (extension.is_packed) {
727    uint32 size;
728    if (!input->ReadVarint32(&size)) return false;
729    io::CodedInputStream::Limit limit = input->PushLimit(size);
730
731    switch (extension.type) {
732#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)        \
733      case WireFormatLite::TYPE_##UPPERCASE:                                   \
734        while (input->BytesUntilLimit() > 0) {                                 \
735          CPP_LOWERCASE value;                                                 \
736          if (!WireFormatLite::ReadPrimitive<                                  \
737                  CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(            \
738                input, &value)) return false;                                  \
739          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
740                             true, value, extension.descriptor);               \
741        }                                                                      \
742        break
743
744      HANDLE_TYPE(   INT32,  Int32,   int32);
745      HANDLE_TYPE(   INT64,  Int64,   int64);
746      HANDLE_TYPE(  UINT32, UInt32,  uint32);
747      HANDLE_TYPE(  UINT64, UInt64,  uint64);
748      HANDLE_TYPE(  SINT32,  Int32,   int32);
749      HANDLE_TYPE(  SINT64,  Int64,   int64);
750      HANDLE_TYPE( FIXED32, UInt32,  uint32);
751      HANDLE_TYPE( FIXED64, UInt64,  uint64);
752      HANDLE_TYPE(SFIXED32,  Int32,   int32);
753      HANDLE_TYPE(SFIXED64,  Int64,   int64);
754      HANDLE_TYPE(   FLOAT,  Float,   float);
755      HANDLE_TYPE(  DOUBLE, Double,  double);
756      HANDLE_TYPE(    BOOL,   Bool,    bool);
757#undef HANDLE_TYPE
758
759      case WireFormatLite::TYPE_ENUM:
760        while (input->BytesUntilLimit() > 0) {
761          int value;
762          if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
763                  input, &value)) return false;
764          if (extension.enum_validity_check.func(
765                  extension.enum_validity_check.arg, value)) {
766            AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
767                    extension.descriptor);
768          }
769        }
770        break;
771
772      case WireFormatLite::TYPE_STRING:
773      case WireFormatLite::TYPE_BYTES:
774      case WireFormatLite::TYPE_GROUP:
775      case WireFormatLite::TYPE_MESSAGE:
776        GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
777        break;
778    }
779
780    input->PopLimit(limit);
781  } else {
782    switch (extension.type) {
783#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                   \
784      case WireFormatLite::TYPE_##UPPERCASE: {                                 \
785        CPP_LOWERCASE value;                                                   \
786        if (!WireFormatLite::ReadPrimitive<                                    \
787                CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(              \
788               input, &value)) return false;                                   \
789        if (extension.is_repeated) {                                          \
790          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
791                             false, value, extension.descriptor);              \
792        } else {                                                               \
793          Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
794                             extension.descriptor);                            \
795        }                                                                      \
796      } break
797
798      HANDLE_TYPE(   INT32,  Int32,   int32);
799      HANDLE_TYPE(   INT64,  Int64,   int64);
800      HANDLE_TYPE(  UINT32, UInt32,  uint32);
801      HANDLE_TYPE(  UINT64, UInt64,  uint64);
802      HANDLE_TYPE(  SINT32,  Int32,   int32);
803      HANDLE_TYPE(  SINT64,  Int64,   int64);
804      HANDLE_TYPE( FIXED32, UInt32,  uint32);
805      HANDLE_TYPE( FIXED64, UInt64,  uint64);
806      HANDLE_TYPE(SFIXED32,  Int32,   int32);
807      HANDLE_TYPE(SFIXED64,  Int64,   int64);
808      HANDLE_TYPE(   FLOAT,  Float,   float);
809      HANDLE_TYPE(  DOUBLE, Double,  double);
810      HANDLE_TYPE(    BOOL,   Bool,    bool);
811#undef HANDLE_TYPE
812
813      case WireFormatLite::TYPE_ENUM: {
814        int value;
815        if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
816                input, &value)) return false;
817
818        if (!extension.enum_validity_check.func(
819                extension.enum_validity_check.arg, value)) {
820          // Invalid value.  Treat as unknown.
821          field_skipper->SkipUnknownEnum(number, value);
822        } else if (extension.is_repeated) {
823          AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
824                  extension.descriptor);
825        } else {
826          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
827                  extension.descriptor);
828        }
829        break;
830      }
831
832      case WireFormatLite::TYPE_STRING:  {
833        string* value = extension.is_repeated ?
834          AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
835          MutableString(number, WireFormatLite::TYPE_STRING,
836                        extension.descriptor);
837        if (!WireFormatLite::ReadString(input, value)) return false;
838        break;
839      }
840
841      case WireFormatLite::TYPE_BYTES:  {
842        string* value = extension.is_repeated ?
843          AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
844          MutableString(number, WireFormatLite::TYPE_STRING,
845                        extension.descriptor);
846        if (!WireFormatLite::ReadBytes(input, value)) return false;
847        break;
848      }
849
850      case WireFormatLite::TYPE_GROUP: {
851        MessageLite* value = extension.is_repeated ?
852            AddMessage(number, WireFormatLite::TYPE_GROUP,
853                       *extension.message_prototype, extension.descriptor) :
854            MutableMessage(number, WireFormatLite::TYPE_GROUP,
855                           *extension.message_prototype, extension.descriptor);
856        if (!WireFormatLite::ReadGroup(number, input, value)) return false;
857        break;
858      }
859
860      case WireFormatLite::TYPE_MESSAGE: {
861        MessageLite* value = extension.is_repeated ?
862            AddMessage(number, WireFormatLite::TYPE_MESSAGE,
863                       *extension.message_prototype, extension.descriptor) :
864            MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
865                           *extension.message_prototype, extension.descriptor);
866        if (!WireFormatLite::ReadMessage(input, value)) return false;
867        break;
868      }
869    }
870  }
871
872  return true;
873}
874
875bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
876                              const MessageLite* containing_type) {
877  FieldSkipper skipper;
878  GeneratedExtensionFinder finder(containing_type);
879  return ParseField(tag, input, &finder, &skipper);
880}
881
882// Defined in extension_set_heavy.cc.
883// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
884//                               const MessageLite* containing_type,
885//                               UnknownFieldSet* unknown_fields)
886
887bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
888                                   ExtensionFinder* extension_finder,
889                                   FieldSkipper* field_skipper) {
890  while (true) {
891    uint32 tag = input->ReadTag();
892    switch (tag) {
893      case 0:
894        return true;
895      case WireFormatLite::kMessageSetItemStartTag:
896        if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
897          return false;
898        }
899        break;
900      default:
901        if (!ParseField(tag, input, extension_finder, field_skipper)) {
902          return false;
903        }
904        break;
905    }
906  }
907}
908
909bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
910                                   const MessageLite* containing_type) {
911  FieldSkipper skipper;
912  GeneratedExtensionFinder finder(containing_type);
913  return ParseMessageSet(input, &finder, &skipper);
914}
915
916// Defined in extension_set_heavy.cc.
917// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
918//                                    const MessageLite* containing_type,
919//                                    UnknownFieldSet* unknown_fields);
920
921bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
922                                       ExtensionFinder* extension_finder,
923                                       FieldSkipper* field_skipper) {
924  // TODO(kenton):  It would be nice to share code between this and
925  // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
926  // differences would be hard to factor out.
927
928  // This method parses a group which should contain two fields:
929  //   required int32 type_id = 2;
930  //   required data message = 3;
931
932  // Once we see a type_id, we'll construct a fake tag for this extension
933  // which is the tag it would have had under the proto2 extensions wire
934  // format.
935  uint32 fake_tag = 0;
936
937  // If we see message data before the type_id, we'll append it to this so
938  // we can parse it later.  This will probably never happen in practice,
939  // as no MessageSet encoder I know of writes the message before the type ID.
940  // But, it's technically valid so we should allow it.
941  // TODO(kenton):  Use a Cord instead?  Do I care?
942  string message_data;
943
944  while (true) {
945    uint32 tag = input->ReadTag();
946    if (tag == 0) return false;
947
948    switch (tag) {
949      case WireFormatLite::kMessageSetTypeIdTag: {
950        uint32 type_id;
951        if (!input->ReadVarint32(&type_id)) return false;
952        fake_tag = WireFormatLite::MakeTag(type_id,
953            WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
954
955        if (!message_data.empty()) {
956          // We saw some message data before the type_id.  Have to parse it
957          // now.
958          io::CodedInputStream sub_input(
959              reinterpret_cast<const uint8*>(message_data.data()),
960              message_data.size());
961          if (!ParseField(fake_tag, &sub_input,
962                          extension_finder, field_skipper)) {
963            return false;
964          }
965          message_data.clear();
966        }
967
968        break;
969      }
970
971      case WireFormatLite::kMessageSetMessageTag: {
972        if (fake_tag == 0) {
973          // We haven't seen a type_id yet.  Append this data to message_data.
974          string temp;
975          uint32 length;
976          if (!input->ReadVarint32(&length)) return false;
977          if (!input->ReadString(&temp, length)) return false;
978          message_data.append(temp);
979        } else {
980          // Already saw type_id, so we can parse this directly.
981          if (!ParseField(fake_tag, input,
982                          extension_finder, field_skipper)) {
983            return false;
984          }
985        }
986
987        break;
988      }
989
990      case WireFormatLite::kMessageSetItemEndTag: {
991        return true;
992      }
993
994      default: {
995        if (!field_skipper->SkipField(input, tag)) return false;
996      }
997    }
998  }
999}
1000
1001void ExtensionSet::SerializeWithCachedSizes(
1002    int start_field_number, int end_field_number,
1003    io::CodedOutputStream* output) const {
1004  map<int, Extension>::const_iterator iter;
1005  for (iter = extensions_.lower_bound(start_field_number);
1006       iter != extensions_.end() && iter->first < end_field_number;
1007       ++iter) {
1008    iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1009  }
1010}
1011
1012void ExtensionSet::SerializeMessageSetWithCachedSizes(
1013    io::CodedOutputStream* output) const {
1014  map<int, Extension>::const_iterator iter;
1015  for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
1016    iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
1017  }
1018}
1019
1020int ExtensionSet::ByteSize() const {
1021  int total_size = 0;
1022
1023  for (map<int, Extension>::const_iterator iter = extensions_.begin();
1024       iter != extensions_.end(); ++iter) {
1025    total_size += iter->second.ByteSize(iter->first);
1026  }
1027
1028  return total_size;
1029}
1030
1031int ExtensionSet::MessageSetByteSize() const {
1032  int total_size = 0;
1033
1034  for (map<int, Extension>::const_iterator iter = extensions_.begin();
1035       iter != extensions_.end(); ++iter) {
1036    total_size += iter->second.MessageSetItemByteSize(iter->first);
1037  }
1038
1039  return total_size;
1040}
1041
1042// Defined in extension_set_heavy.cc.
1043// int ExtensionSet::SpaceUsedExcludingSelf() const
1044
1045bool ExtensionSet::MaybeNewExtension(int number,
1046                                     const FieldDescriptor* descriptor,
1047                                     Extension** result) {
1048  pair<map<int, Extension>::iterator, bool> insert_result =
1049      extensions_.insert(make_pair(number, Extension()));
1050  *result = &insert_result.first->second;
1051  (*result)->descriptor = descriptor;
1052  return insert_result.second;
1053}
1054
1055// ===================================================================
1056// Methods of ExtensionSet::Extension
1057
1058void ExtensionSet::Extension::Clear() {
1059  if (is_repeated) {
1060    switch (cpp_type(type)) {
1061#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1062      case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1063        repeated_##LOWERCASE##_value->Clear();                     \
1064        break
1065
1066      HANDLE_TYPE(  INT32,   int32);
1067      HANDLE_TYPE(  INT64,   int64);
1068      HANDLE_TYPE( UINT32,  uint32);
1069      HANDLE_TYPE( UINT64,  uint64);
1070      HANDLE_TYPE(  FLOAT,   float);
1071      HANDLE_TYPE( DOUBLE,  double);
1072      HANDLE_TYPE(   BOOL,    bool);
1073      HANDLE_TYPE(   ENUM,    enum);
1074      HANDLE_TYPE( STRING,  string);
1075      HANDLE_TYPE(MESSAGE, message);
1076#undef HANDLE_TYPE
1077    }
1078  } else {
1079    if (!is_cleared) {
1080      switch (cpp_type(type)) {
1081        case WireFormatLite::CPPTYPE_STRING:
1082          string_value->clear();
1083          break;
1084        case WireFormatLite::CPPTYPE_MESSAGE:
1085          message_value->Clear();
1086          break;
1087        default:
1088          // No need to do anything.  Get*() will return the default value
1089          // as long as is_cleared is true and Set*() will overwrite the
1090          // previous value.
1091          break;
1092      }
1093
1094      is_cleared = true;
1095    }
1096  }
1097}
1098
1099void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1100    int number,
1101    io::CodedOutputStream* output) const {
1102  if (is_repeated) {
1103    if (is_packed) {
1104      if (cached_size == 0) return;
1105
1106      WireFormatLite::WriteTag(number,
1107          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1108      output->WriteVarint32(cached_size);
1109
1110      switch (real_type(type)) {
1111#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1112        case WireFormatLite::TYPE_##UPPERCASE:                              \
1113          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1114            WireFormatLite::Write##CAMELCASE##NoTag(                        \
1115              repeated_##LOWERCASE##_value->Get(i), output);                \
1116          }                                                                 \
1117          break
1118
1119        HANDLE_TYPE(   INT32,    Int32,   int32);
1120        HANDLE_TYPE(   INT64,    Int64,   int64);
1121        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1122        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1123        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1124        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1125        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1126        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1127        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1128        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1129        HANDLE_TYPE(   FLOAT,    Float,   float);
1130        HANDLE_TYPE(  DOUBLE,   Double,  double);
1131        HANDLE_TYPE(    BOOL,     Bool,    bool);
1132        HANDLE_TYPE(    ENUM,     Enum,    enum);
1133#undef HANDLE_TYPE
1134
1135        case WireFormatLite::TYPE_STRING:
1136        case WireFormatLite::TYPE_BYTES:
1137        case WireFormatLite::TYPE_GROUP:
1138        case WireFormatLite::TYPE_MESSAGE:
1139          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1140          break;
1141      }
1142    } else {
1143      switch (real_type(type)) {
1144#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1145        case WireFormatLite::TYPE_##UPPERCASE:                              \
1146          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1147            WireFormatLite::Write##CAMELCASE(number,                        \
1148              repeated_##LOWERCASE##_value->Get(i), output);                \
1149          }                                                                 \
1150          break
1151
1152        HANDLE_TYPE(   INT32,    Int32,   int32);
1153        HANDLE_TYPE(   INT64,    Int64,   int64);
1154        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1155        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1156        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1157        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1158        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1159        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1160        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1161        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1162        HANDLE_TYPE(   FLOAT,    Float,   float);
1163        HANDLE_TYPE(  DOUBLE,   Double,  double);
1164        HANDLE_TYPE(    BOOL,     Bool,    bool);
1165        HANDLE_TYPE(  STRING,   String,  string);
1166        HANDLE_TYPE(   BYTES,    Bytes,  string);
1167        HANDLE_TYPE(    ENUM,     Enum,    enum);
1168        HANDLE_TYPE(   GROUP,    Group, message);
1169        HANDLE_TYPE( MESSAGE,  Message, message);
1170#undef HANDLE_TYPE
1171      }
1172    }
1173  } else if (!is_cleared) {
1174    switch (real_type(type)) {
1175#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
1176      case WireFormatLite::TYPE_##UPPERCASE:                     \
1177        WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1178        break
1179
1180      HANDLE_TYPE(   INT32,    Int32,    int32_value);
1181      HANDLE_TYPE(   INT64,    Int64,    int64_value);
1182      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1183      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1184      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1185      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1186      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
1187      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
1188      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
1189      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
1190      HANDLE_TYPE(   FLOAT,    Float,    float_value);
1191      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
1192      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
1193      HANDLE_TYPE(  STRING,   String,  *string_value);
1194      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1195      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1196      HANDLE_TYPE(   GROUP,    Group, *message_value);
1197      HANDLE_TYPE( MESSAGE,  Message, *message_value);
1198#undef HANDLE_TYPE
1199    }
1200  }
1201}
1202
1203void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
1204    int number,
1205    io::CodedOutputStream* output) const {
1206  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1207    // Not a valid MessageSet extension, but serialize it the normal way.
1208    SerializeFieldWithCachedSizes(number, output);
1209    return;
1210  }
1211
1212  if (is_cleared) return;
1213
1214  // Start group.
1215  output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
1216
1217  // Write type ID.
1218  WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
1219                              number,
1220                              output);
1221  // Write message.
1222  WireFormatLite::WriteMessageMaybeToArray(
1223      WireFormatLite::kMessageSetMessageNumber,
1224      *message_value,
1225      output);
1226
1227  // End group.
1228  output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
1229}
1230
1231int ExtensionSet::Extension::ByteSize(int number) const {
1232  int result = 0;
1233
1234  if (is_repeated) {
1235    if (is_packed) {
1236      switch (real_type(type)) {
1237#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1238        case WireFormatLite::TYPE_##UPPERCASE:                              \
1239          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1240            result += WireFormatLite::CAMELCASE##Size(                      \
1241              repeated_##LOWERCASE##_value->Get(i));                        \
1242          }                                                                 \
1243          break
1244
1245        HANDLE_TYPE(   INT32,    Int32,   int32);
1246        HANDLE_TYPE(   INT64,    Int64,   int64);
1247        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1248        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1249        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1250        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1251        HANDLE_TYPE(    ENUM,     Enum,    enum);
1252#undef HANDLE_TYPE
1253
1254        // Stuff with fixed size.
1255#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1256        case WireFormatLite::TYPE_##UPPERCASE:                              \
1257          result += WireFormatLite::k##CAMELCASE##Size *                    \
1258                    repeated_##LOWERCASE##_value->size();                   \
1259          break
1260        HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1261        HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1262        HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1263        HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1264        HANDLE_TYPE(   FLOAT,    Float,  float);
1265        HANDLE_TYPE(  DOUBLE,   Double, double);
1266        HANDLE_TYPE(    BOOL,     Bool,   bool);
1267#undef HANDLE_TYPE
1268
1269        case WireFormatLite::TYPE_STRING:
1270        case WireFormatLite::TYPE_BYTES:
1271        case WireFormatLite::TYPE_GROUP:
1272        case WireFormatLite::TYPE_MESSAGE:
1273          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1274          break;
1275      }
1276
1277      cached_size = result;
1278      if (result > 0) {
1279        result += io::CodedOutputStream::VarintSize32(result);
1280        result += io::CodedOutputStream::VarintSize32(
1281            WireFormatLite::MakeTag(number,
1282                WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1283      }
1284    } else {
1285      int tag_size = WireFormatLite::TagSize(number, real_type(type));
1286
1287      switch (real_type(type)) {
1288#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1289        case WireFormatLite::TYPE_##UPPERCASE:                              \
1290          result += tag_size * repeated_##LOWERCASE##_value->size();        \
1291          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1292            result += WireFormatLite::CAMELCASE##Size(                      \
1293              repeated_##LOWERCASE##_value->Get(i));                        \
1294          }                                                                 \
1295          break
1296
1297        HANDLE_TYPE(   INT32,    Int32,   int32);
1298        HANDLE_TYPE(   INT64,    Int64,   int64);
1299        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1300        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1301        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1302        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1303        HANDLE_TYPE(  STRING,   String,  string);
1304        HANDLE_TYPE(   BYTES,    Bytes,  string);
1305        HANDLE_TYPE(    ENUM,     Enum,    enum);
1306        HANDLE_TYPE(   GROUP,    Group, message);
1307        HANDLE_TYPE( MESSAGE,  Message, message);
1308#undef HANDLE_TYPE
1309
1310        // Stuff with fixed size.
1311#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1312        case WireFormatLite::TYPE_##UPPERCASE:                              \
1313          result += (tag_size + WireFormatLite::k##CAMELCASE##Size) *       \
1314                    repeated_##LOWERCASE##_value->size();                   \
1315          break
1316        HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1317        HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1318        HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1319        HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1320        HANDLE_TYPE(   FLOAT,    Float,  float);
1321        HANDLE_TYPE(  DOUBLE,   Double, double);
1322        HANDLE_TYPE(    BOOL,     Bool,   bool);
1323#undef HANDLE_TYPE
1324      }
1325    }
1326  } else if (!is_cleared) {
1327    result += WireFormatLite::TagSize(number, real_type(type));
1328    switch (real_type(type)) {
1329#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                      \
1330      case WireFormatLite::TYPE_##UPPERCASE:                              \
1331        result += WireFormatLite::CAMELCASE##Size(LOWERCASE);             \
1332        break
1333
1334      HANDLE_TYPE(   INT32,    Int32,    int32_value);
1335      HANDLE_TYPE(   INT64,    Int64,    int64_value);
1336      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1337      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1338      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1339      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1340      HANDLE_TYPE(  STRING,   String,  *string_value);
1341      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1342      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1343      HANDLE_TYPE(   GROUP,    Group, *message_value);
1344      HANDLE_TYPE( MESSAGE,  Message, *message_value);
1345#undef HANDLE_TYPE
1346
1347      // Stuff with fixed size.
1348#define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
1349      case WireFormatLite::TYPE_##UPPERCASE:                              \
1350        result += WireFormatLite::k##CAMELCASE##Size;                     \
1351        break
1352      HANDLE_TYPE( FIXED32,  Fixed32);
1353      HANDLE_TYPE( FIXED64,  Fixed64);
1354      HANDLE_TYPE(SFIXED32, SFixed32);
1355      HANDLE_TYPE(SFIXED64, SFixed64);
1356      HANDLE_TYPE(   FLOAT,    Float);
1357      HANDLE_TYPE(  DOUBLE,   Double);
1358      HANDLE_TYPE(    BOOL,     Bool);
1359#undef HANDLE_TYPE
1360    }
1361  }
1362
1363  return result;
1364}
1365
1366int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
1367  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1368    // Not a valid MessageSet extension, but compute the byte size for it the
1369    // normal way.
1370    return ByteSize(number);
1371  }
1372
1373  if (is_cleared) return 0;
1374
1375  int our_size = WireFormatLite::kMessageSetItemTagsSize;
1376
1377  // type_id
1378  our_size += io::CodedOutputStream::VarintSize32(number);
1379
1380  // message
1381  int message_size = message_value->ByteSize();
1382
1383  our_size += io::CodedOutputStream::VarintSize32(message_size);
1384  our_size += message_size;
1385
1386  return our_size;
1387}
1388
1389int ExtensionSet::Extension::GetSize() const {
1390  GOOGLE_DCHECK(is_repeated);
1391  switch (cpp_type(type)) {
1392#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                        \
1393    case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1394      return repeated_##LOWERCASE##_value->size()
1395
1396    HANDLE_TYPE(  INT32,   int32);
1397    HANDLE_TYPE(  INT64,   int64);
1398    HANDLE_TYPE( UINT32,  uint32);
1399    HANDLE_TYPE( UINT64,  uint64);
1400    HANDLE_TYPE(  FLOAT,   float);
1401    HANDLE_TYPE( DOUBLE,  double);
1402    HANDLE_TYPE(   BOOL,    bool);
1403    HANDLE_TYPE(   ENUM,    enum);
1404    HANDLE_TYPE( STRING,  string);
1405    HANDLE_TYPE(MESSAGE, message);
1406#undef HANDLE_TYPE
1407  }
1408
1409  GOOGLE_LOG(FATAL) << "Can't get here.";
1410  return 0;
1411}
1412
1413void ExtensionSet::Extension::Free() {
1414  if (is_repeated) {
1415    switch (cpp_type(type)) {
1416#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1417      case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1418        delete repeated_##LOWERCASE##_value;                       \
1419        break
1420
1421      HANDLE_TYPE(  INT32,   int32);
1422      HANDLE_TYPE(  INT64,   int64);
1423      HANDLE_TYPE( UINT32,  uint32);
1424      HANDLE_TYPE( UINT64,  uint64);
1425      HANDLE_TYPE(  FLOAT,   float);
1426      HANDLE_TYPE( DOUBLE,  double);
1427      HANDLE_TYPE(   BOOL,    bool);
1428      HANDLE_TYPE(   ENUM,    enum);
1429      HANDLE_TYPE( STRING,  string);
1430      HANDLE_TYPE(MESSAGE, message);
1431#undef HANDLE_TYPE
1432    }
1433  } else {
1434    switch (cpp_type(type)) {
1435      case WireFormatLite::CPPTYPE_STRING:
1436        delete string_value;
1437        break;
1438      case WireFormatLite::CPPTYPE_MESSAGE:
1439        delete message_value;
1440        break;
1441      default:
1442        break;
1443    }
1444  }
1445}
1446
1447// Defined in extension_set_heavy.cc.
1448// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1449
1450}  // namespace internal
1451}  // namespace protobuf
1452}  // namespace google
1453