You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by qi...@apache.org on 2018/03/14 03:33:09 UTC

[1/5] mesos git commit: Added a test `ProtobufTest.JsonifyMap`.

Repository: mesos
Updated Branches:
  refs/heads/master fcc6dee4f -> 67cd0de36


Added a test `ProtobufTest.JsonifyMap`.

Review: https://reviews.apache.org/r/59989/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/67cd0de3
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/67cd0de3
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/67cd0de3

Branch: refs/heads/master
Commit: 67cd0de367a8da2f51fec1f1a7e808516794606e
Parents: 98358c0
Author: Qian Zhang <zh...@gmail.com>
Authored: Mon Jul 10 15:22:29 2017 +0800
Committer: Qian Zhang <zh...@gmail.com>
Committed: Wed Mar 14 08:18:53 2018 +0800

----------------------------------------------------------------------
 3rdparty/stout/tests/protobuf_tests.cpp | 118 +++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/67cd0de3/3rdparty/stout/tests/protobuf_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/protobuf_tests.cpp b/3rdparty/stout/tests/protobuf_tests.cpp
index 1c98ce2..a0ef1d1 100644
--- a/3rdparty/stout/tests/protobuf_tests.cpp
+++ b/3rdparty/stout/tests/protobuf_tests.cpp
@@ -678,3 +678,121 @@ TEST(ProtobufTest, JsonifyLargeIntegers)
   // Check JSON -> String.
   EXPECT_EQ(expected, string(jsonify(JSON::Protobuf(message))));
 }
+
+
+TEST(ProtobufTest, JsonifyMap)
+{
+  tests::MapMessage message;
+  (*message.mutable_string_to_bool())["key1"] = true;
+  (*message.mutable_string_to_bool())["key2"] = false;
+  (*message.mutable_string_to_bytes())["key"] = "bytes";
+  (*message.mutable_string_to_double())["key"] = 1.0;
+  (*message.mutable_string_to_enum())["key"] = tests::ONE;
+  (*message.mutable_string_to_float())["key"] = 1.0;
+  (*message.mutable_string_to_string())["key1"] = "value1";
+  (*message.mutable_string_to_string())["key2"] = "value2";
+
+  tests::Nested nested;
+  nested.set_str("nested");
+  (*message.mutable_string_to_nested())["key"] = nested;
+
+  // These numbers are equal or close to the integer limits.
+  (*message.mutable_string_to_int32())["key"] = -2147483647;
+  (*message.mutable_string_to_int64())["key"] = -9223372036854775807;
+  (*message.mutable_string_to_sint32())["key"] = -1234567890;
+  (*message.mutable_string_to_sint64())["key"] = -1234567890123456789;
+  (*message.mutable_string_to_uint32())["key"] = 4294967295;
+  (*message.mutable_string_to_uint64())["key"] = 9223372036854775807;
+
+  (*message.mutable_bool_to_string())[true] = "value1";
+  (*message.mutable_bool_to_string())[false] = "value2";
+
+  // These numbers are equal or close to the integer limits.
+  (*message.mutable_int32_to_string())[-2147483647] = "value";
+  (*message.mutable_int64_to_string())[-9223372036854775807] = "value";
+  (*message.mutable_sint32_to_string())[-1234567890] = "value";
+  (*message.mutable_sint64_to_string())[-1234567890123456789] = "value";
+  (*message.mutable_uint32_to_string())[4294967295] = "value";
+  (*message.mutable_uint64_to_string())[9223372036854775807] = "value";
+
+  // The keys are in alphabetical order.
+  // The value of `string_to_bytes` is base64 encoded.
+  string expected = strings::remove(
+      "{"
+      "  \"bool_to_string\": {"
+      "    \"false\": \"value2\","
+      "    \"true\": \"value1\""
+      "  },"
+      "  \"int32_to_string\": {"
+      "    \"-2147483647\": \"value\""
+      "  },"
+      "  \"int64_to_string\": {"
+      "    \"-9223372036854775807\": \"value\""
+      "  },"
+      "  \"sint32_to_string\": {"
+      "    \"-1234567890\": \"value\""
+      "  },"
+      "  \"sint64_to_string\": {"
+      "    \"-1234567890123456789\": \"value\""
+      "  },"
+      "  \"string_to_bool\": {"
+      "    \"key1\": true,"
+      "    \"key2\": false"
+      "  },"
+      "  \"string_to_bytes\": {"
+      "    \"key\": \"Ynl0ZXM=\""
+      "  },"
+      "  \"string_to_double\": {"
+      "    \"key\": 1.0"
+      "  },"
+      "  \"string_to_enum\": {"
+      "    \"key\": \"ONE\""
+      "  },"
+      "  \"string_to_float\": {"
+      "    \"key\": 1.0"
+      "  },"
+      "  \"string_to_int32\": {"
+      "    \"key\": -2147483647"
+      "  },"
+      "  \"string_to_int64\": {"
+      "    \"key\": -9223372036854775807"
+      "  },"
+      "  \"string_to_nested\": {"
+      "    \"key\": {"
+      "      \"str\": \"nested\""
+      "    }"
+      "  },"
+      "  \"string_to_sint32\": {"
+      "    \"key\": -1234567890"
+      "  },"
+      "  \"string_to_sint64\": {"
+      "    \"key\": -1234567890123456789"
+      "  },"
+      "  \"string_to_string\": {"
+      "    \"key1\": \"value1\","
+      "    \"key2\": \"value2\""
+      "  },"
+      "  \"string_to_uint32\": {"
+      "    \"key\": 4294967295"
+      "  },"
+      "  \"string_to_uint64\": {"
+      "    \"key\": 9223372036854775807"
+      "  },"
+      "  \"uint32_to_string\": {"
+      "    \"4294967295\": \"value\""
+      "  },"
+      "  \"uint64_to_string\": {"
+      "    \"9223372036854775807\": \"value\""
+      "  }"
+      "}",
+      " ");
+
+  JSON::Object object = JSON::protobuf(message);
+  EXPECT_EQ(expected, stringify(object));
+
+  // Test parsing too.
+  Try<tests::MapMessage> parse = protobuf::parse<tests::MapMessage>(object);
+  ASSERT_SOME(parse);
+
+  EXPECT_EQ(object, JSON::protobuf(parse.get()));
+}


