Coverage Report

Created: 2025-11-05 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/sentencepiece/third_party/protobuf-lite/extension_set.cc
Line
Count
Source
1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.  All rights reserved.
3
// https://developers.google.com/protocol-buffers/
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/extension_set.h>
36
37
#include <tuple>
38
#include <unordered_map>
39
#include <utility>
40
#include <google/protobuf/stubs/common.h>
41
#include <google/protobuf/extension_set_inl.h>
42
#include <google/protobuf/parse_context.h>
43
#include <google/protobuf/io/coded_stream.h>
44
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
45
#include <google/protobuf/message_lite.h>
46
#include <google/protobuf/metadata_lite.h>
47
#include <google/protobuf/repeated_field.h>
48
#include <google/protobuf/stubs/map_util.h>
49
#include <google/protobuf/stubs/hash.h>
50
51
#include <google/protobuf/port_def.inc>
52
53
namespace google {
54
namespace protobuf {
55
namespace internal {
56
57
namespace {
58
59
0
inline WireFormatLite::FieldType real_type(FieldType type) {
60
0
  GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
61
0
  return static_cast<WireFormatLite::FieldType>(type);
62
0
}
63
64
0
inline WireFormatLite::CppType cpp_type(FieldType type) {
65
0
  return WireFormatLite::FieldTypeToCppType(real_type(type));
66
0
}
67
68
0
inline bool is_packable(WireFormatLite::WireType type) {
69
0
  switch (type) {
70
0
    case WireFormatLite::WIRETYPE_VARINT:
71
0
    case WireFormatLite::WIRETYPE_FIXED64:
72
0
    case WireFormatLite::WIRETYPE_FIXED32:
73
0
      return true;
74
0
    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
75
0
    case WireFormatLite::WIRETYPE_START_GROUP:
76
0
    case WireFormatLite::WIRETYPE_END_GROUP:
77
0
      return false;
78
79
      // Do not add a default statement. Let the compiler complain when someone
80
      // adds a new wire type.
81
0
  }
82
0
  GOOGLE_LOG(FATAL) << "can't reach here.";
83
0
  return false;
84
0
}
85
86
// Registry stuff.
87
struct ExtensionHasher {
88
0
  std::size_t operator()(const std::pair<const MessageLite*, int>& p) const {
89
0
    return std::hash<const MessageLite*>{}(p.first) ^
90
0
           std::hash<int>{}(p.second);
91
0
  }
92
};
93
94
typedef std::unordered_map<std::pair<const MessageLite*, int>, ExtensionInfo,
95
                           ExtensionHasher>
96
    ExtensionRegistry;
97
98
static const ExtensionRegistry* global_registry = nullptr;
99
100
// This function is only called at startup, so there is no need for thread-
101
// safety.
102
void Register(const MessageLite* containing_type, int number,
103
0
              ExtensionInfo info) {
104
0
  static auto local_static_registry = OnShutdownDelete(new ExtensionRegistry);
105
0
  global_registry = local_static_registry;
106
0
  if (!InsertIfNotPresent(local_static_registry,
107
0
                               std::make_pair(containing_type, number), info)) {
108
0
    GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
109
0
               << containing_type->GetTypeName() << "\", field number "
110
0
               << number << ".";
111
0
  }
112
0
}
113
114
const ExtensionInfo* FindRegisteredExtension(const MessageLite* containing_type,
115
0
                                             int number) {
116
0
  return global_registry == nullptr
117
0
             ? nullptr
118
0
             : FindOrNull(*global_registry,
119
0
                               std::make_pair(containing_type, number));
120
0
}
121
122
}  // namespace
123
124
0
ExtensionFinder::~ExtensionFinder() {}
125
126
0
bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
127
0
  const ExtensionInfo* extension =
128
0
      FindRegisteredExtension(containing_type_, number);
129
0
  if (extension == NULL) {
130
0
    return false;
131
0
  } else {
132
0
    *output = *extension;
133
0
    return true;
134
0
  }
135
0
}
136
137
void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
138
                                     int number, FieldType type,
139
0
                                     bool is_repeated, bool is_packed) {
140
0
  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
141
0
  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
142
0
  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
143
0
  ExtensionInfo info(type, is_repeated, is_packed);
144
0
  Register(containing_type, number, info);
145
0
}
146
147
0
static bool CallNoArgValidityFunc(const void* arg, int number) {
148
  // Note:  Must use C-style cast here rather than reinterpret_cast because
149
  //   the C++ standard at one point did not allow casts between function and
150
  //   data pointers and some compilers enforce this for C++-style casts.  No
151
  //   compiler enforces it for C-style casts since lots of C-style code has
152
  //   relied on these kinds of casts for a long time, despite being
153
  //   technically undefined.  See:
154
  //     http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
155
  // Also note:  Some compilers do not allow function pointers to be "const".
156
  //   Which makes sense, I suppose, because it's meaningless.
157
0
  return ((EnumValidityFunc*)arg)(number);
158
0
}
159
160
void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
161
                                         int number, FieldType type,
162
                                         bool is_repeated, bool is_packed,
163
0
                                         EnumValidityFunc* is_valid) {
164
0
  GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
165
0
  ExtensionInfo info(type, is_repeated, is_packed);
166
0
  info.enum_validity_check.func = CallNoArgValidityFunc;
167
  // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
168
0
  info.enum_validity_check.arg = (void*)is_valid;
169
0
  Register(containing_type, number, info);
170
0
}
171
172
void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
173
                                            int number, FieldType type,
174
                                            bool is_repeated, bool is_packed,
175
0
                                            const MessageLite* prototype) {
176
0
  GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
177
0
        type == WireFormatLite::TYPE_GROUP);
178
0
  ExtensionInfo info(type, is_repeated, is_packed);
179
0
  info.message_info = {prototype};
180
0
  Register(containing_type, number, info);
181
0
}
182
183
184
// ===================================================================
185
// Constructors and basic methods.
186
187
ExtensionSet::ExtensionSet(Arena* arena)
188
115
    : arena_(arena),
189
115
      flat_capacity_(0),
190
115
      flat_size_(0),
191
115
      map_{flat_capacity_ == 0
192
115
               ? NULL
193
115
               : Arena::CreateArray<KeyValue>(arena_, flat_capacity_)} {}
194
195
113
ExtensionSet::~ExtensionSet() {
196
  // Deletes all allocated extensions.
197
113
  if (arena_ == NULL) {
198
113
    ForEach([](int /* number */, Extension& ext) { ext.Free(); });
199
113
    if (PROTOBUF_PREDICT_FALSE(is_large())) {
200
0
      delete map_.large;
201
113
    } else {
202
113
      DeleteFlatMap(map_.flat, flat_capacity_);
203
113
    }
204
113
  }
205
113
}
206
207
void ExtensionSet::DeleteFlatMap(const ExtensionSet::KeyValue* flat,
208
113
                                 uint16 flat_capacity) {
209
113
#ifdef __cpp_sized_deallocation
210
  // Arena::CreateArray already requires a trivially destructible type, but
211
  // ensure this constraint is not violated in the future.
212
113
  static_assert(std::is_trivially_destructible<KeyValue>::value,
213
113
                "CreateArray requires a trivially destructible type");
214
  // A const-cast is needed, but this is safe as we are about to deallocate the
215
  // array.
216
113
  ::operator delete[](const_cast<ExtensionSet::KeyValue*>(flat),
217
113
                      sizeof(*flat) * flat_capacity);
218
#else   // !__cpp_sized_deallocation
219
  delete[] flat;
220
#endif  // !__cpp_sized_deallocation
221
113
}
222
223
// Defined in extension_set_heavy.cc.
224
// void ExtensionSet::AppendToList(const Descriptor* containing_type,
225
//                                 const DescriptorPool* pool,
226
//                                 vector<const FieldDescriptor*>* output) const
227
228
0
bool ExtensionSet::Has(int number) const {
229
0
  const Extension* ext = FindOrNull(number);
230
0
  if (ext == NULL) return false;
231
0
  GOOGLE_DCHECK(!ext->is_repeated);
232
0
  return !ext->is_cleared;
233
0
}
234
235
0
int ExtensionSet::NumExtensions() const {
236
0
  int result = 0;
237
0
  ForEach([&result](int /* number */, const Extension& ext) {
238
0
    if (!ext.is_cleared) {
239
0
      ++result;
240
0
    }
241
0
  });
242
0
  return result;
243
0
}
244
245
0
int ExtensionSet::ExtensionSize(int number) const {
246
0
  const Extension* ext = FindOrNull(number);
247
0
  return ext == NULL ? 0 : ext->GetSize();
248
0
}
249
250
0
FieldType ExtensionSet::ExtensionType(int number) const {
251
0
  const Extension* ext = FindOrNull(number);
252
0
  if (ext == NULL) {
253
0
    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
254
0
    return 0;
255
0
  }
256
0
  if (ext->is_cleared) {
257
0
    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
258
0
  }
259
0
  return ext->type;
260
0
}
261
262
0
void ExtensionSet::ClearExtension(int number) {
263
0
  Extension* ext = FindOrNull(number);
264
0
  if (ext == NULL) return;
265
0
  ext->Clear();
266
0
}
267
268
// ===================================================================
269
// Field accessors
270
271
namespace {
272
273
enum { REPEATED_FIELD, OPTIONAL_FIELD };
274
275
}  // namespace
276
277
#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                                 \
278
0
  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED_FIELD : OPTIONAL_FIELD, LABEL); \
279
0
  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
280
281
// -------------------------------------------------------------------
282
// Primitives
283
284
#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                  \
285
                                                                              \
286
  LOWERCASE ExtensionSet::Get##CAMELCASE(int number, LOWERCASE default_value) \
287
0
      const {                                                                 \
288
0
    const Extension* extension = FindOrNull(number);                          \
289
0
    if (extension == NULL || extension->is_cleared) {                         \
290
0
      return default_value;                                                   \
291
0
    } else {                                                                  \
292
0
      GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE);                     \
293
0
      return extension->LOWERCASE##_value;                                    \
294
0
    }                                                                         \
295
0
  }                                                                           \
296
                                                                              \
297
  void ExtensionSet::Set##CAMELCASE(int number, FieldType type,               \
298
                                    LOWERCASE value,                          \
