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/parse_context.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
#include <google/protobuf/parse_context.h>
32
33
#include <google/protobuf/stubs/stringprintf.h>
34
#include <google/protobuf/io/coded_stream.h>
35
#include <google/protobuf/io/zero_copy_stream.h>
36
#include <google/protobuf/arenastring.h>
37
#include <google/protobuf/message_lite.h>
38
#include <google/protobuf/repeated_field.h>
39
#include <google/protobuf/wire_format_lite.h>
40
#include <google/protobuf/stubs/strutil.h>
41
42
#include <google/protobuf/port_def.inc>
43
44
namespace google {
45
namespace protobuf {
46
namespace internal {
47
48
namespace {
49
50
// Only call if at start of tag.
51
0
bool ParseEndsInSlopRegion(const char* begin, int overrun, int depth) {
52
0
  constexpr int kSlopBytes = EpsCopyInputStream::kSlopBytes;
53
0
  GOOGLE_DCHECK(overrun >= 0);
54
0
  GOOGLE_DCHECK(overrun <= kSlopBytes);
55
0
  auto ptr = begin + overrun;
56
0
  auto end = begin + kSlopBytes;
57
0
  while (ptr < end) {
58
0
    uint32 tag;
59
0
    ptr = ReadTag(ptr, &tag);
60
0
    if (ptr == nullptr || ptr > end) return false;
61
    // ending on 0 tag is allowed and is the major reason for the necessity of
62
    // this function.
63
0
    if (tag == 0) return true;
64
0
    switch (tag & 7) {
65
0
      case 0: {  // Varint
66
0
        uint64 val;
67
0
        ptr = VarintParse(ptr, &val);
68
0
        if (ptr == nullptr) return false;
69
0
        break;
70
0
      }
71
0
      case 1: {  // fixed64
72
0
        ptr += 8;
73
0
        break;
74
0
      }
75
0
      case 2: {  // len delim
76
0
        int32 size = ReadSize(&ptr);
77
0
        if (ptr == nullptr || size > end - ptr) return false;
78
0
        ptr += size;
79
0
        break;
80
0
      }
81
0
      case 3: {  // start group
82
0
        depth++;
83
0
        break;
84
0
      }
85
0
      case 4: {                    // end group
86
0
        if (--depth < 0) return true;  // We exit early
87
0
        break;
88
0
      }
89
0
      case 5: {  // fixed32
90
0
        ptr += 4;
91
0
        break;
92
0
      }
93
0
      default:
94
0
        return false;  // Unknown wireformat
95
0
    }
96
0
  }
97
0
  return false;
98
0
}
99
100
}  // namespace
101
102
0
const char* EpsCopyInputStream::NextBuffer(int overrun, int depth) {
103
0
  if (next_chunk_ == nullptr) return nullptr;  // We've reached end of stream.
104
0
  if (next_chunk_ != buffer_) {
105
0
    GOOGLE_DCHECK(size_ > kSlopBytes);
106
    // The chunk is large enough to be used directly
107
0
    buffer_end_ = next_chunk_ + size_ - kSlopBytes;
108
0
    auto res = next_chunk_;
109
0
    next_chunk_ = buffer_;
110
0
    if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
111
0
    return res;
112
0
  }
113
  // Move the slop bytes of previous buffer to start of the patch buffer.
114
  // Note we must use memmove because the previous buffer could be part of
115
  // buffer_.
116
0
  std::memmove(buffer_, buffer_end_, kSlopBytes);
117
0
  if (overall_limit_ > 0 &&
118
0
      (depth < 0 || !ParseEndsInSlopRegion(buffer_, overrun, depth))) {
119
0
    const void* data;
120
    // ZeroCopyInputStream indicates Next may return 0 size buffers. Hence
121
    // we loop.
122
0
    while (StreamNext(&data)) {
123
0
      if (size_ > kSlopBytes) {
124
        // We got a large chunk
125
0
        std::memcpy(buffer_ + kSlopBytes, data, kSlopBytes);
126
0
        next_chunk_ = static_cast<const char*>(data);
127
0
        buffer_end_ = buffer_ + kSlopBytes;
128
0
        if (aliasing_ >= kNoDelta) aliasing_ = kOnPatch;
129
0
        return buffer_;
130
0
      } else if (size_ > 0) {
131
0
        std::memcpy(buffer_ + kSlopBytes, data, size_);
132
0
        next_chunk_ = buffer_;
133
0
        buffer_end_ = buffer_ + size_;
134
0
        if (aliasing_ >= kNoDelta) aliasing_ = kOnPatch;
135
0
        return buffer_;
136
0
      }
137
0
      GOOGLE_DCHECK(size_ == 0) << size_;
138
0
    }
139
0
    overall_limit_ = 0;  // Next failed, no more needs for next
140
0
  }
141
  // End of stream or array
142
0
  if (aliasing_ == kNoDelta) {
143
    // If there is no more block and aliasing is true, the previous block
144
    // is still valid and we can alias. We have users relying on string_view's
145
    // obtained from protos to outlive the proto, when the parse was from an
146
    // array. This guarantees string_view's are always aliased if parsed from
147
    // an array.
148
0
    aliasing_ = reinterpret_cast<std::uintptr_t>(buffer_end_) -
149
0
                reinterpret_cast<std::uintptr_t>(buffer_);
150
0
  }
151
0
  next_chunk_ = nullptr;
152
0
  buffer_end_ = buffer_ + kSlopBytes;
153
0
  size_ = 0;
154
0
  return buffer_;
155
0
}
156
157
0
const char* EpsCopyInputStream::Next() {
158
0
  GOOGLE_DCHECK(limit_ > kSlopBytes);
159
0
  auto p = NextBuffer(0 /* immaterial */, -1);
160
0
  if (p == nullptr) {
161
0
    limit_end_ = buffer_end_;
162
    // Distinguish ending on a pushed limit or ending on end-of-stream.
163
0
    SetEndOfStream();
164
0
    return nullptr;
165
0
  }
166
0
  limit_ -= buffer_end_ - p;  // Adjust limit_ relative to new anchor
167
0
  limit_end_ = buffer_end_ + std::min(0, limit_);
168
0
  return p;
169
0
}
170
171
std::pair<const char*, bool> EpsCopyInputStream::DoneFallback(int overrun,
172
0
                                                              int depth) {
173
  // Did we exceeded the limit (parse error).
174
0
  if (PROTOBUF_PREDICT_FALSE(overrun > limit_)) return {nullptr, true};
175
0
  GOOGLE_DCHECK(overrun != limit_);  // Guaranteed by caller.
176
0
  GOOGLE_DCHECK(overrun < limit_);   // Follows from above
177
  // TODO(gerbens) Instead of this dcheck we could just assign, and remove
178
  // updating the limit_end from PopLimit, ie.
179
  // limit_end_ = buffer_end_ + (std::min)(0, limit_);
180
  // if (ptr < limit_end_) return {ptr, false};
181
0
  GOOGLE_DCHECK(limit_end_ == buffer_end_ + (std::min)(0, limit_));
182
  // At this point we know the following assertion holds.
183
0
  GOOGLE_DCHECK(limit_ > 0);
184
0
  GOOGLE_DCHECK(limit_end_ == buffer_end_);  // because limit_ > 0
185
0
  const char* p;
186
0
  do {
187
    // We are past the end of buffer_end_, in the slop region.
188
0
    GOOGLE_DCHECK(overrun >= 0);
189
0
    p = NextBuffer(overrun, depth);
190
0
    if (p == nullptr) {
191
      // We are at the end of the stream
192
0
      if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true};
193
0
      GOOGLE_DCHECK(limit_ > 0);
194
0
      limit_end_ = buffer_end_;
195
      // Distinguish ending on a pushed limit or ending on end-of-stream.
196
0
      SetEndOfStream();
197
0
      return {buffer_end_, true};
198
0
    }
199
0
    limit_ -= buffer_end_ - p;  // Adjust limit_ relative to new anchor
200
0
    p += overrun;
201
0
    overrun = p - buffer_end_;
202
0
  } while (overrun >= 0);
203
0
  limit_end_ = buffer_end_ + std::min(0, limit_);
204
0
  return {p, false};
205
0
}
206
207
0
const char* EpsCopyInputStream::SkipFallback(const char* ptr, int size) {
208
0
  return AppendSize(ptr, size, [](const char* p, int s) {});
209
0
}
210
211
const char* EpsCopyInputStream::ReadStringFallback(const char* ptr, int size,
212
0
                                                   std::string* str) {
213
0
  str->clear();
214
0
  if (PROTOBUF_PREDICT_TRUE(size <= buffer_end_ - ptr + limit_)) {
215
    // Reserve the string up to a static safe size. If strings are bigger than
216
    // this we proceed by growing the string as needed. This protects against
217
    // malicious payloads making protobuf hold on to a lot of memory.
218
0
    str->reserve(str->size() + std::min<int>(size, kSafeStringSize));
219
0
  }
220
0
  return AppendSize(ptr, size,
221
0
                    [str](const char* p, int s) { str->append(p, s); });
222
0
}
223
224
const char* EpsCopyInputStream::AppendStringFallback(const char* ptr, int size,
225
0
                                                     std::string* str) {
226
0
  if (PROTOBUF_PREDICT_TRUE(size <= buffer_end_ - ptr + limit_)) {
227
    // Reserve the string up to a static safe size. If strings are bigger than
228
    // this we proceed by growing the string as needed. This protects against
229
    // malicious payloads making protobuf hold on to a lot of memory.
230
0
    str->reserve(str->size() + std::min<int>(size, kSafeStringSize));
231
0
  }
232
0
  return AppendSize(ptr, size,
233
0
                    [str](const char* p, int s) { str->append(p, s); });
234
0
}
235
236
237
template <typename Tag, typename T>
238
const char* EpsCopyInputStream::ReadRepeatedFixed(const char* ptr,
239
                                                  Tag expected_tag,
240
                                                  RepeatedField<T>* out) {
241
  do {
242
    out->Add(UnalignedLoad<T>(ptr));
243
    ptr += sizeof(T);
244
    if (PROTOBUF_PREDICT_FALSE(ptr >= limit_end_)) return ptr;
245
  } while (UnalignedLoad<Tag>(ptr) == expected_tag&& ptr += sizeof(Tag));
246
  return ptr;
247
}
248
249
template <int>
250
void byteswap(void* p);
251
template <>
252
0
void byteswap<1>(void* p) {}
253
template <>
254
0
void byteswap<4>(void* p) {
255
0
  *static_cast<uint32*>(p) = bswap_32(*static_cast<uint32*>(p));
256
0
}
257
template <>
258
0
void byteswap<8>(void* p) {
259
0
  *static_cast<uint64*>(p) = bswap_64(*static_cast<uint64*>(p));
260
0
}
261
262
template <typename T>
263
const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size,
264
0
                                                RepeatedField<T>* out) {
265
0
  int nbytes = buffer_end_ + kSlopBytes - ptr;
266
0
  while (size > nbytes) {
267
0
    int num = nbytes / sizeof(T);
268
0
    int old_entries = out->size();
269
0
    out->Reserve(old_entries + num);
270
0
    int block_size = num * sizeof(T);
271
0
    auto dst = out->AddNAlreadyReserved(num);
272
0
#ifdef PROTOBUF_LITTLE_ENDIAN
273
0
    std::memcpy(dst, ptr, block_size);
274
#else
275
    for (int i = 0; i < num; i++)
276
      dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
277
#endif
278
0
    size -= block_size;
279
0
    if (limit_ <= kSlopBytes) return nullptr;
280
0
    ptr = Next();
281
0
    if (ptr == nullptr) return nullptr;
282
0
    ptr += kSlopBytes - (nbytes - block_size);
283
0
    nbytes = buffer_end_ + kSlopBytes - ptr;
284
0
  }
285
0
  int num = size / sizeof(T);
286
0
  int old_entries = out->size();
287
0
  out->Reserve(old_entries + num);
288
0
  int block_size = num * sizeof(T);
289
0
  auto dst = out->AddNAlreadyReserved(num);
290
0
#ifdef PROTOBUF_LITTLE_ENDIAN
291
0
  std::memcpy(dst, ptr, block_size);
292
#else
293
  for (int i = 0; i < num; i++) dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
294
#endif
295
0
  ptr += block_size;
296
0
  if (size != block_size) return nullptr;
297
0
  return ptr;
298
0
}
Unexecuted instantiation: char const* google::protobuf::internal::EpsCopyInputStream::ReadPackedFixed<unsigned int>(char const*, int, google::protobuf::RepeatedField<unsigned int>*)
Unexecuted instantiation: char const* google::protobuf::internal::EpsCopyInputStream::ReadPackedFixed<int>(char const*, int, google::protobuf::RepeatedField<int>*)
Unexecuted instantiation: char const* google::protobuf::internal::EpsCopyInputStream::ReadPackedFixed<unsigned long>(char const*, int, google::protobuf::RepeatedField<unsigned long>*)
Unexecuted instantiation: char const* google::protobuf::internal::EpsCopyInputStream::ReadPackedFixed<long>(char const*, int, google::protobuf::RepeatedField<long>*)
Unexecuted instantiation: char const* google::protobuf::internal::EpsCopyInputStream::ReadPackedFixed<float>(char const*, int, google::protobuf::RepeatedField<float>*)
Unexecuted instantiation: char const* google::protobuf::internal::EpsCopyInputStream::ReadPackedFixed<double>(char const*, int, google::protobuf::RepeatedField<double>*)
299
300
0
const char* EpsCopyInputStream::InitFrom(io::ZeroCopyInputStream* zcis) {
301
0
  zcis_ = zcis;
302
0
  const void* data;
303
0
  int size;
304
0
  limit_ = INT_MAX;
305
0
  if (zcis->Next(&data, &size)) {
306
0
    overall_limit_ -= size;
307
0
    if (size > kSlopBytes) {
308
0
      auto ptr = static_cast<const char*>(data);
309
0
      limit_ -= size - kSlopBytes;
310
0
      limit_end_ = buffer_end_ = ptr + size - kSlopBytes;
311
0
      next_chunk_ = buffer_;
312
0
      if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
313
0
      return ptr;
314
0
    } else {
315
0
      limit_end_ = buffer_end_ = buffer_ + kSlopBytes;
316
0
      next_chunk_ = buffer_;
317
0
      auto ptr = buffer_ + 2 * kSlopBytes - size;
318
0
      std::memcpy(ptr, data, size);
319
0
      return ptr;
320
0
    }
321
0
  }
322
0
  overall_limit_ = 0;
323
0
  next_chunk_ = nullptr;
324
0
  size_ = 0;
325
0
  limit_end_ = buffer_end_ = buffer_;
326
0
  return buffer_;
327
0
}
328
329
0
const char* ParseContext::ParseMessage(MessageLite* msg, const char* ptr) {
330
0
  return ParseMessage<MessageLite>(msg, ptr);
331
0
}
332
0
const char* ParseContext::ParseMessage(Message* msg, const char* ptr) {
333
  // Use reinterptret case to prevent inclusion of non lite header
334
0
  return ParseMessage(reinterpret_cast<MessageLite*>(msg), ptr);
335
0
}
336
337
0
inline void WriteVarint(uint64 val, std::string* s) {
338
0
  while (val >= 128) {
339
0
    uint8 c = val | 0x80;
340
0
    s->push_back(c);
341
0
    val >>= 7;
342
0
  }
343
0
  s->push_back(val);
344
0
}
345
346
0
void WriteVarint(uint32 num, uint64 val, std::string* s) {
347
0
  WriteVarint(num << 3, s);
348
0
  WriteVarint(val, s);
349
0
}
350
351
0
void WriteLengthDelimited(uint32 num, StringPiece val, std::string* s) {
352
0
  WriteVarint((num << 3) + 2, s);
353
0
  WriteVarint(val.size(), s);
354
0
  s->append(val.data(), val.size());
355
0
}
356
357
0
std::pair<const char*, uint32> VarintParseSlow32(const char* p, uint32 res) {
358
0
  for (std::uint32_t i = 2; i < 5; i++) {
359
0
    uint32 byte = static_cast<uint8>(p[i]);
360
0
    res += (byte - 1) << (7 * i);
361
0
    if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
362
0
      return {p + i + 1, res};
363
0
    }
364
0
  }
365
  // Accept >5 bytes
366
0
  for (std::uint32_t i = 5; i < 10; i++) {
367
0
    uint32 byte = static_cast<uint8>(p[i]);
368
0
    if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
369
0
      return {p + i + 1, res};
370
0
    }
371
0
  }
