Support deprecated_readonly in C# json serializer

This commit is contained in:
Johannes Häggqvist 2023-12-20 23:04:21 +01:00 committed by Johannes Häggqvist
parent 286703ea4e
commit 87d61ba559
15 changed files with 316 additions and 13 deletions

View File

@ -147,6 +147,21 @@ class CSharpGenerator : public BaseGenerator {
std::string one_file_code;
cur_name_space_ = parser_.current_namespace_;
if (parser_.opts.cs_gen_json_serializer &&
parser_.opts.generate_object_based_api) {
std::string contractresolvercode;
GenJsonContractResolver(&contractresolvercode);
if (parser_.opts.one_file) {
one_file_code += contractresolvercode;
} else {
if (!SaveType("JsonContractResolver", *parser_.current_namespace_,
contractresolvercode, true, parser_.opts)) {
return false;
}
}
}
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
std::string enumcode;
@ -2395,6 +2410,9 @@ class CSharpGenerator : public BaseGenerator {
auto utype_name = NamespacedName(*field.value.type.enum_def);
code +=
" [Newtonsoft.Json.JsonProperty(\"" + field.name + "_type\")]\n";
if (field.deprecated == FieldDef::kDeprecatedReadOnly) {
code += " [JsonReadOnly()]\n";
}
if (IsVector(field.value.type)) {
code += " private " + utype_name + "[] " + camel_name + "Type {\n";
code += " get {\n";
@ -2442,6 +2460,8 @@ class CSharpGenerator : public BaseGenerator {
}
if (field.attributes.Lookup("hash")) {
code += " [Newtonsoft.Json.JsonIgnore()]\n";
} else if (field.deprecated == FieldDef::kDeprecatedReadOnly) {
code += " [JsonReadOnly()]\n";
}
}
code += " public " + type_name + " " + camel_name + " { get; set; }\n";
@ -2491,12 +2511,18 @@ class CSharpGenerator : public BaseGenerator {
code += " public static " + class_name +
" DeserializeFromJson(string jsonText) {\n";
code += " return Newtonsoft.Json.JsonConvert.DeserializeObject<" +
class_name + ">(jsonText);\n";
class_name +
">(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {\n";
code += " ContractResolver = new JsonContractResolver(),\n";
code += " });\n";
code += " }\n";
code += " public string SerializeToJson() {\n";
code +=
" return Newtonsoft.Json.JsonConvert.SerializeObject(this, "
"Newtonsoft.Json.Formatting.Indented);\n";
" return Newtonsoft.Json.JsonConvert.SerializeObject(this, new "
"Newtonsoft.Json.JsonSerializerSettings() {\n";
code += " ContractResolver = new JsonContractResolver(),\n";
code += " Formatting = Newtonsoft.Json.Formatting.Indented,\n";
code += " });\n";
code += " }\n";
}
if (parser_.root_struct_def_ == &struct_def) {
@ -2515,6 +2541,35 @@ class CSharpGenerator : public BaseGenerator {
code += "}\n\n";
}
void GenJsonContractResolver(std::string *code_ptr) const {
auto &code = *code_ptr;
code +=
"[AttributeUsage(AttributeTargets.Property | "
"AttributeTargets.Field)]\n";
code += "class JsonReadOnlyAttribute : Attribute {\n";
code += "}\n\n";
code +=
"public class JsonContractResolver : "
"Newtonsoft.Json.Serialization.DefaultContractResolver\n";
code += "{\n";
code +=
" protected override Newtonsoft.Json.Serialization.JsonProperty "
"CreateProperty(System.Reflection.MemberInfo member, "
"Newtonsoft.Json.MemberSerialization memberSerialization)\n";
code += " {\n";
code +=
" var property = base.CreateProperty(member, "
"memberSerialization);\n";
code +=
" if (Attribute.IsDefined(member, "
"typeof(JsonReadOnlyAttribute)))\n";
code += " property.Readable = false;\n";
code += " return property;\n";
code += " }\n";
code += "}\n\n";
}
// This tracks the current namespace used to determine if a type need to be
// prefixed by its namespace
const Namespace *cur_name_space_;

View File

@ -0,0 +1,28 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace KeywordTest
{
using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
}

View File

@ -57,10 +57,15 @@ public class ArrayTableT
}
public static ArrayTableT DeserializeFromJson(string jsonText) {
return Newtonsoft.Json.JsonConvert.DeserializeObject<ArrayTableT>(jsonText);
return Newtonsoft.Json.JsonConvert.DeserializeObject<ArrayTableT>(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
});
}
public string SerializeToJson() {
return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
});
}
public static ArrayTableT DeserializeFromBinary(byte[] fbBuffer) {
return ArrayTable.GetRootAsArrayTable(new ByteBuffer(fbBuffer)).UnPack();

View File

@ -0,0 +1,28 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace MyGame.Example
{
using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
}

View File

@ -1085,10 +1085,15 @@ public class MonsterT
}
public static MonsterT DeserializeFromJson(string jsonText) {
return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterT>(jsonText);
return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterT>(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
});
}
public string SerializeToJson() {
return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
});
}
public static MonsterT DeserializeFromBinary(byte[] fbBuffer) {
return Monster.GetRootAsMonster(new ByteBuffer(fbBuffer)).UnPack();

View File

@ -0,0 +1,28 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace MyGame
{
using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
}

View File

@ -191,10 +191,15 @@ public class MonsterExtraT
}
public static MonsterExtraT DeserializeFromJson(string jsonText) {
return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterExtraT>(jsonText);
return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterExtraT>(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
});
}
public string SerializeToJson() {
return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
});
}
public static MonsterExtraT DeserializeFromBinary(byte[] fbBuffer) {
return MonsterExtra.GetRootAsMonsterExtra(new ByteBuffer(fbBuffer)).UnPack();

View File

@ -0,0 +1,28 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace NamespaceA
{
using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
}

View File

@ -0,0 +1,28 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace NamespaceA.NamespaceB
{
using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
}

View File

@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Color : sbyte
{

View File

@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Color : sbyte
{

View File

@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
public struct ColorTestTable : IFlatbufferObject
{
private Table __p;

View File

@ -9,6 +9,21 @@ using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Value : byte
{
@ -498,10 +513,15 @@ public class CollisionT
}
public static CollisionT DeserializeFromJson(string jsonText) {
return Newtonsoft.Json.JsonConvert.DeserializeObject<CollisionT>(jsonText);
return Newtonsoft.Json.JsonConvert.DeserializeObject<CollisionT>(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
});
}
public string SerializeToJson() {
return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
});
}
public static CollisionT DeserializeFromBinary(byte[] fbBuffer) {
return Collision.GetRootAsCollision(new ByteBuffer(fbBuffer)).UnPack();

View File

@ -0,0 +1,23 @@
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
using global::System;
using global::System.Collections.Generic;
using global::Google.FlatBuffers;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
class JsonReadOnlyAttribute : Attribute {
}
public class JsonContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override Newtonsoft.Json.Serialization.JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (Attribute.IsDefined(member, typeof(JsonReadOnlyAttribute)))
property.Readable = false;
return property;
}
}

View File

@ -197,10 +197,15 @@ public class MovieT
}
public static MovieT DeserializeFromJson(string jsonText) {
return Newtonsoft.Json.JsonConvert.DeserializeObject<MovieT>(jsonText);
return Newtonsoft.Json.JsonConvert.DeserializeObject<MovieT>(jsonText, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
});
}
public string SerializeToJson() {
return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings() {
ContractResolver = new JsonContractResolver(),
Formatting = Newtonsoft.Json.Formatting.Indented,
});
}
public static MovieT DeserializeFromBinary(byte[] fbBuffer) {
return Movie.GetRootAsMovie(new ByteBuffer(fbBuffer)).UnPack();