// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License

#include <gtest/gtest.h>

#include <gmock/gmock.h>

#include <algorithm>
#include <string>

#include <stout/gtest.hpp>
#include <stout/json.hpp>
#include <stout/jsonify.hpp>
#include <stout/protobuf.hpp>
#include <stout/stringify.hpp>
#include <stout/strings.hpp>
#include <stout/uuid.hpp>

#include "protobuf_tests.pb.h"

using std::string;

using google::protobuf::RepeatedPtrField;

namespace tests {

// Trivial equality operators to enable gtest macros.
bool operator==(const SimpleMessage& left, const SimpleMessage& right)
{
  if (left.id() != right.id() ||
      left.numbers().size() != right.numbers().size()) {
    return false;
  }

  return std::equal(
      left.numbers().begin(), left.numbers().end(), right.numbers().begin());
}


bool operator!=(const SimpleMessage& left, const SimpleMessage& right)
{
  return !(left == right);
}

} // namespace tests {


TEST(ProtobufTest, JSON)
{
  tests::Message message;
  message.set_b(true);
  message.set_str("string");
  message.set_bytes("bytes");
  message.set_int32(-1);
  message.set_int64(-1);
  message.set_uint32(1);
  message.set_uint64(1);
  message.set_sint32(-1);
  message.set_sint64(-1);
  message.set_f(1.0);
  message.set_d(1.0);
  message.set_e(tests::ONE);
  message.mutable_nested()->set_str("nested");
  message.add_repeated_bool(true);
  message.add_repeated_string("repeated_string");
  message.add_repeated_bytes("repeated_bytes");
  message.add_repeated_int32(-2);
  message.add_repeated_int64(-2);
  message.add_repeated_uint32(2);
  message.add_repeated_uint64(2);
  message.add_repeated_sint32(-2);
  message.add_repeated_sint64(-2);
  message.add_repeated_float(1.0);
  message.add_repeated_double(1.0);
  message.add_repeated_double(2.0);
  message.add_repeated_enum(tests::TWO);
  message.add_repeated_nested()->set_str("repeated_nested");

  // TODO(bmahler): To dynamically generate a protobuf message,
  // see the commented-out code below.
  //
  //  DescriptorProto proto;
  //
  //  proto.set_name("Message");
  //
  //  FieldDescriptorProto* field = proto.add_field();
  //  field->set_name("str");
  //  field->set_type(FieldDescriptorProto::TYPE_STRING);
  //
  //  const Descriptor* descriptor = proto.descriptor();
  //
  //  DynamicMessageFactory factory;
  //  Message* message = factory.GetPrototype(descriptor);
  //
  //  Reflection* message.getReflection();

  // The keys are in alphabetical order.
  string expected =
    R"~(
    {
      "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
    })~";

  // Remove ' ' and '\n' from `expected` so that we can compare
  // it with the JSON string parsed from protobuf message.
  expected.erase(
      std::remove_if(expected.begin(), expected.end(), ::isspace),
      expected.end());

  // 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 =
    R"~(
    {
      "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));

  // Test parsing too.
  Try<tests::Message> parse = protobuf::parse<tests::Message>(object);
  ASSERT_SOME(parse);

  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());

  object = JSON::protobuf(message);

  // Test parsing too.
  parse = protobuf::parse<tests::Message>(object);
  ASSERT_SOME(parse);

  EXPECT_EQ(object, JSON::protobuf(parse.get()));

  // Now convert JSON to string and parse it back as JSON.
  ASSERT_SOME_EQ(object, JSON::parse(stringify(object)));
}


