示例#1
0
        private static TypeSchemaGreen GetFieldType(string typeName, IDictionary <string, TypeSchemaGreen> known)
        {
            if (known.TryGetValue(typeName, out var res))
            {
                return(res);
            }
            if (WellKnownTypeSchemaGreen.ByCode.TryGetValue(typeName, out var wkt))
            {
                known.Add(wkt.SchemaName, wkt);
                return(wkt);
            }
            if (typeName.EndsWith("[]"))
            {
                var at = new ArrayTypeSchemaGreen(Option.None, -1);
                known.Add(typeName, at);
                var et = GetFieldType(typeName.Substring(0, typeName.Length - 2), known);
                at = new ArrayTypeSchemaGreen(at, Option.None, et.Id);
                known[typeName] = at;
                return(at);
            }
            if (typeName.EndsWith("?"))
            {
                var ot = new NullableTypeSchemaGreen(Option.None, -1);
                known.Add(typeName, ot);
                var et = GetFieldType(typeName.Substring(0, typeName.Length - 1), known);
                ot = new NullableTypeSchemaGreen(ot, Option.None, et.Id);
                known[typeName] = ot;
                return(ot);
            }

            var rt = new RefTypeSchemaGreen();

            known.Add(typeName, rt);
            return(rt);
        }
示例#2
0
        private static TypeSchemaGreen JsonToType(JProperty typeProp, IDictionary <string, TypeSchemaGreen> known)
        {
            if (!(typeProp.Value is JObject jobj))
            {
                throw new SchemaFormatException($"Invalid type description as {typeProp.Path}");
            }

            if (!known.TryGetValue(typeProp.Name, out var type))
            {
                type = new RefTypeSchemaGreen();
                known.Add(typeProp.Name, type);
            }
            var codeName = (string)null;

            if (jobj.TryGetValue("title", StringComparison.InvariantCultureIgnoreCase, out var tkn))
            {
                try
                {
                    codeName = tkn.ToObject <string>();
                }
                catch (Exception ex)
                {
                    throw new SchemaFormatException(
                              $"Invalid token in codeName description at path {tkn.Path}", ex);
                }
            }

            var contract = (string)null;

            if (jobj.TryGetValue("contract", StringComparison.InvariantCultureIgnoreCase, out tkn))
            {
                try
                {
                    contract = tkn.ToObject <string>();
                }
                catch (Exception ex)
                {
                    throw new SchemaFormatException(
                              $"Invalid token in contract description at path {tkn.Path}", ex);
                }
            }

            if (jobj.TryGetValue("fields", StringComparison.InvariantCultureIgnoreCase, out var fieldToken))
            {
                if (!(fieldToken is JObject fields))
                {
                    throw new SchemaFormatException($"Invalid fields description as path {fieldToken.Path}");
                }

                TypeSchemaGreen @base = null;
                if (jobj.TryGetValue("base", StringComparison.InvariantCultureIgnoreCase, out tkn))
                {
                    try
                    {
                        var baseName = tkn.ToObject <string>();
                        if (!known.TryGetValue(baseName, out @base))
                        {
                            @base = new ComplexTypeSchemaGreen(Option.None, baseName, null, null, null, false,
                                                               ImmutableDictionary <string, int> .Empty);
                            known.Add(baseName, @base);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new SchemaFormatException(
                                  $"Invalid token in base type description at path {tkn.Path}", ex);
                    }
                }

                bool isStruct = false;
                if (jobj.TryGetValue("struct", StringComparison.InvariantCultureIgnoreCase, out tkn))
                {
                    try
                    {
                        isStruct = tkn.ToObject <bool>();
                    }
                    catch (Exception ex)
                    {
                        throw new SchemaFormatException(
                                  $"Invalid token in struct type description at path {tkn.Path}", ex);
                    }
                }

                var flds = new Dictionary <string, int>();

                foreach (var property in fields.Properties())
                {
                    var fieldName = property.Name;

                    try
                    {
                        var fieldTypeName = property.Value.ToObject <string>();
                        var fieldType     = GetFieldType(fieldTypeName, known);
                        flds.Add(fieldName, fieldType.Id);
                    }
                    catch (Exception ex)
                    {
                        throw new SchemaFormatException(
                                  $"Invalid token in type field description at path {property.Path}", ex);
                    }
                }

                type = new ComplexTypeSchemaGreen(type, Option.None, typeProp.Name, codeName, contract, @base?.Id,
                                                  isStruct,
                                                  ImmutableDictionary.CreateRange(flds));
                known[typeProp.Name] = type;
                return(type);
            }

            if (jobj.TryGetValue("values", StringComparison.InvariantCultureIgnoreCase, out var valuesToken))
            {
                if (!(valuesToken is JObject values))
                {
                    throw new SchemaFormatException($"Invalid values description as path {fieldToken.Path}");
                }

                TypeSchemaGreen @base = WellKnownTypeSchemaGreen.ByType[typeof(int)];
                if (jobj.TryGetValue("base", StringComparison.InvariantCultureIgnoreCase, out tkn))
                {
                    try
                    {
                        var baseName = tkn.ToObject <string>();
                        if (!known.TryGetValue(baseName, out @base))
                        {
                            @base = WellKnownTypeSchemaGreen.ByCode[baseName];
                            known.Add(baseName, @base);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new SchemaFormatException(
                                  $"Invalid token in based on description at path {tkn.Path}", ex);
                    }
                }

                bool isFlags = false;
                if (jobj.TryGetValue("flags", StringComparison.InvariantCultureIgnoreCase, out tkn))
                {
                    try
                    {
                        isFlags = tkn.ToObject <bool>();
                    }
                    catch (Exception ex)
                    {
                        throw new SchemaFormatException(
                                  $"Invalid token in flags type description at path {tkn.Path}", ex);
                    }
                }

                var vls = new Dictionary <string, long>();

                foreach (var property in values.Properties())
                {
                    var fieldName = property.Name;

                    try
                    {
                        var fieldValue = property.Value.ToObject <long>();
                        vls.Add(fieldName, fieldValue);
                    }
                    catch (Exception ex)
                    {
                        throw new SchemaFormatException(
                                  $"Invalid token in type field description at path {property.Path}", ex);
                    }
                }

                type = new EnumTypeSchemaGreen(type, Option.None, typeProp.Name, codeName, contract, @base.Id, isFlags,
                                               ImmutableDictionary.CreateRange(vls));
                known[typeProp.Name] = type;
                return(type);
            }

            throw new SchemaFormatException($"Unknown type schema at {typeProp.Path}");
        }