Coverage Report

Created: 2024-02-25 06:31

/proc/self/cwd/external/com_google_protobuf/src/google/protobuf/json/internal/parser.cc
Line
Count
Source (jump to first uncovered line)
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/json/internal/parser.h"
32
33
#include <cfloat>
34
#include <cmath>
35
#include <cstdint>
36
#include <cstring>
37
#include <limits>
38
#include <memory>
39
#include <string>
40
#include <utility>
41
42
#include "google/protobuf/type.pb.h"
43
#include "google/protobuf/descriptor.h"
44
#include "google/protobuf/dynamic_message.h"
45
#include "google/protobuf/message.h"
46
#include "absl/base/attributes.h"
47
#include "absl/container/flat_hash_set.h"
48
#include "absl/log/absl_check.h"
49
#include "absl/log/absl_log.h"
50
#include "absl/status/status.h"
51
#include "absl/status/statusor.h"
52
#include "absl/strings/ascii.h"
53
#include "absl/strings/escaping.h"
54
#include "absl/strings/match.h"
55
#include "absl/strings/numbers.h"
56
#include "absl/strings/str_format.h"
57
#include "absl/strings/str_split.h"
58
#include "absl/strings/string_view.h"
59
#include "absl/types/optional.h"
60
#include "absl/types/span.h"
61
#include "google/protobuf/io/zero_copy_sink.h"
62
#include "google/protobuf/io/zero_copy_stream.h"
63
#include "google/protobuf/io/zero_copy_stream_impl_lite.h"
64
#include "google/protobuf/json/internal/descriptor_traits.h"
65
#include "google/protobuf/json/internal/lexer.h"
66
#include "google/protobuf/json/internal/parser_traits.h"
67
#include "google/protobuf/util/type_resolver.h"
68
#include "google/protobuf/stubs/status_macros.h"
69
70
// Must be included last.
71
#include "google/protobuf/port_def.inc"
72
73
namespace google {
74
namespace protobuf {
75
namespace json_internal {
76
namespace {
77
// This file contains code that drives a JsonLexer to visit a JSON document and
78
// convert it into some form of proto.
79
//
80
// This semantic layer is duplicated: proto2-ish code can deserialize directly
81
// into a message, whereas proto3-ish code deserializes into a byte stream,
82
// using TypeResolvers instead of Descriptors.
83
//
84
// The parsing code is templated over which of these two reflection + output
85
// combinations is used. The traits types that collect the per-instantiation
86
// functionality can be found in json_util2_parser_traits-inl.h.
87
88
// This table maps an unsigned `char` value, interpreted as an ASCII character,
89
// to a corresponding value in the base64 alphabet (both traditional and
90
// "web-safe" characters are included).
91
//
92
// If a character is not valid base64, it maps to -1; this is used by the bit
93
// operations that assemble a base64-encoded word to determine if an error
94
// occurred, by checking the sign bit.
95
constexpr signed char kBase64Table[256] = {
96
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
97
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
98
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
99
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
100
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
101
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
102
    -1,       62 /*+*/, -1,       62 /*-*/, -1,       63 /*/ */, 52 /*0*/,
103
    53 /*1*/, 54 /*2*/, 55 /*3*/, 56 /*4*/, 57 /*5*/, 58 /*6*/,  59 /*7*/,
104
    60 /*8*/, 61 /*9*/, -1,       -1,       -1,       -1,        -1,
105
    -1,       -1,       0 /*A*/,  1 /*B*/,  2 /*C*/,  3 /*D*/,   4 /*E*/,
106
    5 /*F*/,  6 /*G*/,  07 /*H*/, 8 /*I*/,  9 /*J*/,  10 /*K*/,  11 /*L*/,
107
    12 /*M*/, 13 /*N*/, 14 /*O*/, 15 /*P*/, 16 /*Q*/, 17 /*R*/,  18 /*S*/,
108
    19 /*T*/, 20 /*U*/, 21 /*V*/, 22 /*W*/, 23 /*X*/, 24 /*Y*/,  25 /*Z*/,
109
    -1,       -1,       -1,       -1,       63 /*_*/, -1,        26 /*a*/,
110
    27 /*b*/, 28 /*c*/, 29 /*d*/, 30 /*e*/, 31 /*f*/, 32 /*g*/,  33 /*h*/,
111
    34 /*i*/, 35 /*j*/, 36 /*k*/, 37 /*l*/, 38 /*m*/, 39 /*n*/,  40 /*o*/,
112
    41 /*p*/, 42 /*q*/, 43 /*r*/, 44 /*s*/, 45 /*t*/, 46 /*u*/,  47 /*v*/,
113
    48 /*w*/, 49 /*x*/, 50 /*y*/, 51 /*z*/, -1,       -1,        -1,
114
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
115
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
116
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
117
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
118
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
119
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
120
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
121
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
122
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
123
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
124
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
125
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
126
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
127
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
128
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
129
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
130
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
131
    -1,       -1,       -1,       -1,       -1,       -1,        -1,
132
    -1,       -1,       -1,       -1};
133
134
0
uint32_t Base64Lookup(char c) {
135
  // Sign-extend return value so high bit will be set on any unexpected char.
136
0
  return static_cast<uint32_t>(kBase64Table[static_cast<uint8_t>(c)]);
137
0
}
138
139
// Decodes `base64` in-place, shrinking the length as appropriate.
140
0
absl::StatusOr<absl::Span<char>> DecodeBase64InPlace(absl::Span<char> base64) {
141
  // We decode in place. This is safe because this is a new buffer (not
142
  // aliasing the input) and because base64 decoding shrinks 4 bytes into 3.
143
0
  char* out = base64.data();
144
0
  const char* ptr = base64.data();
145
0
  const char* end = ptr + base64.size();
146
0
  const char* end4 = ptr + (base64.size() & ~3u);
147
148
0
  for (; ptr < end4; ptr += 4, out += 3) {
149
0
    auto val = Base64Lookup(ptr[0]) << 18 | Base64Lookup(ptr[1]) << 12 |
150
0
               Base64Lookup(ptr[2]) << 6 | Base64Lookup(ptr[3]) << 0;
151
152
0
    if (static_cast<int32_t>(val) < 0) {
153
      // Junk chars or padding. Remove trailing padding, if any.
154
0
      if (end - ptr == 4 && ptr[3] == '=') {
155
0
        if (ptr[2] == '=') {
156
0
          end -= 2;
157
0
        } else {
158
0
          end -= 1;
159
0
        }
160
0
      }
161
0
      break;
162
0
    }
163
164
0
    out[0] = val >> 16;
165
0
    out[1] = (val >> 8) & 0xff;
166
0
    out[2] = val & 0xff;
167
0
  }
168
169
0
  if (ptr < end) {
170
0
    uint32_t val = ~0u;
171
0
    switch (end - ptr) {
172
0
      case 2:
173
0
        val = Base64Lookup(ptr[0]) << 18 | Base64Lookup(ptr[1]) << 12;
174
0
        out[0] = val >> 16;
175
0
        out += 1;
176
0
        break;
177
0
      case 3:
178
0
        val = Base64Lookup(ptr[0]) << 18 | Base64Lookup(ptr[1]) << 12 |
179
0
              Base64Lookup(ptr[2]) << 6;
180
0
        out[0] = val >> 16;
181
0
        out[1] = (val >> 8) & 0xff;
182
0
        out += 2;
183
0
        break;
184
0
    }
185
186
0
    if (static_cast<int32_t>(val) < 0) {
187
0
      return absl::InvalidArgumentError("corrupt base64");
188
0
    }
189
0
  }
190
191
0
  return absl::Span<char>(base64.data(),
192
0
                          static_cast<size_t>(out - base64.data()));
193
0
}
194
195
template <typename T>
196
absl::StatusOr<LocationWith<T>> ParseIntInner(JsonLexer& lex, double lo,
197
0
                                              double hi) {
198
0
  absl::StatusOr<JsonLexer::Kind> kind = lex.PeekKind();
199
0
  RETURN_IF_ERROR(kind.status());
200
201
0
  LocationWith<T> n;
202
0
  switch (*kind) {
203
0
    case JsonLexer::kNum: {
204
0
      absl::StatusOr<LocationWith<MaybeOwnedString>> x = lex.ParseRawNumber();
205
0
      RETURN_IF_ERROR(x.status());
206
0
      n.loc = x->loc;
207
0
      if (absl::SimpleAtoi(x->value.AsView(), &n.value)) {
208
0
        break;
209
0
      }
210
211
0
      double d;
212
0
      if (!absl::SimpleAtod(x->value.AsView(), &d) || !std::isfinite(d)) {
213
0
        return x->loc.Invalid(
214
0
            absl::StrFormat("invalid number: '%s'", x->value.AsView()));
215
0
      }
216
217
      // Conversion overflow here would be UB.
218
0
      if (lo > d || d > hi) {
219
0
        return lex.Invalid("JSON number out of range for int");
220
0
      }
221
0
      n.value = static_cast<T>(d);
222
0
      if (d - static_cast<double>(n.value) != 0) {
223
0
        return lex.Invalid(
224
0
            "expected integer, but JSON number had fractional part");
225
0
      }
226
0
      break;
227
0
    }
228
0
    case JsonLexer::kStr: {
229
0
      absl::StatusOr<LocationWith<MaybeOwnedString>> str = lex.ParseUtf8();
230
0
      RETURN_IF_ERROR(str.status());
231
      // SimpleAtoi will ignore leading and trailing whitespace, so we need
232
      // to check for it ourselves.
233
0
      for (char c : str->value.AsView()) {
234
0
        if (absl::ascii_isspace(c)) {
235
0
          return lex.Invalid("non-number characters in quoted number");
236
0
        }
237
0
      }
238
0
      if (!absl::SimpleAtoi(str->value.AsView(), &n.value)) {
239
0
        return str->loc.Invalid("non-number characters in quoted number");
240
0
      }
241
0
      n.loc = str->loc;
242
0
      break;
243
0
    }
244
0
    default:
245
0
      return lex.Invalid("expected number or string");
246
0
  }
247
248
0
  return n;
249
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<google::protobuf::json_internal::LocationWith<long> > google::protobuf::json_internal::(anonymous namespace)::ParseIntInner<long>(google::protobuf::json_internal::JsonLexer&, double, double)
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<google::protobuf::json_internal::LocationWith<unsigned long> > google::protobuf::json_internal::(anonymous namespace)::ParseIntInner<unsigned long>(google::protobuf::json_internal::JsonLexer&, double, double)
250
251
template <typename Traits>
252
0
absl::StatusOr<int64_t> ParseInt(JsonLexer& lex, Field<Traits> field) {
253
0
  absl::StatusOr<LocationWith<int64_t>> n =
254
0
      ParseIntInner<int64_t>(lex, -9007199254740992.0, 9007199254740992.0);
255
0
  RETURN_IF_ERROR(n.status());
256
257
0
  if (Traits::Is32Bit(field)) {
258
0
    if (std::numeric_limits<int32_t>::min() > n->value ||
259
0
        n->value > std::numeric_limits<int32_t>::max()) {
260
0
      return n->loc.Invalid("integer out of range");
261
0
    }
262
0
  }
263
264
0
  return n->value;
265
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<long> google::protobuf::json_internal::(anonymous namespace)::ParseInt<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field)
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<long> google::protobuf::json_internal::(anonymous namespace)::ParseInt<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field)
266
267
template <typename Traits>
268
0
absl::StatusOr<uint64_t> ParseUInt(JsonLexer& lex, Field<Traits> field) {
269
0
  absl::StatusOr<LocationWith<uint64_t>> n =
270
0
      ParseIntInner<uint64_t>(lex, 0, 18014398509481984.0);
271
0
  RETURN_IF_ERROR(n.status());
272
273
0
  if (Traits::Is32Bit(field)) {
274
0
    if (n->value > std::numeric_limits<uint32_t>::max()) {
275
0
      return n->loc.Invalid("integer out of range");
276
0
    }
277
0
  }
278
279
0
  return n->value;
280
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<unsigned long> google::protobuf::json_internal::(anonymous namespace)::ParseUInt<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field)
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<unsigned long> google::protobuf::json_internal::(anonymous namespace)::ParseUInt<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field)
281
282
template <typename Traits>
283
0
absl::StatusOr<double> ParseFp(JsonLexer& lex, Field<Traits> field) {
284
0
  absl::StatusOr<JsonLexer::Kind> kind = lex.PeekKind();
285
0
  RETURN_IF_ERROR(kind.status());
286
287
0
  double n;
288
0
  switch (*kind) {
289
0
    case JsonLexer::kNum: {
290
0
      absl::StatusOr<LocationWith<double>> d = lex.ParseNumber();
291
0
      RETURN_IF_ERROR(d.status());
292
0
      n = d->value;
293
0
      break;
294
0
    }
295
0
    case JsonLexer::kStr: {
296
0
      absl::StatusOr<LocationWith<MaybeOwnedString>> str = lex.ParseUtf8();
297
0
      RETURN_IF_ERROR(str.status());
298
299
0
      if (str->value == "NaN") {
300
0
        n = NAN;
301
0
      } else if (str->value == "Infinity") {
302
0
        n = INFINITY;
303
0
      } else if (str->value == "-Infinity") {
304
0
        n = -INFINITY;
305
0
      } else if (!absl::SimpleAtod(str->value.AsView(), &n)) {
306
0
        return str->loc.Invalid("non-number characters in quoted number");
307
0
      }
308
0
      break;
309
0
    }
310
0
    default:
311
0
      return lex.Invalid("expected number or string");
312
0
  }
313
314
0
  if (Traits::Is32Bit(field)) {
315
    // Detect out-of-range 32-bit floats by seeing whether the conversion result
316
    // is still finite. Finite extreme values may have textual representations
317
    // that parse to 64-bit values outside the 32-bit range, but which are
318
    // closer to the 32-bit extreme than to the "next value with the same
319
    // precision".
320
0
    if (std::isfinite(n) && !std::isfinite(static_cast<float>(n))) {
321
0
      return lex.Invalid("float out of range");
322
0
    }
323
0
  }
324
325
0
  return n;
326
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<double> google::protobuf::json_internal::(anonymous namespace)::ParseFp<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field)
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<double> google::protobuf::json_internal::(anonymous namespace)::ParseFp<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field)
327
328
template <typename Traits>
329
absl::StatusOr<std::string> ParseStrOrBytes(JsonLexer& lex,
330
0
                                            Field<Traits> field) {
331
0
  absl::StatusOr<LocationWith<MaybeOwnedString>> str = lex.ParseUtf8();
332
0
  RETURN_IF_ERROR(str.status());
333
334
0
  if (Traits::FieldType(field) == FieldDescriptor::TYPE_BYTES) {
335
0
    std::string& b64 = str->value.ToString();
336
0
    absl::StatusOr<absl::Span<char>> decoded =
337
0
        DecodeBase64InPlace(absl::MakeSpan(&b64[0], b64.size()));
338
0
    if (!decoded.ok()) {
339
0
      return str->loc.Invalid(decoded.status().message());
340
0
    }
341
0
    b64.resize(decoded->size());
342
0
  }
343
344
0
  return std::move(str->value.ToString());
345
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > google::protobuf::json_internal::(anonymous namespace)::ParseStrOrBytes<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field)
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > google::protobuf::json_internal::(anonymous namespace)::ParseStrOrBytes<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field)
346
347
template <typename Traits>
348
absl::StatusOr<absl::optional<int32_t>> ParseEnumFromStr(JsonLexer& lex,
349
                                                         MaybeOwnedString& str,
350
0
                                                         Field<Traits> field) {
351
0
  absl::StatusOr<int32_t> value = Traits::EnumNumberByName(
352
0
      field, str.AsView(), lex.options().case_insensitive_enum_parsing);
353
0
  if (value.ok()) {
354
0
    return absl::optional<int32_t>(*value);
355
0
  }
356
357
0
  int32_t i;
358
0
  if (absl::SimpleAtoi(str.AsView(), &i)) {
359
0
    return absl::optional<int32_t>(i);
360
0
  } else if (lex.options().ignore_unknown_fields) {
361
0
    return {absl::nullopt};
362
0
  }
363
364
0
  return value.status();
365
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<absl::lts_20230125::optional<int> > google::protobuf::json_internal::(anonymous namespace)::ParseEnumFromStr<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::MaybeOwnedString&, google::protobuf::json_internal::ParseProto2Descriptor::Field)
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<absl::lts_20230125::optional<int> > google::protobuf::json_internal::(anonymous namespace)::ParseEnumFromStr<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::MaybeOwnedString&, google::protobuf::json_internal::ParseProto3Type::Field)
366
367
// Parses an enum; can return nullopt if a quoted enumerator that we don't
368
// know about is received and `ignore_unknown_fields` is set.
369
template <typename Traits>
370
absl::StatusOr<absl::optional<int32_t>> ParseEnum(JsonLexer& lex,
371
0
                                                  Field<Traits> field) {
372
0
  absl::StatusOr<JsonLexer::Kind> kind = lex.PeekKind();
373
0
  RETURN_IF_ERROR(kind.status());
374
375
0
  int32_t n = 0;
376
0
  switch (*kind) {
377
0
    case JsonLexer::kStr: {
378
0
      absl::StatusOr<LocationWith<MaybeOwnedString>> str = lex.ParseUtf8();
379
0
      RETURN_IF_ERROR(str.status());
380
381
0
      auto e = ParseEnumFromStr<Traits>(lex, str->value, field);
382
0
      RETURN_IF_ERROR(e.status());
383
0
      if (!e->has_value()) {
384
0
        return {absl::nullopt};
385
0
      }
386
0
      n = **e;
387
0
      break;
388
0
    }
389
0
    case JsonLexer::kNum:
390
0
      return ParseInt<Traits>(lex, field);
391
0
    default:
392
0
      return lex.Invalid("expected number or string");
393
0
  }
394
395
0
  return n;
396
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<absl::lts_20230125::optional<int> > google::protobuf::json_internal::(anonymous namespace)::ParseEnum<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field)
Unexecuted instantiation: parser.cc:absl::lts_20230125::StatusOr<absl::lts_20230125::optional<int> > google::protobuf::json_internal::(anonymous namespace)::ParseEnum<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field)
397
398
// Mutually recursive with functions that follow.
399
template <typename Traits>
400
absl::Status ParseMessage(JsonLexer& lex, const Desc<Traits>& desc,
401
                          Msg<Traits>& msg, bool any_reparse);