TEST(ProtobufTest, JSONArray)
{
  tests::SimpleMessage message1;
  message1.set_id("message1");
  message1.add_numbers(1);
  message1.add_numbers(2);

  // Messages with different IDs are not equal.
  tests::SimpleMessage message2;
  message2.set_id("message2");
  message2.add_numbers(1);
  message2.add_numbers(2);

  // The keys are in alphabetical order.
  string expected =
    R"~(
    [
      {
        "id": "message1",
        "numbers": [1, 2]
      },
      {
        "id": "message2",
        "numbers": [1, 2]
      }
    ])~";

  // Remove ' ' and '\n' from `expected` so that we can compare
  // it with the JSON string parsed from protobuf message.
  expected.erase(
      std::remove_if(expected.begin(), expected.end(), ::isspace),
      expected.end());

  tests::ArrayMessage arrayMessage;
  arrayMessage.add_values()->CopyFrom(message1);
  arrayMessage.add_values()->CopyFrom(message2);

  JSON::Array array = JSON::protobuf(arrayMessage.values());

  EXPECT_EQ(expected, stringify(array));
}


// Tests that integer precision is maintained between
// JSON <-> Protobuf conversions.
TEST(ProtobufTest, JsonLargeIntegers)
{
  // These numbers are equal or close to the integer limits.
  tests::Message message;
  message.set_int32(-2147483647);
  message.set_int64(-9223372036854775807);
  message.set_uint32(4294967295U);
  message.set_uint64(9223372036854775807);
  message.set_sint32(-1234567890);
  message.set_sint64(-1234567890123456789);
  message.add_repeated_int32(-2000000000);
  message.add_repeated_int64(-9000000000000000000);
  message.add_repeated_uint32(3000000000U);
  message.add_repeated_uint64(7000000000000000000);
  message.add_repeated_sint32(-1000000000);
  message.add_repeated_sint64(-8000000000000000000);

  // Parts of the protobuf that are required.  Copied from the above test.
  message.set_b(true);
  message.set_str("string");
  message.set_bytes("bytes");
  message.set_f(1.0);
  message.set_d(1.0);
  message.set_e(tests::ONE);
  message.mutable_nested()->set_str("nested");

  // The keys are in alphabetical order.
  string expected =
    R"~(
    {
      "b": true,
      "bytes": "Ynl0ZXM=",
      "d": 1.0,
      "e": "ONE",
      "f": 1.0,
      "int32": -2147483647,
      "int64": -9223372036854775807,
      "nested": {"str": "nested"},
      "optional_default": 42.0,
      "repeated_int32": [-2000000000],
      "repeated_int64": [-9000000000000000000],
      "repeated_sint32": [-1000000000],
      "repeated_sint64": [-8000000000000000000],
      "repeated_uint32": [3000000000],
      "repeated_uint64": [7000000000000000000],
      "sint32": -1234567890,
      "sint64": -1234567890123456789,
      "str": "string",
      "uint32": 4294967295,
      "uint64": 9223372036854775807
    })~";

  // Remove ' ' and '\n' from `expected` so that we can compare
  // it with the JSON string parsed from protobuf message.
  expected.erase(
      std::remove_if(expected.begin(), expected.end(), ::isspace),
      expected.end());

  // Check JSON -> String.
  JSON::Object object = JSON::protobuf(message);
  EXPECT_EQ(expected, stringify(object));

  // Check JSON -> Protobuf.
  Try<tests::Message> parse = protobuf::parse<tests::Message>(object);
  ASSERT_SOME(parse);

  // Check Protobuf -> JSON.
  EXPECT_EQ(object, JSON::protobuf(parse.get()));

  // Check String -> JSON.
  Try<JSON::Object> json = JSON::parse<JSON::Object>(expected);
  EXPECT_SOME_EQ(object, json);
}


