Merge pull request #1326 from the-alien/csharp_json_name

csharp: add support for the json_name option
This commit is contained in:
Jon Skeet 2016-03-30 09:11:59 +01:00
commit 261fde1707
6 changed files with 206 additions and 9 deletions

View File

@ -116,4 +116,11 @@ message TestJsonFieldOrdering {
string o2_string = 3;
}
}
}
message TestJsonName {
// Message for testing the effects for of the json_name option
string name = 1;
string description = 2 [json_name = "desc"];
string guid = 3 [json_name = "exid"];
}

View File

@ -59,5 +59,24 @@ namespace Google.Protobuf
// Underscores aren't reflected in the JSON.
Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
}
[Test]
public void JsonNameParseTest()
{
var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
var parser = new JsonParser(settings);
// It is safe to use either original field name or explicitly specified json_name
Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
}
[Test]
public void JsonNameFormatTest()
{
var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
JsonFormatter.Default.Format(message));
}
}
}

View File

@ -42,10 +42,12 @@ namespace UnitTest.Issues.TestProtos {
"CgtwbGFpbl9pbnQzMhgEIAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghv",
"MV9pbnQzMhgFIAEoBUgAEhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9p",
"bnQzMhgGIAEoBUgBEhMKCW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8y",
"KlUKDE5lZ2F0aXZlRW51bRIWChJORUdBVElWRV9FTlVNX1pFUk8QABIWCglG",
"aXZlQmVsb3cQ+///////////ARIVCghNaW51c09uZRD///////////8BKi4K",
"DkRlcHJlY2F0ZWRFbnVtEhMKD0RFUFJFQ0FURURfWkVSTxAAEgcKA29uZRAB",
"Qh9IAaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZwcm90bzM="));
"IksKDFRlc3RKc29uTmFtZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9u",
"GAIgASgJUgRkZXNjEhIKBGd1aWQYAyABKAlSBGV4aWQqVQoMTmVnYXRpdmVF",
"bnVtEhYKEk5FR0FUSVZFX0VOVU1fWkVSTxAAEhYKCUZpdmVCZWxvdxD7////",
"//////8BEhUKCE1pbnVzT25lEP///////////wEqLgoORGVwcmVjYXRlZEVu",
"dW0SEwoPREVQUkVDQVRFRF9aRVJPEAASBwoDb25lEAFCH0gBqgIaVW5pdFRl",
"c3QuSXNzdWVzLlRlc3RQcm90b3NiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedClrTypeInfo[] {
@ -55,7 +57,8 @@ namespace UnitTest.Issues.TestProtos {
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null)}),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null)
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null)
}));
}
#endregion
@ -1399,6 +1402,166 @@ namespace UnitTest.Issues.TestProtos {
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class TestJsonName : pb::IMessage<TestJsonName> {
private static readonly pb::MessageParser<TestJsonName> _parser = new pb::MessageParser<TestJsonName>(() => new TestJsonName());
public static pb::MessageParser<TestJsonName> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[7]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
public TestJsonName() {
OnConstruction();
}
partial void OnConstruction();
public TestJsonName(TestJsonName other) : this() {
name_ = other.name_;
description_ = other.description_;
guid_ = other.guid_;
}
public TestJsonName Clone() {
return new TestJsonName(this);
}
/// <summary>Field number for the "name" field.</summary>
public const int NameFieldNumber = 1;
private string name_ = "";
/// <summary>
/// json_name field options are not properly handled during deserialization
/// </summary>
public string Name {
get { return name_; }
set {
name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "description" field.</summary>
public const int DescriptionFieldNumber = 2;
private string description_ = "";
public string Description {
get { return description_; }
set {
description_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "guid" field.</summary>
public const int GuidFieldNumber = 3;
private string guid_ = "";
public string Guid {
get { return guid_; }
set {
guid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
public override bool Equals(object other) {
return Equals(other as TestJsonName);
}
public bool Equals(TestJsonName other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (Name != other.Name) return false;
if (Description != other.Description) return false;
if (Guid != other.Guid) return false;
return true;
}
public override int GetHashCode() {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (Description.Length != 0) hash ^= Description.GetHashCode();
if (Guid.Length != 0) hash ^= Guid.GetHashCode();
return hash;
}
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
if (Name.Length != 0) {
output.WriteRawTag(10);
output.WriteString(Name);
}
if (Description.Length != 0) {
output.WriteRawTag(18);
output.WriteString(Description);
}
if (Guid.Length != 0) {
output.WriteRawTag(26);
output.WriteString(Guid);
}
}
public int CalculateSize() {
int size = 0;
if (Name.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
}
if (Description.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Description);
}
if (Guid.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Guid);
}
return size;
}
public void MergeFrom(TestJsonName other) {
if (other == null) {
return;
}
if (other.Name.Length != 0) {
Name = other.Name;
}
if (other.Description.Length != 0) {
Description = other.Description;
}
if (other.Guid.Length != 0) {
Guid = other.Guid;
}
}
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
input.SkipLastField();
break;
case 10: {
Name = input.ReadString();
break;
}
case 18: {
Description = input.ReadString();
break;
}
case 26: {
Guid = input.ReadString();
break;
}
}
}
}
}
#endregion
}

View File

@ -237,11 +237,13 @@ namespace Google.Protobuf
{
writer.Write(PropertySeparator);
}
WriteString(writer, ToCamelCase(accessor.Descriptor.Name));
WriteString(writer, accessor.Descriptor.JsonName);
writer.Write(NameValueSeparator);
WriteValue(writer, value);
first = false;
}
}
return !first;
}

View File

@ -90,6 +90,12 @@ namespace Google.Protobuf.Reflection
/// </summary>
public override string Name { get { return proto.Name; } }
/// <summary>
/// The json_name option of the descriptor's target.
/// </summary>
public string JsonName { get { return proto.JsonName == "" ? JsonFormatter.ToCamelCase(proto.Name) : proto.JsonName; } }
internal FieldDescriptorProto Proto { get { return proto; } }
/// <summary>

View File

@ -102,8 +102,8 @@ namespace Google.Protobuf.Reflection
var map = new Dictionary<string, FieldDescriptor>();
foreach (var field in fields)
{
map[JsonFormatter.ToCamelCase(field.Name)] = field;
map[field.Name] = field;
map[field.JsonName] = field;
}
return new ReadOnlyDictionary<string, FieldDescriptor>(map);
}