299
0
                                    const FieldDescriptor* descriptor) {      \
300
0
    Extension* extension;                                                     \
301
0
    if (MaybeNewExtension(number, descriptor, &extension)) {                  \
302
0
      extension->type = type;                                                 \
303
0
      GOOGLE_DCHECK_EQ(cpp_type(extension->type),                                    \
304
0
                WireFormatLite::CPPTYPE_##UPPERCASE);                         \
305
0
      extension->is_repeated = false;                                         \
306
0
    } else {                                                                  \
307
0
      GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, UPPERCASE);                     \
308
0
    }                                                                         \
309
0
    extension->is_cleared = false;                                            \
310
0
    extension->LOWERCASE##_value = value;                                     \
311
0
  }                                                                           \
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetInt32(int, unsigned char, int, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetInt64(int, unsigned char, long, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetUInt32(int, unsigned char, unsigned int, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetUInt64(int, unsigned char, unsigned long, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetFloat(int, unsigned char, float, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetDouble(int, unsigned char, double, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetBool(int, unsigned char, bool, google::protobuf::FieldDescriptor const*)
312
                                                                              \
313
  LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index)       \
314
0
      const {                                                                 \
315
0
    const Extension* extension = FindOrNull(number);                          \
316
0
    GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";      \
317
0
    GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE);                       \
318
0
    return extension->repeated_##LOWERCASE##_value->Get(index);               \
319
0
  }                                                                           \
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::GetRepeatedInt32(int, int) const
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::GetRepeatedInt64(int, int) const
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::GetRepeatedUInt32(int, int) const
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::GetRepeatedUInt64(int, int) const
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::GetRepeatedFloat(int, int) const
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::GetRepeatedDouble(int, int) const
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::GetRepeatedBool(int, int) const
320
                                                                              \
321
  void ExtensionSet::SetRepeated##CAMELCASE(int number, int index,            \
322
0
                                            LOWERCASE value) {                \
323
0
    Extension* extension = FindOrNull(number);                                \
324
0
    GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";      \
325
0
    GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE);                       \
326
0
    extension->repeated_##LOWERCASE##_value->Set(index, value);               \
327
0
  }                                                                           \
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetRepeatedInt32(int, int, int)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetRepeatedInt64(int, int, long)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetRepeatedUInt32(int, int, unsigned int)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetRepeatedUInt64(int, int, unsigned long)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetRepeatedFloat(int, int, float)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetRepeatedDouble(int, int, double)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::SetRepeatedBool(int, int, bool)
328
                                                                              \
329
  void ExtensionSet::Add##CAMELCASE(int number, FieldType type, bool packed,  \
330
                                    LOWERCASE value,                          \
331
0
                                    const FieldDescriptor* descriptor) {      \
332
0
    Extension* extension;                                                     \
333
0
    if (MaybeNewExtension(number, descriptor, &extension)) {                  \
334
0
      extension->type = type;                                                 \
335
0
      GOOGLE_DCHECK_EQ(cpp_type(extension->type),                                    \
336
0
                WireFormatLite::CPPTYPE_##UPPERCASE);                         \
337
0
      extension->is_repeated = true;                                          \
338
0
      extension->is_packed = packed;                                          \
339
0
      extension->repeated_##LOWERCASE##_value =                               \
340
0
          Arena::CreateMessage<RepeatedField<LOWERCASE>>(arena_);             \
341
0
    } else {                                                                  \
342
0
      GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, UPPERCASE);                     \
343
0
      GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                \
344
0
    }                                                                         \
345
0
    extension->repeated_##LOWERCASE##_value->Add(value);                      \
346
0
  }
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::AddInt32(int, unsigned char, bool, int, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::AddInt64(int, unsigned char, bool, long, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::AddUInt32(int, unsigned char, bool, unsigned int, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::AddUInt64(int, unsigned char, bool, unsigned long, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::AddFloat(int, unsigned char, bool, float, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::AddDouble(int, unsigned char, bool, double, google::protobuf::FieldDescriptor const*)
Unexecuted instantiation: google::protobuf::internal::ExtensionSet::AddBool(int, unsigned char, bool, bool, google::protobuf::FieldDescriptor const*)
347
348
0
PRIMITIVE_ACCESSORS(INT32, int32, Int32)
349
0
PRIMITIVE_ACCESSORS(INT64, int64, Int64)
350
0
PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
351
0
PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
352
0
PRIMITIVE_ACCESSORS(FLOAT, float, Float)
353
0
PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
354
0
PRIMITIVE_ACCESSORS(BOOL, bool, Bool)
355
356
#undef PRIMITIVE_ACCESSORS
357
358
const void* ExtensionSet::GetRawRepeatedField(int number,
359
0
                                              const void* default_value) const {
360
0
  const Extension* extension = FindOrNull(number);
361
0
  if (extension == NULL) {
362
0
    return default_value;
363
0
  }
364
  // We assume that all the RepeatedField<>* pointers have the same
365
  // size and alignment within the anonymous union in Extension.
366
0
  return extension->repeated_int32_value;
367
0
}
368
369
void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
370
                                            bool packed,
371
0
                                            const FieldDescriptor* desc) {
372
0
  Extension* extension;
373
374
  // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
375
  // extension.
376
0
  if (MaybeNewExtension(number, desc, &extension)) {
377
0
    extension->is_repeated = true;
378
0
    extension->type = field_type;
379
0
    extension->is_packed = packed;
380
381
0
    switch (WireFormatLite::FieldTypeToCppType(
382
0
        static_cast<WireFormatLite::FieldType>(field_type))) {
383
0
      case WireFormatLite::CPPTYPE_INT32:
384
0
        extension->repeated_int32_value =
385
0
            Arena::CreateMessage<RepeatedField<int32>>(arena_);
386
0
        break;
387
0
      case WireFormatLite::CPPTYPE_INT64:
388
0
        extension->repeated_int64_value =
389
0
            Arena::CreateMessage<RepeatedField<int64>>(arena_);
390
0
        break;
391
0
      case WireFormatLite::CPPTYPE_UINT32:
392
0
        extension->repeated_uint32_value =
393
0
            Arena::CreateMessage<RepeatedField<uint32>>(arena_);
394
0
        break;
395
0
      case WireFormatLite::CPPTYPE_UINT64:
396
0
        extension->repeated_uint64_value =
397
0
            Arena::CreateMessage<RepeatedField<uint64>>(arena_);
398
0
        break;
399
0
      case WireFormatLite::CPPTYPE_DOUBLE:
400
0
        extension->repeated_double_value =
401
0
            Arena::CreateMessage<RepeatedField<double>>(arena_);
402
0
        break;
403
0
      case WireFormatLite::CPPTYPE_FLOAT:
404
0
        extension->repeated_float_value =
405
0
            Arena::CreateMessage<RepeatedField<float>>(arena_);
406
0
        break;
407
0
      case WireFormatLite::CPPTYPE_BOOL:
408
0
        extension->repeated_bool_value =
409
0
            Arena::CreateMessage<RepeatedField<bool>>(arena_);
410
0
        break;
411
0
      case WireFormatLite::CPPTYPE_ENUM:
412
0
        extension->repeated_enum_value =
413
0
            Arena::CreateMessage<RepeatedField<int>>(arena_);
414
0
        break;
415
0
      case WireFormatLite::CPPTYPE_STRING:
416
0
        extension->repeated_string_value =
417
0
            Arena::CreateMessage<RepeatedPtrField<std::string>>(arena_);
418
0
        break;
419
0
      case WireFormatLite::CPPTYPE_MESSAGE:
420
0
        extension->repeated_message_value =
421
0
            Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_);
422
0
        break;
423
0
    }
424
0
  }
425
426
  // We assume that all the RepeatedField<>* pointers have the same
427
  // size and alignment within the anonymous union in Extension.
428
0
  return extension->repeated_int32_value;
429
0
}
430
431
// Compatible version using old call signature. Does not create extensions when
432
// the don't already exist; instead, just GOOGLE_CHECK-fails.
433
0
void* ExtensionSet::MutableRawRepeatedField(int number) {
434
0
  Extension* extension = FindOrNull(number);
435
0
  GOOGLE_CHECK(extension != NULL) << "Extension not found.";
436
  // We assume that all the RepeatedField<>* pointers have the same
437
  // size and alignment within the anonymous union in Extension.
438
0
  return extension->repeated_int32_value;
439
0
}
440
441
// -------------------------------------------------------------------
442
// Enums
443
444
0
int ExtensionSet::GetEnum(int number, int default_value) const {
445
0
  const Extension* extension = FindOrNull(number);
446
0
  if (extension == NULL || extension->is_cleared) {
447
    // Not present.  Return the default value.
448
0
    return default_value;
449
0
  } else {
450
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM);
451
0
    return extension->enum_value;
452
0
  }
453
0
}
454
455
void ExtensionSet::SetEnum(int number, FieldType type, int value,
456
0
                           const FieldDescriptor* descriptor) {
457
0
  Extension* extension;
458
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
459
0
    extension->type = type;
460
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
461
0
    extension->is_repeated = false;
462
0
  } else {
463
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, ENUM);
464
0
  }
465
0
  extension->is_cleared = false;
466
0
  extension->enum_value = value;
467
0
}
468
469
0
int ExtensionSet::GetRepeatedEnum(int number, int index) const {
470
0
  const Extension* extension = FindOrNull(number);
471
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
472
0
  GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM);
473
0
  return extension->repeated_enum_value->Get(index);
474
0
}
475
476
0
void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
477
0
  Extension* extension = FindOrNull(number);
478
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
479
0
  GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM);
480
0
  extension->repeated_enum_value->Set(index, value);
481
0
}
482
483
void ExtensionSet::AddEnum(int number, FieldType type, bool packed, int value,
484
0
                           const FieldDescriptor* descriptor) {
485
0
  Extension* extension;
486
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
487
0
    extension->type = type;
488
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
489
0
    extension->is_repeated = true;
490
0
    extension->is_packed = packed;
491
0
    extension->repeated_enum_value =
492
0
        Arena::CreateMessage<RepeatedField<int>>(arena_);
493
0
  } else {
494
0
    GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, ENUM);
495
0
    GOOGLE_DCHECK_EQ(extension->is_packed, packed);
496
0
  }
497
0
  extension->repeated_enum_value->Add(value);
498
0
}
499
500
// -------------------------------------------------------------------
501
// Strings
502
503
const std::string& ExtensionSet::GetString(
504
0
    int number, const std::string& default_value) const {
505
0
  const Extension* extension = FindOrNull(number);
506
0
  if (extension == NULL || extension->is_cleared) {
507
    // Not present.  Return the default value.
508
0
    return default_value;
509
0
  } else {
510
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, STRING);
511
0
    return *extension->string_value;
512
0
  }
513
0
}
514
515
std::string* ExtensionSet::MutableString(int number, FieldType type,
516
0
                                         const FieldDescriptor* descriptor) {
517
0
  Extension* extension;
518
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
519
0
    extension->type = type;
520
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
521
0
    extension->is_repeated = false;
522
0
    extension->string_value = Arena::Create<std::string>(arena_);
523
0
  } else {
524
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, STRING);
525
0
  }
526
0
  extension->is_cleared = false;
527
0
  return extension->string_value;
528
0
}
529
530
const std::string& ExtensionSet::GetRepeatedString(int number,
531
0
                                                   int index) const {
532
0
  const Extension* extension = FindOrNull(number);
533
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
534
0
  GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING);
535
0
  return extension->repeated_string_value->Get(index);
536
0
}
537
538
0
std::string* ExtensionSet::MutableRepeatedString(int number, int index) {
539
0
  Extension* extension = FindOrNull(number);
540
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
541
0
  GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING);
542
0
  return extension->repeated_string_value->Mutable(index);
543
0
}
544
545
std::string* ExtensionSet::AddString(int number, FieldType type,
546
0
                                     const FieldDescriptor* descriptor) {
547
0
  Extension* extension;
548
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
549
0
    extension->type = type;
550
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
551
0
    extension->is_repeated = true;
552
0
    extension->is_packed = false;
553
0
    extension->repeated_string_value =
554
0
        Arena::CreateMessage<RepeatedPtrField<std::string>>(arena_);
555
0
  } else {
556
0
    GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, STRING);
557
0
  }
558
0
  return extension->repeated_string_value->Add();
559
0
}
560
561
// -------------------------------------------------------------------
562
// Messages
563
564
const MessageLite& ExtensionSet::GetMessage(
565
0
    int number, const MessageLite& default_value) const {
566
0
  const Extension* extension = FindOrNull(number);
567
0
  if (extension == NULL) {
568
    // Not present.  Return the default value.
569
0
    return default_value;
570
0
  } else {
571
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
572
0
    if (extension->is_lazy) {
573
0
      return extension->lazymessage_value->GetMessage(default_value);
574
0
    } else {
575
0
      return *extension->message_value;
576
0
    }
577
0
  }
578
0
}
579
580
// Defined in extension_set_heavy.cc.
581
// const MessageLite& ExtensionSet::GetMessage(int number,
582
//                                             const Descriptor* message_type,
583
//                                             MessageFactory* factory) const
584
585
MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
586
                                          const MessageLite& prototype,
