| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- namespace SharpGLTF.SchemaReflection
- {
- /// <summary>
- /// Base class for all schema Types
- /// </summary>
- /// <remarks>
- /// Derived classes:
- /// - <see cref="StringType"/><br/>
- /// - <see cref="ObjectType"/><br/>
- /// - <see cref="BlittableType"/><br/>
- /// - <see cref="EnumType"/><br/>
- /// - <see cref="ArrayType"/><br/>
- /// - <see cref="DictionaryType"/><br/>
- /// - <see cref="ClassType"/><br/>
- /// - <see cref="ReferenceType"/><br/>
- /// </remarks>
- public abstract partial class SchemaType
- {
- #region constructor
- protected SchemaType(Context ctx) { _Owner = ctx; }
- #endregion
- #region data
- /// <summary>
- /// context where this type is stored
- /// </summary>
- private readonly Context _Owner;
- /// <summary>
- /// identifier used for serialization and deserialization
- /// </summary>
- public abstract string PersistentName { get; }
- #endregion
- #region properties
- public String Description { get; set; }
- public Context Owner => _Owner;
- #endregion
- }
- /// <summary>
- /// Represents a <see cref="String"/> type.
- /// </summary>
- [System.Diagnostics.DebuggerDisplay("StringType {PersistentName}")]
- public sealed class StringType : SchemaType
- {
- #region constructor
- internal StringType(Context ctx) : base(ctx) { }
- #endregion
- #region properties
- public override string PersistentName => typeof(String).Name;
- #endregion
- }
- /// <summary>
- /// Represents an undefined <see cref="Object"/> type.
- /// </summary>
- /// <remarks>
- /// undefined objects are serialized/deserialized as <see cref="System.Text.Json.Nodes.JsonNode"/>
- /// </remarks>
- [System.Diagnostics.DebuggerDisplay("ObjectType {PersistentName}")]
- public sealed class ObjectType : SchemaType
- {
- #region constructor
- internal ObjectType(Context ctx) : base(ctx) { }
- #endregion
- #region properties
- public override string PersistentName => typeof(System.Text.Json.Nodes.JsonNode).FullName;
- #endregion
- }
- /// <summary>
- /// Represents a "by value" type <see cref="Boolean"/>, <see cref="Int32"/>, <see cref="Single"/>, etc
- /// </summary>
- /// <remarks>
- /// This type can optionally be set as nullable.
- /// </remarks>
- [System.Diagnostics.DebuggerDisplay("BlittableType {PersistentName}")]
- public sealed class BlittableType : SchemaType
- {
- #region constructor
- internal BlittableType(Context ctx, TypeInfo t, bool isNullable) : base(ctx)
- {
- if (t == typeof(String).GetTypeInfo()) isNullable = false;
- _Type = t;
- _IsNullable = isNullable;
- }
- #endregion
- #region data
- // https://en.wikipedia.org/wiki/Blittable_types
- private readonly TypeInfo _Type;
- private readonly Boolean _IsNullable;
- #endregion
- #region properties
- public TypeInfo DataType => _Type;
- public bool IsNullable => _IsNullable;
- public override string PersistentName => _IsNullable ? $"{_Type.Name}?" : _Type.Name;
- #endregion
- }
- [System.Diagnostics.DebuggerDisplay("EnumType {PersistentName}")]
- public sealed class EnumType : SchemaType
- {
- #region constructor
- internal EnumType(Context ctx, string name, bool isNullable) : base(ctx)
- {
- _PersistentName = name;
- _IsNullable = isNullable;
- }
- #endregion
- #region data
- private readonly String _PersistentName;
- private readonly Boolean _IsNullable;
- private bool _UseIntegers;
- private readonly Dictionary<string, int> _Values = new Dictionary<string, int>();
- #endregion
- #region properties
- public bool IsNullable => _IsNullable;
- public override string PersistentName => _PersistentName;
-
- public bool UseIntegers { get => _UseIntegers; set => _UseIntegers = value; }
- public SchemaType ItemType => UseIntegers ? (SchemaType)Owner.UseBlittable(typeof(int).GetTypeInfo()) : Owner.UseString();
- public IEnumerable<KeyValuePair<string, int>> Values => _Values;
- #endregion
- #region API
- public void SetValue(string key, int val) { _Values[key] = val; }
- #endregion
- }
- [System.Diagnostics.DebuggerDisplay("ArrayType {PersistentName}")]
- public sealed class ArrayType : SchemaType
- {
- #region constructor
- internal ArrayType(Context ctx, SchemaType element) : base(ctx)
- {
- _ItemType = element;
- }
- #endregion
- #region data
- private readonly SchemaType _ItemType;
- public SchemaType ItemType => _ItemType;
- #endregion
- #region properties
- public override string PersistentName => $"{_ItemType.PersistentName}[]";
- #endregion
- }
- [System.Diagnostics.DebuggerDisplay("DictionaryType {PersistentName}")]
- public sealed class DictionaryType : SchemaType
- {
- #region lifecycle
- internal DictionaryType(Context ctx, SchemaType key,SchemaType val) : base(ctx)
- {
- _KeyType = key;
- _ValueType = val;
- }
- #endregion
- #region data
-
- private readonly SchemaType _KeyType;
- private readonly SchemaType _ValueType;
- #endregion
- #region properties
- public SchemaType KeyType => _KeyType;
- public SchemaType ValueType => _ValueType;
- public override string PersistentName => $"<{_KeyType.PersistentName},{_ValueType.PersistentName}>[]";
- #endregion
- }
- /// <summary>
- /// Represents a field property within a <see cref="ClassType"/>
- /// </summary>
- [System.Diagnostics.DebuggerDisplay("FieldInfo {_FieldType} {FieldType.PersistentName} {PersistentName}")]
- public sealed class FieldInfo
- {
- #region lifecycle
- internal FieldInfo(ClassType owner, string name)
- {
- _Owner = owner;
- _PersistentName = name;
- }
- #endregion
- #region data
- private readonly ClassType _Owner;
- private readonly String _PersistentName;
- private SchemaType _FieldType;
- private Object _ExclusiveMinimumValue;
- private Object _InclusiveMinimumValue;
- private Object _DefaultValue;
- private Object _InclusiveMaximumValue;
- private Object _ExclusiveMaximumValue;
- private int _MinItems;
- private int _MaxItems;
- #endregion
- #region properties
- public ClassType DeclaringClass => _Owner;
- public String Description { get; set; }
- public String PersistentName => _PersistentName;
- public SchemaType FieldType { get => _FieldType; set => _FieldType = value; }
-
- public Object ExclusiveMinimumValue { get => _ExclusiveMinimumValue; set => _ExclusiveMinimumValue = value; }
- public Object InclusiveMinimumValue { get => _InclusiveMinimumValue; set => _InclusiveMinimumValue = value; }
- public Object DefaultValue { get => _DefaultValue; set => _DefaultValue = value; }
- public Object InclusiveMaximumValue { get => _InclusiveMaximumValue; set => _InclusiveMaximumValue = value; }
- public Object ExclusiveMaximumValue { get => _ExclusiveMaximumValue; set => _ExclusiveMaximumValue = value; }
- public int MinItems { get => _MinItems; set => _MinItems = value; }
- public int MaxItems { get => _MaxItems; set => _MaxItems = value; }
- #endregion
- #region fluent api
- public FieldInfo SetDataType(SchemaType type) { _FieldType = type; return this; }
- public FieldInfo SetDataType(Type type, bool isNullable)
- {
- if (type == typeof(string)) { _FieldType = DeclaringClass.Owner.UseString(); return this; }
- _FieldType = DeclaringClass.Owner.UseBlittable(type.GetTypeInfo(), isNullable);
- return this;
- }
- public FieldInfo RemoveDefaultValue() { _DefaultValue = null; return this; }
- public FieldInfo SetDefaultValue(string defval) { _DefaultValue = defval; return this; }
- public FieldInfo SetLimits(Decimal? min, Decimal? max) { _InclusiveMinimumValue = min; _InclusiveMaximumValue = max; return this; }
- public FieldInfo SetItemsRange(int min, int max = int.MaxValue) { _MinItems = min; _MaxItems = max; return this; }
- #endregion
- #region comparer helper
- private sealed class _Comparer : IEqualityComparer<FieldInfo> , IComparer<FieldInfo>
- {
- public int Compare(FieldInfo x, FieldInfo y)
- {
- var xx = _Adjust(x._PersistentName);
- var yy = _Adjust(y._PersistentName);
- return string.CompareOrdinal(xx, yy);
- }
- private static string _Adjust(string name)
- {
- if (name.StartsWith("asset")) return "____" + name;
- if (name.StartsWith("extensions")) return "___" + name;
- return name;
- }
- public bool Equals(FieldInfo x, FieldInfo y) { return Compare(x,y) == 0; }
- public int GetHashCode(FieldInfo obj) { return obj._PersistentName.GetHashCode(StringComparison.Ordinal); }
- }
- private static readonly _Comparer _DefaultComparer = new _Comparer();
- public static IEqualityComparer<FieldInfo> EqualityComparer => _DefaultComparer;
- public static IComparer<FieldInfo> Comparer => _DefaultComparer;
- #endregion
- }
- [System.Diagnostics.DebuggerDisplay("ClassType {PersistentName} : {BaseClass.PersistentName}")]
- public sealed class ClassType : SchemaType
- {
- #region constructor
- internal ClassType(Context ctx, string name) : base(ctx)
- {
- _PersistentName = name;
- }
- #endregion
- #region data
- private readonly String _PersistentName;
- private readonly SortedSet<FieldInfo> _Fields = new SortedSet<FieldInfo>(FieldInfo.Comparer);
- private ClassType _BaseClass;
-
- public override string PersistentName => _PersistentName;
- public ClassType BaseClass { get => _BaseClass; set => _BaseClass = value; }
- public IEnumerable<FieldInfo> Fields => _Fields;
- /// <summary>
- /// True to prevent to codegen emitter to emit this class
- /// </summary>
- public bool IgnoredByEmitter { get; set; }
- #endregion
- #region API
- public FieldInfo GetField(string name)
- {
- return _Fields.First(item => item.PersistentName == name);
- }
- public FieldInfo UseField(string name)
- {
- var f = new FieldInfo(this, name);
- _Fields.Add(f);
- return GetField(name);
- }
- #endregion
- }
- /// <summary>
- /// not used
- /// </summary>
- public sealed class ReferenceType : SchemaType
- {
- #region constructor
- internal ReferenceType(Context ctx, SchemaType refType) : base(ctx)
- {
- _ReferencedType = refType;
- }
- #endregion
- #region data
- // In code it has the representation List<Node>();
- // In serialization, it has the representation List<int>();
- private readonly SchemaType _ReferencedType;
- #pragma warning disable CA1065 // Do not raise exceptions in unexpected locations
- public override string PersistentName => throw new NotImplementedException();
- #pragma warning restore CA1065 // Do not raise exceptions in unexpected locations
- #endregion
- }
-
- }
|