372
0
  return {nullptr, 0};
373
0
}
374
375
0
std::pair<const char*, uint64> VarintParseSlow64(const char* p, uint32 res32) {
376
0
  uint64 res = res32;
377
0
  for (std::uint32_t i = 2; i < 10; i++) {
378
0
    uint64 byte = static_cast<uint8>(p[i]);
379
0
    res += (byte - 1) << (7 * i);
380
0
    if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
381
0
      return {p + i + 1, res};
382
0
    }
383
0
  }
384
0
  return {nullptr, 0};
385
0
}
386
387
0
std::pair<const char*, uint32> ReadTagFallback(const char* p, uint32 res) {
388
0
  for (std::uint32_t i = 2; i < 5; i++) {
389
0
    uint32 byte = static_cast<uint8>(p[i]);
390
0
    res += (byte - 1) << (7 * i);
391
0
    if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
392
0
      return {p + i + 1, res};
393
0
    }
394
0
  }
395
0
  return {nullptr, 0};
396
0
}
397
398
0
std::pair<const char*, int32> ReadSizeFallback(const char* p, uint32 res) {
399
0
  for (std::uint32_t i = 1; i < 4; i++) {
400
0
    uint32 byte = static_cast<uint8>(p[i]);
401
0
    res += (byte - 1) << (7 * i);
402
0
    if (PROTOBUF_PREDICT_TRUE(byte < 128)) {
403
0
      return {p + i + 1, res};
404
0
    }
405
0
  }
406
0
  std::uint32_t byte = static_cast<uint8>(p[4]);
407
0
  if (PROTOBUF_PREDICT_FALSE(byte >= 8)) return {nullptr, 0};  // size >= 2gb
408
0
  res += (byte - 1) << 28;
409
  // Protect against sign integer overflow in PushLimit. Limits are relative
410
  // to buffer ends and ptr could potential be kSlopBytes beyond a buffer end.
411
  // To protect against overflow we reject limits absurdly close to INT_MAX.
412
0
  if (PROTOBUF_PREDICT_FALSE(res > INT_MAX - ParseContext::kSlopBytes)) {
413
0
    return {nullptr, 0};
414
0
  }
415
0
  return {p + 5, res};
416
0
}
417
418
const char* StringParser(const char* begin, const char* end, void* object,
419
0
                         ParseContext*) {
420
0
  auto str = static_cast<std::string*>(object);
421
0
  str->append(begin, end - begin);
422
0
  return end;
423
0
}
424
425
// Defined in wire_format_lite.cc
426
void PrintUTF8ErrorLog(const char* field_name, const char* operation_str,
427
                       bool emit_stacktrace);