TEST(ProtobufTest, SimpleMessageEquals)
{
  tests::SimpleMessage message1;
  message1.set_id("message1");
  message1.add_numbers(1);
  message1.add_numbers(2);

  // Obviously, a message should equal to itself.
  EXPECT_EQ(message1, message1);

  // Messages with different IDs are not equal.
  tests::SimpleMessage message2;
  message2.set_id("message2");
  message2.add_numbers(1);
  message2.add_numbers(2);

  EXPECT_NE(message1, message2);

  // Messages with not identical collection of numbers are not equal.
  tests::SimpleMessage message3;
  message3.set_id("message1");
  message3.add_numbers(1);

  EXPECT_NE(message1, message3);

  tests::SimpleMessage message4;
  message4.set_id("message1");
  message4.add_numbers(2);
  message4.add_numbers(1);

  EXPECT_NE(message1, message4);

  // Different messages with the same ID and collection of numbers should
  // be equal. Their JSON counterparts should be equal as well.
  tests::SimpleMessage message5;
  message5.set_id("message1");
  message5.add_numbers(1);
  message5.add_numbers(2);

  EXPECT_EQ(message1, message5);
  EXPECT_EQ(JSON::protobuf(message1), JSON::protobuf(message5));
}


TEST(ProtobufTest, ParseJSONArray)
{
  tests::SimpleMessage message;
  message.set_id("message1");
  message.add_numbers(1);
  message.add_numbers(2);

  // Convert protobuf message to a JSON object.
  JSON::Object object = JSON::protobuf(message);

  // Populate JSON array with JSON objects, conversion JSON::Object ->
  // JSON::Value is implicit.
  JSON::Array array;
  array.values.push_back(object);
  array.values.push_back(object);

  // Parse JSON array into a collection of protobuf messages.
  auto parse =
    protobuf::parse<RepeatedPtrField<tests::SimpleMessage>>(array);
  ASSERT_SOME(parse);
  auto repeated = parse.get();

  // Make sure the parsed message equals to the original one.
  EXPECT_EQ(message, repeated.Get(0));
  EXPECT_EQ(message, repeated.Get(1));
}


TEST(ProtobufTest, ParseJSONNull)
{
  tests::Nested nested;
  nested.set_str("value");

  // Test message with optional field set to 'null'.
  string message =
    R"~(
    {
      "str": "value",
      "optional_str": null
    })~";

  Try<JSON::Object> json = JSON::parse<JSON::Object>(message);
  ASSERT_SOME(json);

  Try<tests::Nested> parse = protobuf::parse<tests::Nested>(json.get());
  ASSERT_SOME(parse);

  EXPECT_EQ(parse->SerializeAsString(), nested.SerializeAsString());

  // Test message with repeated field set to 'null'.
  message =
    R"~(
    {
      "str": "value",
      "repeated_str": null
    })~";

  json = JSON::parse<JSON::Object>(message);
  ASSERT_SOME(json);

  parse = protobuf::parse<tests::Nested>(json.get());
  ASSERT_SOME(parse);

  EXPECT_EQ(parse->SerializeAsString(), nested.SerializeAsString());

  // Test message with required field set to 'null'.
  message =
    R"~(
    {
      "str": null
    })~";

  json = JSON::parse<JSON::Object>(message);
  ASSERT_SOME(json);

  EXPECT_ERROR(protobuf::parse<tests::Nested>(json.get()));
}


TEST(ProtobufTest, ParseJSONNestedError)
{
  // Here we trigger an error parsing the 'nested' message, i.e., set
  // the string type field `nested.str` to a number.
  string message =
    R"~(
    {
      "b": true,
      "str": "string",
      "bytes": "Ynl0ZXM=",
      "f": 1.0,
      "d": 1.0,
      "e": "ONE",
      "nested": {
          "str": 1.0
      }
    })~";

  Try<JSON::Object> json = JSON::parse<JSON::Object>(message);
  ASSERT_SOME(json);

  Try<tests::Message> parse = protobuf::parse<tests::Message>(json.get());
  ASSERT_ERROR(parse);

  EXPECT_TRUE(strings::contains(
      parse.error(), "Not expecting a JSON number for field"));
}