587
0
                                          const FieldDescriptor* descriptor) {
588
0
  Extension* extension;
589
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
590
0
    extension->type = type;
591
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
592
0
    extension->is_repeated = false;
593
0
    extension->is_lazy = false;
594
0
    extension->message_value = prototype.New(arena_);
595
0
    extension->is_cleared = false;
596
0
    return extension->message_value;
597
0
  } else {
598
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
599
0
    extension->is_cleared = false;
600
0
    if (extension->is_lazy) {
601
0
      return extension->lazymessage_value->MutableMessage(prototype);
602
0
    } else {
603
0
      return extension->message_value;
604
0
    }
605
0
  }
606
0
}
607
608
// Defined in extension_set_heavy.cc.
609
// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
610
//                                           const Descriptor* message_type,
611
//                                           MessageFactory* factory)
612
613
void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
614
                                       const FieldDescriptor* descriptor,
615
0
                                       MessageLite* message) {
616
0
  if (message == NULL) {
617
0
    ClearExtension(number);
618
0
    return;
619
0
  }
620
0
  Arena* message_arena = message->GetArena();
621
0
  Extension* extension;
622
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
623
0
    extension->type = type;
624
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
625
0
    extension->is_repeated = false;
626
0
    extension->is_lazy = false;
627
0
    if (message_arena == arena_) {
628
0
      extension->message_value = message;
629
0
    } else if (message_arena == NULL) {
630
0
      extension->message_value = message;
631
0
      arena_->Own(message);  // not NULL because not equal to message_arena
632
0
    } else {
633
0
      extension->message_value = message->New(arena_);
634
0
      extension->message_value->CheckTypeAndMergeFrom(*message);
635
0
    }
636
0
  } else {
637
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
638
0
    if (extension->is_lazy) {
639
0
      extension->lazymessage_value->SetAllocatedMessage(message);
640
0
    } else {
641
0
      if (arena_ == NULL) {
642
0
        delete extension->message_value;
643
0
      }
644
0
      if (message_arena == arena_) {
645
0
        extension->message_value = message;
646
0
      } else if (message_arena == NULL) {
647
0
        extension->message_value = message;
648
0
        arena_->Own(message);  // not NULL because not equal to message_arena
649
0
      } else {
650
0
        extension->message_value = message->New(arena_);
651
0
        extension->message_value->CheckTypeAndMergeFrom(*message);
652
0
      }
653
0
    }
654
0
  }
655
0
  extension->is_cleared = false;
656
0
}
657
658
void ExtensionSet::UnsafeArenaSetAllocatedMessage(
659
    int number, FieldType type, const FieldDescriptor* descriptor,
660
0
    MessageLite* message) {
661
0
  if (message == NULL) {
662
0
    ClearExtension(number);
663
0
    return;
664
0
  }
665
0
  Extension* extension;
666
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
667
0
    extension->type = type;
668
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
669
0
    extension->is_repeated = false;
670
0
    extension->is_lazy = false;
671
0
    extension->message_value = message;
672
0
  } else {
673
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
674
0
    if (extension->is_lazy) {
675
0
      extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message);
676
0
    } else {
677
0
      if (arena_ == NULL) {
678
0
        delete extension->message_value;
679
0
      }
680
0
      extension->message_value = message;
681
0
    }
682
0
  }
683
0
  extension->is_cleared = false;
684
0
}
685
686
MessageLite* ExtensionSet::ReleaseMessage(int number,
687
0
                                          const MessageLite& prototype) {
688
0
  Extension* extension = FindOrNull(number);
689
0
  if (extension == NULL) {
690
    // Not present.  Return NULL.
691
0
    return NULL;
692
0
  } else {
693
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
694
0
    MessageLite* ret = NULL;
695
0
    if (extension->is_lazy) {
696
0
      ret = extension->lazymessage_value->ReleaseMessage(prototype);
697
0
      if (arena_ == NULL) {
698
0
        delete extension->lazymessage_value;
699
0
      }
700
0
    } else {
701
0
      if (arena_ == NULL) {
702
0
        ret = extension->message_value;
703
0
      } else {
704
        // ReleaseMessage() always returns a heap-allocated message, and we are
705
        // on an arena, so we need to make a copy of this message to return.
706
0
        ret = extension->message_value->New();
707
0
        ret->CheckTypeAndMergeFrom(*extension->message_value);
708
0
      }
709
0
    }
710
0
    Erase(number);
711
0
    return ret;
712
0
  }
713
0
}
714
715
MessageLite* ExtensionSet::UnsafeArenaReleaseMessage(
716
0
    int number, const MessageLite& prototype) {
717
0
  Extension* extension = FindOrNull(number);
718
0
  if (extension == NULL) {
719
    // Not present.  Return NULL.
720
0
    return NULL;
721
0
  } else {
722
0
    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE);
723
0
    MessageLite* ret = NULL;
724
0
    if (extension->is_lazy) {
725
0
      ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(prototype);
726
0
      if (arena_ == NULL) {
727
0
        delete extension->lazymessage_value;
728
0
      }
729
0
    } else {
730
0
      ret = extension->message_value;
731
0
    }
732
0
    Erase(number);
733
0
    return ret;
734
0
  }
735
0
}
736
737
// Defined in extension_set_heavy.cc.
738
// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
739
//                                           MessageFactory* factory);
740
741
const MessageLite& ExtensionSet::GetRepeatedMessage(int number,
742
0
                                                    int index) const {
743
0
  const Extension* extension = FindOrNull(number);
744
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
745
0
  GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE);
746
0
  return extension->repeated_message_value->Get(index);
747
0
}
748
749
0
MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
750
0
  Extension* extension = FindOrNull(number);
751
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
752
0
  GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE);
753
0
  return extension->repeated_message_value->Mutable(index);
754
0
}
755
756
MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
757
                                      const MessageLite& prototype,
758
0
                                      const FieldDescriptor* descriptor) {
759
0
  Extension* extension;
760
0
  if (MaybeNewExtension(number, descriptor, &extension)) {
761
0
    extension->type = type;
762
0
    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
763
0
    extension->is_repeated = true;
764
0
    extension->repeated_message_value =
765
0
        Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_);
766
0
  } else {
767
0
    GOOGLE_DCHECK_TYPE(*extension, REPEATED_FIELD, MESSAGE);
768
0
  }
769
770
  // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
771
  // allocate an abstract object, so we have to be tricky.
772
0
  MessageLite* result = reinterpret_cast<internal::RepeatedPtrFieldBase*>(
773
0
                            extension->repeated_message_value)
774
0
                            ->AddFromCleared<GenericTypeHandler<MessageLite>>();
775
0
  if (result == NULL) {
776
0
    result = prototype.New(arena_);
777
0
    extension->repeated_message_value->AddAllocated(result);
778
0
  }
779
0
  return result;
