aboutsummaryrefslogtreecommitdiffhomepage
path: root/csharp/src/Google.Protobuf/JsonFormatter.cs
diff options
context:
space:
mode:
authorGravatar Jon Skeet <jonskeet@google.com>2015-09-04 12:41:14 +0100
committerGravatar Jon Skeet <jonskeet@google.com>2015-11-03 19:05:11 +0000
commitfb2488225fbd239f7880e3b493cbfd2f19da755b (patch)
treee51173d483b91a77708dd3bdbffa1577bf89bbec /csharp/src/Google.Protobuf/JsonFormatter.cs
parentaa3675415ec8da317793a3e151e44daaebc21ff8 (diff)
Implement JSON parsing in C#.
This includes all the well-known types except Any. Some aspects are likely to require further work when the details of the JSON parsing expectations are hammered out in more detail. Some of these have "ignored" tests already. Note that the choice *not* to use Json.NET was made for two reasons: - Going from 0 dependencies to 1 dependency is a big hit, and there's not much benefit here - Json.NET parses more leniently than we'd want; accommodating that would be nearly as much work as writing the tokenizer This only really affects the JsonTokenizer, which could be replaced by Json.NET. The JsonParser code would be about the same length with Json.NET... but I wouldn't be as confident in it.
Diffstat (limited to 'csharp/src/Google.Protobuf/JsonFormatter.cs')
-rw-r--r--csharp/src/Google.Protobuf/JsonFormatter.cs15
1 files changed, 12 insertions, 3 deletions
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 3f9bd478..2070f62b 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -189,6 +189,7 @@ namespace Google.Protobuf
}
// Converted from src/google/protobuf/util/internal/utility.cc ToCamelCase
+ // TODO: Use the new field in FieldDescriptor.
internal static string ToCamelCase(string input)
{
bool capitalizeNext = false;
@@ -382,10 +383,19 @@ namespace Google.Protobuf
WriteNull(builder);
return;
}
- // For wrapper types, the value will be the (possibly boxed) "native" value,
- // so we can write it as if we were unconditionally writing the Value field for the wrapper type.
+ // For wrapper types, the value will either be the (possibly boxed) "native" value,
+ // or the message itself if we're formatting it at the top level (e.g. just calling ToString on the object itself).
+ // If it's the message form, we can extract the value first, which *will* be the (possibly boxed) native value,
+ // and then proceed, writing it as if we were definitely in a field. (We never need to wrap it in an extra string...
+ // WriteValue will do the right thing.)
+ // TODO: Detect this differently when we have dynamic messages.
if (descriptor.File == Int32Value.Descriptor.File)
{
+ if (value is IMessage)
+ {
+ var message = (IMessage) value;
+ value = message.Descriptor.Fields[Wrappers.WrapperValueFieldNumber].Accessor.GetValue(message);
+ }
WriteValue(builder, value);
return;
}
@@ -750,7 +760,6 @@ namespace Google.Protobuf
private readonly bool formatDefaultValues;
-
/// <summary>
/// Whether fields whose values are the default for the field type (e.g. 0 for integers)
/// should be formatted (true) or omitted (false).