Skip to content

Commit

Permalink
Merge pull request protocolbuffers#1707 from jskeet/format-value
Browse files Browse the repository at this point in the history
Expose JsonFormatter.WriteValue.
  • Loading branch information
jtattermusch authored Jun 23, 2016
2 parents a897ebb + 0421238 commit 6f67be6
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 25 deletions.
47 changes: 47 additions & 0 deletions csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
using Google.Protobuf.Reflection;

using static Google.Protobuf.JsonParserTest; // For WrapInQuotes
using System.IO;
using Google.Protobuf.Collections;

namespace Google.Protobuf
{
Expand Down Expand Up @@ -528,6 +530,51 @@ public void Wrappers_Standalone(System.Type wrapperType, object value, string ex
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
Expand Down
36 changes: 11 additions & 25 deletions csharp/src/Google.Protobuf/JsonFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,16 @@ private static bool IsDefaultValue(IFieldAccessor accessor, object value)
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)
{
Expand Down Expand Up @@ -447,15 +455,7 @@ private void WriteValue(TextWriter writer, object value)
}
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
{
Expand Down Expand Up @@ -723,20 +723,6 @@ internal void WriteDictionary(TextWriter writer, IDictionary dictionary)
writer.Write(first ? "}" : " }");
}

/// <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>
Expand Down

0 comments on commit 6f67be6

Please sign in to comment.