Converted `JSON::String` to bool and numbers. Previsouly when converting a JSON to a protobuf message in stout, we cannot handle the fields like below which are actually valid. "int32": "-2147483647" "int64": "-9223372036854775807" "float": "1.5" "bool": "true" The conversion will fail with an error like "Not expecting a JSON string for field 'int32'".
So in this patch, `Try<Nothing> operator()(const JSON::String& string)` was enhanced to be able to convert `JSON::String` to bool and numbers. This is to match Google's json -> protobuf behavior, see the doc below for details: https://developers.google.com/protocol-buffers/docs/proto3#json Review: https://reviews.apache.org/r/66025 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/499afcc0 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/499afcc0 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/499afcc0 Branch: refs/heads/master Commit: 499afcc00c0510bfa42d641358604c7bf59e3e13 Parents: fcc6dee Author: Qian Zhang <zhq527...@gmail.com> Authored: Sun Mar 11 21:11:24 2018 +0800 Committer: Qian Zhang <zhq527...@gmail.com> Committed: Wed Mar 14 08:18:53 2018 +0800 ---------------------------------------------------------------------- 3rdparty/stout/include/stout/protobuf.hpp | 32 +++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/499afcc0/3rdparty/stout/include/stout/protobuf.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/include/stout/protobuf.hpp b/3rdparty/stout/include/stout/protobuf.hpp index 4a1605e..69a54c9 100644 --- a/3rdparty/stout/include/stout/protobuf.hpp +++ b/3rdparty/stout/include/stout/protobuf.hpp @@ -412,7 +412,6 @@ struct Parser : boost::static_visitor<Try<Nothing>> break; case google::protobuf::FieldDescriptor::TYPE_BYTES: { Try<std::string> decode = base64::decode(string.value); - if (decode.isError()) { return Error("Failed to base64 decode bytes field" " '" + field->name() + "': " + decode.error()); @@ -452,6 +451,37 @@ struct Parser : boost::static_visitor<Try<Nothing>> } break; } + case google::protobuf::FieldDescriptor::TYPE_DOUBLE: + case google::protobuf::FieldDescriptor::TYPE_FLOAT: + case google::protobuf::FieldDescriptor::TYPE_INT64: + case google::protobuf::FieldDescriptor::TYPE_SINT64: + case google::protobuf::FieldDescriptor::TYPE_SFIXED64: + case google::protobuf::FieldDescriptor::TYPE_UINT64: + case google::protobuf::FieldDescriptor::TYPE_FIXED64: + case google::protobuf::FieldDescriptor::TYPE_INT32: + case google::protobuf::FieldDescriptor::TYPE_SINT32: + case google::protobuf::FieldDescriptor::TYPE_SFIXED32: + case google::protobuf::FieldDescriptor::TYPE_UINT32: + case google::protobuf::FieldDescriptor::TYPE_FIXED32: { + Try<JSON::Number> number = JSON::parse<JSON::Number>(string.value); + if (number.isError()) { + return Error( + "Failed to parse '" + string.value + "' as a JSON number " + "for field '" + field->name() + "': " + number.error()); + } + + return operator()(number.get()); + } + case google::protobuf::FieldDescriptor::TYPE_BOOL: { + Try<JSON::Boolean> boolean = JSON::parse<JSON::Boolean>(string.value); + if (boolean.isError()) { + return Error( + "Failed to parse '" + string.value + "' as a JSON boolean " + "for field '" + field->name() + "': " + boolean.error()); + } + + return operator()(boolean.get()); + } default: return Error("Not expecting a JSON string for field '" + field->name() + "'");