public static Dictionary ToOpenApiSchemas()

in src/Microsoft.Azure.WebJobs.Extensions.OpenApi.Core/Extensions/OpenApiSchemaExtensions.cs [49:296]


        public static Dictionary<string, OpenApiSchema> ToOpenApiSchemas(this Type type, NamingStrategy namingStrategy, OpenApiSchemaVisibilityAttribute attribute = null, bool returnSingleSchema = false, int depth = 0)
        {
            type.ThrowIfNullOrDefault();

            var schema = (OpenApiSchema)null;
            var schemeName = type.GetOpenApiTypeName(namingStrategy);

            if (depth == 8)
            {
                schema = new OpenApiSchema()
                {
                    Type = type.ToDataType(),
                    Format = type.ToDataFormat()
                };

                return new Dictionary<string, OpenApiSchema>() { { schemeName, schema } };
            }

            depth++;

            if (type.IsJObjectType())
            {
                schema = typeof(object).ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;

                return new Dictionary<string, OpenApiSchema>() { { schemeName, schema } };
            }

            if (type.IsOpenApiNullable(out var unwrappedValueType))
            {
                schema = unwrappedValueType.ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;
                schema.Nullable = true;

                return new Dictionary<string, OpenApiSchema>() { { schemeName, schema } };
            }

            schema = new OpenApiSchema()
            {
                Type = type.ToDataType(),
                Format = type.ToDataFormat()
            };

            if (!attribute.IsNullOrDefault())
            {
                var visibility = new OpenApiString(attribute.Visibility.ToDisplayName());

                schema.Extensions.Add("x-ms-visibility", visibility);
            }

            if (type.IsUnflaggedEnumType())
            {
                var converterAttribute = type.GetCustomAttribute<JsonConverterAttribute>();
                if (!converterAttribute.IsNullOrDefault()
                    && typeof(StringEnumConverter).IsAssignableFrom(converterAttribute.ConverterType))
                {
                    var enums = type.ToOpenApiStringCollection(namingStrategy);

                    schema.Type = "string";
                    schema.Format = null;
                    schema.Enum = enums;
                    schema.Default = enums.First();
                }
                else
                {
                    var enums = type.ToOpenApiIntegerCollection();

                    schema.Enum = enums;
                    schema.Default = enums.First();
                }
            }

            if (type.IsSimpleType())
            {
                return new Dictionary<string, OpenApiSchema>() { { schemeName, schema } };
            }

            if (type.IsOpenApiDictionary())
            {
                schema.AdditionalProperties = type.GetGenericArguments()[1].ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;

                return new Dictionary<string, OpenApiSchema>() { { schemeName, schema } };
            }

            if (type.IsOpenApiArray())
            {
                schema.Type = "array";
                schema.Items = (type.GetElementType() ?? type.GetGenericArguments()[0]).ToOpenApiSchemas(namingStrategy, null, true, depth).Single().Value;

                return new Dictionary<string, OpenApiSchema>() { { schemeName, schema } };
            }

            var allProperties = type.IsInterface
                                    ? new[] { type }.Concat(type.GetInterfaces()).SelectMany(i => i.GetProperties())
                                    : type.GetProperties();
            var properties = allProperties.Where(p => !p.ExistsCustomAttribute<JsonIgnoreAttribute>());

            var retVal = new Dictionary<string, OpenApiSchema>();
            foreach (var property in properties)
            {
                var visibility = property.GetCustomAttribute<OpenApiSchemaVisibilityAttribute>(inherit: false);
                var propertyName = property.GetJsonPropertyName(namingStrategy);

                var ts = property.DeclaringType.GetGenericArguments();
                if (!ts.Any())
                {
                    if (property.PropertyType.IsUnflaggedEnumType() && !returnSingleSchema)
                    {
                        var recur1 = property.PropertyType.ToOpenApiSchemas(namingStrategy, visibility, false, depth);
                        retVal.AddRange(recur1);

                        var enumReference = new OpenApiReference()
                        {
                            Type = ReferenceType.Schema,
                            Id = property.PropertyType.GetOpenApiReferenceId(false, false)
                        };

                        var schema1 = new OpenApiSchema() { Reference = enumReference };
                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = schema1;
                    }
                    else if (property.PropertyType.IsSimpleType() || Nullable.GetUnderlyingType(property.PropertyType) != null || returnSingleSchema)
                    {
                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visibility, true, depth).Single().Value;
                    }
                    else if (property.PropertyType.IsOpenApiDictionary())
                    {
                        var elementType = property.PropertyType.GetGenericArguments()[1];
                        if (elementType.IsSimpleType() || elementType.IsOpenApiDictionary() || elementType.IsOpenApiArray())
                        {
                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visibility, true, depth).Single().Value;
                        }
                        else
                        {
                            var recur1 = elementType.ToOpenApiSchemas(namingStrategy, visibility, false, depth);
                            retVal.AddRange(recur1);

                            var elementReference = new OpenApiReference()
                            {
                                Type = ReferenceType.Schema,
                                Id = elementType.GetOpenApiReferenceId(false, false)
                            };

                            var dictionarySchema = new OpenApiSchema()
                            {
                                Type = "object",
                                AdditionalProperties = new OpenApiSchema() { Reference = elementReference }
                            };

                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = dictionarySchema;
                        }
                    }
                    else if (property.PropertyType.IsOpenApiArray())
                    {
                        var elementType = property.PropertyType.GetElementType() ?? property.PropertyType.GetGenericArguments()[0];
                        if (elementType.IsSimpleType() || elementType.IsOpenApiDictionary() || elementType.IsOpenApiArray())
                        {
                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visibility, true, depth).Single().Value;
                        }
                        else
                        {
                            var elementReference = elementType.ToOpenApiSchemas(namingStrategy, visibility, false, depth);
                            retVal.AddRange(elementReference);

                            var reference1 = new OpenApiReference()
                            {
                                Type = ReferenceType.Schema,
                                Id = elementType.GetOpenApiReferenceId(false, false)
                            };
                            var arraySchema = new OpenApiSchema()
                            {
                                Type = "array",
                                Items = new OpenApiSchema()
                                {
                                    Reference = reference1
                                }
                            };

                            schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = arraySchema;
                        }

                    }
                    else
                    {
                        var recur1 = property.PropertyType.ToOpenApiSchemas(namingStrategy, visibility, false, depth);
                        retVal.AddRange(recur1);

                        var reference1 = new OpenApiReference()
                        {
                            Type = ReferenceType.Schema,
                            Id = property.PropertyType.GetOpenApiReferenceId(false, false)
                        };

                        var schema1 = new OpenApiSchema() { Reference = reference1 };

                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = schema1;
                    }

                    continue;
                }

                var reference = new OpenApiReference()
                {
                    Type = ReferenceType.Schema,
                    Id = property.PropertyType.GetOpenApiRootReferenceId()
                };

                var referenceSchema = new OpenApiSchema() { Reference = reference };

                if (!ts.Contains(property.PropertyType))
                {
                    if (property.PropertyType.IsOpenApiDictionary())
                    {
                        reference.Id = property.PropertyType.GetOpenApiReferenceId(true, false);
                        var dictionarySchema = new OpenApiSchema()
                        {
                            Type = "object",
                            AdditionalProperties = referenceSchema
                        };

                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = dictionarySchema;

                        continue;
                    }

                    if (property.PropertyType.IsOpenApiArray())
                    {
                        reference.Id = property.PropertyType.GetOpenApiReferenceId(false, true);
                        var arraySchema = new OpenApiSchema()
                        {
                            Type = "array",
                            Items = referenceSchema
                        };

                        schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = arraySchema;

                        continue;
                    }

                    schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = property.PropertyType.ToOpenApiSchemas(namingStrategy, visibility, true, depth).Single().Value;

                    continue;
                }

                schema.Properties[namingStrategy.GetPropertyName(propertyName, false)] = referenceSchema;
            }

            retVal[schemeName] = schema;

            return retVal;
        }