402
template <typename Traits>
403
absl::Status ParseField(JsonLexer& lex, const Desc<Traits>& desc,
404
                        absl::string_view name, Msg<Traits>& msg);
405
406
template <typename Traits>
407
absl::Status ParseSingular(JsonLexer& lex, Field<Traits> field,
408
0
                           Msg<Traits>& msg) {
409
0
  auto field_type = Traits::FieldType(field);
410
0
  if (lex.Peek(JsonLexer::kNull)) {
411
0
    auto message_type = ClassifyMessage(Traits::FieldTypeName(field));
412
0
    switch (field_type) {
413
0
      case FieldDescriptor::TYPE_ENUM:
414
0
        if (message_type == MessageType::kNull) {
415
0
          Traits::SetEnum(field, msg, 0);
416
0
        }
417
0
        break;
418
0
      case FieldDescriptor::TYPE_MESSAGE: {
419
0
        if (message_type == MessageType::kValue) {
420
0
          return Traits::NewMsg(
421
0
              field, msg,
422
0
              [&](const Desc<Traits>& type, Msg<Traits>& msg) -> absl::Status {
423
0
                auto field = Traits::FieldByNumber(type, 1);
424
0
                ABSL_DCHECK(field.has_value());
425
0
                RETURN_IF_ERROR(lex.Expect("null"));
426
0
                Traits::SetEnum(Traits::MustHaveField(type, 1), msg, 0);
427
0
                return absl::OkStatus();
428
0
              });
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseSingular<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)#1}::operator()(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&) const
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseSingular<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&)#1}::operator()(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&) const
429
0
        }
430
0
        break;
431
0
      }
432
0
      default:
433
0
        break;
434
0
    }