// Tests when parsing protobuf from JSON, for the optional enum field which
// has an unrecognized enum value, after the parsing the field will be unset
// and its getter will return the default enum value. For the repeated enum
// field which contains an unrecognized enum value, after the parsing the
// field will not contain that unrecognized value anymore.
TEST(ProtobufTest, ParseJSONUnrecognizedEnum)
{
  string message =
    R"~(
    {
      "e1": "XXX",
      "e2": "",
      "repeated_enum": ["ONE", "XXX", "", "TWO"]
    })~";

  Try<JSON::Object> json = JSON::parse<JSON::Object>(message);
  ASSERT_SOME(json);

  Try<tests::EnumMessage> parse =
    protobuf::parse<tests::EnumMessage>(json.get());

  ASSERT_SOME(parse);

  EXPECT_FALSE(parse->has_e1());
  EXPECT_EQ(tests::UNKNOWN, parse->e1());
  EXPECT_FALSE(parse->has_e2());
  EXPECT_EQ(tests::UNKNOWN, parse->e2());

  EXPECT_EQ(2, parse->repeated_enum_size());
  EXPECT_EQ(tests::ONE, parse->repeated_enum(0));
  EXPECT_EQ(tests::TWO, parse->repeated_enum(1));
}


TEST(ProtobufTest, Jsonify)
{
  tests::Message message;
  message.set_b(true);
  message.set_str("string");
  message.set_bytes("bytes");
  message.set_int32(-1);
  message.set_int64(-1);
  message.set_uint32(1);
  message.set_uint64(1);
  message.set_sint32(-1);
  message.set_sint64(-1);
  message.set_f(1.0);
  message.set_d(1.0);
  message.set_e(tests::ONE);
  message.mutable_nested()->set_str("nested");
  message.add_repeated_bool(true);
  message.add_repeated_string("repeated_string");
  message.add_repeated_bytes("repeated_bytes");
  message.add_repeated_int32(-2);
  message.add_repeated_int64(-2);
  message.add_repeated_uint32(2);
  message.add_repeated_uint64(2);
  message.add_repeated_sint32(-2);
  message.add_repeated_sint64(-2);
  message.add_repeated_float(1.0);
  message.add_repeated_double(1.0);
  message.add_repeated_double(2.0);
  message.add_repeated_enum(tests::TWO);
  message.add_repeated_nested()->set_str("repeated_nested");

  // TODO(bmahler): To dynamically generate a protobuf message,
  // see the commented-out code below.
  //  DescriptorProto proto;
  //
  //  proto.set_name("Message");
  //
  //  FieldDescriptorProto* field = proto.add_field();
  //  field->set_name("str");
  //  field->set_type(FieldDescriptorProto::TYPE_STRING);
  //
  //  const Descriptor* descriptor = proto.descriptor();
  //
  //  DynamicMessageFactory factory;
  //  Message* message = factory.GetPrototype(descriptor);
  //
  //  Reflection* message.getReflection();

  // The keys are in alphabetical order.
  string expected =
    R"~(
    {
      "b": true,
      "str": "string",
      "bytes": "Ynl0ZXM=",
      "int32": -1,
      "int64": -1,
      "uint32": 1,
      "uint64": 1,
      "sint32": -1,
      "sint64": -1,
      "f": 1.0,
      "d": 1.0,
      "e": "ONE",
      "nested": { "str": "nested"},
      "repeated_bool": [true],
      "repeated_string": ["repeated_string"],
      "repeated_bytes": ["cmVwZWF0ZWRfYnl0ZXM="],
      "repeated_int32": [-2],
      "repeated_int64": [-2],
      "repeated_uint32": [2],
      "repeated_uint64": [2],
      "repeated_sint32": [-2],
      "repeated_sint64": [-2],
      "repeated_float": [1.0],
      "repeated_double": [1.0, 2.0],
      "repeated_enum": ["TWO"],
      "repeated_nested": [ { "str": "repeated_nested" } ],
      "optional_default": 42.0
    })~";

  // Remove ' ' and '\n' from `expected` so that we can compare
  // it with the JSON string parsed from protobuf message.
  expected.erase(
      std::remove_if(expected.begin(), expected.end(), ::isspace),
      expected.end());

  EXPECT_EQ(expected, string(jsonify(JSON::Protobuf(message))));
}


