/// <summary>
        /// Create a <see cref="OpenApiSchema"/> for a <see cref="IEdmTypeReference"/>.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="edmTypeReference">The Edm type reference.</param>
        /// <returns>The created <see cref="OpenApiSchema"/>.</returns>
        public static OpenApiSchema CreateEdmTypeSchema(this ODataContext context, IEdmTypeReference edmTypeReference)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(edmTypeReference, nameof(edmTypeReference));

            switch (edmTypeReference.TypeKind())
            {
            case EdmTypeKind.Collection:
                // Collection-valued structural and navigation are represented as Schema Objects of type array.
                // The value of the items keyword is a Schema Object specifying the type of the items.
                return(new OpenApiSchema
                {
                    Type = "array",
                    Items = context.CreateEdmTypeSchema(edmTypeReference.AsCollection().ElementType())
                });

            // Complex, enum, entity, entity reference are represented as JSON References to the Schema Object of the complex,
            // enum, entity and entity reference type, either as local references for types directly defined in the CSDL document,
            // or as external references for types defined in referenced CSDL documents.
            case EdmTypeKind.Complex:
            case EdmTypeKind.Entity:
                return(context.CreateStructuredTypeSchema(edmTypeReference.AsStructured()));

            case EdmTypeKind.Enum:
                return(context.CreateEnumTypeSchema(edmTypeReference.AsEnum()));

            // Primitive properties of type Edm.PrimitiveType, Edm.Stream, and any of the Edm.Geo* types are
            // represented as Schema Objects that are JSON References to definitions in the Definitions Object
            case EdmTypeKind.Primitive:
                IEdmPrimitiveTypeReference primitiveTypeReference = (IEdmPrimitiveTypeReference)edmTypeReference;
                return(context.CreateSchema(primitiveTypeReference));

            case EdmTypeKind.TypeDefinition:
                return(context.CreateSchema(((IEdmTypeDefinitionReference)edmTypeReference).TypeDefinition().UnderlyingType));

            case EdmTypeKind.EntityReference:
                return(context.CreateTypeDefinitionSchema(edmTypeReference.AsTypeDefinition()));

            case EdmTypeKind.None:
            default:
                throw Error.NotSupported(String.Format(SRResource.NotSupportedEdmTypeKind, edmTypeReference.TypeKind()));
            }
        }
        /// <summary>
        /// Create a <see cref="OpenApiSchema"/> for a <see cref="IEdmPrimitiveTypeReference"/>.
        /// </summary>
        /// <param name="context">The OData context.</param>
        /// <param name="primitiveType">The Edm primitive reference.</param>
        /// <returns>The created <see cref="OpenApiSchema"/>.</returns>
        public static OpenApiSchema CreateSchema(this ODataContext context, IEdmPrimitiveTypeReference primitiveType)
        {
            Utils.CheckArgumentNull(context, nameof(context));
            Utils.CheckArgumentNull(primitiveType, nameof(primitiveType));

            OpenApiSchema schema = context.CreateSchema(primitiveType.PrimitiveDefinition());

            if (schema != null)
            {
                switch (primitiveType.PrimitiveKind())
                {
                case EdmPrimitiveTypeKind.Binary:     // binary
                    IEdmBinaryTypeReference binaryTypeReference = (IEdmBinaryTypeReference)primitiveType;
                    schema.MaxLength = binaryTypeReference.MaxLength;
                    break;

                case EdmPrimitiveTypeKind.Decimal:     // decimal
                    IEdmDecimalTypeReference decimalTypeReference = (IEdmDecimalTypeReference)primitiveType;
                    if (decimalTypeReference.Precision != null)
                    {
                        if (decimalTypeReference.Scale != null)
                        {
                            // The precision is represented with the maximum and minimum keywords and a value of ±(10^ (precision - scale) - 10^ scale).
                            double tmp = Math.Pow(10, decimalTypeReference.Precision.Value - decimalTypeReference.Scale.Value)
                                         - Math.Pow(10, -decimalTypeReference.Scale.Value);
                            schema.Minimum = (decimal?)(tmp * -1.0);
                            schema.Maximum = (decimal?)(tmp);
                        }
                        else
                        {
                            // If the scale facet has a numeric value, and ±(10^precision - 1) if the scale is variable
                            double tmp = Math.Pow(10, decimalTypeReference.Precision.Value) - 1;
                            schema.Minimum = (decimal?)(tmp * -1.0);
                            schema.Maximum = (decimal?)(tmp);
                        }
                    }

                    // The scale of properties of type Edm.Decimal are represented with the OpenAPI Specification keyword multipleOf and a value of 10 ^ -scale
                    schema.MultipleOf = decimalTypeReference.Scale == null ? null : (decimal?)(Math.Pow(10, decimalTypeReference.Scale.Value * -1));
                    break;

                case EdmPrimitiveTypeKind.String:     // string
                    IEdmStringTypeReference stringTypeReference = (IEdmStringTypeReference)primitiveType;
                    schema.MaxLength = stringTypeReference.MaxLength;
                    break;
                }

                // Nullable properties are marked with the keyword nullable and a value of true.
                schema.Nullable = primitiveType.IsNullable ? true : false;
            }

            return(schema);
        }
        private static IOpenApiAny GetTypeNameForExample(ODataContext context, IEdmTypeReference edmTypeReference)
        {
            switch (edmTypeReference.TypeKind())
            {
            case EdmTypeKind.Primitive:
                IEdmPrimitiveType primitiveType = edmTypeReference.AsPrimitive().PrimitiveDefinition();
                OpenApiSchema     schema        = context.CreateSchema(primitiveType);

                if (edmTypeReference.IsBoolean())
                {
                    return(new OpenApiBoolean(true));
                }
                else
                {
                    if (schema.Reference != null)
                    {
                        return(new OpenApiString(schema.Reference.Id));
                    }
                    else
                    {
                        return(new OpenApiString(schema.Type ?? schema.Format));
                    }
                }

            case EdmTypeKind.Entity:
            case EdmTypeKind.Complex:
            case EdmTypeKind.Enum:
                OpenApiObject obj = new OpenApiObject();
                obj[Constants.OdataType] = new OpenApiString(edmTypeReference.FullName());
                return(obj);

            case EdmTypeKind.Collection:
                OpenApiArray      array       = new OpenApiArray();
                IEdmTypeReference elementType = edmTypeReference.AsCollection().ElementType();
                array.Add(GetTypeNameForExample(context, elementType));
                return(array);

            case EdmTypeKind.Untyped:
            case EdmTypeKind.TypeDefinition:
            case EdmTypeKind.EntityReference:
            default:
                throw new OpenApiException("Not support for the type kind " + edmTypeReference.TypeKind());
            }
        }
 public static OpenApiSchema CreateSchemaTypeDefinitionSchema(this ODataContext context, IEdmTypeDefinition typeDefinition)
 {
     return(context.CreateSchema(typeDefinition.UnderlyingType));
 }