780
0
}
781
782
// Defined in extension_set_heavy.cc.
783
// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
784
//                                       const Descriptor* message_type,
785
//                                       MessageFactory* factory)
786
787
#undef GOOGLE_DCHECK_TYPE
788
789
0
void ExtensionSet::RemoveLast(int number) {
790
0
  Extension* extension = FindOrNull(number);
791
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
792
0
  GOOGLE_DCHECK(extension->is_repeated);
793
794
0
  switch (cpp_type(extension->type)) {
795
0
    case WireFormatLite::CPPTYPE_INT32:
796
0
      extension->repeated_int32_value->RemoveLast();
797
0
      break;
798
0
    case WireFormatLite::CPPTYPE_INT64:
799
0
      extension->repeated_int64_value->RemoveLast();
800
0
      break;
801
0
    case WireFormatLite::CPPTYPE_UINT32:
802
0
      extension->repeated_uint32_value->RemoveLast();
803
0
      break;
804
0
    case WireFormatLite::CPPTYPE_UINT64:
805
0
      extension->repeated_uint64_value->RemoveLast();
806
0
      break;
807
0
    case WireFormatLite::CPPTYPE_FLOAT:
808
0
      extension->repeated_float_value->RemoveLast();
809
0
      break;
810
0
    case WireFormatLite::CPPTYPE_DOUBLE:
811
0
      extension->repeated_double_value->RemoveLast();
812
0
      break;
813
0
    case WireFormatLite::CPPTYPE_BOOL:
814
0
      extension->repeated_bool_value->RemoveLast();
815
0
      break;
816
0
    case WireFormatLite::CPPTYPE_ENUM:
817
0
      extension->repeated_enum_value->RemoveLast();
818
0
      break;
819
0
    case WireFormatLite::CPPTYPE_STRING:
820
0
      extension->repeated_string_value->RemoveLast();
821
0
      break;
822
0
    case WireFormatLite::CPPTYPE_MESSAGE:
823
0
      extension->repeated_message_value->RemoveLast();
824
0
      break;
825
0
  }
826
0
}
827
828
0
MessageLite* ExtensionSet::ReleaseLast(int number) {
829
0
  Extension* extension = FindOrNull(number);
830
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
831
0
  GOOGLE_DCHECK(extension->is_repeated);
832
0
  GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
833
0
  return extension->repeated_message_value->ReleaseLast();
834
0
}
835
836
0
void ExtensionSet::SwapElements(int number, int index1, int index2) {
837
0
  Extension* extension = FindOrNull(number);
838
0
  GOOGLE_CHECK(extension != NULL) << "Index out-of-bounds (field is empty).";
839
0
  GOOGLE_DCHECK(extension->is_repeated);
840
841
0
  switch (cpp_type(extension->type)) {
842
0
    case WireFormatLite::CPPTYPE_INT32:
843
0
      extension->repeated_int32_value->SwapElements(index1, index2);
844
0
      break;
845
0
    case WireFormatLite::CPPTYPE_INT64:
846
0
      extension->repeated_int64_value->SwapElements(index1, index2);
847
0
      break;
848
0
    case WireFormatLite::CPPTYPE_UINT32:
849
0
      extension->repeated_uint32_value->SwapElements(index1, index2);
850
0
      break;
851
0
    case WireFormatLite::CPPTYPE_UINT64:
852
0
      extension->repeated_uint64_value->SwapElements(index1, index2);
853
0
      break;
854
0
    case WireFormatLite::CPPTYPE_FLOAT:
855
0
      extension->repeated_float_value->SwapElements(index1, index2);
856
0
      break;
857
0
    case WireFormatLite::CPPTYPE_DOUBLE:
858
0
      extension->repeated_double_value->SwapElements(index1, index2);
859
0
      break;
860
0
    case WireFormatLite::CPPTYPE_BOOL:
861
0
      extension->repeated_bool_value->SwapElements(index1, index2);
862
0
      break;
863
0
    case WireFormatLite::CPPTYPE_ENUM:
864
0
      extension->repeated_enum_value->SwapElements(index1, index2);
865
0
      break;
866
0
    case WireFormatLite::CPPTYPE_STRING:
867
0
      extension->repeated_string_value->SwapElements(index1, index2);
868
0
      break;
869
0
    case WireFormatLite::CPPTYPE_MESSAGE:
870
0
      extension->repeated_message_value->SwapElements(index1, index2);
871
0
      break;
872
0
  }
873
0
}
874
875
// ===================================================================
876
877
0
void ExtensionSet::Clear() {
878
0
  ForEach([](int /* number */, Extension& ext) { ext.Clear(); });
879
0
}
880
881
namespace {
882
// Computes the size of a std::set_union without constructing the union.
883
template <typename ItX, typename ItY>
884
0
size_t SizeOfUnion(ItX it_xs, ItX end_xs, ItY it_ys, ItY end_ys) {
885
0
  size_t result = 0;
886
0
  while (it_xs != end_xs && it_ys != end_ys) {
887
0
    ++result;
888
0
    if (it_xs->first < it_ys->first) {
889
0
      ++it_xs;
890
0
    } else if (it_xs->first == it_ys->first) {
891
0
      ++it_xs;
892
0
      ++it_ys;
893
0
    } else {
894
0
      ++it_ys;
895
0
    }
896
0
  }
897
0
  result += std::distance(it_xs, end_xs);
898
0
  result += std::distance(it_ys, end_ys);
899
0
  return result;
900
0
}
Unexecuted instantiation: extension_set.cc:unsigned long google::protobuf::internal::(anonymous namespace)::SizeOfUnion<google::protobuf::internal::ExtensionSet::KeyValue*, google::protobuf::internal::ExtensionSet::KeyValue const*>(google::protobuf::internal::ExtensionSet::KeyValue*, google::protobuf::internal::ExtensionSet::KeyValue*, google::protobuf::internal::ExtensionSet::KeyValue const*, google::protobuf::internal::ExtensionSet::KeyValue const*)
Unexecuted instantiation: extension_set.cc:unsigned long google::protobuf::internal::(anonymous namespace)::SizeOfUnion<google::protobuf::internal::ExtensionSet::KeyValue*, std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<int, google::protobuf::internal::ExtensionSet::Extension>, std::__1::__tree_node<std::__1::__value_type<int, google::protobuf::internal::ExtensionSet::Extension>, void*>*, long> > >(google::protobuf::internal::ExtensionSet::KeyValue*, google::protobuf::internal::ExtensionSet::KeyValue*, std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<int, google::protobuf::internal::ExtensionSet::Extension>, std::__1::__tree_node<std::__1::__value_type<int, google::protobuf::internal::ExtensionSet::Extension>, void*>*, long> >, std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<int, google::protobuf::internal::ExtensionSet::Extension>, std::__1::__tree_node<std::__1::__value_type<int, google::protobuf::internal::ExtensionSet::Extension>, void*>*, long> >)
901
}  // namespace
902
903
0
void ExtensionSet::MergeFrom(const ExtensionSet& other) {
904
0
  if (PROTOBUF_PREDICT_TRUE(!is_large())) {
905
0
    if (PROTOBUF_PREDICT_TRUE(!other.is_large())) {
906
0
      GrowCapacity(SizeOfUnion(flat_begin(), flat_end(), other.flat_begin(),
907
0
                               other.flat_end()));
908
0
    } else {
909
0
      GrowCapacity(SizeOfUnion(flat_begin(), flat_end(),
910
0
                               other.map_.large->begin(),
911
0
                               other.map_.large->end()));
912
0
    }
913
0
  }
914
0
  other.ForEach([this](int number, const Extension& ext) {
915
0
    this->InternalExtensionMergeFrom(number, ext);
916
0
  });
917
0
}
918
919
void ExtensionSet::InternalExtensionMergeFrom(
920
0
    int number, const Extension& other_extension) {
921
0
  if (other_extension.is_repeated) {
922
0
    Extension* extension;
923
0
    bool is_new =
924
0
        MaybeNewExtension(number, other_extension.descriptor, &extension);
925
0
    if (is_new) {
926
      // Extension did not already exist in set.
927
0
      extension->type = other_extension.type;
928
0
      extension->is_packed = other_extension.is_packed;
929
0
      extension->is_repeated = true;
930
0
    } else {
931
0
      GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
932
0
      GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
933
0
      GOOGLE_DCHECK(extension->is_repeated);
934
0
    }
935
936
0
    switch (cpp_type(other_extension.type)) {
937
0
#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
938
0
  case WireFormatLite::CPPTYPE_##UPPERCASE:              \
939
0
    if (is_new) {                                        \
940
0
      extension->repeated_##LOWERCASE##_value =          \
941
0
          Arena::CreateMessage<REPEATED_TYPE>(arena_);   \
942
0
    }                                                    \
943
0
    extension->repeated_##LOWERCASE##_value->MergeFrom(  \
944
0
        *other_extension.repeated_##LOWERCASE##_value);  \
945
0
    break;
946
947
0
      HANDLE_TYPE(INT32, int32, RepeatedField<int32>);
948
0
      HANDLE_TYPE(INT64, int64, RepeatedField<int64>);
949
0
      HANDLE_TYPE(UINT32, uint32, RepeatedField<uint32>);
950
0
      HANDLE_TYPE(UINT64, uint64, RepeatedField<uint64>);
951
0
      HANDLE_TYPE(FLOAT, float, RepeatedField<float>);
952
0
      HANDLE_TYPE(DOUBLE, double, RepeatedField<double>);
953
0
      HANDLE_TYPE(BOOL, bool, RepeatedField<bool>);
954
0
      HANDLE_TYPE(ENUM, enum, RepeatedField<int>);
955
0
      HANDLE_TYPE(STRING, string, RepeatedPtrField<std::string>);
956
0
#undef HANDLE_TYPE
957
958
0
      case WireFormatLite::CPPTYPE_MESSAGE:
959
0
        if (is_new) {
960
0
          extension->repeated_message_value =
961
0
              Arena::CreateMessage<RepeatedPtrField<MessageLite>>(arena_);
962
0
        }
963
        // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
964
        // it would attempt to allocate new objects.
965
0
        RepeatedPtrField<MessageLite>* other_repeated_message =
966
0
            other_extension.repeated_message_value;
967
0
        for (int i = 0; i < other_repeated_message->size(); i++) {
968
0
          const MessageLite& other_message = other_repeated_message->Get(i);
969
0
          MessageLite* target =
970
0
              reinterpret_cast<internal::RepeatedPtrFieldBase*>(
971
0
                  extension->repeated_message_value)
972
0
                  ->AddFromCleared<GenericTypeHandler<MessageLite>>();
973
0
          if (target == NULL) {
974
0
            target = other_message.New(arena_);
975
0
            extension->repeated_message_value->AddAllocated(target);
976
0
          }
977
0
          target->CheckTypeAndMergeFrom(other_message);
978
0
        }
979
0
        break;
980
0
    }
981
0
  } else {
982
0
    if (!other_extension.is_cleared) {
983
0
      switch (cpp_type(other_extension.type)) {
984
0
#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)  \
985
0
  case WireFormatLite::CPPTYPE_##UPPERCASE:           \
986
0
    Set##CAMELCASE(number, other_extension.type,      \
987
0
                   other_extension.LOWERCASE##_value, \
988
0
                   other_extension.descriptor);       \
989
0
    break;
990
991
0
        HANDLE_TYPE(INT32, int32, Int32);
992
0
        HANDLE_TYPE(INT64, int64, Int64);
993
0
        HANDLE_TYPE(UINT32, uint32, UInt32);
994
0
        HANDLE_TYPE(UINT64, uint64, UInt64);
995
0
        HANDLE_TYPE(FLOAT, float, Float);
996
0
        HANDLE_TYPE(DOUBLE, double, Double);
997
0
        HANDLE_TYPE(BOOL, bool, Bool);
998
0
        HANDLE_TYPE(ENUM, enum, Enum);
999
0
#undef HANDLE_TYPE
1000
0
        case WireFormatLite::CPPTYPE_STRING:
1001
0
          SetString(number, other_extension.type, *other_extension.string_value,
1002
0
                    other_extension.descriptor);
1003
0
          break;
1004
0
        case WireFormatLite::CPPTYPE_MESSAGE: {
1005
0
          Extension* extension;
1006
0
          bool is_new =
1007
0
              MaybeNewExtension(number, other_extension.descriptor, &extension);
1008
0
          if (is_new) {
1009
0
            extension->type = other_extension.type;
1010
0
            extension->is_packed = other_extension.is_packed;
1011
0
            extension->is_repeated = false;
1012
0
            if (other_extension.is_lazy) {
1013
0
              extension->is_lazy = true;
1014
0
              extension->lazymessage_value =
1015
0
                  other_extension.lazymessage_value->New(arena_);
1016
0
              extension->lazymessage_value->MergeFrom(
1017
0
                  *other_extension.lazymessage_value);
1018
0
            } else {
1019
0
              extension->is_lazy = false;
1020
0
              extension->message_value =
1021
0
                  other_extension.message_value->New(arena_);
1022
0
              extension->message_value->CheckTypeAndMergeFrom(
1023
0
                  *other_extension.message_value);
1024
0
            }
1025
0
          } else {
1026
0
            GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
1027
0
            GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
1028
0
            GOOGLE_DCHECK(!extension->is_repeated);
1029
0
            if (other_extension.is_lazy) {
1030
0
              if (extension->is_lazy) {
1031
0
                extension->lazymessage_value->MergeFrom(
1032
0
                    *other_extension.lazymessage_value);
1033
0
              } else {
1034
0
                extension->message_value->CheckTypeAndMergeFrom(
1035
0
                    other_extension.lazymessage_value->GetMessage(
1036
0
                        *extension->message_value));
1037
0
              }
1038
0
            } else {
1039
0
              if (extension->is_lazy) {
1040
0
                extension->lazymessage_value
1041
0
                    ->MutableMessage(*other_extension.message_value)
1042
0
                    ->CheckTypeAndMergeFrom(*other_extension.message_value);
1043
0
              } else {
1044
0
                extension->message_value->CheckTypeAndMergeFrom(
1045
0
                    *other_extension.message_value);
1046
0
              }
1047
0
            }
1048
0
          }
1049
0
          extension->is_cleared = false;
1050
0
          break;
1051
0
        }
1052
0
      }
1053
0
    }
1054
0
  }
1055
0
}
1056
1057
0
void ExtensionSet::Swap(ExtensionSet* x) {
1058
0
  if (GetArena() == x->GetArena()) {
1059
0
    using std::swap;
1060
0
    swap(flat_capacity_, x->flat_capacity_);
1061
0
    swap(flat_size_, x->flat_size_);
1062
0
    swap(map_, x->map_);
1063
0
  } else {
1064
    // TODO(cfallin, rohananil): We maybe able to optimize a case where we are
1065
    // swapping from heap to arena-allocated extension set, by just Own()'ing
1066
    // the extensions.
1067
0
    ExtensionSet extension_set;
1068
0
    extension_set.MergeFrom(*x);
1069
0
    x->Clear();
1070
0
    x->MergeFrom(*this);
1071
0
    Clear();
1072
0
    MergeFrom(extension_set);
1073
0
  }
1074
0
}
1075
1076
0
void ExtensionSet::SwapExtension(ExtensionSet* other, int number) {
1077
0
  if (this == other) return;
1078
0
  Extension* this_ext = FindOrNull(number);
1079
0
  Extension* other_ext = other->FindOrNull(number);
1080
1081
0
  if (this_ext == NULL && other_ext == NULL) {
1082
0
    return;
1083
0
  }
1084
1085
0
  if (this_ext != NULL && other_ext != NULL) {
1086
0
    if (GetArena() == other->GetArena()) {
1087
0
      using std::swap;
1088
0
      swap(*this_ext, *other_ext);
1089
0
    } else {
1090
      // TODO(cfallin, rohananil): We could further optimize these cases,
1091
      // especially avoid creation of ExtensionSet, and move MergeFrom logic
1092
      // into Extensions itself (which takes arena as an argument).
1093
      // We do it this way to reuse the copy-across-arenas logic already
1094
      // implemented in ExtensionSet's MergeFrom.
1095
0
      ExtensionSet temp;
1096
0
      temp.InternalExtensionMergeFrom(number, *other_ext);
1097
0
      Extension* temp_ext = temp.FindOrNull(number);
1098
0
      other_ext->Clear();
1099
0
      other->InternalExtensionMergeFrom(number, *this_ext);
1100
0
      this_ext->Clear();
1101
0
      InternalExtensionMergeFrom(number, *temp_ext);
1102
0
    }
1103
0
    return;
1104
0
  }
1105
1106
0
  if (this_ext == NULL) {
1107
0
    if (GetArena() == other->GetArena()) {
1108
0
      *Insert(number).first = *other_ext;
1109
0
    } else {
1110
0
      InternalExtensionMergeFrom(number, *other_ext);
1111
0
    }
1112
0
    other->Erase(number);
1113
0
    return;
1114
0
  }
1115
1116
0
  if (other_ext == NULL) {
1117
0
    if (GetArena() == other->GetArena()) {
1118
0
      *other->Insert(number).first = *this_ext;
1119
0
    } else {
1120
0
      other->InternalExtensionMergeFrom(number, *this_ext);
1121
0
    }
1122
0
    Erase(number);
1123
0
    return;
1124
0
  }
1125
0
}
1126
1127
113
bool ExtensionSet::IsInitialized() const {
1128
  // Extensions are never required.  However, we need to check that all
1129
  // embedded messages are initialized.
1130
113
  if (PROTOBUF_PREDICT_FALSE(is_large())) {
1131
0
    for (const auto& kv : *map_.large) {
1132
0
      if (!kv.second.IsInitialized()) return false;
1133
0
    }
1134
0
    return true;
1135
0
  }
1136
113
  for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) {
1137
0
    if (!it->second.IsInitialized()) return false;
1138
0
  }