TEST(ProtobufTest, JsonifyArray)
{
  tests::SimpleMessage message1;
  message1.set_id("message1");
  message1.add_numbers(1);
  message1.add_numbers(2);

  // Messages with different IDs are not equal.
  tests::SimpleMessage message2;
  message2.set_id("message2");
  message2.add_numbers(1);
  message2.add_numbers(2);

  // The keys are in alphabetical order.
  string expected =
    R"~(
    [
      {
        "id": "message1",
        "numbers": [1, 2]
      },
      {
        "id": "message2",
        "numbers": [1, 2]
      }
    ])~";

  // Remove ' ' and '\n' from `expected` so that we can compare
  // it with the JSON string parsed from protobuf message.
  expected.erase(
      std::remove_if(expected.begin(), expected.end(), ::isspace),
      expected.end());

  tests::ArrayMessage arrayMessage;
  arrayMessage.add_values()->CopyFrom(message1);
  arrayMessage.add_values()->CopyFrom(message2);

  string actual = jsonify([&arrayMessage](JSON::ArrayWriter* writer) {
    foreach (const tests::SimpleMessage& message, arrayMessage.values()) {
      writer->element(JSON::Protobuf(message));
    }
  });

  EXPECT_EQ(expected, actual);
}


// Tests that integer precision is maintained between
// JSON <-> Protobuf conversions.
TEST(ProtobufTest, JsonifyLargeIntegers)
{
  // These numbers are equal or close to the integer limits.
  tests::Message message;
  message.set_int32(-2147483647);
  message.set_int64(-9223372036854775807);
  message.set_uint32(4294967295U);
  message.set_uint64(9223372036854775807);
  message.set_sint32(-1234567890);
  message.set_sint64(-1234567890123456789);
  message.add_repeated_int32(-2000000000);
  message.add_repeated_int64(-9000000000000000000);
  message.add_repeated_uint32(3000000000U);
  message.add_repeated_uint64(7000000000000000000);
  message.add_repeated_sint32(-1000000000);
  message.add_repeated_sint64(-8000000000000000000);

  // Parts of the protobuf that are required.  Copied from the above test.
  message.set_b(true);
  message.set_str("string");
  message.set_bytes("bytes");
  message.set_f(1.0);
  message.set_d(1.0);
  message.set_e(tests::ONE);
  message.mutable_nested()->set_str("nested");

  // The keys are in alphabetical order.
  string expected =
    R"~(
    {
      "b": true,
      "str": "string",
      "bytes": "Ynl0ZXM=",
      "int32": -2147483647,
      "int64": -9223372036854775807,
      "uint32": 4294967295,
      "uint64": 9223372036854775807,
      "sint32": -1234567890,
      "sint64": -1234567890123456789,
      "f": 1.0,
      "d": 1.0,
      "e": "ONE",
      "nested": {"str": "nested"},
      "repeated_int32": [-2000000000],
      "repeated_int64": [-9000000000000000000],
      "repeated_uint32": [3000000000],
      "repeated_uint64": [7000000000000000000],
      "repeated_sint32": [-1000000000],
      "repeated_sint64": [-8000000000000000000],
      "optional_default": 42.0
    })~";

  // Remove ' ' and '\n' from `expected` so that we can compare
  // it with the JSON string parsed from protobuf message.
  expected.erase(
      std::remove_if(expected.begin(), expected.end(), ::isspace),
      expected.end());

  // 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 =
    R"~(
    {
      "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"
      }
    })~";

  // Remove ' ' and '\n' from `expected` so that we can compare
  // it with the JSON string parsed from protobuf message.
  expected.erase(
      std::remove_if(expected.begin(), expected.end(), ::isspace),
      expected.end());

  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()));
}