435
0
    return lex.Expect("null");
436
0
  }
437
438
0
  switch (field_type) {
439
0
    case FieldDescriptor::TYPE_FLOAT: {
440
0
      auto x = ParseFp<Traits>(lex, field);
441
0
      RETURN_IF_ERROR(x.status());
442
0
      Traits::SetFloat(field, msg, *x);
443
0
      break;
444
0
    }
445
0
    case FieldDescriptor::TYPE_DOUBLE: {
446
0
      auto x = ParseFp<Traits>(lex, field);
447
0
      RETURN_IF_ERROR(x.status());
448
0
      Traits::SetDouble(field, msg, *x);
449
0
      break;
450
0
    }
451
452
0
    case FieldDescriptor::TYPE_SFIXED64:
453
0
    case FieldDescriptor::TYPE_SINT64:
454
0
    case FieldDescriptor::TYPE_INT64: {
455
0
      auto x = ParseInt<Traits>(lex, field);
456
0
      RETURN_IF_ERROR(x.status());
457
0
      Traits::SetInt64(field, msg, *x);
458
0
      break;
459
0
    }
460
0
    case FieldDescriptor::TYPE_FIXED64:
461
0
    case FieldDescriptor::TYPE_UINT64: {
462
0
      auto x = ParseUInt<Traits>(lex, field);
463
0
      RETURN_IF_ERROR(x.status());
464
0
      Traits::SetUInt64(field, msg, *x);
465
0
      break;
466
0
    }
467
468
0
    case FieldDescriptor::TYPE_SFIXED32:
469
0
    case FieldDescriptor::TYPE_SINT32:
470
0
    case FieldDescriptor::TYPE_INT32: {
471
0
      auto x = ParseInt<Traits>(lex, field);
472
0
      RETURN_IF_ERROR(x.status());
473
0
      Traits::SetInt32(field, msg, static_cast<int32_t>(*x));
474
0
      break;
475
0
    }
476
0
    case FieldDescriptor::TYPE_FIXED32:
477
0
    case FieldDescriptor::TYPE_UINT32: {
478
0
      auto x = ParseUInt<Traits>(lex, field);
479
0
      RETURN_IF_ERROR(x.status());
480
0
      Traits::SetUInt32(field, msg, static_cast<uint32_t>(*x));
481
0
      break;
482
0
    }
483
0
    case FieldDescriptor::TYPE_BOOL: {
484
0
      absl::StatusOr<JsonLexer::Kind> kind = lex.PeekKind();
485
0
      RETURN_IF_ERROR(kind.status());
486
487
0
      switch (*kind) {
488
0
        case JsonLexer::kTrue:
489
0
          RETURN_IF_ERROR(lex.Expect("true"));
490
0
          Traits::SetBool(field, msg, true);
491
0
          break;
492
0
        case JsonLexer::kFalse:
493
0
          RETURN_IF_ERROR(lex.Expect("false"));
494
0
          Traits::SetBool(field, msg, false);
495
0
          break;
496
0
        case JsonLexer::kStr: {
497
0
          if (!lex.options().allow_legacy_syntax) {
498
0
            goto bad;
499
0
          }
500
501
0
          auto x = lex.ParseUtf8();
502
0
          RETURN_IF_ERROR(x.status());
503
504
0
          bool flag;
505
0
          if (!absl::SimpleAtob(x->value, &flag)) {
506
            // Is this error a lie? Do we accept things otyher than "true" and
507
            // "false" because SimpleAtob does? Absolutely!
508
0
            return x->loc.Invalid("expected 'true' or 'false'");
509
0
          }
510
0
          Traits::SetBool(field, msg, flag);
511
512
0
          break;
513
0
        }
514
0
        bad:
515
0
        default:
516
0
          return lex.Invalid("expected 'true' or 'false'");
517
0
      }
518
0
      break;
519
0
    }
520
0
    case FieldDescriptor::TYPE_STRING:
521
0
    case FieldDescriptor::TYPE_BYTES: {
522
0
      auto x = ParseStrOrBytes<Traits>(lex, field);
523
0
      RETURN_IF_ERROR(x.status());
524
0
      Traits::SetString(field, msg, *x);
525
0
      break;
526
0
    }
527
0
    case FieldDescriptor::TYPE_ENUM: {
528
0
      absl::StatusOr<absl::optional<int32_t>> x = ParseEnum<Traits>(lex, field);
529
0
      RETURN_IF_ERROR(x.status());
530
531
0
      if (x->has_value() || Traits::IsImplicitPresence(field)) {
532
0
        Traits::SetEnum(field, msg, x->value_or(0));
533
0
      }
534
0
      break;
535
0
    }
536
0
    case FieldDescriptor::TYPE_MESSAGE:
537
0
    case FieldDescriptor::TYPE_GROUP: {
538
0
      return Traits::NewMsg(
539
0
          field, msg,
540
0
          [&](const Desc<Traits>& type, Msg<Traits>& msg) -> absl::Status {
541
0
            return ParseMessage<Traits>(lex, type, msg,
542
0
                                        /*any_reparse=*/false);
543
0
          });
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseSingular<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)#2}::operator()(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&) const
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseSingular<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&)#2}::operator()(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&) const
544
0
    }
545
0
    default:
546
0
      return lex.Invalid(
547
0
          absl::StrCat("unsupported field type: ", Traits::FieldType(field)));
548
0
  }
549
550
0
  return absl::OkStatus();