1139
113
  return true;
1140
113
}
1141
1142
bool ExtensionSet::FindExtensionInfoFromTag(uint32 tag,
1143
                                            ExtensionFinder* extension_finder,
1144
                                            int* field_number,
1145
                                            ExtensionInfo* extension,
1146
0
                                            bool* was_packed_on_wire) {
1147
0
  *field_number = WireFormatLite::GetTagFieldNumber(tag);
1148
0
  WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
1149
0
  return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
1150
0
                                          extension_finder, extension,
1151
0
                                          was_packed_on_wire);
1152
0
}
1153
1154
bool ExtensionSet::FindExtensionInfoFromFieldNumber(
1155
    int wire_type, int field_number, ExtensionFinder* extension_finder,
1156
0
    ExtensionInfo* extension, bool* was_packed_on_wire) {
1157
0
  if (!extension_finder->Find(field_number, extension)) {
1158
0
    return false;
1159
0
  }
1160
1161
0
  WireFormatLite::WireType expected_wire_type =
1162
0
      WireFormatLite::WireTypeForFieldType(real_type(extension->type));
1163
1164
  // Check if this is a packed field.
1165
0
  *was_packed_on_wire = false;
1166
0
  if (extension->is_repeated &&
1167
0
      wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
1168
0
      is_packable(expected_wire_type)) {
1169
0
    *was_packed_on_wire = true;
1170
0
    return true;
1171
0
  }
1172
  // Otherwise the wire type must match.
1173
0
  return expected_wire_type == wire_type;
1174
0
}
1175
1176
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1177
                              ExtensionFinder* extension_finder,
1178
0
                              FieldSkipper* field_skipper) {
1179
0
  int number;
1180
0
  bool was_packed_on_wire;
1181
0
  ExtensionInfo extension;
1182
0
  if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension,
1183
0
                                &was_packed_on_wire)) {
1184
0
    return field_skipper->SkipField(input, tag);
1185
0
  } else {
1186
0
    return ParseFieldWithExtensionInfo(number, was_packed_on_wire, extension,
1187
0
                                       input, field_skipper);
1188
0
  }
1189
0
}
1190
1191
const char* ExtensionSet::ParseField(uint64 tag, const char* ptr,
1192
                                     const MessageLite* containing_type,
1193
                                     internal::InternalMetadata* metadata,
1194
0
                                     internal::ParseContext* ctx) {
1195
0
  GeneratedExtensionFinder finder(containing_type);
1196
0
  int number = tag >> 3;
1197
0
  bool was_packed_on_wire;
1198
0
  ExtensionInfo extension;
1199
0
  if (!FindExtensionInfoFromFieldNumber(tag & 7, number, &finder, &extension,
1200
0
                                        &was_packed_on_wire)) {
1201
0
    return UnknownFieldParse(
1202
0
        tag, metadata->mutable_unknown_fields<std::string>(), ptr, ctx);
1203
0
  }
1204
0
  return ParseFieldWithExtensionInfo<std::string>(
1205
0
      number, was_packed_on_wire, extension, metadata, ptr, ctx);
1206
0
}
1207
1208
const char* ExtensionSet::ParseMessageSetItem(
1209
    const char* ptr, const MessageLite* containing_type,
1210
0
    internal::InternalMetadata* metadata, internal::ParseContext* ctx) {
1211
0
  return ParseMessageSetItemTmpl<MessageLite, std::string>(ptr, containing_type,
1212
0
                                                           metadata, ctx);
1213
0
}
1214
1215
bool ExtensionSet::ParseFieldWithExtensionInfo(int number,
1216
                                               bool was_packed_on_wire,
1217
                                               const ExtensionInfo& extension,
1218
                                               io::CodedInputStream* input,
1219
0
                                               FieldSkipper* field_skipper) {
1220
  // Explicitly not read extension.is_packed, instead check whether the field
1221
  // was encoded in packed form on the wire.
1222
0
  if (was_packed_on_wire) {
1223
0
    uint32 size;
1224
0
    if (!input->ReadVarint32(&size)) return false;
1225
0
    io::CodedInputStream::Limit limit = input->PushLimit(size);
1226
1227
0
    switch (extension.type) {
1228
0
#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                \
1229
0
  case WireFormatLite::TYPE_##UPPERCASE:                                    \
1230
0
    while (input->BytesUntilLimit() > 0) {                                  \
1231
0
      CPP_LOWERCASE value;                                                  \
1232
0
      if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE,                     \
1233
0
                                         WireFormatLite::TYPE_##UPPERCASE>( \
1234
0
              input, &value))                                               \
1235
0
        return false;                                                       \
1236
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
1237
0
                         extension.is_packed, value, extension.descriptor); \
1238
0
    }                                                                       \
1239
0
    break
1240
1241
0
      HANDLE_TYPE(INT32, Int32, int32);
1242
0
      HANDLE_TYPE(INT64, Int64, int64);
1243
0
      HANDLE_TYPE(UINT32, UInt32, uint32);
1244
0
      HANDLE_TYPE(UINT64, UInt64, uint64);
1245
0
      HANDLE_TYPE(SINT32, Int32, int32);
1246
0
      HANDLE_TYPE(SINT64, Int64, int64);
1247
0
      HANDLE_TYPE(FIXED32, UInt32, uint32);
1248
0
      HANDLE_TYPE(FIXED64, UInt64, uint64);
1249
0
      HANDLE_TYPE(SFIXED32, Int32, int32);
1250
0
      HANDLE_TYPE(SFIXED64, Int64, int64);
1251
0
      HANDLE_TYPE(FLOAT, Float, float);
1252
0
      HANDLE_TYPE(DOUBLE, Double, double);
1253
0
      HANDLE_TYPE(BOOL, Bool, bool);
1254
0
#undef HANDLE_TYPE
1255
1256
0
      case WireFormatLite::TYPE_ENUM:
1257
0
        while (input->BytesUntilLimit() > 0) {
1258
0
          int value;
1259
0
          if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1260
0
                  input, &value))
1261
0
            return false;
1262
0
          if (extension.enum_validity_check.func(
1263
0
                  extension.enum_validity_check.arg, value)) {
1264
0
            AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
1265
0
                    value, extension.descriptor);
1266
0
          } else {
1267
            // Invalid value.  Treat as unknown.
1268
0
            field_skipper->SkipUnknownEnum(number, value);
1269
0
          }
1270
0
        }
1271
0
        break;
1272
1273
0
      case WireFormatLite::TYPE_STRING:
1274
0
      case WireFormatLite::TYPE_BYTES:
1275
0
      case WireFormatLite::TYPE_GROUP:
1276
0
      case WireFormatLite::TYPE_MESSAGE:
1277
0
        GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1278
0
        break;
1279
0
    }
1280
1281
0
    input->PopLimit(limit);
1282
0
  } else {
1283
0
    switch (extension.type) {
1284
0
#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                \
1285
0
  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
1286
0
    CPP_LOWERCASE value;                                                    \
1287
0
    if (!WireFormatLite::ReadPrimitive<CPP_LOWERCASE,                       \
1288
0
                                       WireFormatLite::TYPE_##UPPERCASE>(   \
1289
0
            input, &value))                                                 \
1290
0
      return false;                                                         \
1291
0
    if (extension.is_repeated) {                                            \
1292
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
1293
0
                         extension.is_packed, value, extension.descriptor); \
1294
0
    } else {                                                                \
1295
0
      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
1296
0
                         extension.descriptor);                             \
1297
0
    }                                                                       \
1298
0
  } break
1299
1300
0
      HANDLE_TYPE(INT32, Int32, int32);
1301
0
      HANDLE_TYPE(INT64, Int64, int64);
1302
0
      HANDLE_TYPE(UINT32, UInt32, uint32);
1303
0
      HANDLE_TYPE(UINT64, UInt64, uint64);
1304
0
      HANDLE_TYPE(SINT32, Int32, int32);
1305
0
      HANDLE_TYPE(SINT64, Int64, int64);
1306
0
      HANDLE_TYPE(FIXED32, UInt32, uint32);
1307
0
      HANDLE_TYPE(FIXED64, UInt64, uint64);
1308
0
      HANDLE_TYPE(SFIXED32, Int32, int32);
1309
0
      HANDLE_TYPE(SFIXED64, Int64, int64);
1310
0
      HANDLE_TYPE(FLOAT, Float, float);
1311
0
      HANDLE_TYPE(DOUBLE, Double, double);
1312
0
      HANDLE_TYPE(BOOL, Bool, bool);
1313
0
#undef HANDLE_TYPE
1314
1315
0
      case WireFormatLite::TYPE_ENUM: {
1316
0
        int value;
1317
0
        if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1318
0
                input, &value))
1319
0
          return false;
1320
1321
0
        if (!extension.enum_validity_check.func(
1322
0
                extension.enum_validity_check.arg, value)) {
1323
          // Invalid value.  Treat as unknown.
1324
0
          field_skipper->SkipUnknownEnum(number, value);
1325
0
        } else if (extension.is_repeated) {
1326
0
          AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
1327
0
                  extension.descriptor);
1328
0
        } else {
1329
0
          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1330
0
                  extension.descriptor);
1331
0
        }
1332
0
        break;
1333
0
      }
1334
1335
0
      case WireFormatLite::TYPE_STRING: {
1336
0
        std::string* value =
1337
0
            extension.is_repeated
1338
0
                ? AddString(number, WireFormatLite::TYPE_STRING,
1339
0
                            extension.descriptor)
1340
0
                : MutableString(number, WireFormatLite::TYPE_STRING,
1341
0
                                extension.descriptor);
1342
0
        if (!WireFormatLite::ReadString(input, value)) return false;
1343
0
        break;
1344
0
      }
1345
1346
0
      case WireFormatLite::TYPE_BYTES: {
1347
0
        std::string* value =
1348
0
            extension.is_repeated
1349
0
                ? AddString(number, WireFormatLite::TYPE_BYTES,
1350
0
                            extension.descriptor)
1351
0
                : MutableString(number, WireFormatLite::TYPE_BYTES,
1352
0
                                extension.descriptor);
1353
0
        if (!WireFormatLite::ReadBytes(input, value)) return false;
1354
0
        break;
1355
0
      }
1356
1357
0
      case WireFormatLite::TYPE_GROUP: {
1358
0
        MessageLite* value =
1359
0
            extension.is_repeated
1360
0
                ? AddMessage(number, WireFormatLite::TYPE_GROUP,
1361
0
                             *extension.message_info.prototype,
1362
0
                             extension.descriptor)
1363
0
                : MutableMessage(number, WireFormatLite::TYPE_GROUP,
1364
0
                                 *extension.message_info.prototype,
1365
0
                                 extension.descriptor);
1366
0
        if (!WireFormatLite::ReadGroup(number, input, value)) return false;
1367
0
        break;
1368
0
      }
1369
1370
0
      case WireFormatLite::TYPE_MESSAGE: {
1371
0
        MessageLite* value =
1372
0
            extension.is_repeated
1373
0
                ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
1374
0
                             *extension.message_info.prototype,
1375
0
                             extension.descriptor)
1376
0
                : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
1377
0
                                 *extension.message_info.prototype,
1378
0
                                 extension.descriptor);
