aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Jon Skeet <jonskeet@google.com>2016-01-15 11:39:54 +0000
committerGravatar Jon Skeet <jonskeet@google.com>2016-01-15 11:39:54 +0000
commit022a9b267561a3fccfcfaa7023779b969692bf74 (patch)
tree5f1644de36c2e597e394d396c87336ca73c9e403
parent1fc485928fc7a6483b700867f1a6cb2acfa8da5d (diff)
Allow the original field name (rather than camel-cased) when parsing JSON
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonParserTest.cs8
-rw-r--r--csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs18
2 files changed, 23 insertions, 3 deletions
diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
index d3c3a489..aa090d12 100644
--- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
@@ -72,6 +72,14 @@ namespace Google.Protobuf
}
[Test]
+ public void OriginalFieldNameAccepted()
+ {
+ var json = "{ \"single_int32\": 10 }";
+ var expected = new TestAllTypes { SingleInt32 = 10 };
+ Assert.AreEqual(expected, TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
public void SourceContextRoundtrip()
{
AssertRoundtrip(new SourceContext { FileName = "foo.proto" });
diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
index d1732b2e..f43803a6 100644
--- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
@@ -92,11 +92,22 @@ namespace Google.Protobuf.Reflection
new FieldDescriptor(field, file, this, index, generatedCodeInfo?.PropertyNames[index]));
fieldsInNumberOrder = new ReadOnlyCollection<FieldDescriptor>(fieldsInDeclarationOrder.OrderBy(field => field.FieldNumber).ToArray());
// TODO: Use field => field.Proto.JsonName when we're confident it's appropriate. (And then use it in the formatter, too.)
- jsonFieldMap = new ReadOnlyDictionary<string, FieldDescriptor>(fieldsInNumberOrder.ToDictionary(field => JsonFormatter.ToCamelCase(field.Name)));
+ jsonFieldMap = CreateJsonFieldMap(fieldsInNumberOrder);
file.DescriptorPool.AddSymbol(this);
Fields = new FieldCollection(this);
}
+ private static ReadOnlyDictionary<string, FieldDescriptor> CreateJsonFieldMap(IList<FieldDescriptor> fields)
+ {
+ var map = new Dictionary<string, FieldDescriptor>();
+ foreach (var field in fields)
+ {
+ map[JsonFormatter.ToCamelCase(field.Name)] = field;
+ map[field.Name] = field;
+ }
+ return new ReadOnlyDictionary<string, FieldDescriptor>(map);
+ }
+
/// <summary>
/// The brief name of the descriptor's target.
/// </summary>
@@ -255,9 +266,10 @@ namespace Google.Protobuf.Reflection
// TODO: consider making this public in the future. (Being conservative for now...)
/// <value>
- /// Returns a read-only dictionary mapping the field names in this message as they're used
+ /// Returns a read-only dictionary mapping the field names in this message as they're available
/// in the JSON representation to the field descriptors. For example, a field <c>foo_bar</c>
- /// in the message would result in an entry with a key <c>fooBar</c>.
+ /// in the message would result two entries, one with a key <c>fooBar</c> and one with a key
+ /// <c>foo_bar</c>, both referring to the same field.
/// </value>
internal IDictionary<string, FieldDescriptor> ByJsonName() => messageDescriptor.jsonFieldMap;