<commit_before>﻿//-----------------------------------------------------------------------
// <copyright file="SwaggerParameter.cs" company="NSwag">
//     Copyright (c) <NAME>. All rights reserved.
// </copyright>
// <license>https://github.com/RicoSuter/NSwag/blob/master/LICENSE.md</license>
// <author><NAME>, <EMAIL></author>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using NJsonSchema;

namespace NSwag
{
    /// <summary>Describes an operation parameter. </summary>
    public class OpenApiParameter : JsonSchema
    {
        private string _name;
        private OpenApiParameterKind _kind;
        private OpenApiParameterStyle _style;
        private bool _isRequired = false;
        private JsonSchema _schema;
        private IDictionary<string, OpenApiExample> _examples;
        private bool _explode;
        private int? _position;

        [JsonIgnore]
        internal OpenApiOperation ParentOperation => Parent as OpenApiOperation;

        /// <summary>Gets or sets the name.</summary>
        [JsonProperty(PropertyName = "name", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public string Name
        {
            get => _name;
            set
            {
                _name = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the kind of the parameter.</summary>
        [JsonProperty(PropertyName = "in", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public OpenApiParameterKind Kind
        {
            get => _kind;
            set
            {
                _kind = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the style of the parameter (OpenAPI only).</summary>
        [JsonProperty(PropertyName = "style", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public OpenApiParameterStyle Style
        {
            get => _style;
            set
            {
                _style = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the explode setting for the parameter (OpenAPI only).</summary>
        [JsonProperty(PropertyName = "explode", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool Explode
        {
            get => _explode;
            set
            {
                _explode = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets a value indicating whether the parameter is required (default: false).</summary>
        [JsonProperty(PropertyName = "required", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public bool IsRequired
        {
            get => _isRequired;
            set
            {
                _isRequired = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets a value indicating whether passing empty-valued parameters is allowed (default: false).</summary>
        [JsonProperty(PropertyName = "allowEmptyValue", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public bool AllowEmptyValue { get; set; }

        /// <summary>Gets or sets the description. </summary>
        [Newtonsoft.Json.JsonProperty("description", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public override string Description
        {
            get => base.Description;
            set
            {
                base.Description = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets the actual parameter.</summary>
        [JsonIgnore]
        public OpenApiParameter ActualParameter => Reference is OpenApiParameter ? (OpenApiParameter)Reference : this;

        /// <summary>Gets or sets the format of the array if type array is used.</summary>
        [JsonProperty(PropertyName = "collectionFormat", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public OpenApiParameterCollectionFormat CollectionFormat { get; set; }

        /// <summary>Gets or sets the headers (OpenAPI only).</summary>
        [JsonProperty(PropertyName = "examples", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public IDictionary<string, OpenApiExample> Examples
        {
            get => _examples;
            set
            {
                _examples = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the schema which is only available when <see cref="Kind"/> == body.</summary>
        [JsonProperty(PropertyName = "schema", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public JsonSchema Schema
        {
            get => _schema;
            set
            {
                _schema = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the custom schema which is used when <see cref="Kind"/> != body.</summary>
        [JsonProperty(PropertyName = "x-schema", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public JsonSchema CustomSchema { get; set; }

        /// <summary>Gets or sets the name.</summary>
        [JsonProperty(PropertyName = "x-position", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public int? Position
        {
            get => _position;
            set
            {
                _position = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets the actual schema, either the parameter schema itself (or its reference) or the <see cref="Schema"/> property when <see cref="Kind"/> == body.</summary>
        /// <exception cref="InvalidOperationException" accessor="get">The schema reference path is not resolved.</exception>
        [JsonIgnore]
        public override JsonSchema ActualSchema
        {
            get
            {
                if (Reference is OpenApiParameter parameter)
                {
                    return parameter.ActualSchema;
                }
                else
                {
                    return Schema?.ActualSchema ?? CustomSchema?.ActualSchema ?? base.ActualSchema;
                }
            }
        }

        /// <summary>Gets a value indicating whether the validated data can be null.</summary>
        /// <param name="schemaType">The schema type.</param>
        /// <returns>The result.</returns>
        public override bool IsNullable(SchemaType schemaType)
        {
            if (schemaType == SchemaType.Swagger2)
            {
                if (IsNullableRaw == null)
                {
                    return IsRequired == false;
                }

                return IsNullableRaw.Value;
            }
            else if (schemaType == SchemaType.OpenApi3)
            {
                if (IsNullableRaw.HasValue)
                {
                    return IsNullableRaw.Value;
                }
                else if (Schema != null)
                {
                    return Schema.IsNullable(schemaType);
                }
                else if (CustomSchema != null)
                {
                    return CustomSchema.IsNullable(schemaType);
                }
            }

            return base.IsNullable(schemaType);
        }

        /// <summary>Gets a value indicating whether this is an XML body parameter.</summary>
        [JsonIgnore]
        public bool IsXmlBodyParameter
        {
            get
            {
                if (Kind != OpenApiParameterKind.Body)
                {
                    return false;
                }

                var parent = Parent as OpenApiOperation;
                var consumes = parent?.ActualConsumes?.Any() == true ?
                    parent.ActualConsumes :
                    parent?.RequestBody?.Content.Keys;

                return consumes?.Any() == true &&
                       consumes.Any(p => p.Contains("application/xml")) &&
                       consumes.Any(p => p.Contains("application/json")) == false;
            }
        }

        /// <summary>Gets a value indicating whether this is a binary body parameter.</summary>
        [JsonIgnore]
        public bool IsBinaryBodyParameter
        {
            get
            {
                if (Kind != OpenApiParameterKind.Body || IsXmlBodyParameter)
                {
                    return false;
                }

                var parent = Parent as OpenApiOperation;
                if (parent?.ActualConsumes?.Any() == true)
                {
                    var consumes = parent.ActualConsumes;
                    return consumes?.Any() == true &&
                           consumes.Any(p => p.Contains("*/*")) == false && // supports json
                           consumes.Any(p => p.Contains("application/json")) == false;
                }
                else
                {
                    var consumes = parent?.RequestBody?.Content;
                    return consumes?.Any() == true &&
                           consumes.Any(p => p.Key.Contains("*/*") && !p.Value.Schema.IsBinary) == false && // supports json
                           consumes.Any(p => p.Key.Contains("application/json") && p.Value.Schema?.IsBinary != true) == false;<commit_msg>Allow custom json-based content type (#2633)<commit_after>﻿//-----------------------------------------------------------------------
// <copyright file="SwaggerParameter.cs" company="NSwag">
//     Copyright (c) <NAME>. All rights reserved.
// </copyright>
// <license>https://github.com/RicoSuter/NSwag/blob/master/LICENSE.md</license>
// <author><NAME>, <EMAIL></author>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using NJsonSchema;

namespace NSwag
{
    /// <summary>Describes an operation parameter. </summary>
    public class OpenApiParameter : JsonSchema
    {
        private string _name;
        private OpenApiParameterKind _kind;
        private OpenApiParameterStyle _style;
        private bool _isRequired = false;
        private JsonSchema _schema;
        private IDictionary<string, OpenApiExample> _examples;
        private bool _explode;
        private int? _position;

        [JsonIgnore]
        internal OpenApiOperation ParentOperation => Parent as OpenApiOperation;

        /// <summary>Gets or sets the name.</summary>
        [JsonProperty(PropertyName = "name", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public string Name
        {
            get => _name;
            set
            {
                _name = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the kind of the parameter.</summary>
        [JsonProperty(PropertyName = "in", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public OpenApiParameterKind Kind
        {
            get => _kind;
            set
            {
                _kind = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the style of the parameter (OpenAPI only).</summary>
        [JsonProperty(PropertyName = "style", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public OpenApiParameterStyle Style
        {
            get => _style;
            set
            {
                _style = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the explode setting for the parameter (OpenAPI only).</summary>
        [JsonProperty(PropertyName = "explode", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public bool Explode
        {
            get => _explode;
            set
            {
                _explode = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets a value indicating whether the parameter is required (default: false).</summary>
        [JsonProperty(PropertyName = "required", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public bool IsRequired
        {
            get => _isRequired;
            set
            {
                _isRequired = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets a value indicating whether passing empty-valued parameters is allowed (default: false).</summary>
        [JsonProperty(PropertyName = "allowEmptyValue", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public bool AllowEmptyValue { get; set; }

        /// <summary>Gets or sets the description. </summary>
        [Newtonsoft.Json.JsonProperty("description", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public override string Description
        {
            get => base.Description;
            set
            {
                base.Description = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets the actual parameter.</summary>
        [JsonIgnore]
        public OpenApiParameter ActualParameter => Reference is OpenApiParameter ? (OpenApiParameter)Reference : this;

        /// <summary>Gets or sets the format of the array if type array is used.</summary>
        [JsonProperty(PropertyName = "collectionFormat", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public OpenApiParameterCollectionFormat CollectionFormat { get; set; }

        /// <summary>Gets or sets the headers (OpenAPI only).</summary>
        [JsonProperty(PropertyName = "examples", DefaultValueHandling = DefaultValueHandling.Ignore)]
        public IDictionary<string, OpenApiExample> Examples
        {
            get => _examples;
            set
            {
                _examples = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the schema which is only available when <see cref="Kind"/> == body.</summary>
        [JsonProperty(PropertyName = "schema", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public JsonSchema Schema
        {
            get => _schema;
            set
            {
                _schema = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets or sets the custom schema which is used when <see cref="Kind"/> != body.</summary>
        [JsonProperty(PropertyName = "x-schema", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public JsonSchema CustomSchema { get; set; }

        /// <summary>Gets or sets the name.</summary>
        [JsonProperty(PropertyName = "x-position", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
        public int? Position
        {
            get => _position;
            set
            {
                _position = value;
                ParentOperation?.UpdateRequestBody(this);
            }
        }

        /// <summary>Gets the actual schema, either the parameter schema itself (or its reference) or the <see cref="Schema"/> property when <see cref="Kind"/> == body.</summary>
        /// <exception cref="InvalidOperationException" accessor="get">The schema reference path is not resolved.</exception>
        [JsonIgnore]
        public override JsonSchema ActualSchema
        {
            get
            {
                if (Reference is OpenApiParameter parameter)
                {
                    return parameter.ActualSchema;
                }
                else
                {
                    return Schema?.ActualSchema ?? CustomSchema?.ActualSchema ?? base.ActualSchema;
                }
            }
        }

        /// <summary>Gets a value indicating whether the validated data can be null.</summary>
        /// <param name="schemaType">The schema type.</param>
        /// <returns>The result.</returns>
        public override bool IsNullable(SchemaType schemaType)
        {
            if (schemaType == SchemaType.Swagger2)
            {
                if (IsNullableRaw == null)
                {
                    return IsRequired == false;
                }

                return IsNullableRaw.Value;
            }
            else if (schemaType == SchemaType.OpenApi3)
            {
                if (IsNullableRaw.HasValue)
                {
                    return IsNullableRaw.Value;
                }
                else if (Schema != null)
                {
                    return Schema.IsNullable(schemaType);
                }
                else if (CustomSchema != null)
                {
                    return CustomSchema.IsNullable(schemaType);
                }
            }

            return base.IsNullable(schemaType);
        }

        /// <summary>Gets a value indicating whether this is an XML body parameter.</summary>
        [JsonIgnore]
        public bool IsXmlBodyParameter
        {
            get
            {
                if (Kind != OpenApiParameterKind.Body)
                {
                    return false;
                }

                var parent = Parent as OpenApiOperation;
                var consumes = parent?.ActualConsumes?.Any() == true ?
                    parent.ActualConsumes :
                    parent?.RequestBody?.Content.Keys;

                return consumes?.Any() == true &&
                       consumes.Any(p => p.Contains("application/xml")) &&
                       consumes.Any(p => p.StartsWith("application/") && p.EndsWith("json")) == false;
            }
        }

        /// <summary>Gets a value indicating whether this is a binary body parameter.</summary>
        [JsonIgnore]
        public bool IsBinaryBodyParameter
        {
            get
            {
                if (Kind != OpenApiParameterKind.Body || IsXmlBodyParameter)
                {
                    return false;
                }

                var parent = Parent as OpenApiOperation;
                if (parent?.ActualConsumes?.Any() == true)
                {
                    var consumes = parent.ActualConsumes;
                    return consumes?.Any() == true &&
                           consumes.Any(p => p.Contains("*/*")) == false && // supports json
                           consumes.Any(p => p.StartsWith("application/") && p.EndsWith("json")) == false;
                }
                else
                {
                    var consumes = parent?.RequestBody?.Content;
                    return consumes?.Any() == true &&
                           consumes.Any(p => p.Key.Contains("*/*") && !p.Value.Schema.IsBinary) == false && // supports json
                           consumes.Any(p => p.Key.StartsWith("application/") && p.Key.EndsWith("json") && p.Value.Schema?.IsBinary != true) == false;
{'fraction_non_alphanumeric': 0.10873486214893069, 'fraction_numerical': 0.0004122648801855192, 'mean_word_length': 1.587121717104386, 'pattern_counts': {'":': 0, '<': 117, '<?xml version=': 0, '>': 151, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7372110', 'n_tokens_mistral': 4626, 'n_tokens_neox': 4428, 'n_words': 1105}