1379
0
        if (!WireFormatLite::ReadMessage(input, value)) return false;
1380
0
        break;
1381
0
      }
1382
0
    }
1383
0
  }
1384
1385
0
  return true;
1386
0
}
1387
1388
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1389
0
                              const MessageLite* containing_type) {
1390
0
  FieldSkipper skipper;
1391
0
  GeneratedExtensionFinder finder(containing_type);
1392
0
  return ParseField(tag, input, &finder, &skipper);
1393
0
}
1394
1395
bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1396
                              const MessageLite* containing_type,
1397
0
                              io::CodedOutputStream* unknown_fields) {
1398
0
  CodedOutputStreamFieldSkipper skipper(unknown_fields);
1399
0
  GeneratedExtensionFinder finder(containing_type);
1400
0
  return ParseField(tag, input, &finder, &skipper);
1401
0
}
1402
1403
bool ExtensionSet::ParseMessageSetLite(io::CodedInputStream* input,
1404
                                       ExtensionFinder* extension_finder,
1405
0
                                       FieldSkipper* field_skipper) {
1406
0
  while (true) {
1407
0
    const uint32 tag = input->ReadTag();
1408
0
    switch (tag) {
1409
0
      case 0:
1410
0
        return true;
1411
0
      case WireFormatLite::kMessageSetItemStartTag:
1412
0
        if (!ParseMessageSetItemLite(input, extension_finder, field_skipper)) {
1413
0
          return false;
1414
0
        }
1415
0
        break;
1416
0
      default:
1417
0
        if (!ParseField(tag, input, extension_finder, field_skipper)) {
1418
0
          return false;
1419
0
        }
1420
0
        break;
1421
0
    }
1422
0
  }
1423
0
}
1424
1425
bool ExtensionSet::ParseMessageSetItemLite(io::CodedInputStream* input,
1426
                                           ExtensionFinder* extension_finder,
1427
0
                                           FieldSkipper* field_skipper) {
1428
0
  struct MSLite {
1429
0
    bool ParseField(int type_id, io::CodedInputStream* input) {
1430
0
      return me->ParseField(
1431
0
          WireFormatLite::WIRETYPE_LENGTH_DELIMITED + 8 * type_id, input,
1432
0
          extension_finder, field_skipper);
1433
0
    }
1434
1435
0
    bool SkipField(uint32 tag, io::CodedInputStream* input) {
1436
0
      return field_skipper->SkipField(input, tag);
1437
0
    }
1438
1439
0
    ExtensionSet* me;
1440
0
    ExtensionFinder* extension_finder;
1441
0
    FieldSkipper* field_skipper;
1442
0
  };
1443
1444
0
  return ParseMessageSetItemImpl(input,
1445
0
                                 MSLite{this, extension_finder, field_skipper});
1446
0
}
1447
1448
bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1449
                                   const MessageLite* containing_type,
1450
0
                                   std::string* unknown_fields) {
1451
0
  io::StringOutputStream zcis(unknown_fields);
1452
0
  io::CodedOutputStream output(&zcis);
1453
0
  CodedOutputStreamFieldSkipper skipper(&output);
1454
0
  GeneratedExtensionFinder finder(containing_type);
1455
0
  return ParseMessageSetLite(input, &finder, &skipper);
1456
0
}
1457
1458
uint8* ExtensionSet::_InternalSerialize(int start_field_number,
1459
                                        int end_field_number, uint8* target,
1460
113
                                        io::EpsCopyOutputStream* stream) const {
1461
113
  if (PROTOBUF_PREDICT_FALSE(is_large())) {
1462
0
    const auto& end = map_.large->end();
1463
0
    for (auto it = map_.large->lower_bound(start_field_number);
1464
0
         it != end && it->first < end_field_number; ++it) {
1465
0
      target = it->second.InternalSerializeFieldWithCachedSizesToArray(
1466
0
          it->first, target, stream);
1467
0
    }
1468
0
    return target;
1469
0
  }
1470
113
  const KeyValue* end = flat_end();
1471
113
  for (const KeyValue* it = std::lower_bound(
1472
113
           flat_begin(), end, start_field_number, KeyValue::FirstComparator());
1473
113
       it != end && it->first < end_field_number; ++it) {
1474
0
    target = it->second.InternalSerializeFieldWithCachedSizesToArray(
1475
0
        it->first, target, stream);
1476
0
  }
1477
113
  return target;
1478
113
}
1479
1480
uint8* ExtensionSet::InternalSerializeMessageSetWithCachedSizesToArray(
1481
0
    uint8* target, io::EpsCopyOutputStream* stream) const {
1482
0
  ForEach([&target, stream](int number, const Extension& ext) {
1483
0
    target = ext.InternalSerializeMessageSetItemWithCachedSizesToArray(
1484
0
        number, target, stream);
1485
0
  });
1486
0
  return target;
1487
0
}
1488
1489
113
size_t ExtensionSet::ByteSize() const {
1490
113
  size_t total_size = 0;
1491
113
  ForEach([&total_size](int number, const Extension& ext) {
1492
0
    total_size += ext.ByteSize(number);
1493
0
  });
1494
113
  return total_size;
1495
113
}
1496
1497
// Defined in extension_set_heavy.cc.
1498
// int ExtensionSet::SpaceUsedExcludingSelf() const
1499
1500
bool ExtensionSet::MaybeNewExtension(int number,
1501
                                     const FieldDescriptor* descriptor,
1502
0
                                     Extension** result) {
1503
0
  bool extension_is_new = false;
1504
0
  std::tie(*result, extension_is_new) = Insert(number);
1505
0
  (*result)->descriptor = descriptor;
1506
0
  return extension_is_new;
1507
0
}
1508
1509
// ===================================================================
1510
// Methods of ExtensionSet::Extension
1511
1512
0
void ExtensionSet::Extension::Clear() {
1513
0
  if (is_repeated) {
1514
0
    switch (cpp_type(type)) {
1515
0
#define HANDLE_TYPE(UPPERCASE, LOWERCASE)   \
1516
0
  case WireFormatLite::CPPTYPE_##UPPERCASE: \
1517
0
    repeated_##LOWERCASE##_value->Clear();  \
1518
0
    break
1519
1520
0
      HANDLE_TYPE(INT32, int32);
1521
0
      HANDLE_TYPE(INT64, int64);
1522
0
      HANDLE_TYPE(UINT32, uint32);
1523
0
      HANDLE_TYPE(UINT64, uint64);
1524
0
      HANDLE_TYPE(FLOAT, float);
1525
0
      HANDLE_TYPE(DOUBLE, double);
1526
0
      HANDLE_TYPE(BOOL, bool);
1527
0
      HANDLE_TYPE(ENUM, enum);
1528
0
      HANDLE_TYPE(STRING, string);
1529
0
      HANDLE_TYPE(MESSAGE, message);
1530
0
#undef HANDLE_TYPE
1531
0
    }
1532
0
  } else {
1533
0
    if (!is_cleared) {
1534
0
      switch (cpp_type(type)) {
1535
0
        case WireFormatLite::CPPTYPE_STRING:
1536
0
          string_value->clear();
1537
0
          break;
1538
0
        case WireFormatLite::CPPTYPE_MESSAGE:
1539
0
          if (is_lazy) {
1540
0
            lazymessage_value->Clear();
1541
0
          } else {
1542
0
            message_value->Clear();
1543
0
          }
1544
0
          break;
1545
0
        default:
1546
          // No need to do anything.  Get*() will return the default value
1547
          // as long as is_cleared is true and Set*() will overwrite the
1548
          // previous value.
1549
0
          break;
1550
0
      }
1551
1552
0
      is_cleared = true;
1553
0
    }
1554
0
  }
1555
0
}
1556
1557
0
size_t ExtensionSet::Extension::ByteSize(int number) const {
1558
0
  size_t result = 0;
1559
1560
0
  if (is_repeated) {
1561
0
    if (is_packed) {
1562
0
      switch (real_type(type)) {
1563
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                 \
1564
0
  case WireFormatLite::TYPE_##UPPERCASE:                             \
1565
0
    for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1566
0
      result += WireFormatLite::CAMELCASE##Size(                     \
1567
0
          repeated_##LOWERCASE##_value->Get(i));                     \
1568
0
    }                                                                \
1569
0
    break
1570
1571
0
        HANDLE_TYPE(INT32, Int32, int32);
1572
0
        HANDLE_TYPE(INT64, Int64, int64);
1573
0
        HANDLE_TYPE(UINT32, UInt32, uint32);
1574
0
        HANDLE_TYPE(UINT64, UInt64, uint64);
1575
0
        HANDLE_TYPE(SINT32, SInt32, int32);
1576
0
        HANDLE_TYPE(SINT64, SInt64, int64);
1577
0
        HANDLE_TYPE(ENUM, Enum, enum);
1578
0
#undef HANDLE_TYPE
1579
1580
        // Stuff with fixed size.
1581
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)             \
1582
0
  case WireFormatLite::TYPE_##UPPERCASE:                         \
1583
0
    result += WireFormatLite::k##CAMELCASE##Size *               \
1584
0
              FromIntSize(repeated_##LOWERCASE##_value->size()); \
1585
0
    break
1586
0
        HANDLE_TYPE(FIXED32, Fixed32, uint32);
1587
0
        HANDLE_TYPE(FIXED64, Fixed64, uint64);
1588
0
        HANDLE_TYPE(SFIXED32, SFixed32, int32);
1589
0
        HANDLE_TYPE(SFIXED64, SFixed64, int64);
1590
0
        HANDLE_TYPE(FLOAT, Float, float);
1591
0
        HANDLE_TYPE(DOUBLE, Double, double);
1592
0
        HANDLE_TYPE(BOOL, Bool, bool);
1593
0
#undef HANDLE_TYPE
1594
1595
0
        case WireFormatLite::TYPE_STRING:
1596
0
        case WireFormatLite::TYPE_BYTES:
1597
0
        case WireFormatLite::TYPE_GROUP:
1598
0
        case WireFormatLite::TYPE_MESSAGE:
1599
0
          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1600
0
          break;
1601
0
      }
1602
1603
0
      cached_size = ToCachedSize(result);
1604
0
      if (result > 0) {
1605
0
        result += io::CodedOutputStream::VarintSize32(result);
1606
0
        result += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
1607
0
            number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1608
0
      }
1609
0
    } else {
1610
0
      size_t tag_size = WireFormatLite::TagSize(number, real_type(type));
1611
1612
0
      switch (real_type(type)) {
1613
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
1614
0
  case WireFormatLite::TYPE_##UPPERCASE:                                    \
1615
0
    result += tag_size * FromIntSize(repeated_##LOWERCASE##_value->size()); \
1616
0
    for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {        \
1617
0
      result += WireFormatLite::CAMELCASE##Size(                            \
1618
0
          repeated_##LOWERCASE##_value->Get(i));                            \
1619
0
    }                                                                       \
1620
0
    break
1621
1622
0
        HANDLE_TYPE(INT32, Int32, int32);
1623
0
        HANDLE_TYPE(INT64, Int64, int64);
1624
0
        HANDLE_TYPE(UINT32, UInt32, uint32);
1625
0
        HANDLE_TYPE(UINT64, UInt64, uint64);
1626
0
        HANDLE_TYPE(SINT32, SInt32, int32);
1627
0
        HANDLE_TYPE(SINT64, SInt64, int64);
1628
0
        HANDLE_TYPE(STRING, String, string);
1629
0
        HANDLE_TYPE(BYTES, Bytes, string);
1630
0
        HANDLE_TYPE(ENUM, Enum, enum);
1631
0
        HANDLE_TYPE(GROUP, Group, message);
1632
0
        HANDLE_TYPE(MESSAGE, Message, message);
1633
0
#undef HANDLE_TYPE
1634
1635
        // Stuff with fixed size.
1636
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)             \
1637
0
  case WireFormatLite::TYPE_##UPPERCASE:                         \
1638
0
    result += (tag_size + WireFormatLite::k##CAMELCASE##Size) *  \
1639
0
              FromIntSize(repeated_##LOWERCASE##_value->size()); \
1640
0
    break
1641
0
        HANDLE_TYPE(FIXED32, Fixed32, uint32);
1642
0
        HANDLE_TYPE(FIXED64, Fixed64, uint64);
1643
0
        HANDLE_TYPE(SFIXED32, SFixed32, int32);
1644
0
        HANDLE_TYPE(SFIXED64, SFixed64, int64);
1645
0
        HANDLE_TYPE(FLOAT, Float, float);
1646
0
        HANDLE_TYPE(DOUBLE, Double, double);
1647
0
        HANDLE_TYPE(BOOL, Bool, bool);
1648
0
#undef HANDLE_TYPE
1649
0
      }
1650
0
    }
1651
0
  } else if (!is_cleared) {
1652
0
    result += WireFormatLite::TagSize(number, real_type(type));
1653
0
    switch (real_type(type)) {
1654
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)      \
1655
0
  case WireFormatLite::TYPE_##UPPERCASE:                  \
1656
0
    result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
1657
0
    break
1658
1659
0
      HANDLE_TYPE(INT32, Int32, int32_value);
1660
0
      HANDLE_TYPE(INT64, Int64, int64_value);
1661
0
      HANDLE_TYPE(UINT32, UInt32, uint32_value);
1662
0
      HANDLE_TYPE(UINT64, UInt64, uint64_value);
1663
0
      HANDLE_TYPE(SINT32, SInt32, int32_value);
1664
0
      HANDLE_TYPE(SINT64, SInt64, int64_value);
1665
0
      HANDLE_TYPE(STRING, String, *string_value);
1666
0
      HANDLE_TYPE(BYTES, Bytes, *string_value);
1667
0
      HANDLE_TYPE(ENUM, Enum, enum_value);
1668
0
      HANDLE_TYPE(GROUP, Group, *message_value);
1669
0
#undef HANDLE_TYPE
1670
0
      case WireFormatLite::TYPE_MESSAGE: {
1671
0
        if (is_lazy) {
1672
0
          size_t size = lazymessage_value->ByteSizeLong();
1673
0
          result += io::CodedOutputStream::VarintSize32(size) + size;
1674
0
        } else {
1675
0
          result += WireFormatLite::MessageSize(*message_value);
1676
0
        }
1677
0
        break;
1678
0
      }
1679
1680
      // Stuff with fixed size.
1681
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE)         \
1682
0
  case WireFormatLite::TYPE_##UPPERCASE:          \
1683
0
    result += WireFormatLite::k##CAMELCASE##Size; \
1684
0
    break
1685
0
        HANDLE_TYPE(FIXED32, Fixed32);
1686
0
        HANDLE_TYPE(FIXED64, Fixed64);
1687
0
        HANDLE_TYPE(SFIXED32, SFixed32);
1688
0
        HANDLE_TYPE(SFIXED64, SFixed64);
1689
0
        HANDLE_TYPE(FLOAT, Float);
1690
0
        HANDLE_TYPE(DOUBLE, Double);
1691
0
        HANDLE_TYPE(BOOL, Bool);
1692
0
#undef HANDLE_TYPE
1693
0
    }
1694
0
  }