[2/5] mesos git commit: Added protobuf map support to stout JSON<->protobuf conversion.

Posted by qi...@apache.org.
Added protobuf map support to stout JSON<->protobuf conversion.

Map is a feature of proto2 syntax, but it can only be compiled
with 3.0.0+ protobuf compiler, see the following discussion for
details:

https://groups.google.com/forum/#!topic/protobuf/p4WxcplrlA4

We have already upgraded the compiler from 2.6.1 to 3.3.0 in
MESOS-7228. This patch adds map support in the json <-> protobuf
conversion in stout.

Review: https://reviews.apache.org/r/59987/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5b226140
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5b226140
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5b226140

Branch: refs/heads/master
Commit: 5b2261409e2b391d9182c5579e1df481c7f0779f
Parents: 61e7765
Author: Qian Zhang <zh...@gmail.com>
Authored: Mon Jul 10 15:21:55 2017 +0800
Committer: Qian Zhang <zh...@gmail.com>
Committed: Wed Mar 14 08:18:53 2018 +0800

----------------------------------------------------------------------
 3rdparty/stout/include/stout/protobuf.hpp | 201 ++++++++++++++++---------
 1 file changed, 134 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/5b226140/3rdparty/stout/include/stout/protobuf.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/protobuf.hpp b/3rdparty/stout/include/stout/protobuf.hpp
