aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Skeet <jonskeet@google.com>2016-06-23 10:46:21 +0100
committerJon Skeet <jonskeet@google.com>2016-06-23 12:31:10 +0100
commit0421238cc1ab0f671249d967ad5f14e73feccf5e (patch)
tree9ed9d11d7ecd1b4dde736951f8bdca7c753cc1f1
parenta897ebb6a89d983527807daa62b1d071eb5052b6 (diff)
downloadprotobuf-0421238cc1ab0f671249d967ad5f14e73feccf5e.tar.gz
protobuf-0421238cc1ab0f671249d967ad5f14e73feccf5e.tar.bz2
protobuf-0421238cc1ab0f671249d967ad5f14e73feccf5e.zip
Expose JsonFormatter.WriteValue.
This isn't useful to most users, but can be handy in advanced use cases, as requested in #1465.
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs47
-rw-r--r--csharp/src/Google.Protobuf/JsonFormatter.cs36
2 files changed, 58 insertions, 25 deletions
diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
index 77f9c434..51b3ca2d 100644
--- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -38,6 +38,8 @@ using Google.Protobuf.WellKnownTypes;
using Google.Protobuf.Reflection;
using static Google.Protobuf.JsonParserTest; // For WrapInQuotes
+using System.IO;
+using Google.Protobuf.Collections;
namespace Google.Protobuf
{
@@ -528,6 +530,51 @@ namespace Google.Protobuf
Assert.AreEqual(expectedJson, JsonFormatter.Default.Format(populated));
}
+ // Sanity tests for WriteValue. Not particularly comprehensive, as it's all covered above already,
+ // as FormatMessage uses WriteValue.
+
+ [TestCase(null, "null")]
+ [TestCase(1, "1")]
+ [TestCase(1L, "'1'")]
+ [TestCase(0.5f, "0.5")]
+ [TestCase(0.5d, "0.5")]
+ [TestCase("text", "'text'")]
+ [TestCase("x\ny", @"'x\ny'")]
+ [TestCase(ForeignEnum.ForeignBar, "'FOREIGN_BAR'")]
+ public void WriteValue_Constant(object value, string expectedJson)
+ {
+ AssertWriteValue(value, expectedJson);
+ }
+
+ [Test]
+ public void WriteValue_Timestamp()
+ {
+ var value = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
+ AssertWriteValue(value, "'1673-06-19T12:34:56Z'");
+ }
+
+ [Test]
+ public void WriteValue_Message()
+ {
+ var value = new TestAllTypes { SingleInt32 = 100, SingleInt64 = 3210987654321L };
+ AssertWriteValue(value, "{ 'singleInt32': 100, 'singleInt64': '3210987654321' }");
+ }
+
+ [Test]
+ public void WriteValue_List()
+ {
+ var value = new RepeatedField<int> { 1, 2, 3 };
+ AssertWriteValue(value, "[ 1, 2, 3 ]");
+ }
+
+ private static void AssertWriteValue(object value, string expectedJson)
+ {
+ var writer = new StringWriter();
+ JsonFormatter.Default.WriteValue(writer, value);
+ string actual = writer.ToString();
+ AssertJson(expectedJson, actual);
+ }
+
/// <summary>
/// Checks that the actual JSON is the same as the expected JSON - but after replacing
/// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 83772473..2aa98cd1 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -377,8 +377,16 @@ namespace Google.Protobuf
throw new ArgumentException("Invalid field type");
}
}
-
- private void WriteValue(TextWriter writer, object value)
+
+ /// <summary>
+ /// Writes a single value to the given writer as JSON. Only types understood by
+ /// Protocol Buffers can be written in this way. This method is only exposed for
+ /// advanced use cases; most users should be using <see cref="Format(IMessage)"/>
+ /// or <see cref="Format(IMessage, TextWriter)"/>.
+ /// </summary>
+ /// <param name="writer">The writer to write the value to. Must not be null.</param>
+ /// <param name="value">The value to write. May be null.</param>
+ public void WriteValue(TextWriter writer, object value)
{
if (value == null)
{
@@ -447,15 +455,7 @@ namespace Google.Protobuf
}
else if (value is IMessage)
{
- IMessage message = (IMessage) value;
- if (message.Descriptor.IsWellKnownType)
- {
- WriteWellKnownTypeValue(writer, message.Descriptor, value);
- }
- else
- {
- WriteMessage(writer, (IMessage)value);
- }
+ Format((IMessage)value, writer);
}
else
{
@@ -724,20 +724,6 @@ namespace Google.Protobuf
}
/// <summary>
- /// Returns whether or not a singular value can be represented in JSON.
- /// Currently only relevant for enums, where unknown values can't be represented.
- /// For repeated/map fields, this always returns true.
- /// </summary>
- private bool CanWriteSingleValue(object value)
- {
- if (value is System.Enum)
- {
- return System.Enum.IsDefined(value.GetType(), value);
- }
- return true;
- }
-
- /// <summary>
/// Writes a string (including leading and trailing double quotes) to a builder, escaping as required.
/// </summary>
/// <remarks>