1695
1696
0
  return result;
1697
0
}
1698
1699
0
int ExtensionSet::Extension::GetSize() const {
1700
0
  GOOGLE_DCHECK(is_repeated);
1701
0
  switch (cpp_type(type)) {
1702
0
#define HANDLE_TYPE(UPPERCASE, LOWERCASE)   \
1703
0
  case WireFormatLite::CPPTYPE_##UPPERCASE: \
1704
0
    return repeated_##LOWERCASE##_value->size()
1705
1706
0
    HANDLE_TYPE(INT32, int32);
1707
0
    HANDLE_TYPE(INT64, int64);
1708
0
    HANDLE_TYPE(UINT32, uint32);
1709
0
    HANDLE_TYPE(UINT64, uint64);
1710
0
    HANDLE_TYPE(FLOAT, float);
1711
0
    HANDLE_TYPE(DOUBLE, double);
1712
0
    HANDLE_TYPE(BOOL, bool);
1713
0
    HANDLE_TYPE(ENUM, enum);
1714
0
    HANDLE_TYPE(STRING, string);
1715
0
    HANDLE_TYPE(MESSAGE, message);
1716
0
#undef HANDLE_TYPE
1717
0
  }
1718
1719
0
  GOOGLE_LOG(FATAL) << "Can't get here.";
1720
0
  return 0;
1721
0
}
1722
1723
// This function deletes all allocated objects. This function should be only
1724
// called if the Extension was created with an arena.
1725
0
void ExtensionSet::Extension::Free() {
1726
0
  if (is_repeated) {
1727
0
    switch (cpp_type(type)) {
1728
0
#define HANDLE_TYPE(UPPERCASE, LOWERCASE)   \
1729
0
  case WireFormatLite::CPPTYPE_##UPPERCASE: \
1730
0
    delete repeated_##LOWERCASE##_value;    \
1731
0
    break
1732
1733
0
      HANDLE_TYPE(INT32, int32);
1734
0
      HANDLE_TYPE(INT64, int64);
1735
0
      HANDLE_TYPE(UINT32, uint32);
1736
0
      HANDLE_TYPE(UINT64, uint64);
1737
0
      HANDLE_TYPE(FLOAT, float);
1738
0
      HANDLE_TYPE(DOUBLE, double);
1739
0
      HANDLE_TYPE(BOOL, bool);
1740
0
      HANDLE_TYPE(ENUM, enum);
1741
0
      HANDLE_TYPE(STRING, string);
1742
0
      HANDLE_TYPE(MESSAGE, message);
1743
0
#undef HANDLE_TYPE
1744
0
    }
1745
0
  } else {
1746
0
    switch (cpp_type(type)) {
1747
0
      case WireFormatLite::CPPTYPE_STRING:
1748
0
        delete string_value;
1749
0
        break;
1750
0
      case WireFormatLite::CPPTYPE_MESSAGE:
1751
0
        if (is_lazy) {
1752
0
          delete lazymessage_value;
1753
0
        } else {
1754
0
          delete message_value;
1755
0
        }
1756
0
        break;
1757
0
      default:
1758
0
        break;
1759
0
    }
1760
0
  }
1761
0
}
1762
1763
// Defined in extension_set_heavy.cc.
1764
// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1765
1766
0
bool ExtensionSet::Extension::IsInitialized() const {
1767
0
  if (cpp_type(type) == WireFormatLite::CPPTYPE_MESSAGE) {
1768
0
    if (is_repeated) {
1769
0
      for (int i = 0; i < repeated_message_value->size(); i++) {
1770
0
        if (!repeated_message_value->Get(i).IsInitialized()) {
1771
0
          return false;
1772
0
        }
1773
0
      }
1774
0
    } else {
1775
0
      if (!is_cleared) {
1776
0
        if (is_lazy) {
1777
0
          if (!lazymessage_value->IsInitialized()) return false;
1778
0
        } else {
1779
0
          if (!message_value->IsInitialized()) return false;
1780
0
        }
1781
0
      }
1782
0
    }
1783
0
  }
1784
0
  return true;
1785
0
}
1786
1787
// Dummy key method to avoid weak vtable.
1788
0
void ExtensionSet::LazyMessageExtension::UnusedKeyMethod() {}
1789
1790
0
const ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) const {
1791
0
  if (PROTOBUF_PREDICT_FALSE(is_large())) {
1792
0
    return FindOrNullInLargeMap(key);
1793
0
  }
1794
0
  const KeyValue* end = flat_end();
1795
0
  const KeyValue* it =
1796
0
      std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1797
0
  if (it != end && it->first == key) {
1798
0
    return &it->second;
1799
0
  }
1800
0
  return NULL;
1801
0
}
1802
1803
const ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap(
1804
0
    int key) const {
1805
0
  assert(is_large());
1806
0
  LargeMap::const_iterator it = map_.large->find(key);
1807
0
  if (it != map_.large->end()) {
1808
0
    return &it->second;
1809
0
  }
1810
0
  return NULL;
1811
0
}
1812
1813
0
ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) {
1814
0
  if (PROTOBUF_PREDICT_FALSE(is_large())) {
1815
0
    return FindOrNullInLargeMap(key);
1816
0
  }
1817
0
  KeyValue* end = flat_end();
1818
0
  KeyValue* it =
1819
0
      std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1820
0
  if (it != end && it->first == key) {
1821
0
    return &it->second;
1822
0
  }
1823
0
  return NULL;
1824
0
}
1825
1826
0
ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap(int key) {
1827
0
  assert(is_large());
1828
0
  LargeMap::iterator it = map_.large->find(key);
1829
0
  if (it != map_.large->end()) {
1830
0
    return &it->second;
1831
0
  }
1832
0
  return NULL;
1833
0
}
1834
1835
0
std::pair<ExtensionSet::Extension*, bool> ExtensionSet::Insert(int key) {
1836
0
  if (PROTOBUF_PREDICT_FALSE(is_large())) {
1837
0
    auto maybe = map_.large->insert({key, Extension()});
1838
0
    return {&maybe.first->second, maybe.second};
1839
0
  }
1840
0
  KeyValue* end = flat_end();
1841
0
  KeyValue* it =
1842
0
      std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1843
0
  if (it != end && it->first == key) {
1844
0
    return {&it->second, false};
1845
0
  }
1846
0
  if (flat_size_ < flat_capacity_) {
1847
0
    std::copy_backward(it, end, end + 1);
1848
0
    ++flat_size_;
1849
0
    it->first = key;
1850
0
    it->second = Extension();
1851
0
    return {&it->second, true};
1852
0
  }
1853
0
  GrowCapacity(flat_size_ + 1);
1854
0
  return Insert(key);
1855
0
}
1856
1857
0
void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) {
1858
0
  if (PROTOBUF_PREDICT_FALSE(is_large())) {
1859
0
    return;  // LargeMap does not have a "reserve" method.
1860
0
  }
1861
0
  if (flat_capacity_ >= minimum_new_capacity) {
1862
0
    return;
1863
0
  }
1864
1865
0
  auto new_flat_capacity = flat_capacity_;
1866
0
  do {
1867
0
    new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 4;
1868
0
  } while (new_flat_capacity < minimum_new_capacity);
1869
1870
0
  const KeyValue* begin = flat_begin();
1871
0
  const KeyValue* end = flat_end();
1872
0
  AllocatedData new_map;
1873
0
  if (new_flat_capacity > kMaximumFlatCapacity) {
1874
0
    new_map.large = Arena::Create<LargeMap>(arena_);
1875
0
    LargeMap::iterator hint = new_map.large->begin();
1876
0
    for (const KeyValue* it = begin; it != end; ++it) {
1877
0
      hint = new_map.large->insert(hint, {it->first, it->second});
1878
0
    }
1879
0
  } else {
1880
0
    new_map.flat = Arena::CreateArray<KeyValue>(arena_, new_flat_capacity);
1881
0
    std::copy(begin, end, new_map.flat);
1882
0
  }
1883
1884
0
  if (arena_ == nullptr) {
1885
0
    DeleteFlatMap(begin, flat_capacity_);
1886
0
  }
1887
0
  flat_capacity_ = new_flat_capacity;
1888
0
  map_ = new_map;
1889
0
  if (is_large()) {
1890
0
    flat_size_ = 0;
1891
0
  }
1892
0
}
1893
1894
// static
1895
constexpr uint16 ExtensionSet::kMaximumFlatCapacity;
1896
1897
0
void ExtensionSet::Erase(int key) {
1898
0
  if (PROTOBUF_PREDICT_FALSE(is_large())) {
1899
0
    map_.large->erase(key);
1900
0
    return;
1901
0
  }
1902
0
  KeyValue* end = flat_end();
1903
0
  KeyValue* it =
1904
0
      std::lower_bound(flat_begin(), end, key, KeyValue::FirstComparator());
1905
0
  if (it != end && it->first == key) {
1906
0
    std::copy(it + 1, end, it);
1907
0
    --flat_size_;
1908
0
  }
1909
0
}
1910
1911
// ==================================================================
1912
// Default repeated field instances for iterator-compatible accessors
1913
1914
0
const RepeatedPrimitiveDefaults* RepeatedPrimitiveDefaults::default_instance() {
1915
0
  static auto instance = OnShutdownDelete(new RepeatedPrimitiveDefaults);
1916
0
  return instance;
1917
0
}
1918
1919
const RepeatedStringTypeTraits::RepeatedFieldType*
1920
0
RepeatedStringTypeTraits::GetDefaultRepeatedField() {
1921
0
  static auto instance = OnShutdownDelete(new RepeatedFieldType);
1922
0
  return instance;
1923
0
}
1924
1925
uint8* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray(
1926
0
    int number, uint8* target, io::EpsCopyOutputStream* stream) const {
1927
0
  if (is_repeated) {
1928
0
    if (is_packed) {
1929
0
      if (cached_size == 0) return target;
1930
1931
0
      target = stream->EnsureSpace(target);
1932
0
      target = WireFormatLite::WriteTagToArray(
1933
0
          number, WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
1934
0
      target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
1935
1936
0
      switch (real_type(type)) {
1937
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                 \
1938
0
  case WireFormatLite::TYPE_##UPPERCASE:                             \
1939
0
    for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1940
0
      target = stream->EnsureSpace(target);                          \
1941
0
      target = WireFormatLite::Write##CAMELCASE##NoTagToArray(       \
1942
0
          repeated_##LOWERCASE##_value->Get(i), target);             \
1943
0
    }                                                                \
1944
0
    break
1945
1946
0
        HANDLE_TYPE(INT32, Int32, int32);
1947
0
        HANDLE_TYPE(INT64, Int64, int64);
1948
0
        HANDLE_TYPE(UINT32, UInt32, uint32);
1949
0
        HANDLE_TYPE(UINT64, UInt64, uint64);
1950
0
        HANDLE_TYPE(SINT32, SInt32, int32);
1951
0
        HANDLE_TYPE(SINT64, SInt64, int64);
1952
0
        HANDLE_TYPE(FIXED32, Fixed32, uint32);
1953
0
        HANDLE_TYPE(FIXED64, Fixed64, uint64);
1954
0
        HANDLE_TYPE(SFIXED32, SFixed32, int32);
1955
0
        HANDLE_TYPE(SFIXED64, SFixed64, int64);
1956
0
        HANDLE_TYPE(FLOAT, Float, float);
1957
0
        HANDLE_TYPE(DOUBLE, Double, double);
1958
0
        HANDLE_TYPE(BOOL, Bool, bool);
1959
0
        HANDLE_TYPE(ENUM, Enum, enum);
1960
0
#undef HANDLE_TYPE
1961
1962
0
        case WireFormatLite::TYPE_STRING:
1963
0
        case WireFormatLite::TYPE_BYTES:
1964
0
        case WireFormatLite::TYPE_GROUP:
1965
0
        case WireFormatLite::TYPE_MESSAGE:
1966
0
          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1967
0
          break;
1968
0
      }
1969
0
    } else {
1970
0
      switch (real_type(type)) {
1971
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                 \
1972
0
  case WireFormatLite::TYPE_##UPPERCASE:                             \
1973
0
    for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1974
0
      target = stream->EnsureSpace(target);                          \
1975
0
      target = WireFormatLite::Write##CAMELCASE##ToArray(            \
1976
0
          number, repeated_##LOWERCASE##_value->Get(i), target);     \
1977
0
    }                                                                \
1978
0
    break
1979
1980
0
        HANDLE_TYPE(INT32, Int32, int32);
1981
0
        HANDLE_TYPE(INT64, Int64, int64);
1982
0
        HANDLE_TYPE(UINT32, UInt32, uint32);
1983
0
        HANDLE_TYPE(UINT64, UInt64, uint64);
1984
0
        HANDLE_TYPE(SINT32, SInt32, int32);
1985
0
        HANDLE_TYPE(SINT64, SInt64, int64);
1986
0
        HANDLE_TYPE(FIXED32, Fixed32, uint32);
1987
0
        HANDLE_TYPE(FIXED64, Fixed64, uint64);
1988
0
        HANDLE_TYPE(SFIXED32, SFixed32, int32);
1989
0
        HANDLE_TYPE(SFIXED64, SFixed64, int64);
1990
0
        HANDLE_TYPE(FLOAT, Float, float);
1991
0
        HANDLE_TYPE(DOUBLE, Double, double);
1992
0
        HANDLE_TYPE(BOOL, Bool, bool);
1993
0
        HANDLE_TYPE(ENUM, Enum, enum);
1994
0
#undef HANDLE_TYPE
1995
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                 \
1996
0
  case WireFormatLite::TYPE_##UPPERCASE:                             \
1997
0
    for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1998
0
      target = stream->EnsureSpace(target);                          \
1999
0
      target = stream->WriteString(                                  \
2000
0
          number, repeated_##LOWERCASE##_value->Get(i), target);     \
2001
0
    }                                                                \
2002
0
    break
2003
0
        HANDLE_TYPE(STRING, String, string);
2004
0
        HANDLE_TYPE(BYTES, Bytes, string);
2005
0
#undef HANDLE_TYPE
2006
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                     \
2007
0
  case WireFormatLite::TYPE_##UPPERCASE:                                 \
2008
0
    for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {     \
2009
0
      target = stream->EnsureSpace(target);                              \
2010
0
      target = WireFormatLite::InternalWrite##CAMELCASE(                 \
2011
0
          number, repeated_##LOWERCASE##_value->Get(i), target, stream); \
2012
0
    }                                                                    \
2013
0
    break
2014
2015
0
        HANDLE_TYPE(GROUP, Group, message);
2016
0
        HANDLE_TYPE(MESSAGE, Message, message);
2017
0
#undef HANDLE_TYPE
2018
0
      }
2019
0
    }
2020
0
  } else if (!is_cleared) {
2021
0
    switch (real_type(type)) {
2022
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                               \
2023
0
  case WireFormatLite::TYPE_##UPPERCASE:                                       \
2024
0
    target = stream->EnsureSpace(target);                                      \
2025
0
    target = WireFormatLite::Write##CAMELCASE##ToArray(number, VALUE, target); \
2026
0
    break
2027
2028
0
      HANDLE_TYPE(INT32, Int32, int32_value);
2029
0
      HANDLE_TYPE(INT64, Int64, int64_value);
2030
0
      HANDLE_TYPE(UINT32, UInt32, uint32_value);
2031
0
      HANDLE_TYPE(UINT64, UInt64, uint64_value);
2032
0
      HANDLE_TYPE(SINT32, SInt32, int32_value);
2033
0
      HANDLE_TYPE(SINT64, SInt64, int64_value);
2034
0
      HANDLE_TYPE(FIXED32, Fixed32, uint32_value);
2035
0
      HANDLE_TYPE(FIXED64, Fixed64, uint64_value);
2036
0
      HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
2037
0
      HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
2038
0
      HANDLE_TYPE(FLOAT, Float, float_value);
2039
0
      HANDLE_TYPE(DOUBLE, Double, double_value);
2040
0
      HANDLE_TYPE(BOOL, Bool, bool_value);
2041
0
      HANDLE_TYPE(ENUM, Enum, enum_value);
2042
0
#undef HANDLE_TYPE
2043
0
#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)         \
2044
0
  case WireFormatLite::TYPE_##UPPERCASE:                 \
2045
0
    target = stream->EnsureSpace(target);                \
2046
0
    target = stream->WriteString(number, VALUE, target); \
2047
0
    break
2048
0
      HANDLE_TYPE(STRING, String, *string_value);
2049
0
      HANDLE_TYPE(BYTES, Bytes, *string_value);
2050
0
#undef HANDLE_TYPE
2051
0
      case WireFormatLite::TYPE_GROUP:
2052
0
        target = stream->EnsureSpace(target);
2053
0
        target = WireFormatLite::InternalWriteGroup(number, *message_value,
2054
0
                                                    target, stream);
2055
0
        break;
2056
0
      case WireFormatLite::TYPE_MESSAGE:
2057
0
        if (is_lazy) {
2058
0
          target =
2059
0
              lazymessage_value->WriteMessageToArray(number, target, stream);
2060
0
        } else {
2061
0
          target = stream->EnsureSpace(target);
2062
0
          target = WireFormatLite::InternalWriteMessage(number, *message_value,
2063
0
                                                        target, stream);
2064
0
        }
2065
0
        break;
2066
0
    }
2067
0
  }