551
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseSingular<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseSingular<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)
552
553
template <typename Traits>
554
0
absl::Status EmitNull(JsonLexer& lex, Field<Traits> field, Msg<Traits>& msg) {
555
0
  switch (Traits::FieldType(field)) {
556
0
    case FieldDescriptor::TYPE_FLOAT:
557
0
      Traits::SetFloat(field, msg, 0);
558
0
      break;
559
0
    case FieldDescriptor::TYPE_DOUBLE:
560
0
      Traits::SetDouble(field, msg, 0);
561
0
      break;
562
0
    case FieldDescriptor::TYPE_SFIXED64:
563
0
    case FieldDescriptor::TYPE_SINT64:
564
0
    case FieldDescriptor::TYPE_INT64:
565
0
      Traits::SetInt64(field, msg, 0);
566
0
      break;
567
0
    case FieldDescriptor::TYPE_FIXED64:
568
0
    case FieldDescriptor::TYPE_UINT64:
569
0
      Traits::SetUInt64(field, msg, 0);
570
0
      break;
571
0
    case FieldDescriptor::TYPE_SFIXED32:
572
0
    case FieldDescriptor::TYPE_SINT32:
573
0
    case FieldDescriptor::TYPE_INT32:
574
0
      Traits::SetInt32(field, msg, 0);
575
0
      break;
576
0
    case FieldDescriptor::TYPE_FIXED32:
577
0
    case FieldDescriptor::TYPE_UINT32:
578
0
      Traits::SetUInt32(field, msg, 0);
579
0
      break;
580
0
    case FieldDescriptor::TYPE_BOOL:
581
0
      Traits::SetBool(field, msg, false);
582
0
      break;
583
0
    case FieldDescriptor::TYPE_STRING:
584
0
    case FieldDescriptor::TYPE_BYTES:
585
0
      Traits::SetString(field, msg, "");
586
0
      break;
587
0
    case FieldDescriptor::TYPE_ENUM:
588
0
      Traits::SetEnum(field, msg, 0);
589
0
      break;
590
0
    case FieldDescriptor::TYPE_MESSAGE:
591
0
    case FieldDescriptor::TYPE_GROUP:
592
0
      return Traits::NewMsg(field, msg,
593
0
                            [](const auto&, const auto&) -> absl::Status {
594
0
                              return absl::OkStatus();
595
0
                            });
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::EmitNull<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<google::protobuf::Descriptor, google::protobuf::json_internal::ParseProto2Descriptor::Msg>(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg const&) const
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::EmitNull<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<google::protobuf::json_internal::ResolverPool::Message, google::protobuf::json_internal::ParseProto3Type::Msg>(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg const&) const
596
0
    default:
597
0
      return lex.Invalid(
598
0
          absl::StrCat("unsupported field type: ", Traits::FieldType(field)));
599
0
  }
600
0
  return absl::OkStatus();
601
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::EmitNull<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::EmitNull<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)
602
603
template <typename Traits>
604
0
absl::Status ParseArray(JsonLexer& lex, Field<Traits> field, Msg<Traits>& msg) {
605
0
  if (lex.Peek(JsonLexer::kNull)) {
606
0
    return lex.Expect("null");
607
0
  }
608
609
0
  return lex.VisitArray([&]() -> absl::Status {
610
0
    lex.path().NextRepeated();
611
0
    MessageType type = ClassifyMessage(Traits::FieldTypeName(field));
612
613
0
    if (lex.Peek(JsonLexer::kNull)) {
614
0
      if (type == MessageType::kValue) {
615
0
        return ParseSingular<Traits>(lex, field, msg);
616
0
      }
617
0
      if (type == MessageType::kNull) {
618
0
        return ParseSingular<Traits>(lex, field, msg);
619
0
      }
620
621
0
      if (lex.options().allow_legacy_syntax) {
622
0
        RETURN_IF_ERROR(lex.Expect("null"));
623
0
        return EmitNull<Traits>(lex, field, msg);
624
0
      }
625
0
      return lex.Invalid("null cannot occur inside of repeated fields");
626
0
    }
627
628
    // Note that this is sufficient to catch when we are inside of a ListValue,
629
    // because a ListValue's sole field is of type Value. Thus, we only need to
630
    // classify cases in which we are inside of an array and parsing messages
631
    // that like looking like arrays.
632
    //
633
    // This will also correctly handle e.g. writing out a ListValue with the
634
    // legacy syntax of `{"values": [[0], [1], [2]]}`, which does not go through
635
    // the custom parser handler.
636
0
    bool can_flatten =
637
0
        type != MessageType::kValue && type != MessageType::kList;
638
0
    if (can_flatten && lex.options().allow_legacy_syntax &&
639
0
        lex.Peek(JsonLexer::kArr)) {
640
      // You read that right. In legacy mode, if we encounter an array within
641
      // an array, we just flatten it as part of the current array!
642
      //
643
      // This DOES NOT apply when parsing a google.protobuf.Value or a
644
      // google.protobuf.ListValue!
645
0
      return ParseArray<Traits>(lex, field, msg);
646
0
    }
647
0
    return ParseSingular<Traits>(lex, field, msg);
648
0
  });
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseArray<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda()#1}::operator()() const
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseArray<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda()#1}::operator()() const
649
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseArray<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseArray<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)
650
651
template <typename Traits>
652
0
absl::Status ParseMap(JsonLexer& lex, Field<Traits> field, Msg<Traits>& msg) {
653
0
  if (lex.Peek(JsonLexer::kNull)) {
654
0
    return lex.Expect("null");
655
0
  }
656
657
0
  absl::flat_hash_set<std::string> keys_seen;
658
0
  return lex.VisitObject(
659
0
      [&](LocationWith<MaybeOwnedString>& key) -> absl::Status {
660
0
        lex.path().NextRepeated();
661
0
        auto insert_result = keys_seen.emplace(key.value.AsView());
662
0
        if (!insert_result.second) {
663
0
          return key.loc.Invalid(absl::StrFormat(
664
0
              "got unexpectedly-repeated repeated map key: '%s'",
665
0
              key.value.AsView()));
666
0
        }
667
0
        return Traits::NewMsg(
668
0
            field, msg,
669
0
            [&](const Desc<Traits>& type, Msg<Traits>& entry) -> absl::Status {
670
0
              auto key_field = Traits::KeyField(type);
671
0
              switch (Traits::FieldType(key_field)) {
672
0
                case FieldDescriptor::TYPE_INT64:
673
0
                case FieldDescriptor::TYPE_SINT64:
674
0
                case FieldDescriptor::TYPE_SFIXED64: {
675
0
                  int64_t n;
676
0
                  if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
677
0
                    return key.loc.Invalid(
678
0
                        "non-number characters in quoted number");
679
0
                  }
680
0
                  Traits::SetInt64(key_field, entry, n);
681
0
                  break;
682
0
                }
683
0
                case FieldDescriptor::TYPE_UINT64:
684
0
                case FieldDescriptor::TYPE_FIXED64: {
685
0
                  uint64_t n;
686
0
                  if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
687
0
                    return key.loc.Invalid(
688
0
                        "non-number characters in quoted number");
689
0
                  }
690
0
                  Traits::SetUInt64(key_field, entry, n);
691
0
                  break;
692
0
                }
693
0
                case FieldDescriptor::TYPE_INT32:
694
0
                case FieldDescriptor::TYPE_SINT32:
695
0
                case FieldDescriptor::TYPE_SFIXED32: {
696
0
                  int32_t n;
697
0
                  if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
698
0
                    return key.loc.Invalid(
699
0
                        "non-number characters in quoted number");
700
0
                  }
701
0
                  Traits::SetInt32(key_field, entry, n);
702
0
                  break;
703
0
                }
704
0
                case FieldDescriptor::TYPE_UINT32:
705
0
                case FieldDescriptor::TYPE_FIXED32: {
706
0
                  uint32_t n;
707
0
                  if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
708
0
                    return key.loc.Invalid(
709
0
                        "non-number characters in quoted number");
710
0
                  }
711
0
                  Traits::SetUInt32(key_field, entry, n);
712
0
                  break;
713
0
                }
714
0
                case FieldDescriptor::TYPE_BOOL: {
715
0
                  if (key.value == "true") {
716
0
                    Traits::SetBool(key_field, entry, true);
717
0
                  } else if (key.value == "false") {
718
0
                    Traits::SetBool(key_field, entry, false);
719
0
                  } else {
720
0
                    return key.loc.Invalid(absl::StrFormat(
721
0
                        "expected bool string, got '%s'", key.value.AsView()));
722
0
                  }
723
0
                  break;
724
0
                }
725
0
                case FieldDescriptor::TYPE_ENUM: {
726
0
                  MaybeOwnedString key_str = key.value;
727
0
                  auto e = ParseEnumFromStr<Traits>(lex, key_str, field);
728
0
                  RETURN_IF_ERROR(e.status());
729
0
                  Traits::SetEnum(key_field, entry, e->value_or(0));
730
0
                  break;
731
0
                }
732
0
                case FieldDescriptor::TYPE_STRING: {
733
0
                  Traits::SetString(key_field, entry,
734
0
                                    std::move(key.value.ToString()));
735
0
                  break;
736
0
                }
737
0
                default:
738
0
                  return lex.Invalid("unsupported map key type");
739
0
              }
740
741
0
              return ParseSingular<Traits>(lex, Traits::ValueField(type),
742
0
                                           entry);
743
0
            });
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseMap<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&)#1}::operator()(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&) const::{lambda(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)#1}::operator()(google::protobuf::Descriptor const, google::protobuf::json_internal::ParseProto2Descriptor::Msg) const
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseMap<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&)#1}::operator()(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&) const::{lambda(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&)#1}::operator()(google::protobuf::json_internal::ResolverPool::Message const, google::protobuf::json_internal::ParseProto3Type::Msg) const
744
0
      });
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseMap<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&)#1}::operator()(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&) const
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseMap<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&)#1}::operator()(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&) const
745
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseMap<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Field, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseMap<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Field, google::protobuf::json_internal::ParseProto3Type::Msg&)
746
747
absl::optional<uint32_t> TakeTimeDigitsWithSuffixAndAdvance(
748
0
    absl::string_view& data, int max_digits, absl::string_view end) {
749
0
  ABSL_DCHECK_LE(max_digits, 9);
750
751
0
  uint32_t val = 0;
752
0
  int limit = max_digits;
753
0
  while (!data.empty()) {
754
0
    if (limit-- < 0) {
755
0
      return absl::nullopt;
756
0
    }
757
0
    uint32_t digit = data[0] - '0';
758
0
    if (digit >= 10) {
759
0
      break;
760
0
    }
761
762
0
    val *= 10;
763
0
    val += digit;
764
0
    data = data.substr(1);
765
0
  }
766
0
  if (!absl::StartsWith(data, end)) {
767
0
    return absl::nullopt;
768
0
  }
769
770
0
  data = data.substr(end.size());
771
0
  return val;
772
0
}
773
774
0
absl::optional<int32_t> TakeNanosAndAdvance(absl::string_view& data) {
775
0
  int32_t frac_secs = 0;
776
0
  size_t frac_digits = 0;
777
0
  if (absl::StartsWith(data, ".")) {
778
0
    for (char c : data.substr(1)) {
779
0
      if (!absl::ascii_isdigit(c)) {
780
0
        break;
781
0
      }
782
0
      ++frac_digits;
783
0
    }
784
0
    auto digits = data.substr(1, frac_digits);
785
0
    if (frac_digits == 0 || frac_digits > 9 ||
786
0
        !absl::SimpleAtoi(digits, &frac_secs)) {
787
0
      return absl::nullopt;
788
0
    }
789
0
    data = data.substr(frac_digits + 1);
790
0
  }
791
0
  for (int i = 0; i < 9 - frac_digits; ++i) {
792
0
    frac_secs *= 10;
793
0
  }
794
0
  return frac_secs;
795
0
}
796
797
template <typename Traits>
798
absl::Status ParseTimestamp(JsonLexer& lex, const Desc<Traits>& desc,
799
0
                            Msg<Traits>& msg) {
800
0
  if (lex.Peek(JsonLexer::kNull)) {
801
0
    return lex.Expect("null");
802
0
  }
803
804
0
  absl::StatusOr<LocationWith<MaybeOwnedString>> str = lex.ParseUtf8();
805
0
  RETURN_IF_ERROR(str.status());
806
807
0
  absl::string_view data = str->value.AsView();
808
0
  if (data.size() < 20) {
809
0
    return str->loc.Invalid("timestamp string too short");
810
0
  }
811
812
0
  int64_t secs;
813
0
  {
814
    /* 1972-01-01T01:00:00 */
815
0
    auto year = TakeTimeDigitsWithSuffixAndAdvance(data, 4, "-");
816
0
    if (!year.has_value() || *year == 0) {
817
0
      return str->loc.Invalid("bad year in timestamp");
818
0
    }
819
0
    auto mon = TakeTimeDigitsWithSuffixAndAdvance(data, 2, "-");
820
0
    if (!mon.has_value() || *mon == 0) {
821
0
      return str->loc.Invalid("bad month in timestamp");
822
0
    }
823
0
    auto day = TakeTimeDigitsWithSuffixAndAdvance(data, 2, "T");
824
0
    if (!day.has_value() || *day == 0) {
825
0
      return str->loc.Invalid("bad day in timestamp");
826
0
    }
827
0
    auto hour = TakeTimeDigitsWithSuffixAndAdvance(data, 2, ":");
828
0
    if (!hour.has_value()) {
829
0
      return str->loc.Invalid("bad hours in timestamp");
830
0
    }
831
0
    auto min = TakeTimeDigitsWithSuffixAndAdvance(data, 2, ":");
832
0
    if (!min.has_value()) {
833
0
      return str->loc.Invalid("bad minutes in timestamp");
834
0
    }
835
0
    auto sec = TakeTimeDigitsWithSuffixAndAdvance(data, 2, "");
836
0
    if (!sec.has_value()) {
837
0
      return str->loc.Invalid("bad seconds in timestamp");
838
0
    }
839
840
0
    uint32_t m_adj = *mon - 3;  // March-based month.
841
0
    uint32_t carry = m_adj > *mon ? 1 : 0;
842
843
0
    uint32_t year_base = 4800;  // Before min year, multiple of 400.
844
0
    uint32_t y_adj = *year + year_base - carry;
845
846
0
    uint32_t month_days = ((m_adj + carry * 12) * 62719 + 769) / 2048;
847
0
    uint32_t leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400;
848
0
    int32_t epoch_days =
849
0
        y_adj * 365 + leap_days + month_days + (*day - 1) - 2472632;
850
851
0
    secs = int64_t{epoch_days} * 86400 + *hour * 3600 + *min * 60 + *sec;
852
0
  }
853
854
0
  auto nanos = TakeNanosAndAdvance(data);
855
0
  if (!nanos.has_value()) {
856
0
    return str->loc.Invalid("timestamp had bad nanoseconds");
857
0
  }
858
859
0
  if (data.empty()) {
860
0
    return str->loc.Invalid("timestamp missing timezone offset");
861
0
  }
862
863
0
  {
864
    // [+-]hh:mm or Z
865
0
    bool neg = false;
866
0
    switch (data[0]) {
867
0
      case '-':
868
0
        neg = true;
869
0
        ABSL_FALLTHROUGH_INTENDED;
870
0
      case '+': {
871
0
        if (data.size() != 6) {
872
0
          return str->loc.Invalid("timestamp offset of wrong size.");
873
0
        }
874
875
0
        data = data.substr(1);
876
0
        auto hour = TakeTimeDigitsWithSuffixAndAdvance(data, 2, ":");
877
0
        auto mins = TakeTimeDigitsWithSuffixAndAdvance(data, 2, "");
878
0
        if (!hour.has_value() || !mins.has_value()) {
879
0
          return str->loc.Invalid("timestamp offset has bad hours and minutes");
880
0
        }
881
882
0
        int64_t offset = (*hour * 60 + *mins) * 60;
883
0
        secs += (neg ? offset : -offset);
884
0
        break;
885
0
      }
886
      // Lowercase z is not accepted, per the spec.
887
0
      case 'Z':
888
0
        if (data.size() == 1) {
889
0
          break;
890
0
        }
891
0
        ABSL_FALLTHROUGH_INTENDED;
892
0
      default:
893
0
        return str->loc.Invalid("bad timezone offset");
894
0
    }
895
0
  }
896
897
0
  Traits::SetInt64(Traits::MustHaveField(desc, 1), msg, secs);
898
0
  Traits::SetInt32(Traits::MustHaveField(desc, 2), msg, *nanos);
899
900
0
  return absl::OkStatus();
901
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseTimestamp<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseTimestamp<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)
902
903
template <typename Traits>
904
absl::Status ParseDuration(JsonLexer& lex, const Desc<Traits>& desc,
905
0
                           Msg<Traits>& msg) {
906
0
  if (lex.Peek(JsonLexer::kNull)) {
907
0
    return lex.Expect("null");
908
0
  }
909
910
0
  constexpr int64_t kMaxSeconds = int64_t{3652500} * 86400;
911
912
0
  absl::StatusOr<LocationWith<MaybeOwnedString>> str = lex.ParseUtf8();
913
0
  RETURN_IF_ERROR(str.status());
914
915
0
  size_t int_part_end = 0;
916
0
  for (char c : str->value.AsView()) {
917
0
    if (!absl::ascii_isdigit(c) && c != '-') {
918
0
      break;
919
0
    }
920
0
    ++int_part_end;
921
0
  }
922
0
  if (int_part_end == 0) {
923
0
    return str->loc.Invalid("duration must start with an integer");
924
0
  }
925
926
0
  absl::string_view sec_digits = str->value.AsView().substr(0, int_part_end);
927
0
  int64_t secs;
928
0
  if (!absl::SimpleAtoi(sec_digits, &secs)) {
929
0
    return str->loc.Invalid("duration had bad seconds");
930
0
  }
931
932
0
  if (secs > kMaxSeconds || secs < -kMaxSeconds) {
933
0
    return str->loc.Invalid("duration out of range");
934
0
  }
935
936
0
  absl::string_view rest = str->value.AsView().substr(int_part_end);
937
0
  auto nanos = TakeNanosAndAdvance(rest);
938
0
  if (!nanos.has_value()) {
939
0
    return str->loc.Invalid("duration had bad nanoseconds");
940
0
  }
941
942
0
  bool isNegative = (secs < 0) || absl::StartsWith(sec_digits, "-");
943
0
  if (isNegative) {
944
0
    *nanos *= -1;
945
0
  }
946
947
0
  if (rest != "s") {
948
0
    return str->loc.Invalid("duration must end with a single 's'");
949
0
  }
950
951
0
  Traits::SetInt64(Traits::MustHaveField(desc, 1), msg, secs);
952
0
  Traits::SetInt32(Traits::MustHaveField(desc, 2), msg, *nanos);
953
954
0
  return absl::OkStatus();
955
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseDuration<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseDuration<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)
956
957
template <typename Traits>
958
absl::Status ParseFieldMask(JsonLexer& lex, const Desc<Traits>& desc,
959
0
                            Msg<Traits>& msg) {
960
0
  absl::StatusOr<LocationWith<MaybeOwnedString>> str = lex.ParseUtf8();
961
0
  RETURN_IF_ERROR(str.status());
962
0
  auto paths = str->value.AsView();
963
964
  // The special case of the empty string is not handled correctly below,
965
  // because StrSplit("", ',') is [""], not [].
966
0
  if (paths.empty()) {
967
0
    return absl::OkStatus();
968
0
  }
969
970
  // google.protobuf.FieldMask has a single field with number 1.
971
0
  auto paths_field = Traits::MustHaveField(desc, 1);
972
0
  for (absl::string_view path : absl::StrSplit(paths, ',')) {
973
0
    std::string snake_path;
974
    // Assume approximately six-letter words, so add one extra space for an
975
    // underscore for every six bytes.
976
0
    snake_path.reserve(path.size() * 7 / 6);
977
0
    for (char c : path) {
978
0
      if (absl::ascii_isdigit(c) || absl::ascii_islower(c) || c == '.') {
979
0
        snake_path.push_back(c);
980
0
      } else if (absl::ascii_isupper(c)) {
981
0
        snake_path.push_back('_');
982
0
        snake_path.push_back(absl::ascii_tolower(c));
983
0
      } else if (lex.options().allow_legacy_syntax) {
984
0
        snake_path.push_back(c);
985
0
      } else {
986
0
        return str->loc.Invalid("unexpected character in FieldMask");
987
0
      }
988
0
    }
989
0
    Traits::SetString(paths_field, msg, snake_path);
990
0
  }
991
992
0
  return absl::OkStatus();
993
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseFieldMask<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseFieldMask<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)
994
995
template <typename Traits>
996
absl::Status ParseAny(JsonLexer& lex, const Desc<Traits>& desc,
997
0
                      Msg<Traits>& msg) {
998
  // Buffer an entire object. Because @type can occur anywhere, we're forced
999
  // to do this.
1000
0
  RETURN_IF_ERROR(lex.SkipToToken());
1001
0
  auto mark = lex.BeginMark();
1002
1003
  // Search for @type, buffering the entire object along the way so we can
1004
  // reparse it.
1005
0
  absl::optional<MaybeOwnedString> type_url;
1006
0
  RETURN_IF_ERROR(lex.VisitObject(
1007
0
      [&](const LocationWith<MaybeOwnedString>& key) -> absl::Status {
1008
0
        if (key.value == "@type") {
1009
0
          if (type_url.has_value()) {
1010
0
            return key.loc.Invalid("repeated @type in Any");
1011
0
          }
1012
1013
0
          absl::StatusOr<LocationWith<MaybeOwnedString>> maybe_url =
1014
0
              lex.ParseUtf8();
1015
0
          RETURN_IF_ERROR(maybe_url.status());
1016
0
          type_url = std::move(maybe_url)->value;
1017
0
          return absl::OkStatus();
1018
0
        }
1019
0
        return lex.SkipValue();
1020
0
      }));
1021
1022
  // Build a new lexer over the skipped object.
1023
0
  absl::string_view any_text = mark.value.UpToUnread();
1024
0
  io::ArrayInputStream in(any_text.data(), any_text.size());
1025
  // Copying lex.options() is important; it inherits the recursion
1026
  // limit.
1027
0
  JsonLexer any_lex(&in, lex.options(), &lex.path(), mark.loc);
1028
1029
0
  if (!type_url.has_value() && !lex.options().allow_legacy_syntax) {
1030
0
    return mark.loc.Invalid("missing @type in Any");
1031
0
  }
1032
1033
0
  if (type_url.has_value()) {
1034
0
    Traits::SetString(Traits::MustHaveField(desc, 1), msg, type_url->AsView());
1035
0
    return Traits::NewDynamic(
1036
0
        Traits::MustHaveField(desc, 2), type_url->ToString(), msg,
1037
0
        [&](const Desc<Traits>& desc, Msg<Traits>& msg) {
1038
0
          auto pop = any_lex.path().Push("<any>", FieldDescriptor::TYPE_MESSAGE,
1039
0
                                         Traits::TypeName(desc));
1040
0
          return ParseMessage<Traits>(any_lex, desc, msg,
1041
0
                                      /*any_reparse=*/true);
1042
0
        });
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseAny<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)#1}::operator()(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&) const
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseAny<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&)#1}::operator()(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&) const
1043
0
  } else {
1044
    // Empty {} is accepted in legacy mode.
1045
0
    ABSL_DCHECK(lex.options().allow_legacy_syntax);
1046
0
    RETURN_IF_ERROR(any_lex.VisitObject([&](auto&) {
1047
0
      return mark.loc.Invalid(
1048
0
          "in legacy mode, missing @type in Any is only allowed for an empty "
1049
0
          "object");
1050
0
    }));
1051
0
    return absl::OkStatus();
1052
0
  }
