Skip to content

Commit

Permalink
noop: move map key parsing into a new function
Browse files Browse the repository at this point in the history
The only diff is in how we return lex error in unsupported map key type:

```
// before
return lex.Invalid("unsupported map key type");

// now
return key.loc.Invalid("unsupported map key type");
```

The motivation was to simplify the function call (1 parameter less), and
I believe that the two are equivalent:

https://github.com/protocolbuffers/protobuf/blob/0cda26d48db0241f6aca0e931ff0a31acea1a6c2/src/google/protobuf/json/internal/lexer.h#L113
  • Loading branch information
antongrbin committed Apr 19, 2024
1 parent 3494bb1 commit 7f8b7d6
Showing 1 changed file with 77 additions and 70 deletions.
147 changes: 77 additions & 70 deletions src/google/protobuf/json/internal/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,81 @@ absl::Status ParseArray(JsonLexer& lex, Field<Traits> field, Msg<Traits>& msg) {
});
}

// Parses map key from already consumed string 'key' into the key field of the
// map entry message 'entry' of type 'type'.
template <typename Traits>
absl::Status ParseMapKey(const json_internal::ParseOptions& options,
const Desc<Traits>& type,
Msg<Traits>& entry,
LocationWith<MaybeOwnedString>& key) {
auto key_field = Traits::KeyField(type);
switch (Traits::FieldType(key_field)) {
case FieldDescriptor::TYPE_INT64:
case FieldDescriptor::TYPE_SINT64:
case FieldDescriptor::TYPE_SFIXED64: {
int64_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid("non-number characters in quoted number");
}
Traits::SetInt64(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_UINT64:
case FieldDescriptor::TYPE_FIXED64: {
uint64_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid("non-number characters in quoted number");
}
Traits::SetUInt64(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_SINT32:
case FieldDescriptor::TYPE_SFIXED32: {
int32_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid("non-number characters in quoted number");
}
Traits::SetInt32(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_UINT32:
case FieldDescriptor::TYPE_FIXED32: {
uint32_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid("non-number characters in quoted number");
}
Traits::SetUInt32(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_BOOL: {
if (key.value == "true") {
Traits::SetBool(key_field, entry, true);
} else if (key.value == "false") {
Traits::SetBool(key_field, entry, false);
} else {
return key.loc.Invalid(absl::StrFormat("expected bool string, got '%s'",
key.value.AsView()));
}
break;
}
case FieldDescriptor::TYPE_ENUM: {
MaybeOwnedString key_str = key.value;
auto e = ParseEnumFromStr<Traits>(options, key_str, key_field);
RETURN_IF_ERROR(e.status());
Traits::SetEnum(key_field, entry, e->value_or(0));
break;
}
case FieldDescriptor::TYPE_STRING: {
Traits::SetString(key_field, entry, std::move(key.value.ToString()));
break;
}
default:
return key.loc.Invalid("unsupported map key type");
}
return absl::OkStatus();
}

template <typename Traits>
absl::Status ParseMap(JsonLexer& lex, Field<Traits> field, Msg<Traits>& msg) {
if (lex.Peek(JsonLexer::kNull)) {
Expand All @@ -644,76 +719,8 @@ absl::Status ParseMap(JsonLexer& lex, Field<Traits> field, Msg<Traits>& msg) {
return Traits::NewMsg(
field, msg,
[&](const Desc<Traits>& type, Msg<Traits>& entry) -> absl::Status {
auto key_field = Traits::KeyField(type);
switch (Traits::FieldType(key_field)) {
case FieldDescriptor::TYPE_INT64:
case FieldDescriptor::TYPE_SINT64:
case FieldDescriptor::TYPE_SFIXED64: {
int64_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid(
"non-number characters in quoted number");
}
Traits::SetInt64(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_UINT64:
case FieldDescriptor::TYPE_FIXED64: {
uint64_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid(
"non-number characters in quoted number");
}
Traits::SetUInt64(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_SINT32:
case FieldDescriptor::TYPE_SFIXED32: {
int32_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid(
"non-number characters in quoted number");
}
Traits::SetInt32(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_UINT32:
case FieldDescriptor::TYPE_FIXED32: {
uint32_t n;
if (!absl::SimpleAtoi(key.value.AsView(), &n)) {
return key.loc.Invalid(
"non-number characters in quoted number");
}
Traits::SetUInt32(key_field, entry, n);
break;
}
case FieldDescriptor::TYPE_BOOL: {
if (key.value == "true") {
Traits::SetBool(key_field, entry, true);
} else if (key.value == "false") {
Traits::SetBool(key_field, entry, false);
} else {
return key.loc.Invalid(absl::StrFormat(
"expected bool string, got '%s'", key.value.AsView()));
}
break;
}
case FieldDescriptor::TYPE_ENUM: {
MaybeOwnedString key_str = key.value;
auto e = ParseEnumFromStr<Traits>(lex, key_str, field);
RETURN_IF_ERROR(e.status());
Traits::SetEnum(key_field, entry, e->value_or(0));
break;
}
case FieldDescriptor::TYPE_STRING: {
Traits::SetString(key_field, entry,
std::move(key.value.ToString()));
break;
}
default:
return lex.Invalid("unsupported map key type");
}
RETURN_IF_ERROR(
ParseMapKey<Traits>(lex.options(), type, entry, key));

return ParseSingular<Traits>(lex, Traits::ValueField(type),
entry);
Expand Down

0 comments on commit 7f8b7d6

Please sign in to comment.