2068
0
  return target;
2069
0
}
2070
2071
uint8*
2072
ExtensionSet::Extension::InternalSerializeMessageSetItemWithCachedSizesToArray(
2073
0
    int number, uint8* target, io::EpsCopyOutputStream* stream) const {
2074
0
  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
2075
    // Not a valid MessageSet extension, but serialize it the normal way.
2076
0
    GOOGLE_LOG(WARNING) << "Invalid message set extension.";
2077
0
    return InternalSerializeFieldWithCachedSizesToArray(number, target, stream);
2078
0
  }
2079
2080
0
  if (is_cleared) return target;
2081
2082
0
  target = stream->EnsureSpace(target);
2083
  // Start group.
2084
0
  target = io::CodedOutputStream::WriteTagToArray(
2085
0
      WireFormatLite::kMessageSetItemStartTag, target);
2086
  // Write type ID.
2087
0
  target = WireFormatLite::WriteUInt32ToArray(
2088
0
      WireFormatLite::kMessageSetTypeIdNumber, number, target);
2089
  // Write message.
2090
0
  if (is_lazy) {
2091
0
    target = lazymessage_value->WriteMessageToArray(
2092
0
        WireFormatLite::kMessageSetMessageNumber, target, stream);
2093
0
  } else {
2094
0
    target = WireFormatLite::InternalWriteMessage(
2095
0
        WireFormatLite::kMessageSetMessageNumber, *message_value, target,
2096
0
        stream);
2097
0
  }
2098
  // End group.
2099
0
  target = stream->EnsureSpace(target);
2100
0
  target = io::CodedOutputStream::WriteTagToArray(
2101
0
      WireFormatLite::kMessageSetItemEndTag, target);
2102
0
  return target;
2103
0
}
2104
2105
0
size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
2106
0
  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
2107
    // Not a valid MessageSet extension, but compute the byte size for it the
2108
    // normal way.
2109
0
    return ByteSize(number);
2110
0
  }
2111
2112
0
  if (is_cleared) return 0;
2113
2114
0
  size_t our_size = WireFormatLite::kMessageSetItemTagsSize;
2115
2116
  // type_id
2117
0
  our_size += io::CodedOutputStream::VarintSize32(number);
2118
2119
  // message
2120
0
  size_t message_size = 0;
2121
0
  if (is_lazy) {
2122
0
    message_size = lazymessage_value->ByteSizeLong();
2123
0
  } else {
2124
0
    message_size = message_value->ByteSizeLong();
2125
0
  }
2126
2127
0
  our_size += io::CodedOutputStream::VarintSize32(message_size);
2128
0
  our_size += message_size;
2129
2130
0
  return our_size;
2131
0
}
2132
2133
0
size_t ExtensionSet::MessageSetByteSize() const {
2134
0
  size_t total_size = 0;
2135
0
  ForEach([&total_size](int number, const Extension& ext) {
2136
0
    total_size += ext.MessageSetItemByteSize(number);
2137
0
  });
2138
0
  return total_size;
2139
0
}
2140
2141
}  // namespace internal
2142
}  // namespace protobuf
2143
}  // namespace google