using Bright.Collections; using Luban.Common.Utils; using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.Utils; using Luban.Job.Common.Types; using Luban.Job.Common.TypeVisitors; using System; using System.Collections.Generic; using System.Text.Json; namespace Luban.Job.Cfg.DataCreators { public class JsonDataCreator : ITypeFuncVisitor { public static JsonDataCreator Ins { get; } = new JsonDataCreator(); public DType Accept(TBool type, JsonElement x, DefAssembly ass) { return DBool.ValueOf(x.GetBoolean()); } public DType Accept(TByte type, JsonElement x, DefAssembly ass) { return DByte.ValueOf(x.GetByte()); } public DType Accept(TShort type, JsonElement x, DefAssembly ass) { return DShort.ValueOf(x.GetInt16()); } public DType Accept(TFshort type, JsonElement x, DefAssembly ass) { return DFshort.ValueOf(x.GetInt16()); } public DType Accept(TInt type, JsonElement x, DefAssembly ass) { return DInt.ValueOf(x.GetInt32()); } public DType Accept(TFint type, JsonElement x, DefAssembly ass) { return DFint.ValueOf(x.GetInt32()); } public DType Accept(TLong type, JsonElement x, DefAssembly ass) { return DLong.ValueOf(x.GetInt64()); } public DType Accept(TFlong type, JsonElement x, DefAssembly ass) { return DFlong.ValueOf(x.GetInt64()); } public DType Accept(TFloat type, JsonElement x, DefAssembly ass) { return DFloat.ValueOf(x.GetSingle()); } public DType Accept(TDouble type, JsonElement x, DefAssembly ass) { return DDouble.ValueOf(x.GetDouble()); } public DType Accept(TEnum type, JsonElement x, DefAssembly ass) { return new DEnum(type, x.GetString()); } public DType Accept(TString type, JsonElement x, DefAssembly ass) { return DString.ValueOf(x.GetString()); } public DType Accept(TBytes type, JsonElement x, DefAssembly ass) { throw new NotImplementedException(); } public DType Accept(TText type, JsonElement x, DefAssembly ass) { if (!x.TryGetProperty("key", out var keyEle)) { throw new Exception("text 缺失 key属性"); } if (!x.TryGetProperty("text", out var textEle)) { throw new Exception("text 缺失 text属性"); } string key = keyEle.GetString(); if (key == null) { throw new Exception("text key不是字符串"); } string text = textEle.GetString(); if (text == null) { throw new Exception("text text不是字符串"); } DataUtil.ValidateText(key, text); return new DText(key, text); } public DType Accept(TBean type, JsonElement x, DefAssembly ass) { var bean = (DefBean)type.Bean; DefBean implBean; if (bean.IsAbstractType) { if (!x.TryGetProperty(DefBean.FALLBACK_TYPE_NAME_KEY, out var typeNameProp) && !x.TryGetProperty(DefBean.JSON_TYPE_NAME_KEY, out typeNameProp)) { throw new Exception($"结构:'{bean.FullName}' 是多态类型,必须用 '{DefBean.JSON_TYPE_NAME_KEY}' 字段指定 子类名"); } string subType = typeNameProp.GetString(); implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType); } else { implBean = bean; } var fields = new List(); foreach (DefField f in implBean.HierarchyFields) { if (x.TryGetProperty(f.Name, out var ele)) { if (ele.ValueKind == JsonValueKind.Null || ele.ValueKind == JsonValueKind.Undefined) { if (f.CType.IsNullable) { fields.Add(null); } else { throw new Exception($"结构:'{implBean.FullName}' 字段:'{f.Name}' 不能 null or undefined "); } } else { try { fields.Add(f.CType.Apply(this, ele, ass)); } catch (DataCreateException dce) { dce.Push(bean, f); throw; } catch (Exception e) { var dce = new DataCreateException(e, ""); dce.Push(bean, f); throw dce; } } } else if (f.CType.IsNullable) { fields.Add(null); } else { throw new Exception($"结构:'{implBean.FullName}' 字段:'{f.Name}' 缺失"); } } return new DBean(type, implBean, fields); } private List ReadList(TType type, JsonElement e, DefAssembly ass) { var list = new List(); foreach (var c in e.EnumerateArray()) { list.Add(type.Apply(this, c, ass)); } return list; } public DType Accept(TArray type, JsonElement x, DefAssembly ass) { return new DArray(type, ReadList(type.ElementType, x, ass)); } public DType Accept(TList type, JsonElement x, DefAssembly ass) { return new DList(type, ReadList(type.ElementType, x, ass)); } public DType Accept(TSet type, JsonElement x, DefAssembly ass) { return new DSet(type, ReadList(type.ElementType, x, ass)); } public DType Accept(TMap type, JsonElement x, DefAssembly ass) { var map = new Dictionary(); foreach (var e in x.EnumerateArray()) { if (e.GetArrayLength() != 2) { throw new ArgumentException($"json map 类型的 成员数据项:{e} 必须是 [key,value] 形式的列表"); } DType key = type.KeyType.Apply(this, e[0], ass); DType value = type.ValueType.Apply(this, e[1], ass); if (!map.TryAdd(key, value)) { throw new Exception($"map 的 key:{key} 重复"); } } return new DMap(type, map); } public DType Accept(TDateTime type, JsonElement x, DefAssembly ass) { return DataUtil.CreateDateTime(x.GetString()); } public DType Accept(TVector2 type, JsonElement x, DefAssembly ass) { return new DVector2(new System.Numerics.Vector2(x.GetProperty("x").GetSingle(), x.GetProperty("y").GetSingle())); } public DType Accept(TVector3 type, JsonElement x, DefAssembly ass) { return new DVector3(new System.Numerics.Vector3(x.GetProperty("x").GetSingle(), x.GetProperty("y").GetSingle(), x.GetProperty("z").GetSingle())); } public DType Accept(TVector4 type, JsonElement x, DefAssembly ass) { return new DVector4(new System.Numerics.Vector4(x.GetProperty("x").GetSingle(), x.GetProperty("y").GetSingle(), x.GetProperty("z").GetSingle(), x.GetProperty("w").GetSingle())); } } }