extension_set.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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                              UnknownFieldSet* unknown_fields) {
890  FieldSkipper skipper(unknown_fields);
891  GeneratedExtensionFinder finder(containing_type);
892  return ParseField(tag, input, &finder, &skipper);
893}
894
895// Defined in extension_set_heavy.cc.
896// bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
897//                                    const Message* containing_type,
898//                                    UnknownFieldSet* unknown_fields)
899
900bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
901                                   ExtensionFinder* extension_finder,
902                                   FieldSkipper* field_skipper) {
903  while (true) {
904    uint32 tag = input->ReadTag();
905    switch (tag) {
906      case 0:
907        return true;
908      case WireFormatLite::kMessageSetItemStartTag:
909        if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
910          return false;
911        }
912        break;
913      default:
914        if (!ParseField(tag, input, extension_finder, field_skipper)) {
915          return false;
916        }
917        break;
918    }
919  }
920}
921
922bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
923                                   const MessageLite* containing_type,
924                                   UnknownFieldSet* unknown_fields) {
925  FieldSkipper skipper(unknown_fields);
926  GeneratedExtensionFinder finder(containing_type);
927  return ParseMessageSet(input, &finder, &skipper);
928}
929
930// Defined in extension_set_heavy.cc.
931// bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
932//                                         const Message* containing_type,
933//                                         UnknownFieldSet* unknown_fields);
934
935bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
936                                       ExtensionFinder* extension_finder,
937                                       FieldSkipper* field_skipper) {
938  // TODO(kenton):  It would be nice to share code between this and
939  // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
940  // differences would be hard to factor out.
941
942  // This method parses a group which should contain two fields:
943  //   required int32 type_id = 2;
944  //   required data message = 3;
945
946  // Once we see a type_id, we'll construct a fake tag for this extension
947  // which is the tag it would have had under the proto2 extensions wire
948  // format.
949  uint32 fake_tag = 0;
950
951  // If we see message data before the type_id, we'll append it to this so
952  // we can parse it later.  This will probably never happen in practice,
953  // as no MessageSet encoder I know of writes the message before the type ID.
954  // But, it's technically valid so we should allow it.
955  // TODO(kenton):  Use a Cord instead?  Do I care?
956  string message_data;
957
958  while (true) {
959    uint32 tag = input->ReadTag();
960    if (tag == 0) return false;
961
962    switch (tag) {
963      case WireFormatLite::kMessageSetTypeIdTag: {
964        uint32 type_id;
965        if (!input->ReadVarint32(&type_id)) return false;
966        fake_tag = WireFormatLite::MakeTag(type_id,
967            WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
968
969        if (!message_data.empty()) {
970          // We saw some message data before the type_id.  Have to parse it
971          // now.
972          io::CodedInputStream sub_input(
973              reinterpret_cast<const uint8*>(message_data.data()),
974              message_data.size());
975          if (!ParseField(fake_tag, &sub_input,
976                          extension_finder, field_skipper)) {
977            return false;
978          }
979          message_data.clear();
980        }
981
982        break;
983      }
984
985      case WireFormatLite::kMessageSetMessageTag: {
986        if (fake_tag == 0) {
987          // We haven't seen a type_id yet.  Append this data to message_data.
988          string temp;
989          uint32 length;
990          if (!input->ReadVarint32(&length)) return false;
991          if (!input->ReadString(&temp, length)) return false;
992          message_data.append(temp);
993        } else {
994          // Already saw type_id, so we can parse this directly.
995          if (!ParseField(fake_tag, input,
996                          extension_finder, field_skipper)) {
997            return false;
998          }
999        }
1000
1001        break;
1002      }
1003
1004      case WireFormatLite::kMessageSetItemEndTag: {
1005        return true;
1006      }
1007
1008      default: {
1009        if (!field_skipper->SkipField(input, tag)) return false;
1010      }
1011    }
1012  }
1013}
1014
1015void ExtensionSet::SerializeWithCachedSizes(
1016    int start_field_number, int end_field_number,
1017    io::CodedOutputStream* output) const {
1018  map<int, Extension>::const_iterator iter;
1019  for (iter = extensions_.lower_bound(start_field_number);
1020       iter != extensions_.end() && iter->first < end_field_number;
1021       ++iter) {
1022    iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1023  }
1024}
1025
1026void ExtensionSet::SerializeMessageSetWithCachedSizes(
1027    io::CodedOutputStream* output) const {
1028  map<int, Extension>::const_iterator iter;
1029  for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
1030    iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
1031  }
1032}
1033
1034int ExtensionSet::ByteSize() const {
1035  int total_size = 0;
1036
1037  for (map<int, Extension>::const_iterator iter = extensions_.begin();
1038       iter != extensions_.end(); ++iter) {
1039    total_size += iter->second.ByteSize(iter->first);
1040  }
1041
1042  return total_size;
1043}
1044
1045int ExtensionSet::MessageSetByteSize() const {
1046  int total_size = 0;
1047
1048  for (map<int, Extension>::const_iterator iter = extensions_.begin();
1049       iter != extensions_.end(); ++iter) {
1050    total_size += iter->second.MessageSetItemByteSize(iter->first);
1051  }
1052
1053  return total_size;
1054}
1055
1056// Defined in extension_set_heavy.cc.
1057// int ExtensionSet::SpaceUsedExcludingSelf() const
1058
1059bool ExtensionSet::MaybeNewExtension(int number,
1060                                     const FieldDescriptor* descriptor,
1061                                     Extension** result) {
1062  pair<map<int, Extension>::iterator, bool> insert_result =
1063      extensions_.insert(make_pair(number, Extension()));
1064  *result = &insert_result.first->second;
1065  (*result)->descriptor = descriptor;
1066  return insert_result.second;
1067}
1068
1069// ===================================================================
1070// Methods of ExtensionSet::Extension
1071
1072void ExtensionSet::Extension::Clear() {
1073  if (is_repeated) {
1074    switch (cpp_type(type)) {
1075#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1076      case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1077        repeated_##LOWERCASE##_value->Clear();                     \
1078        break
1079
1080      HANDLE_TYPE(  INT32,   int32);
1081      HANDLE_TYPE(  INT64,   int64);
1082      HANDLE_TYPE( UINT32,  uint32);
1083      HANDLE_TYPE( UINT64,  uint64);
1084      HANDLE_TYPE(  FLOAT,   float);
1085      HANDLE_TYPE( DOUBLE,  double);
1086      HANDLE_TYPE(   BOOL,    bool);
1087      HANDLE_TYPE(   ENUM,    enum);
1088      HANDLE_TYPE( STRING,  string);
1089      HANDLE_TYPE(MESSAGE, message);
1090#undef HANDLE_TYPE
1091    }
1092  } else {
1093    if (!is_cleared) {
1094      switch (cpp_type(type)) {
1095        case WireFormatLite::CPPTYPE_STRING:
1096          string_value->clear();
1097          break;
1098        case WireFormatLite::CPPTYPE_MESSAGE:
1099          message_value->Clear();
1100          break;
1101        default:
1102          // No need to do anything.  Get*() will return the default value
1103          // as long as is_cleared is true and Set*() will overwrite the
1104          // previous value.
1105          break;
1106      }
1107
1108      is_cleared = true;
1109    }
1110  }
1111}
1112
1113void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1114    int number,
1115    io::CodedOutputStream* output) const {
1116  if (is_repeated) {
1117    if (is_packed) {
1118      if (cached_size == 0) return;
1119
1120      WireFormatLite::WriteTag(number,
1121          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1122      output->WriteVarint32(cached_size);
1123
1124      switch (real_type(type)) {
1125#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1126        case WireFormatLite::TYPE_##UPPERCASE:                              \
1127          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1128            WireFormatLite::Write##CAMELCASE##NoTag(                        \
1129              repeated_##LOWERCASE##_value->Get(i), output);                \
1130          }                                                                 \
1131          break
1132
1133        HANDLE_TYPE(   INT32,    Int32,   int32);
1134        HANDLE_TYPE(   INT64,    Int64,   int64);
1135        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1136        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1137        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1138        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1139        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1140        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1141        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1142        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1143        HANDLE_TYPE(   FLOAT,    Float,   float);
1144        HANDLE_TYPE(  DOUBLE,   Double,  double);
1145        HANDLE_TYPE(    BOOL,     Bool,    bool);
1146        HANDLE_TYPE(    ENUM,     Enum,    enum);
1147#undef HANDLE_TYPE
1148
1149        case WireFormatLite::TYPE_STRING:
1150        case WireFormatLite::TYPE_BYTES:
1151        case WireFormatLite::TYPE_GROUP:
1152        case WireFormatLite::TYPE_MESSAGE:
1153          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1154          break;
1155      }
1156    } else {
1157      switch (real_type(type)) {
1158#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1159        case WireFormatLite::TYPE_##UPPERCASE:                              \
1160          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1161            WireFormatLite::Write##CAMELCASE(number,                        \
1162              repeated_##LOWERCASE##_value->Get(i), output);                \
1163          }                                                                 \
1164          break
1165
1166        HANDLE_TYPE(   INT32,    Int32,   int32);
1167        HANDLE_TYPE(   INT64,    Int64,   int64);
1168        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1169        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1170        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1171        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1172        HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
1173        HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
1174        HANDLE_TYPE(SFIXED32, SFixed32,   int32);
1175        HANDLE_TYPE(SFIXED64, SFixed64,   int64);
1176        HANDLE_TYPE(   FLOAT,    Float,   float);
1177        HANDLE_TYPE(  DOUBLE,   Double,  double);
1178        HANDLE_TYPE(    BOOL,     Bool,    bool);
1179        HANDLE_TYPE(  STRING,   String,  string);
1180        HANDLE_TYPE(   BYTES,    Bytes,  string);
1181        HANDLE_TYPE(    ENUM,     Enum,    enum);
1182        HANDLE_TYPE(   GROUP,    Group, message);
1183        HANDLE_TYPE( MESSAGE,  Message, message);
1184#undef HANDLE_TYPE
1185      }
1186    }
1187  } else if (!is_cleared) {
1188    switch (real_type(type)) {
1189#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
1190      case WireFormatLite::TYPE_##UPPERCASE:                     \
1191        WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1192        break
1193
1194      HANDLE_TYPE(   INT32,    Int32,    int32_value);
1195      HANDLE_TYPE(   INT64,    Int64,    int64_value);
1196      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1197      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1198      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1199      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1200      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
1201      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
1202      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
1203      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
1204      HANDLE_TYPE(   FLOAT,    Float,    float_value);
1205      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
1206      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
1207      HANDLE_TYPE(  STRING,   String,  *string_value);
1208      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1209      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1210      HANDLE_TYPE(   GROUP,    Group, *message_value);
1211      HANDLE_TYPE( MESSAGE,  Message, *message_value);
1212#undef HANDLE_TYPE
1213    }
1214  }
1215}
1216
1217void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
1218    int number,
1219    io::CodedOutputStream* output) const {
1220  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1221    // Not a valid MessageSet extension, but serialize it the normal way.
1222    SerializeFieldWithCachedSizes(number, output);
1223    return;
1224  }
1225
1226  if (is_cleared) return;
1227
1228  // Start group.
1229  output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
1230
1231  // Write type ID.
1232  WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
1233                              number,
1234                              output);
1235  // Write message.
1236  WireFormatLite::WriteMessageMaybeToArray(
1237      WireFormatLite::kMessageSetMessageNumber,
1238      *message_value,
1239      output);
1240
1241  // End group.
1242  output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
1243}
1244
1245int ExtensionSet::Extension::ByteSize(int number) const {
1246  int result = 0;
1247
1248  if (is_repeated) {
1249    if (is_packed) {
1250      switch (real_type(type)) {
1251#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1252        case WireFormatLite::TYPE_##UPPERCASE:                              \
1253          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1254            result += WireFormatLite::CAMELCASE##Size(                      \
1255              repeated_##LOWERCASE##_value->Get(i));                        \
1256          }                                                                 \
1257          break
1258
1259        HANDLE_TYPE(   INT32,    Int32,   int32);
1260        HANDLE_TYPE(   INT64,    Int64,   int64);
1261        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1262        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1263        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1264        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1265        HANDLE_TYPE(    ENUM,     Enum,    enum);
1266#undef HANDLE_TYPE
1267
1268        // Stuff with fixed size.
1269#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1270        case WireFormatLite::TYPE_##UPPERCASE:                              \
1271          result += WireFormatLite::k##CAMELCASE##Size *                    \
1272                    repeated_##LOWERCASE##_value->size();                   \
1273          break
1274        HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1275        HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1276        HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1277        HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1278        HANDLE_TYPE(   FLOAT,    Float,  float);
1279        HANDLE_TYPE(  DOUBLE,   Double, double);
1280        HANDLE_TYPE(    BOOL,     Bool,   bool);
1281#undef HANDLE_TYPE
1282
1283        case WireFormatLite::TYPE_STRING:
1284        case WireFormatLite::TYPE_BYTES:
1285        case WireFormatLite::TYPE_GROUP:
1286        case WireFormatLite::TYPE_MESSAGE:
1287          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1288          break;
1289      }
1290
1291      cached_size = result;
1292      if (result > 0) {
1293        result += io::CodedOutputStream::VarintSize32(result);
1294        result += io::CodedOutputStream::VarintSize32(
1295            WireFormatLite::MakeTag(number,
1296                WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1297      }
1298    } else {
1299      int tag_size = WireFormatLite::TagSize(number, real_type(type));
1300
1301      switch (real_type(type)) {
1302#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1303        case WireFormatLite::TYPE_##UPPERCASE:                              \
1304          result += tag_size * repeated_##LOWERCASE##_value->size();        \
1305          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
1306            result += WireFormatLite::CAMELCASE##Size(                      \
1307              repeated_##LOWERCASE##_value->Get(i));                        \
1308          }                                                                 \
1309          break
1310
1311        HANDLE_TYPE(   INT32,    Int32,   int32);
1312        HANDLE_TYPE(   INT64,    Int64,   int64);
1313        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
1314        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
1315        HANDLE_TYPE(  SINT32,   SInt32,   int32);
1316        HANDLE_TYPE(  SINT64,   SInt64,   int64);
1317        HANDLE_TYPE(  STRING,   String,  string);
1318        HANDLE_TYPE(   BYTES,    Bytes,  string);
1319        HANDLE_TYPE(    ENUM,     Enum,    enum);
1320        HANDLE_TYPE(   GROUP,    Group, message);
1321        HANDLE_TYPE( MESSAGE,  Message, message);
1322#undef HANDLE_TYPE
1323
1324        // Stuff with fixed size.
1325#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1326        case WireFormatLite::TYPE_##UPPERCASE:                              \
1327          result += (tag_size + WireFormatLite::k##CAMELCASE##Size) *       \
1328                    repeated_##LOWERCASE##_value->size();                   \
1329          break
1330        HANDLE_TYPE( FIXED32,  Fixed32, uint32);
1331        HANDLE_TYPE( FIXED64,  Fixed64, uint64);
1332        HANDLE_TYPE(SFIXED32, SFixed32,  int32);
1333        HANDLE_TYPE(SFIXED64, SFixed64,  int64);
1334        HANDLE_TYPE(   FLOAT,    Float,  float);
1335        HANDLE_TYPE(  DOUBLE,   Double, double);
1336        HANDLE_TYPE(    BOOL,     Bool,   bool);
1337#undef HANDLE_TYPE
1338      }
1339    }
1340  } else if (!is_cleared) {
1341    result += WireFormatLite::TagSize(number, real_type(type));
1342    switch (real_type(type)) {
1343#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                      \
1344      case WireFormatLite::TYPE_##UPPERCASE:                              \
1345        result += WireFormatLite::CAMELCASE##Size(LOWERCASE);             \
1346        break
1347
1348      HANDLE_TYPE(   INT32,    Int32,    int32_value);
1349      HANDLE_TYPE(   INT64,    Int64,    int64_value);
1350      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
1351      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
1352      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
1353      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
1354      HANDLE_TYPE(  STRING,   String,  *string_value);
1355      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
1356      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
1357      HANDLE_TYPE(   GROUP,    Group, *message_value);
1358      HANDLE_TYPE( MESSAGE,  Message, *message_value);
1359#undef HANDLE_TYPE
1360
1361      // Stuff with fixed size.
1362#define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
1363      case WireFormatLite::TYPE_##UPPERCASE:                              \
1364        result += WireFormatLite::k##CAMELCASE##Size;                     \
1365        break
1366      HANDLE_TYPE( FIXED32,  Fixed32);
1367      HANDLE_TYPE( FIXED64,  Fixed64);
1368      HANDLE_TYPE(SFIXED32, SFixed32);
1369      HANDLE_TYPE(SFIXED64, SFixed64);
1370      HANDLE_TYPE(   FLOAT,    Float);
1371      HANDLE_TYPE(  DOUBLE,   Double);
1372      HANDLE_TYPE(    BOOL,     Bool);
1373#undef HANDLE_TYPE
1374    }
1375  }
1376
1377  return result;
1378}
1379
1380int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
1381  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
1382    // Not a valid MessageSet extension, but compute the byte size for it the
1383    // normal way.
1384    return ByteSize(number);
1385  }
1386
1387  if (is_cleared) return 0;
1388
1389  int our_size = WireFormatLite::kMessageSetItemTagsSize;
1390
1391  // type_id
1392  our_size += io::CodedOutputStream::VarintSize32(number);
1393
1394  // message
1395  int message_size = message_value->ByteSize();
1396
1397  our_size += io::CodedOutputStream::VarintSize32(message_size);
1398  our_size += message_size;
1399
1400  return our_size;
1401}
1402
1403int ExtensionSet::Extension::GetSize() const {
1404  GOOGLE_DCHECK(is_repeated);
1405  switch (cpp_type(type)) {
1406#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                        \
1407    case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1408      return repeated_##LOWERCASE##_value->size()
1409
1410    HANDLE_TYPE(  INT32,   int32);
1411    HANDLE_TYPE(  INT64,   int64);
1412    HANDLE_TYPE( UINT32,  uint32);
1413    HANDLE_TYPE( UINT64,  uint64);
1414    HANDLE_TYPE(  FLOAT,   float);
1415    HANDLE_TYPE( DOUBLE,  double);
1416    HANDLE_TYPE(   BOOL,    bool);
1417    HANDLE_TYPE(   ENUM,    enum);
1418    HANDLE_TYPE( STRING,  string);
1419    HANDLE_TYPE(MESSAGE, message);
1420#undef HANDLE_TYPE
1421  }
1422
1423  GOOGLE_LOG(FATAL) << "Can't get here.";
1424  return 0;
1425}
1426
1427void ExtensionSet::Extension::Free() {
1428  if (is_repeated) {
1429    switch (cpp_type(type)) {
1430#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
1431      case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
1432        delete repeated_##LOWERCASE##_value;                       \
1433        break
1434
1435      HANDLE_TYPE(  INT32,   int32);
1436      HANDLE_TYPE(  INT64,   int64);
1437      HANDLE_TYPE( UINT32,  uint32);
1438      HANDLE_TYPE( UINT64,  uint64);
1439      HANDLE_TYPE(  FLOAT,   float);
1440      HANDLE_TYPE( DOUBLE,  double);
1441      HANDLE_TYPE(   BOOL,    bool);
1442      HANDLE_TYPE(   ENUM,    enum);
1443      HANDLE_TYPE( STRING,  string);
1444      HANDLE_TYPE(MESSAGE, message);
1445#undef HANDLE_TYPE
1446    }
1447  } else {
1448    switch (cpp_type(type)) {
1449      case WireFormatLite::CPPTYPE_STRING:
1450        delete string_value;
1451        break;
1452      case WireFormatLite::CPPTYPE_MESSAGE:
1453        delete message_value;
1454        break;
1455      default:
1456        break;
1457    }
1458  }
1459}
1460
1461// Defined in extension_set_heavy.cc.
1462// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1463
1464}  // namespace internal
1465}  // namespace protobuf
1466}  // namespace google
1467