index 69a54c9..2fa5072 100644
--- a/3rdparty/stout/include/stout/protobuf.hpp
+++ b/3rdparty/stout/include/stout/protobuf.hpp
@@ -382,12 +382,51 @@ struct Parser : boost::static_visitor<Try<Nothing>>
   {
     switch (field->type()) {
       case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
-        // TODO(gilbert): We currently push up the nested error
-        // messages without wrapping the error message (due to
-        // the recursive nature of parse). We should pass along
-        // variable information in order to construct a helpful
-        // error message, e.g. "Failed to parse field 'a.b.c': ...".
-        if (field->is_repeated()) {
+        if (field->is_map()) {
+          foreachpair (
+              const std::string& name,
+              const JSON::Value& value,
+              object.values) {
+            google::protobuf::Message* entry =
+              reflection->AddMessage(message, field);
+
+            // A map is equivalent to:
+            //
+            //   message MapFieldEntry {
+            //     optional key_type key = 1;
+            //     optional value_type value = 2;
+            //   }
+            //
+            //   repeated MapFieldEntry map_field = N;
+            //
+            // See the link below for details:
+            // https://developers.google.com/protocol-buffers/docs/proto#maps
+            const google::protobuf::FieldDescriptor* key_field =
+              entry->GetDescriptor()->FindFieldByNumber(1);
+
+            JSON::Value key(name);
+
+            Try<Nothing> apply =
+              boost::apply_visitor(Parser(entry, key_field), key);
+
+            if (apply.isError()) {
+              return Error(apply.error());
+            }
+
+            const google::protobuf::FieldDescriptor* value_field =
+              entry->GetDescriptor()->FindFieldByNumber(2);
+
+            apply = boost::apply_visitor(Parser(entry, value_field), value);
+            if (apply.isError()) {
+              return Error(apply.error());
+            }
+          }
+        } else if (field->is_repeated()) {
+          // TODO(gilbert): We currently push up the nested error
+          // messages without wrapping the error message (due to
+          // the recursive nature of parse). We should pass along
+          // variable information in order to construct a helpful
+          // error message, e.g. "Failed to parse field 'a.b.c': ...".
           return parse(reflection->AddMessage(message, field), object);
         } else {
           return parse(reflection->MutableMessage(message, field), object);
@@ -864,6 +903,56 @@ inline Object protobuf(const google::protobuf::Message& message)
   const google::protobuf::Descriptor* descriptor = message.GetDescriptor();
   const google::protobuf::Reflection* reflection = message.GetReflection();
 
+  auto value_for_field = [](
+      const google::protobuf::Message& message,
+      const google::protobuf::FieldDescriptor* field) -> JSON::Value {
+    const google::protobuf::Reflection* reflection = message.GetReflection();
+
+    switch (field->type()) {
+      case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
+        return JSON::Number(reflection->GetDouble(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_FLOAT:
+        return JSON::Number(reflection->GetFloat(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_INT64:
+      case google::protobuf::FieldDescriptor::TYPE_SINT64:
+      case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
+        return JSON::Number(reflection->GetInt64(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_UINT64:
+      case google::protobuf::FieldDescriptor::TYPE_FIXED64:
+        return JSON::Number(reflection->GetUInt64(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_INT32:
+      case google::protobuf::FieldDescriptor::TYPE_SINT32:
+      case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
+        return JSON::Number(reflection->GetInt32(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_UINT32:
+      case google::protobuf::FieldDescriptor::TYPE_FIXED32:
+        return JSON::Number(reflection->GetUInt32(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_BOOL:
+        if (reflection->GetBool(message, field)) {
+          return JSON::Boolean(true);
+        } else {
+          return JSON::Boolean(false);
+        }
+        break;
+      case google::protobuf::FieldDescriptor::TYPE_STRING:
+        return JSON::String(reflection->GetString(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_BYTES:
+        return JSON::String(
+            base64::encode(reflection->GetString(message, field)));
+      case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
+        return protobuf(reflection->GetMessage(message, field));
+      case google::protobuf::FieldDescriptor::TYPE_ENUM:
+        return JSON::String(reflection->GetEnum(message, field)->name());
+      case google::protobuf::FieldDescriptor::TYPE_GROUP:
+        // Deprecated! We abort here instead of using a Try as return value,
+        // because we expect this code path to never be taken.
+        ABORT("Unhandled protobuf field type: " +
+              stringify(field->type()));
+    }
+
+    UNREACHABLE();
+  };
+
   // We first look through all the possible fields to determine both
   // the set fields _and_ the optional fields with a default that
   // are not set. Reflection::ListFields() alone will only include
@@ -886,7 +975,44 @@ inline Object protobuf(const google::protobuf::Message& message)
   }
 
   foreach (const google::protobuf::FieldDescriptor* field, fields) {
-    if (field->is_repeated()) {
+    if (field->is_map()) {
+      JSON::Object map;
+
+      int fieldSize = reflection->FieldSize(message, field);
+      for (int i = 0; i < fieldSize; ++i) {
+        const google::protobuf::Message& entry =
+          reflection->GetRepeatedMessage(message, field, i);
+
+        // A map is equivalent to:
+        //
+        //   message MapFieldEntry {
+        //     optional key_type key = 1;
+        //     optional value_type value = 2;
+        //   }
+        //
+        //   repeated MapFieldEntry map_field = N;
+        //
+        // See the link below for details:
+        // https://developers.google.com/protocol-buffers/docs/proto#maps
+        const google::protobuf::FieldDescriptor* key_field =
+          entry.GetDescriptor()->FindFieldByNumber(1);
+
+        const google::protobuf::FieldDescriptor* value_field =
+          entry.GetDescriptor()->FindFieldByNumber(2);
+
+        JSON::Value key = value_for_field(entry, key_field);
+
+        std::string name;
+        if (key.is<JSON::String>()) {
+          name = key.as<JSON::String>().value;
+        } else {
+          name = jsonify(key);
+        }
+
+        map.values[name] = value_for_field(entry, value_field);
+      }
+      object.values[field->name()] = map;
+    } else if (field->is_repeated()) {
       JSON::Array array;
       int fieldSize = reflection->FieldSize(message, field);
       array.values.reserve(fieldSize);
@@ -954,66 +1080,7 @@ inline Object protobuf(const google::protobuf::Message& message)
       }
       object.values[field->name()] = array;
     } else {
-      switch (field->type()) {
-        case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
-          object.values[field->name()] =
-              JSON::Number(reflection->GetDouble(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_FLOAT:
-          object.values[field->name()] =
-              JSON::Number(reflection->GetFloat(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_INT64:
-        case google::protobuf::FieldDescriptor::TYPE_SINT64:
-        case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
-          object.values[field->name()] =
-              JSON::Number(reflection->GetInt64(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_UINT64:
-        case google::protobuf::FieldDescriptor::TYPE_FIXED64:
-          object.values[field->name()] =
-              JSON::Number(reflection->GetUInt64(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_INT32:
-        case google::protobuf::FieldDescriptor::TYPE_SINT32:
-        case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
-          object.values[field->name()] =
-              JSON::Number(reflection->GetInt32(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_UINT32:
-        case google::protobuf::FieldDescriptor::TYPE_FIXED32:
-          object.values[field->name()] =
-              JSON::Number(reflection->GetUInt32(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_BOOL:
-          if (reflection->GetBool(message, field)) {
-            object.values[field->name()] = JSON::Boolean(true);
-          } else {
-            object.values[field->name()] = JSON::Boolean(false);
-          }
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_STRING:
-          object.values[field->name()] =
-              JSON::String(reflection->GetString(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_BYTES:
-          object.values[field->name()] = JSON::String(
-              base64::encode(reflection->GetString(message, field)));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
-          object.values[field->name()] =
-            protobuf(reflection->GetMessage(message, field));
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_ENUM:
-          object.values[field->name()] =
-              JSON::String(reflection->GetEnum(message, field)->name());
-          break;
-        case google::protobuf::FieldDescriptor::TYPE_GROUP:
-          // Deprecated! We abort here instead of using a Try as return value,
-          // because we expect this code path to never be taken.
-          ABORT("Unhandled protobuf field type: " +
-                stringify(field->type()));
-      }
+      object.values[field->name()] = value_for_field(message, field);
     }
   }
 


[4/5] mesos git commit: Added a new protobuf message `MapMessage` for protobuf tests.

Posted by qi...@apache.org.
Added a new protobuf message `MapMessage` for protobuf tests.

Review: https://reviews.apache.org/r/59988/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/98358c01
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/98358c01
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/98358c01

Branch: refs/heads/master
Commit: 98358c01af6ebb1c9f2fcea9dca96389f3a6e1ed
Parents: 5b22614
Author: Qian Zhang <zh...@gmail.com>
Authored: Mon Jul 10 15:22:20 2017 +0800
Committer: Qian Zhang <zh...@gmail.com>
Committed: Wed Mar 14 08:18:53 2018 +0800

----------------------------------------------------------------------
 3rdparty/stout/tests/protobuf_tests.proto | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/98358c01/3rdparty/stout/tests/protobuf_tests.proto
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/protobuf_tests.proto b/3rdparty/stout/tests/protobuf_tests.proto
index cf8aadc..5e20215 100644
--- a/3rdparty/stout/tests/protobuf_tests.proto
+++ b/3rdparty/stout/tests/protobuf_tests.proto
@@ -105,3 +105,28 @@ message EnumMessage {
   optional Enum e2 = 2;
   repeated Enum repeated_enum = 3;
 }
+
+
+// A message for testing map.
+message MapMessage {
+  map<string, string> string_to_string = 1;
+  map<string, bool> string_to_bool = 2;
+  map<string, bytes> string_to_bytes = 3;
+  map<string, int32> string_to_int32 = 4;
+  map<string, int64> string_to_int64 = 5;
+  map<string, uint32> string_to_uint32 = 6;
+  map<string, uint64> string_to_uint64 = 7;
+  map<string, sint32> string_to_sint32 = 8;
+  map<string, sint64> string_to_sint64 = 9;
+  map<string, float> string_to_float = 10;
+  map<string, double> string_to_double = 11;
+  map<string, Enum> string_to_enum = 12;
+  map<string, Nested> string_to_nested = 13;
+  map<bool, string> bool_to_string = 14;
+  map<int32, string> int32_to_string = 15;
+  map<int64, string> int64_to_string = 16;
+  map<uint32,string> uint32_to_string = 17;
+  map<uint64, string> uint64_to_string = 18;
+  map<sint32, string> sint32_to_string = 19;
+  map<sint64, string> sint64_to_string = 20;
+}


[3/5] mesos git commit: Converted `JSON::String` to bool and numbers.

Posted by qi...@apache.org.
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 <zh...@gmail.com>
Authored: Sun Mar 11 21:11:24 2018 +0800
Committer: Qian Zhang <zh...@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() + "'");


[5/5] mesos git commit: Updated `ProtobufTest.JSON` for parsing JSON::String to bools & numbers.

Posted by qi...@apache.org.
Updated `ProtobufTest.JSON` for parsing JSON::String to bools & numbers.

Review: https://reviews.apache.org/r/66026


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/61e77658
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/61e77658
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/61e77658

Branch: refs/heads/master
Commit: 61e77658ad1fc9eb72f1b0fa26c4c3257e265fbb
Parents: 499afcc
Author: Qian Zhang <zh...@gmail.com>
Authored: Mon Mar 12 09:15:10 2018 +0800
Committer: Qian Zhang <zh...@gmail.com>
Committed: Wed Mar 14 08:18:53 2018 +0800

----------------------------------------------------------------------
 3rdparty/stout/tests/protobuf_tests.cpp | 44 ++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/61e77658/3rdparty/stout/tests/protobuf_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/protobuf_tests.cpp b/3rdparty/stout/tests/protobuf_tests.cpp
index be35ad0..1c98ce2 100644
--- a/3rdparty/stout/tests/protobuf_tests.cpp
+++ b/3rdparty/stout/tests/protobuf_tests.cpp
@@ -136,6 +136,40 @@ TEST(ProtobufTest, JSON)
       "}",
       " ");
 
+  // The only difference between this JSON string and the above one is, all
+  // the bools and numbers are in the format of strings.
+  string accepted = strings::remove(
+      "{"
+      "  \"b\": \"true\","
+      "  \"bytes\": \"Ynl0ZXM=\","
+      "  \"d\": \"1.0\","
+      "  \"e\": \"ONE\","
+      "  \"f\": \"1.0\","
+      "  \"int32\": \"-1\","
+      "  \"int64\": \"-1\","
+      "  \"nested\": { \"str\": \"nested\"},"
+      "  \"optional_default\": \"42.0\","
+      "  \"repeated_bool\": [\"true\"],"
+      "  \"repeated_bytes\": [\"cmVwZWF0ZWRfYnl0ZXM=\"],"
+      "  \"repeated_double\": [\"1.0\", \"2.0\"],"
+      "  \"repeated_enum\": [\"TWO\"],"
+      "  \"repeated_float\": [\"1.0\"],"
+      "  \"repeated_int32\": [\"-2\"],"
+      "  \"repeated_int64\": [\"-2\"],"
+      "  \"repeated_nested\": [ { \"str\": \"repeated_nested\" } ],"
+      "  \"repeated_sint32\": [\"-2\"],"
+      "  \"repeated_sint64\": [\"-2\"],"
+      "  \"repeated_string\": [\"repeated_string\"],"
+      "  \"repeated_uint32\": [\"2\"],"
+      "  \"repeated_uint64\": [\"2\"],"
+      "  \"sint32\": \"-1\","
+      "  \"sint64\": \"-1\","
+      "  \"str\": \"string\","
+      "  \"uint32\": \"1\","
+      "  \"uint64\": \"1\""
+      "}",
+      " ");
+
   JSON::Object object = JSON::protobuf(message);
 
   EXPECT_EQ(expected, stringify(object));
@@ -146,6 +180,16 @@ TEST(ProtobufTest, JSON)
 
   EXPECT_EQ(object, JSON::protobuf(parse.get()));
 
+  // Test all the bools and numbers in the JSON string `accepted` can be
+  // successfully parsed.
+  Try<JSON::Object> json = JSON::parse<JSON::Object>(accepted);
+  ASSERT_SOME(json);
+
+  parse = protobuf::parse<tests::Message>(json.get());
+  ASSERT_SOME(parse);
+
+  EXPECT_EQ(object, JSON::protobuf(parse.get()));
+
   // Modify the message to test (de-)serialization of random bytes generated
   // by UUID.
   message.set_bytes(id::UUID::random().toBytes());