1053
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseAny<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseAny<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)
1054
1055
// These are mutually recursive with ParseValue.
1056
template <typename Traits>
1057
absl::Status ParseStructValue(JsonLexer& lex, const Desc<Traits>& desc,
1058
                              Msg<Traits>& msg);
1059
template <typename Traits>
1060
absl::Status ParseListValue(JsonLexer& lex, const Desc<Traits>& desc,
1061
                            Msg<Traits>& msg);
1062
1063
template <typename Traits>
1064
absl::Status ParseValue(JsonLexer& lex, const Desc<Traits>& desc,
1065
0
                        Msg<Traits>& msg) {
1066
0
  auto kind = lex.PeekKind();
1067
0
  RETURN_IF_ERROR(kind.status());
1068
  // NOTE: The field numbers 1 through 6 are the numbers of the oneof fields
1069
  // in google.protobuf.Value. Conformance tests verify the correctness of
1070
  // these numbers.
1071
0
  switch (*kind) {
1072
0
    case JsonLexer::kNull: {
1073
0
      auto field = Traits::MustHaveField(desc, 1);
1074
0
      auto pop =
1075
0
          lex.path().Push(Traits::FieldName(field), Traits::FieldType(field),
1076
0
                          Traits::FieldTypeName(field));
1077
1078
0
      RETURN_IF_ERROR(lex.Expect("null"));
1079
0
      Traits::SetEnum(field, msg, 0);
1080
0
      break;
1081
0
    }
1082
0
    case JsonLexer::kNum: {
1083
0
      auto field = Traits::MustHaveField(desc, 2);
1084
0
      auto pop =
1085
0
          lex.path().Push(Traits::FieldName(field), Traits::FieldType(field),
1086
0
                          Traits::FieldTypeName(field));
1087
1088
0
      auto number = lex.ParseNumber();
1089
0
      RETURN_IF_ERROR(number.status());
1090
0
      Traits::SetDouble(field, msg, number->value);
1091
0
      break;
1092
0
    }
1093
0
    case JsonLexer::kStr: {
1094
0
      auto field = Traits::MustHaveField(desc, 3);
1095
0
      auto pop =
1096
0
          lex.path().Push(Traits::FieldName(field), Traits::FieldType(field),
1097
0
                          Traits::FieldTypeName(field));
1098
1099
0
      auto str = lex.ParseUtf8();
1100
0
      RETURN_IF_ERROR(str.status());
1101
0
      Traits::SetString(field, msg, std::move(str->value.ToString()));
1102
0
      break;
1103
0
    }
1104
0
    case JsonLexer::kFalse:
1105
0
    case JsonLexer::kTrue: {
1106
0
      auto field = Traits::MustHaveField(desc, 4);
1107
0
      auto pop =
1108
0
          lex.path().Push(Traits::FieldName(field), Traits::FieldType(field),
1109
0
                          Traits::FieldTypeName(field));
1110
1111
      // "Quoted" bools, including non-standard Abseil Atob bools, are not
1112
      // supported, because all strings are treated as genuine JSON strings.
1113
0
      if (*kind == JsonLexer::kTrue) {
1114
0
        RETURN_IF_ERROR(lex.Expect("true"));
1115
0
        Traits::SetBool(field, msg, true);
1116
0
      } else {
1117
0
        RETURN_IF_ERROR(lex.Expect("false"));
1118
0
        Traits::SetBool(field, msg, false);
1119
0
      }
1120
0
      break;
1121
0
    }
1122
0
    case JsonLexer::kObj: {
1123
0
      auto field = Traits::MustHaveField(desc, 5);
1124
0
      auto pop =
1125
0
          lex.path().Push(Traits::FieldName(field), Traits::FieldType(field),
1126
0
                          Traits::FieldTypeName(field));
1127
1128
0
      return Traits::NewMsg(field, msg, [&](auto& desc, auto& msg) {
1129
0
        return ParseStructValue<Traits>(lex, desc, msg);
1130
0
      });
Unexecuted instantiation: parser.cc:auto google::protobuf::json_internal::(anonymous namespace)::ParseValue<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(auto:1&, auto:2&)#1}::operator()<google::protobuf::Descriptor const, google::protobuf::json_internal::ParseProto2Descriptor::Msg>(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&) const
Unexecuted instantiation: parser.cc:auto google::protobuf::json_internal::(anonymous namespace)::ParseValue<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(auto:1&, auto:2&)#1}::operator()<google::protobuf::json_internal::ResolverPool::Message const, google::protobuf::json_internal::ParseProto3Type::Msg>(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&) const
1131
0
    }
1132
0
    case JsonLexer::kArr: {
1133
0
      auto field = Traits::MustHaveField(desc, 6);
1134
0
      auto pop =
1135
0
          lex.path().Push(Traits::FieldName(field), Traits::FieldType(field),
1136
0
                          Traits::FieldTypeName(field));
1137
1138
0
      return Traits::NewMsg(field, msg, [&](auto& desc, auto& msg) {
1139
0
        return ParseListValue<Traits>(lex, desc, msg);
1140
0
      });
Unexecuted instantiation: parser.cc:auto google::protobuf::json_internal::(anonymous namespace)::ParseValue<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)::{lambda(auto:1&, auto:2&)#2}::operator()<google::protobuf::Descriptor const, google::protobuf::json_internal::ParseProto2Descriptor::Msg>(google::protobuf::Descriptor const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&) const
Unexecuted instantiation: parser.cc:auto google::protobuf::json_internal::(anonymous namespace)::ParseValue<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)::{lambda(auto:1&, auto:2&)#2}::operator()<google::protobuf::json_internal::ResolverPool::Message const, google::protobuf::json_internal::ParseProto3Type::Msg>(google::protobuf::json_internal::ResolverPool::Message const&, google::protobuf::json_internal::ParseProto3Type::Msg&) const
1141
0
    }
1142
0
  }
1143
1144
0
  return absl::OkStatus();
1145
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseValue<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseValue<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)
1146
1147
template <typename Traits>
1148
absl::Status ParseStructValue(JsonLexer& lex, const Desc<Traits>& desc,
1149
0
                              Msg<Traits>& msg) {
1150
0
  auto entry_field = Traits::MustHaveField(desc, 1);
1151
0
  auto pop = lex.path().Push("<struct>", FieldDescriptor::TYPE_MESSAGE,
1152
0
                             Traits::FieldTypeName(entry_field));
1153
1154
  // Structs are always cleared even if set to {}.
1155
0
  Traits::RecordAsSeen(entry_field, msg);
1156
1157
  // Parsing a map does the right thing: Struct has a single map<string,
1158
  // Value> field; keys are correctly parsed as strings, and the values
1159
  // recurse into ParseMessage, which will be routed into ParseValue. This
1160
  // results in some extra overhead, but performance is not what we're going
1161
  // for here.
1162
0
  return ParseMap<Traits>(lex, entry_field, msg);
1163
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseStructValue<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseStructValue<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)
1164
1165
template <typename Traits>
1166
absl::Status ParseListValue(JsonLexer& lex, const Desc<Traits>& desc,
1167
0
                            Msg<Traits>& msg) {
1168
0
  auto entry_field = Traits::MustHaveField(desc, 1);
1169
0
  auto pop = lex.path().Push("<list>", FieldDescriptor::TYPE_MESSAGE,
1170
0
                             Traits::FieldTypeName(entry_field));
1171
1172
  // ListValues are always cleared even if set to [].
1173
0
  Traits::RecordAsSeen(entry_field, msg);
1174
  // Parsing an array does the right thing: see the analogous comment in
1175
  // ParseStructValue.
1176
0
  return ParseArray<Traits>(lex, entry_field, msg);
1177
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseListValue<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseListValue<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&)
1178
1179
template <typename Traits>
1180
absl::Status ParseField(JsonLexer& lex, const Desc<Traits>& desc,
1181
0
                        absl::string_view name, Msg<Traits>& msg) {
1182
0
  absl::optional<Field<Traits>> field;
1183
0
  if (absl::StartsWith(name, "[") && absl::EndsWith(name, "]")) {
1184
0
    absl::string_view extn_name = name.substr(1, name.size() - 2);
1185
0
    field = Traits::ExtensionByName(desc, extn_name);
1186
1187
0
    if (field.has_value()) {
1188
      // The check for whether this is an invalid field occurs below, since it
1189
      // is combined for both extension and non-extension fields.
1190
0
      auto correct_type_name = Traits::TypeName(desc);
1191
0
      if (Traits::TypeName(Traits::ContainingType(*field)) !=
1192
0
          correct_type_name) {
1193
0
        return lex.Invalid(absl::StrFormat(
1194
0
            "'%s' is a known extension name, but is not an extension "
1195
0
            "of '%s' as expected",
1196
0
            extn_name, correct_type_name));
1197
0
      }
1198
0
    }
1199
0
  } else {
1200
0
    field = Traits::FieldByName(desc, name);
1201
0
  }
1202
1203
0
  if (!field.has_value()) {
1204
0
    if (!lex.options().ignore_unknown_fields) {
1205
0
      return lex.Invalid(absl::StrFormat("no such field: '%s'", name));
1206
0
    }
1207
0
    return lex.SkipValue();
1208
0
  }
1209
1210
0
  auto pop = lex.path().Push(name, Traits::FieldType(*field),
1211
0
                             Traits::FieldTypeName(*field));
1212
1213
0
  if (Traits::HasParsed(
1214
0
          *field, msg,
1215
0
          /*allow_repeated_non_oneof=*/lex.options().allow_legacy_syntax) &&
1216
0
      !lex.Peek(JsonLexer::kNull)) {
1217
0
    return lex.Invalid(absl::StrFormat(
1218
0
        "'%s' has already been set (either directly or as part of a oneof)",
1219
0
        name));
1220
0
  }
1221
1222
0
  if (Traits::IsMap(*field)) {
1223
0
    return ParseMap<Traits>(lex, *field, msg);
1224
0
  }
1225
1226
0
  if (Traits::IsRepeated(*field)) {
1227
0
    if (lex.options().allow_legacy_syntax && !lex.Peek(JsonLexer::kArr)) {
1228
      // The original ESF parser permits a single element in place of an array
1229
      // thereof.
1230
0
      return ParseSingular<Traits>(lex, *field, msg);
1231
0
    }
1232
0
    return ParseArray<Traits>(lex, *field, msg);
1233
0
  }
1234
1235
0
  return ParseSingular<Traits>(lex, *field, msg);
1236
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseField<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, absl::lts_20230125::string_view, google::protobuf::json_internal::ParseProto2Descriptor::Msg&)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseField<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, absl::lts_20230125::string_view, google::protobuf::json_internal::ParseProto3Type::Msg&)
1237
1238
template <typename Traits>
1239
absl::Status ParseMessage(JsonLexer& lex, const Desc<Traits>& desc,
1240
0
                          Msg<Traits>& msg, bool any_reparse) {
1241
0
  MessageType type = ClassifyMessage(Traits::TypeName(desc));
1242
0
  if (!any_reparse) {
1243
0
    switch (type) {
1244
0
      case MessageType::kAny:
1245
0
        return ParseAny<Traits>(lex, desc, msg);
1246
0
      case MessageType::kValue:
1247
0
        return ParseValue<Traits>(lex, desc, msg);
1248
0
      case MessageType::kStruct:
1249
0
        return ParseStructValue<Traits>(lex, desc, msg);
1250
0
      default:
1251
0
        break;
1252
0
    }
1253
    // For some types, the ESF parser permits parsing the "non-special" version.
1254
    // It is not clear if this counts as out-of-spec, but we're treating it as
1255
    // such.
1256
0
    bool is_upcoming_object = lex.Peek(JsonLexer::kObj);
1257
0
    if (!(is_upcoming_object && lex.options().allow_legacy_syntax)) {
1258
0
      switch (type) {
1259
0
        case MessageType::kList:
1260
0
          return ParseListValue<Traits>(lex, desc, msg);
1261
0
        case MessageType::kWrapper: {
1262
0
          return ParseSingular<Traits>(lex, Traits::MustHaveField(desc, 1),
1263
0
                                       msg);
1264
0
        }
1265
0
        case MessageType::kTimestamp:
1266
0
          return ParseTimestamp<Traits>(lex, desc, msg);
1267
0
        case MessageType::kDuration:
1268
0
          return ParseDuration<Traits>(lex, desc, msg);
1269
0
        case MessageType::kFieldMask:
1270
0
          return ParseFieldMask<Traits>(lex, desc, msg);
1271
0
        default:
1272
0
          break;
1273
0
      }
1274
0
    }
1275
0
  }
1276
1277
0
  return lex.VisitObject(
1278
0
      [&](LocationWith<MaybeOwnedString>& name) -> absl::Status {
1279
        // If this is a well-known type, we expect its contents to be inside
1280
        // of a JSON field named "value".
1281
0
        if (any_reparse) {
1282
0
          if (name.value == "@type") {
1283
0
            RETURN_IF_ERROR(lex.SkipValue());
1284
0
            return absl::OkStatus();
1285
0
          }
1286
0
          if (type != MessageType::kNotWellKnown) {
1287
0
            if (name.value != "value") {
1288
0
              return lex.Invalid(
1289
0
                  "fields in a well-known-typed Any must be @type or value");
1290
0
            }
1291
            // Parse the upcoming value as the message itself. This is *not*
1292
            // an Any reparse because we do not expect to see @type in the
1293
            // upcoming value.
1294
0
            return ParseMessage<Traits>(lex, desc, msg,
1295
0
                                        /*any_reparse=*/false);
1296
0
          }
1297
0
        }
1298
1299
0
        return ParseField<Traits>(lex, desc, name.value.AsView(), msg);
1300
0
      });
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseMessage<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&, bool)::{lambda(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&)#1}::operator()(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&) const
Unexecuted instantiation: parser.cc:google::protobuf::json_internal::(anonymous namespace)::ParseMessage<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&, bool)::{lambda(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&)#1}::operator()(google::protobuf::json_internal::LocationWith<google::protobuf::json_internal::MaybeOwnedString>&) const
1301
0
}
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseMessage<google::protobuf::json_internal::ParseProto2Descriptor>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto2Descriptor::Desc const&, google::protobuf::json_internal::ParseProto2Descriptor::Msg&, bool)
Unexecuted instantiation: parser.cc:absl::lts_20230125::Status google::protobuf::json_internal::(anonymous namespace)::ParseMessage<google::protobuf::json_internal::ParseProto3Type>(google::protobuf::json_internal::JsonLexer&, google::protobuf::json_internal::ParseProto3Type::Desc const&, google::protobuf::json_internal::ParseProto3Type::Msg&, bool)
1302
}  // namespace
1303
1304
absl::Status JsonStringToMessage(absl::string_view input, Message* message,
1305
0
                                 json_internal::ParseOptions options) {
1306
0
  MessagePath path(message->GetDescriptor()->full_name());
1307
0
  if (PROTOBUF_DEBUG) {
1308
0
    ABSL_DLOG(INFO) << "json2/input: " << absl::CHexEscape(input);
1309
0
  }
1310
0
  io::ArrayInputStream in(input.data(), input.size());
1311
0
  JsonLexer lex(&in, options, &path);
1312
1313
0
  ParseProto2Descriptor::Msg msg(message);
1314
0
  absl::Status s =
1315
0
      ParseMessage<ParseProto2Descriptor>(lex, *message->GetDescriptor(), msg,
1316
0
                                          /*any_reparse=*/false);
1317
0
  if (s.ok() && !lex.AtEof()) {
1318
0
    s = absl::InvalidArgumentError(
1319
0
        "extraneous characters after end of JSON object");
1320
0
  }
1321
1322
0
  if (PROTOBUF_DEBUG) {
1323
0
    ABSL_DLOG(INFO) << "json2/status: " << s;
1324
0
    ABSL_DLOG(INFO) << "json2/output: " << message->DebugString();
1325
0
  }
1326
0
  return s;
1327
0
}
1328
1329
absl::Status JsonToBinaryStream(google::protobuf::util::TypeResolver* resolver,
1330
                                const std::string& type_url,
1331
                                io::ZeroCopyInputStream* json_input,
1332
                                io::ZeroCopyOutputStream* binary_output,
1333
0
                                json_internal::ParseOptions options) {
1334
  // NOTE: Most of the contortions in this function are to allow for capture of
1335
  // input and output of the parser in ABSL_DLOG mode. Destruction order is very
1336
  // critical in this function, because io::ZeroCopy*Stream types usually only
1337
  // flush on destruction.
1338
1339
  // For ABSL_DLOG, we would like to print out the input and output, which
1340
  // requires buffering both instead of doing "zero copy". This block, and the
1341
  // one at the end of the function, set up and tear down interception of the
1342
  // input and output streams.
1343
0
  std::string copy;
1344
0
  std::string out;
1345
0
  absl::optional<io::ArrayInputStream> tee_input;
1346
0
  absl::optional<io::StringOutputStream> tee_output;
1347
0
  if (PROTOBUF_DEBUG) {
1348
0
    const void* data;
1349
0
    int len;
1350
0
    while (json_input->Next(&data, &len)) {
1351
0
      copy.resize(copy.size() + len);
1352
0
      std::memcpy(&copy[copy.size() - len], data, len);
1353
0
    }
1354
0
    tee_input.emplace(copy.data(), copy.size());
1355
0
    tee_output.emplace(&out);
1356
0
    ABSL_DLOG(INFO) << "json2/input: " << absl::CHexEscape(copy);
1357
0
  }
1358
1359
  // This scope forces the CodedOutputStream inside of `msg` to flush before we
1360
  // possibly handle logging the binary protobuf output.
1361
0
  absl::Status s;
1362
0
  {
1363
0
    MessagePath path(type_url);
1364
0
    JsonLexer lex(tee_input.has_value() ? &*tee_input : json_input, options,
1365
0
                  &path);
1366
0
    Msg<ParseProto3Type> msg(tee_output.has_value() ? &*tee_output
1367
0
                                                    : binary_output);
1368
1369
0
    ResolverPool pool(resolver);
1370
0
    auto desc = pool.FindMessage(type_url);
1371
0
    RETURN_IF_ERROR(desc.status());
1372
1373
0
    s = ParseMessage<ParseProto3Type>(lex, **desc, msg, /*any_reparse=*/false);
1374
0
    if (s.ok() && !lex.AtEof()) {
1375
0
      s = absl::InvalidArgumentError(
1376
0
          "extraneous characters after end of JSON object");
1377
0
    }
1378
0
  }
1379
1380
0
  if (PROTOBUF_DEBUG) {
1381
0
    tee_output.reset();  // Flush the output stream.
1382
0
    io::zc_sink_internal::ZeroCopyStreamByteSink(binary_output)
1383
0
        .Append(out.data(), out.size());
1384
0
    ABSL_DLOG(INFO) << "json2/status: " << s;
1385
0
    ABSL_DLOG(INFO) << "json2/output: " << absl::BytesToHexString(out);
1386
0
  }
1387
1388
0
  return s;
1389
0
}
1390
}  // namespace json_internal
1391
}  // namespace protobuf
1392
}  // namespace google