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