428
429
0
bool VerifyUTF8(StringPiece str, const char* field_name) {
430
0
  if (!IsStructurallyValidUTF8(str)) {
431
0
    PrintUTF8ErrorLog(field_name, "parsing", false);
432
0
    return false;
433
0
  }
434
0
  return true;
435
0
}
436
437
const char* InlineGreedyStringParser(std::string* s, const char* ptr,
438
0
                                     ParseContext* ctx) {
439
0
  int size = ReadSize(&ptr);
440
0
  if (!ptr) return nullptr;
441
0
  return ctx->ReadString(ptr, size, s);
442
0
}
443
444
445
template <typename T, bool sign>
446
0
const char* VarintParser(void* object, const char* ptr, ParseContext* ctx) {
447
0
  return ctx->ReadPackedVarint(ptr, [object](uint64 varint) {
448
0
    T val;
449
0
    if (sign) {
450
0
      if (sizeof(T) == 8) {
451
0
        val = WireFormatLite::ZigZagDecode64(varint);
452
0
      } else {
453
0
        val = WireFormatLite::ZigZagDecode32(varint);
454
0
      }
455
0
    } else {
456
0
      val = varint;
457
0
    }
458
0
    static_cast<RepeatedField<T>*>(object)->Add(val);
459
0
  });
Unexecuted instantiation: google::protobuf::internal::VarintParser<int, false>(void*, char const*, google::protobuf::internal::ParseContext*)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Unexecuted instantiation: google::protobuf::internal::VarintParser<unsigned int, false>(void*, char const*, google::protobuf::internal::ParseContext*)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Unexecuted instantiation: google::protobuf::internal::VarintParser<long, false>(void*, char const*, google::protobuf::internal::ParseContext*)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Unexecuted instantiation: google::protobuf::internal::VarintParser<unsigned long, false>(void*, char const*, google::protobuf::internal::ParseContext*)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Unexecuted instantiation: google::protobuf::internal::VarintParser<int, true>(void*, char const*, google::protobuf::internal::ParseContext*)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Unexecuted instantiation: google::protobuf::internal::VarintParser<long, true>(void*, char const*, google::protobuf::internal::ParseContext*)::{lambda(unsigned long)#1}::operator()(unsigned long) const
Unexecuted instantiation: google::protobuf::internal::VarintParser<bool, false>(void*, char const*, google::protobuf::internal::ParseContext*)::{lambda(unsigned long)#1}::operator()(unsigned long) const
460
0
}
Unexecuted instantiation: char const* google::protobuf::internal::VarintParser<int, false>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::VarintParser<unsigned int, false>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::VarintParser<long, false>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::VarintParser<unsigned long, false>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::VarintParser<int, true>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::VarintParser<long, true>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::VarintParser<bool, false>(void*, char const*, google::protobuf::internal::ParseContext*)
461
462
const char* PackedInt32Parser(void* object, const char* ptr,
463
0
                              ParseContext* ctx) {
464
0
  return VarintParser<int32, false>(object, ptr, ctx);
465
0
}
466
const char* PackedUInt32Parser(void* object, const char* ptr,
467
0
                               ParseContext* ctx) {
468
0
  return VarintParser<uint32, false>(object, ptr, ctx);
469
0
}
470
const char* PackedInt64Parser(void* object, const char* ptr,
471
0
                              ParseContext* ctx) {
472
0
  return VarintParser<int64, false>(object, ptr, ctx);
473
0
}
474
const char* PackedUInt64Parser(void* object, const char* ptr,
475
0
                               ParseContext* ctx) {
476
0
  return VarintParser<uint64, false>(object, ptr, ctx);
477
0
}
478
const char* PackedSInt32Parser(void* object, const char* ptr,
479
0
                               ParseContext* ctx) {
480
0
  return VarintParser<int32, true>(object, ptr, ctx);
481
0
}
482
const char* PackedSInt64Parser(void* object, const char* ptr,
483
0
                               ParseContext* ctx) {
484
0
  return VarintParser<int64, true>(object, ptr, ctx);
485
0
}
486
487
0
const char* PackedEnumParser(void* object, const char* ptr, ParseContext* ctx) {
488
0
  return VarintParser<int, false>(object, ptr, ctx);
489
0
}
490
491
0
const char* PackedBoolParser(void* object, const char* ptr, ParseContext* ctx) {
492
0
  return VarintParser<bool, false>(object, ptr, ctx);
493
0
}
494
495
template <typename T>
496
0
const char* FixedParser(void* object, const char* ptr, ParseContext* ctx) {
497
0
  int size = ReadSize(&ptr);
498
0
  GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
499
0
  return ctx->ReadPackedFixed(ptr, size,
500
0
                              static_cast<RepeatedField<T>*>(object));
501
0
}
Unexecuted instantiation: char const* google::protobuf::internal::FixedParser<unsigned int>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::FixedParser<int>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::FixedParser<unsigned long>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::FixedParser<long>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::FixedParser<float>(void*, char const*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::FixedParser<double>(void*, char const*, google::protobuf::internal::ParseContext*)
502
503
const char* PackedFixed32Parser(void* object, const char* ptr,
504
0
                                ParseContext* ctx) {
505
0
  return FixedParser<uint32>(object, ptr, ctx);
506
0
}
507
const char* PackedSFixed32Parser(void* object, const char* ptr,
508
0
                                 ParseContext* ctx) {
509
0
  return FixedParser<int32>(object, ptr, ctx);
510
0
}
511
const char* PackedFixed64Parser(void* object, const char* ptr,
512
0
                                ParseContext* ctx) {
513
0
  return FixedParser<uint64>(object, ptr, ctx);
514
0
}
515
const char* PackedSFixed64Parser(void* object, const char* ptr,
516
0
                                 ParseContext* ctx) {
517
0
  return FixedParser<int64>(object, ptr, ctx);
518
0
}
519
const char* PackedFloatParser(void* object, const char* ptr,
520
0
                              ParseContext* ctx) {
521
0
  return FixedParser<float>(object, ptr, ctx);
522
0
}
523
const char* PackedDoubleParser(void* object, const char* ptr,
524
0
                               ParseContext* ctx) {
525
0
  return FixedParser<double>(object, ptr, ctx);
526
0
}
527
528
class UnknownFieldLiteParserHelper {
529
 public:
530
  explicit UnknownFieldLiteParserHelper(std::string* unknown)
531
0
      : unknown_(unknown) {}
532
533
0
  void AddVarint(uint32 num, uint64 value) {
534
0
    if (unknown_ == nullptr) return;
535
0
    WriteVarint(num * 8, unknown_);
536
0
    WriteVarint(value, unknown_);
537
0
  }
538
0
  void AddFixed64(uint32 num, uint64 value) {
539
0
    if (unknown_ == nullptr) return;
540
0
    WriteVarint(num * 8 + 1, unknown_);
541
0
    char buffer[8];
542
0
    io::CodedOutputStream::WriteLittleEndian64ToArray(
543
0
        value, reinterpret_cast<uint8*>(buffer));
544
0
    unknown_->append(buffer, 8);
545
0
  }
546
  const char* ParseLengthDelimited(uint32 num, const char* ptr,
547
0
                                   ParseContext* ctx) {
548
0
    int size = ReadSize(&ptr);
549
0
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
550
0
    if (unknown_ == nullptr) return ctx->Skip(ptr, size);
551
0
    WriteVarint(num * 8 + 2, unknown_);
552
0
    WriteVarint(size, unknown_);
553
0
    return ctx->AppendString(ptr, size, unknown_);
554
0
  }
555
0
  const char* ParseGroup(uint32 num, const char* ptr, ParseContext* ctx) {
556
0
    if (unknown_) WriteVarint(num * 8 + 3, unknown_);
557
0
    ptr = ctx->ParseGroup(this, ptr, num * 8 + 3);
558
0
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
559
0
    if (unknown_) WriteVarint(num * 8 + 4, unknown_);
560
0
    return ptr;
561
0
  }
562
0
  void AddFixed32(uint32 num, uint32 value) {
563
0
    if (unknown_ == nullptr) return;
564
0
    WriteVarint(num * 8 + 5, unknown_);
565
0
    char buffer[4];
566
0
    io::CodedOutputStream::WriteLittleEndian32ToArray(
567
0
        value, reinterpret_cast<uint8*>(buffer));
568
0
    unknown_->append(buffer, 4);
569
0
  }
570
571
0
  const char* _InternalParse(const char* ptr, ParseContext* ctx) {
572
0
    return WireFormatParser(*this, ptr, ctx);
573
0
  }
574
575
 private:
576
  std::string* unknown_;
577
};
578
579
const char* UnknownGroupLiteParse(std::string* unknown, const char* ptr,
580
0
                                  ParseContext* ctx) {
581
0
  UnknownFieldLiteParserHelper field_parser(unknown);
582
0
  return WireFormatParser(field_parser, ptr, ctx);
583
0
}
584
585
const char* UnknownFieldParse(uint32 tag, std::string* unknown, const char* ptr,
586
0
                              ParseContext* ctx) {
587
0
  UnknownFieldLiteParserHelper field_parser(unknown);
588
0
  return FieldParser(tag, field_parser, ptr, ctx);
589
0
}
590
591
}  // namespace internal
592
}  // namespace protobuf
593
}  // namespace google