{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.OpenApi.Internal where
import Prelude ()
import Prelude.Compat
import           Control.Applicative
import           Control.Lens          ((&), (.~), (?~))
import           Data.Aeson            hiding (Encoding)
import qualified Data.Aeson.Types      as JSON
import           Data.Data             (Constr, Data (..), DataType, Fixity (..), Typeable,
                                        constrIndex, mkConstr, mkDataType)
import           Data.Hashable         (Hashable (..))
import qualified Data.HashMap.Strict   as HashMap
import           Data.HashSet.InsOrd   (InsOrdHashSet)
import           Data.Map              (Map)
import qualified Data.Map              as Map
import           Data.Monoid           (Monoid (..))
import           Data.Scientific       (Scientific)
import           Data.Semigroup.Compat (Semigroup (..))
import           Data.String           (IsString (..))
import           Data.Text             (Text)
import qualified Data.Text             as Text
import           Data.Text.Encoding    (encodeUtf8)
import           GHC.Generics          (Generic)
import           Network.HTTP.Media    (MediaType, mainType, parameters, parseAccept, subType, (//),
                                        (/:))
import           Network.Socket        (HostName, PortNumber)
import           Text.Read             (readMaybe)
import           Data.HashMap.Strict.InsOrd (InsOrdHashMap)
import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
import Generics.SOP.TH                  (deriveGeneric)
import Data.OpenApi.Internal.AesonUtils (sopSwaggerGenericToJSON
                                        ,sopSwaggerGenericToJSONWithOpts
                                        ,sopSwaggerGenericParseJSON
                                        ,HasSwaggerAesonOptions(..)
                                        ,AesonDefaultValue(..)
                                        ,mkSwaggerAesonOptions
                                        ,saoAdditionalPairs
                                        ,saoSubObject)
import Data.OpenApi.Internal.Utils
import Data.OpenApi.Internal.AesonUtils (sopSwaggerGenericToEncoding)
type Definitions = InsOrdHashMap Text
data OpenApi = OpenApi
  { 
    
    _openApiInfo :: Info
    
    
    
  , _openApiServers :: [Server]
    
  , _openApiPaths :: InsOrdHashMap FilePath PathItem
    
  , _openApiComponents :: Components
    
    
    
    
    
  , _openApiSecurity :: [SecurityRequirement]
    
    
    
    
    
  , _openApiTags :: InsOrdHashSet Tag
    
  , _openApiExternalDocs :: Maybe ExternalDocs
  } deriving (Eq, Show, Generic, Data, Typeable)
data Info = Info
  { 
    _infoTitle :: Text
    
    
  , _infoDescription :: Maybe Text
    
  , _infoTermsOfService :: Maybe Text
    
  , _infoContact :: Maybe Contact
    
  , _infoLicense :: Maybe License
    
    
  , _infoVersion :: Text
  } deriving (Eq, Show, Generic, Data, Typeable)
data Contact = Contact
  { 
    _contactName  :: Maybe Text
    
  , _contactUrl   :: Maybe URL
    
  , _contactEmail :: Maybe Text
  } deriving (Eq, Show, Generic, Data, Typeable)
data License = License
  { 
    _licenseName :: Text
    
  , _licenseUrl :: Maybe URL
  } deriving (Eq, Show, Generic, Data, Typeable)
instance IsString License where
  fromString s = License (fromString s) Nothing
data Server = Server
  { 
    
    
    
    _serverUrl :: Text
    
    
  , _serverDescription :: Maybe Text
    
    
  , _serverVariables :: InsOrdHashMap Text ServerVariable
  } deriving (Eq, Show, Generic, Data, Typeable)
data ServerVariable = ServerVariable
  { 
    
    _serverVariableEnum :: Maybe (InsOrdHashSet Text) 
    
    
    
    
  , _serverVariableDefault :: Text
    
    
  , _serverVariableDescription :: Maybe Text
  } deriving (Eq, Show, Generic, Data, Typeable)
instance IsString Server where
  fromString s = Server (fromString s) Nothing mempty
data Components = Components
  { _componentsSchemas :: Definitions Schema
  , _componentsResponses :: Definitions Response
  , _componentsParameters :: Definitions Param
  , _componentsExamples :: Definitions Example
  , _componentsRequestBodies :: Definitions RequestBody
  , _componentsHeaders :: Definitions Header
  , _componentsSecuritySchemes :: Definitions SecurityScheme
  , _componentsLinks :: Definitions Link
  , _componentsCallbacks :: Definitions Callback
  } deriving (Eq, Show, Generic, Data, Typeable)
data PathItem = PathItem
  { 
    _pathItemSummary :: Maybe Text
    
    
  , _pathItemDescription :: Maybe Text
    
  , _pathItemGet :: Maybe Operation
    
  , _pathItemPut :: Maybe Operation
    
  , _pathItemPost :: Maybe Operation
    
  , _pathItemDelete :: Maybe Operation
    
  , _pathItemOptions :: Maybe Operation
    
  , _pathItemHead :: Maybe Operation
    
  , _pathItemPatch :: Maybe Operation
    
  , _pathItemTrace :: Maybe Operation
    
  , _pathItemServers :: [Server]
    
    
    
    
  , _pathItemParameters :: [Referenced Param]
  } deriving (Eq, Show, Generic, Data, Typeable)
data Operation = Operation
  { 
    
    _operationTags :: InsOrdHashSet TagName
    
    
  , _operationSummary :: Maybe Text
    
    
  , _operationDescription :: Maybe Text
    
  , _operationExternalDocs :: Maybe ExternalDocs
    
    
    
    
    
  , _operationOperationId :: Maybe Text
    
    
    
    
    
  , _operationParameters :: [Referenced Param]
    
    
    
    
    
  , _operationRequestBody :: Maybe (Referenced RequestBody)
    
  , _operationResponses :: Responses
    
    
    
    
  , _operationCallbacks :: InsOrdHashMap Text (Referenced Callback)
    
    
    
  , _operationDeprecated :: Maybe Bool
    
    
    
    
    
  , _operationSecurity :: [SecurityRequirement]
    
    
    
  , _operationServers :: [Server]
  } deriving (Eq, Show, Generic, Data, Typeable)
instance Data MediaType where
  gunfold k z c = case constrIndex c of
    1 -> k (k (k (z (\main sub params -> foldl (/:) (main // sub) (Map.toList params)))))
    _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type MediaType."
  toConstr _ = mediaTypeConstr
  dataTypeOf _ = mediaTypeData
mediaTypeConstr = mkConstr mediaTypeData "MediaType" [] Prefix
mediaTypeData = mkDataType "MediaType" [mediaTypeConstr]
instance Hashable MediaType where
  hashWithSalt salt mt = salt `hashWithSalt` show mt
data RequestBody = RequestBody
  { 
    
    _requestBodyDescription :: Maybe Text
    
    
    
    
  , _requestBodyContent :: InsOrdHashMap MediaType MediaTypeObject
    
    
  , _requestBodyRequired :: Maybe Bool
  } deriving (Eq, Show, Generic, Data, Typeable)
data MediaTypeObject = MediaTypeObject
  { _mediaTypeObjectSchema :: Maybe (Referenced Schema)
    
    
  , _mediaTypeObjectExample :: Maybe Value
    
    
  , _mediaTypeObjectExamples :: InsOrdHashMap Text (Referenced Example)
    
    
    
    
  , _mediaTypeObjectEncoding :: InsOrdHashMap Text Encoding
  } deriving (Eq, Show, Generic, Data, Typeable)
data Style
  = StyleMatrix
    
  | StyleLabel
    
  | StyleForm
    
    
    
  | StyleSimple
    
    
  | StyleSpaceDelimited
    
    
  | StylePipeDelimited
    
    
  | StyleDeepObject
    
  deriving (Eq, Show, Generic, Data, Typeable)
data Encoding = Encoding
  { 
    
    
    
    
    
    
    _encodingContentType :: Maybe MediaType
    
    
    
    
  , _encodingHeaders :: InsOrdHashMap Text (Referenced Header)
    
    
    
    
    
  , _encodingStyle :: Maybe Style
    
    
    
    
    
    
    
  , _encodingExplode :: Maybe Bool
    
    
    
    
    
  , _encodingAllowReserved :: Maybe Bool
  } deriving (Eq, Show, Generic, Data, Typeable)
newtype MimeList = MimeList { getMimeList :: [MediaType] }
  deriving (Eq, Show, Semigroup, Monoid, Typeable)
mimeListConstr :: Constr
mimeListConstr = mkConstr mimeListDataType "MimeList" ["getMimeList"] Prefix
mimeListDataType :: DataType
mimeListDataType = mkDataType "Data.OpenApi.MimeList" [mimeListConstr]
instance Data MimeList where
  gunfold k z c = case constrIndex c of
    1 -> k (z (MimeList . map fromString))
    _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type MimeList."
  toConstr (MimeList _) = mimeListConstr
  dataTypeOf _ = mimeListDataType
data Param = Param
  { 
    
    _paramName :: Text
    
    
    
  , _paramDescription :: Maybe Text
    
    
    
  , _paramRequired :: Maybe Bool
    
    
  , _paramDeprecated :: Maybe Bool
    
  , _paramIn :: ParamLocation
    
    
    
  , _paramAllowEmptyValue :: Maybe Bool
    
    
    
    
    
  , _paramAllowReserved :: Maybe Bool
    
  , _paramSchema :: Maybe (Referenced Schema)
    
    
    
    
  , _paramStyle :: Maybe Style
    
    
    
    
  , _paramExplode :: Maybe Bool
    
    
    
    
    
    
    
  , _paramExample :: Maybe Value
    
    
    
    
    
  , _paramExamples :: InsOrdHashMap Text (Referenced Example)
    
    
    
  } deriving (Eq, Show, Generic, Data, Typeable)
data Example = Example
  { 
    _exampleSummary :: Maybe Text
    
    
  , _exampleDescription :: Maybe Text
    
    
    
    
    
  , _exampleValue :: Maybe Value
    
    
    
    
  , _exampleExternalValue :: Maybe URL
  } deriving (Eq, Show, Generic, Typeable, Data)
data ExpressionOrValue
  = Expression Text
  | Value Value
  deriving (Eq, Show, Generic, Typeable, Data)
data Link = Link
  { 
    
    
    
    _linkOperationRef :: Maybe Text
    
    
  , _linkOperationId :: Maybe Text
    
    
    
    
    
  , _linkParameters :: InsOrdHashMap Text ExpressionOrValue
    
  , _linkRequestBody :: Maybe ExpressionOrValue
    
  , _linkDescription :: Maybe Text
    
  , _linkServer :: Maybe Server
  } deriving (Eq, Show, Generic, Typeable, Data)
data OpenApiItems where
  OpenApiItemsObject    :: Referenced Schema   -> OpenApiItems
  OpenApiItemsArray     :: [Referenced Schema] -> OpenApiItems
  deriving (Eq, Show, Typeable, Data)
data OpenApiType where
  OpenApiString   :: OpenApiType
  OpenApiNumber   :: OpenApiType
  OpenApiInteger  :: OpenApiType
  OpenApiBoolean  :: OpenApiType
  OpenApiArray    :: OpenApiType
  OpenApiNull     :: OpenApiType
  OpenApiObject   :: OpenApiType
  deriving (Eq, Show, Typeable, Generic, Data)
data ParamLocation
  = 
    
    ParamQuery
    
  | ParamHeader
    
    
    
  | ParamPath
    
  | ParamCookie
  deriving (Eq, Show, Generic, Data, Typeable)
type Format = Text
type ParamName = Text
data Schema = Schema
  { _schemaTitle :: Maybe Text
  , _schemaDescription :: Maybe Text
  , _schemaRequired :: [ParamName]
  , _schemaNullable :: Maybe Bool
  , _schemaAllOf :: Maybe [Referenced Schema]
  , _schemaOneOf :: Maybe [Referenced Schema]
  , _schemaNot :: Maybe (Referenced Schema)
  , _schemaAnyOf :: Maybe [Referenced Schema]
  , _schemaProperties :: InsOrdHashMap Text (Referenced Schema)
  , _schemaAdditionalProperties :: Maybe AdditionalProperties
  , _schemaDiscriminator :: Maybe Discriminator
  , _schemaReadOnly :: Maybe Bool
  , _schemaWriteOnly :: Maybe Bool
  , _schemaXml :: Maybe Xml
  , _schemaExternalDocs :: Maybe ExternalDocs
  , _schemaExample :: Maybe Value
  , _schemaDeprecated :: Maybe Bool
  , _schemaMaxProperties :: Maybe Integer
  , _schemaMinProperties :: Maybe Integer
  , 
    
    
    
    
    _schemaDefault :: Maybe Value
  , _schemaType :: Maybe OpenApiType
  , _schemaFormat :: Maybe Format
  , _schemaItems :: Maybe OpenApiItems
  , _schemaMaximum :: Maybe Scientific
  , _schemaExclusiveMaximum :: Maybe Bool
  , _schemaMinimum :: Maybe Scientific
  , _schemaExclusiveMinimum :: Maybe Bool
  , _schemaMaxLength :: Maybe Integer
  , _schemaMinLength :: Maybe Integer
  , _schemaPattern :: Maybe Pattern
  , _schemaMaxItems :: Maybe Integer
  , _schemaMinItems :: Maybe Integer
  , _schemaUniqueItems :: Maybe Bool
  , _schemaEnum :: Maybe [Value]
  , _schemaMultipleOf :: Maybe Scientific
  } deriving (Eq, Show, Generic, Data, Typeable)
type Pattern = Text
data Discriminator = Discriminator
  { 
    _discriminatorPropertyName :: Text
    
  , _discriminatorMapping :: InsOrdHashMap Text Text
  } deriving (Eq, Show, Generic, Data, Typeable)
data NamedSchema = NamedSchema
  { _namedSchemaName :: Maybe Text
  , _namedSchemaSchema :: Schema
  } deriving (Eq, Show, Generic, Data, Typeable)
data Xml = Xml
  { 
    
    
    
    
    _xmlName :: Maybe Text
    
    
  , _xmlNamespace :: Maybe Text
    
  , _xmlPrefix :: Maybe Text
    
    
  , _xmlAttribute :: Maybe Bool
    
    
    
    
    
    
  , _xmlWrapped :: Maybe Bool
  } deriving (Eq, Show, Generic, Data, Typeable)
data Responses = Responses
  { 
    
   _responsesDefault :: Maybe (Referenced Response)
    
    
  , _responsesResponses :: InsOrdHashMap HttpStatusCode (Referenced Response)
  } deriving (Eq, Show, Generic, Data, Typeable)
type HttpStatusCode = Int
data Response = Response
  { 
    
    _responseDescription :: Text
    
    
    
    
  , _responseContent :: InsOrdHashMap MediaType MediaTypeObject
    
  , _responseHeaders :: InsOrdHashMap HeaderName (Referenced Header)
    
    
    
  , _responseLinks :: InsOrdHashMap Text (Referenced Link)
  } deriving (Eq, Show, Generic, Data, Typeable)
instance IsString Response where
  fromString s = Response (fromString s) mempty mempty mempty
newtype Callback = Callback (InsOrdHashMap Text PathItem)
  deriving (Eq, Show, Generic, Data, Typeable)
type HeaderName = Text
data Header = Header
  { 
    _headerDescription :: Maybe HeaderName
  , _headerRequired :: Maybe Bool
  , _headerDeprecated :: Maybe Bool
  , _headerAllowEmptyValue :: Maybe Bool
  , _headerExplode :: Maybe Bool
  , _headerExample :: Maybe Value
  , _headerExamples :: InsOrdHashMap Text (Referenced Example)
  , _headerSchema :: Maybe (Referenced Schema)
  } deriving (Eq, Show, Generic, Data, Typeable)
data ApiKeyLocation
  = ApiKeyQuery
  | ApiKeyHeader
  | ApiKeyCookie
  deriving (Eq, Show, Generic, Data, Typeable)
data ApiKeyParams = ApiKeyParams
  { 
    _apiKeyName :: Text
    
  , _apiKeyIn :: ApiKeyLocation
  } deriving (Eq, Show, Generic, Data, Typeable)
type AuthorizationURL = Text
type TokenURL = Text
newtype OAuth2ImplicitFlow
  = OAuth2ImplicitFlow {_oAuth2ImplicitFlowAuthorizationUrl :: AuthorizationURL}
  deriving (Eq, Show, Generic, Data, Typeable)
newtype OAuth2PasswordFlow
  = OAuth2PasswordFlow {_oAuth2PasswordFlowTokenUrl :: TokenURL}
  deriving (Eq, Show, Generic, Data, Typeable)
newtype OAuth2ClientCredentialsFlow
  = OAuth2ClientCredentialsFlow {_oAuth2ClientCredentialsFlowTokenUrl :: TokenURL}
  deriving (Eq, Show, Generic, Data, Typeable)
data OAuth2AuthorizationCodeFlow = OAuth2AuthorizationCodeFlow
  { _oAuth2AuthorizationCodeFlowAuthorizationUrl :: AuthorizationURL
  , _oAuth2AuthorizationCodeFlowTokenUrl :: TokenURL
  } deriving (Eq, Show, Generic, Data, Typeable)
data OAuth2Flow p = OAuth2Flow
  { _oAuth2Params :: p
    
  , _oAath2RefreshUrl :: Maybe URL
    
    
    
  , _oAuth2Scopes :: InsOrdHashMap Text Text
  } deriving (Eq, Show, Generic, Data, Typeable)
data OAuth2Flows = OAuth2Flows
  { 
    _oAuth2FlowsImplicit :: Maybe (OAuth2Flow OAuth2ImplicitFlow)
    
  , _oAuth2FlowsPassword :: Maybe (OAuth2Flow OAuth2PasswordFlow)
    
  , _oAuth2FlowsClientCredentials :: Maybe (OAuth2Flow OAuth2ClientCredentialsFlow)
    
  , _oAuth2FlowsAuthorizationCode :: Maybe (OAuth2Flow OAuth2AuthorizationCodeFlow)
  } deriving (Eq, Show, Generic, Data, Typeable)
data SecuritySchemeType
  = SecuritySchemeHttp
  | SecuritySchemeApiKey ApiKeyParams
  | SecuritySchemeOAuth2 OAuth2Flows
  | SecuritySchemeOpenIdConnect URL
  deriving (Eq, Show, Generic, Data, Typeable)
data SecurityScheme = SecurityScheme
  { 
    _securitySchemeType :: SecuritySchemeType
    
  , _securitySchemeDescription :: Maybe Text
  } deriving (Eq, Show, Generic, Data, Typeable)
newtype SecurityDefinitions
  = SecurityDefinitions (Definitions SecurityScheme)
  deriving (Eq, Show, Generic, Data, Typeable)
newtype SecurityRequirement = SecurityRequirement
  { getSecurityRequirement :: InsOrdHashMap Text [Text]
  } deriving (Eq, Read, Show, Semigroup, Monoid, ToJSON, FromJSON, Data, Typeable)
type TagName = Text
data Tag = Tag
  { 
    _tagName :: TagName
    
    
  , _tagDescription :: Maybe Text
    
  , _tagExternalDocs :: Maybe ExternalDocs
  } deriving (Eq, Ord, Show, Generic, Data, Typeable)
instance Hashable Tag
instance IsString Tag where
  fromString s = Tag (fromString s) Nothing Nothing
data ExternalDocs = ExternalDocs
  { 
    
    _externalDocsDescription :: Maybe Text
    
  , _externalDocsUrl :: URL
  } deriving (Eq, Ord, Show, Generic, Data, Typeable)
instance Hashable ExternalDocs
newtype Reference = Reference { getReference :: Text }
  deriving (Eq, Show, Data, Typeable)
data Referenced a
  = Ref Reference
  | Inline a
  deriving (Eq, Show, Functor, Data, Typeable)
instance IsString a => IsString (Referenced a) where
  fromString = Inline . fromString
newtype URL = URL { getUrl :: Text } deriving (Eq, Ord, Show, Hashable, ToJSON, FromJSON, Data, Typeable)
data AdditionalProperties
  = AdditionalPropertiesAllowed Bool
  | AdditionalPropertiesSchema (Referenced Schema)
  deriving (Eq, Show, Data, Typeable)
deriveGeneric ''Server
deriveGeneric ''Components
deriveGeneric ''Header
deriveGeneric ''OAuth2Flow
deriveGeneric ''OAuth2Flows
deriveGeneric ''Operation
deriveGeneric ''Param
deriveGeneric ''PathItem
deriveGeneric ''Response
deriveGeneric ''RequestBody
deriveGeneric ''MediaTypeObject
deriveGeneric ''Responses
deriveGeneric ''SecurityScheme
deriveGeneric ''Schema
deriveGeneric ''OpenApi
deriveGeneric ''Example
deriveGeneric ''Encoding
deriveGeneric ''Link
instance Semigroup OpenApi where
  (<>) = genericMappend
instance Monoid OpenApi where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Info where
  (<>) = genericMappend
instance Monoid Info where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Contact where
  (<>) = genericMappend
instance Monoid Contact where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Components where
  (<>) = genericMappend
instance Monoid Components where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup PathItem where
  (<>) = genericMappend
instance Monoid PathItem where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Schema where
  (<>) = genericMappend
instance Monoid Schema where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Param where
  (<>) = genericMappend
instance Monoid Param where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Header where
  (<>) = genericMappend
instance Monoid Header where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Responses where
  (<>) = genericMappend
instance Monoid Responses where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Response where
  (<>) = genericMappend
instance Monoid Response where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup MediaTypeObject where
  (<>) = genericMappend
instance Monoid MediaTypeObject where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Encoding where
  (<>) = genericMappend
instance Monoid Encoding where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup ExternalDocs where
  (<>) = genericMappend
instance Monoid ExternalDocs where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup Operation where
  (<>) = genericMappend
instance Monoid Operation where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup (OAuth2Flow p) where
  l@OAuth2Flow{ _oAath2RefreshUrl = lUrl, _oAuth2Scopes = lScopes }
    <> OAuth2Flow { _oAath2RefreshUrl = rUrl, _oAuth2Scopes = rScopes } =
      l { _oAath2RefreshUrl = swaggerMappend lUrl rUrl, _oAuth2Scopes = lScopes <> rScopes }
instance Semigroup OAuth2Flows where
  l <> r = OAuth2Flows
    { _oAuth2FlowsImplicit = _oAuth2FlowsImplicit l <> _oAuth2FlowsImplicit r
    , _oAuth2FlowsPassword = _oAuth2FlowsPassword l <> _oAuth2FlowsPassword r
    , _oAuth2FlowsClientCredentials = _oAuth2FlowsClientCredentials l <> _oAuth2FlowsClientCredentials r
    , _oAuth2FlowsAuthorizationCode = _oAuth2FlowsAuthorizationCode l <> _oAuth2FlowsAuthorizationCode r
    }
instance Monoid OAuth2Flows where
  mempty = genericMempty
  mappend = (<>)
instance Semigroup SecurityScheme where
  SecurityScheme (SecuritySchemeOAuth2 lFlows) lDesc
    <> SecurityScheme (SecuritySchemeOAuth2 rFlows) rDesc =
      SecurityScheme (SecuritySchemeOAuth2 $ lFlows <> rFlows) (swaggerMappend lDesc rDesc)
  l <> _ = l
instance Semigroup SecurityDefinitions where
  (SecurityDefinitions sd1) <> (SecurityDefinitions sd2) =
     SecurityDefinitions $ InsOrdHashMap.unionWith (<>) sd1 sd2
instance Monoid SecurityDefinitions where
  mempty = SecurityDefinitions InsOrdHashMap.empty
  mappend = (<>)
instance Semigroup RequestBody where
  (<>) = genericMappend
instance Monoid RequestBody where
  mempty = genericMempty
  mappend = (<>)
instance SwaggerMonoid Info
instance SwaggerMonoid Components
instance SwaggerMonoid PathItem
instance SwaggerMonoid Schema
instance SwaggerMonoid Param
instance SwaggerMonoid Responses
instance SwaggerMonoid Response
instance SwaggerMonoid ExternalDocs
instance SwaggerMonoid Operation
instance (Eq a, Hashable a) => SwaggerMonoid (InsOrdHashSet a)
instance SwaggerMonoid MimeList
deriving instance SwaggerMonoid URL
instance SwaggerMonoid OpenApiType where
  swaggerMempty = OpenApiString
  swaggerMappend _ y = y
instance SwaggerMonoid ParamLocation where
  swaggerMempty = ParamQuery
  swaggerMappend _ y = y
instance {-# OVERLAPPING #-} SwaggerMonoid (InsOrdHashMap FilePath PathItem) where
  swaggerMempty = InsOrdHashMap.empty
  swaggerMappend = InsOrdHashMap.unionWith mappend
instance Monoid a => SwaggerMonoid (Referenced a) where
  swaggerMempty = Inline mempty
  swaggerMappend (Inline x) (Inline y) = Inline (mappend x y)
  swaggerMappend _ y = y
instance ToJSON Style where
  toJSON = genericToJSON (jsonPrefix "Style")
instance ToJSON OpenApiType where
  toJSON = genericToJSON (jsonPrefix "Swagger")
instance ToJSON ParamLocation where
  toJSON = genericToJSON (jsonPrefix "Param")
instance ToJSON Info where
  toJSON = genericToJSON (jsonPrefix "Info")
instance ToJSON Contact where
  toJSON = genericToJSON (jsonPrefix "Contact")
instance ToJSON License where
  toJSON = genericToJSON (jsonPrefix "License")
instance ToJSON ServerVariable where
  toJSON = genericToJSON (jsonPrefix "ServerVariable")
instance ToJSON ApiKeyLocation where
  toJSON = genericToJSON (jsonPrefix "ApiKey")
instance ToJSON ApiKeyParams where
  toJSON = genericToJSON (jsonPrefix "apiKey")
instance ToJSON Tag where
  toJSON = genericToJSON (jsonPrefix "Tag")
instance ToJSON ExternalDocs where
  toJSON = genericToJSON (jsonPrefix "ExternalDocs")
instance ToJSON Xml where
  toJSON = genericToJSON (jsonPrefix "Xml")
instance ToJSON Discriminator where
  toJSON = genericToJSON (jsonPrefix "Discriminator")
instance ToJSON OAuth2ImplicitFlow where
  toJSON = genericToJSON (jsonPrefix "OAuth2ImplicitFlow")
instance ToJSON OAuth2PasswordFlow where
  toJSON = genericToJSON (jsonPrefix "OAuth2PasswordFlow")
instance ToJSON OAuth2ClientCredentialsFlow where
  toJSON = genericToJSON (jsonPrefix "OAuth2ClientCredentialsFlow")
instance ToJSON OAuth2AuthorizationCodeFlow where
  toJSON = genericToJSON (jsonPrefix "OAuth2AuthorizationCodeFlow")
instance FromJSON Style where
  parseJSON = genericParseJSON (jsonPrefix "Style")
instance FromJSON OpenApiType where
  parseJSON = genericParseJSON (jsonPrefix "Swagger")
instance FromJSON ParamLocation where
  parseJSON = genericParseJSON (jsonPrefix "Param")
instance FromJSON Info where
  parseJSON = genericParseJSON (jsonPrefix "Info")
instance FromJSON Contact where
  parseJSON = genericParseJSON (jsonPrefix "Contact")
instance FromJSON License where
  parseJSON = genericParseJSON (jsonPrefix "License")
instance FromJSON ServerVariable where
  parseJSON = genericParseJSON (jsonPrefix "ServerVariable")
instance FromJSON ApiKeyLocation where
  parseJSON = genericParseJSON (jsonPrefix "ApiKey")
instance FromJSON ApiKeyParams where
  parseJSON = genericParseJSON (jsonPrefix "apiKey")
instance FromJSON Tag where
  parseJSON = genericParseJSON (jsonPrefix "Tag")
instance FromJSON ExternalDocs where
  parseJSON = genericParseJSON (jsonPrefix "ExternalDocs")
instance FromJSON Discriminator where
  parseJSON = genericParseJSON (jsonPrefix "Discriminator")
instance FromJSON OAuth2ImplicitFlow where
  parseJSON = genericParseJSON (jsonPrefix "OAuth2ImplicitFlow")
instance FromJSON OAuth2PasswordFlow where
  parseJSON = genericParseJSON (jsonPrefix "OAuth2PasswordFlow")
instance FromJSON OAuth2ClientCredentialsFlow where
  parseJSON = genericParseJSON (jsonPrefix "OAuth2ClientCredentialsFlow")
instance FromJSON OAuth2AuthorizationCodeFlow where
  parseJSON = genericParseJSON (jsonPrefix "OAuth2AuthorizationCodeFlow")
instance ToJSON MediaType where
  toJSON = toJSON . show
  toEncoding = toEncoding . show
instance ToJSONKey MediaType where
  toJSONKey = JSON.toJSONKeyText (Text.pack . show)
instance (Eq p, ToJSON p, AesonDefaultValue p) => ToJSON (OAuth2Flow p) where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON OAuth2Flows where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON SecuritySchemeType where
  toJSON SecuritySchemeHttp
      = object [ "type" .= ("http" :: Text) ]
  toJSON (SecuritySchemeApiKey params)
      = toJSON params
    <+> object [ "type" .= ("apiKey" :: Text) ]
  toJSON (SecuritySchemeOAuth2 params) = object
    [ "type" .= ("oauth2" :: Text)
    , "flows" .= toJSON params
    ]
  toJSON (SecuritySchemeOpenIdConnect url) = object
    [ "type" .= ("openIdConnect" :: Text)
    , "openIdConnectUrl" .= url
    ]
instance ToJSON OpenApi where
  toJSON a = sopSwaggerGenericToJSON a &
    if InsOrdHashMap.null (_openApiPaths a)
    then (<+> object ["paths" .= object []])
    else id
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Server where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON SecurityScheme where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Schema where
  toJSON = sopSwaggerGenericToJSONWithOpts $
      mkSwaggerAesonOptions "schema" & saoSubObject ?~ "items"
instance ToJSON Header where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON OpenApiItems where
  toJSON (OpenApiItemsObject x) = object [ "items" .= x ]
  toJSON (OpenApiItemsArray  []) = object
    [ "items" .= object []
    , "maxItems" .= (0 :: Int)
    , "example" .= Array mempty
    ]
  toJSON (OpenApiItemsArray  x) = object [ "items" .= x ]
instance ToJSON Components where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON MimeList where
  toJSON (MimeList xs) = toJSON (map show xs)
instance ToJSON Param where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Responses where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Response where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Operation where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON PathItem where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON RequestBody where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON MediaTypeObject where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Example where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Encoding where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON Link where
  toJSON = sopSwaggerGenericToJSON
  toEncoding = sopSwaggerGenericToEncoding
instance ToJSON SecurityDefinitions where
  toJSON (SecurityDefinitions sd) = toJSON sd
instance ToJSON Reference where
  toJSON (Reference ref) = object [ "$ref" .= ref ]
referencedToJSON :: ToJSON a => Text -> Referenced a -> Value
referencedToJSON prefix (Ref (Reference ref)) = object [ "$ref" .= (prefix <> ref) ]
referencedToJSON _ (Inline x) = toJSON x
instance ToJSON (Referenced Schema)   where toJSON = referencedToJSON "#/components/schemas/"
instance ToJSON (Referenced Param)    where toJSON = referencedToJSON "#/components/parameters/"
instance ToJSON (Referenced Response) where toJSON = referencedToJSON "#/components/responses/"
instance ToJSON (Referenced RequestBody) where toJSON = referencedToJSON "#/components/requestBodies/"
instance ToJSON (Referenced Example)  where toJSON = referencedToJSON "#/components/examples/"
instance ToJSON (Referenced Header)   where toJSON = referencedToJSON "#/components/headers/"
instance ToJSON (Referenced Link)     where toJSON = referencedToJSON "#/components/links/"
instance ToJSON (Referenced Callback) where toJSON = referencedToJSON "#/components/callbacks/"
instance ToJSON AdditionalProperties where
  toJSON (AdditionalPropertiesAllowed b) = toJSON b
  toJSON (AdditionalPropertiesSchema s) = toJSON s
instance ToJSON ExpressionOrValue where
  toJSON (Expression expr) = toJSON expr
  toJSON (Value val) = toJSON val
instance ToJSON Callback where
  toJSON (Callback ps) = toJSON ps
instance FromJSON MediaType where
  parseJSON = withText "MediaType" $ \str ->
    maybe (fail $ "Invalid media type literal " <> Text.unpack str) pure $ parseAccept $ encodeUtf8 str
instance FromJSONKey MediaType where
  fromJSONKey = FromJSONKeyTextParser (parseJSON . String)
instance (Eq p, FromJSON p, AesonDefaultValue p) => FromJSON (OAuth2Flow p) where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON OAuth2Flows where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON SecuritySchemeType where
  parseJSON js@(Object o) = do
    (t :: Text) <- o .: "type"
    case t of
      "http"   -> pure SecuritySchemeHttp
      "apiKey" -> SecuritySchemeApiKey <$> parseJSON js
      "oauth2" -> SecuritySchemeOAuth2 <$> (o .: "flows")
      "openIdConnect" -> SecuritySchemeOpenIdConnect <$> (o .: "openIdConnectUrl")
      _ -> empty
  parseJSON _ = empty
instance FromJSON OpenApi where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Server where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON SecurityScheme where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Schema where
  parseJSON = fmap nullaryCleanup . sopSwaggerGenericParseJSON
    where nullaryCleanup :: Schema -> Schema
          nullaryCleanup s =
            if _schemaItems s == Just (OpenApiItemsArray [])
              then s { _schemaExample = Nothing
                     , _schemaMaxItems = Nothing
                     }
              else s
instance FromJSON Header where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON OpenApiItems where
  parseJSON js@(Object obj)
      | null obj  = pure $ OpenApiItemsArray [] 
      | otherwise = OpenApiItemsObject <$> parseJSON js
  parseJSON js@(Array _)  = OpenApiItemsArray  <$> parseJSON js
  parseJSON _ = empty
instance FromJSON Components where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON MimeList where
  parseJSON js = MimeList . map fromString <$> parseJSON js
instance FromJSON Param where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Responses where
  parseJSON (Object o) = Responses
    <$> o .:? "default"
    <*> parseJSON (Object (HashMap.delete "default" o))
  parseJSON _ = empty
instance FromJSON Example where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Response where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Operation where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON PathItem where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON SecurityDefinitions where
  parseJSON js = SecurityDefinitions <$> parseJSON js
instance FromJSON RequestBody where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON MediaTypeObject where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Encoding where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Link where
  parseJSON = sopSwaggerGenericParseJSON
instance FromJSON Reference where
  parseJSON (Object o) = Reference <$> o .: "$ref"
  parseJSON _ = empty
referencedParseJSON :: FromJSON a => Text -> Value -> JSON.Parser (Referenced a)
referencedParseJSON prefix js@(Object o) = do
  ms <- o .:? "$ref"
  case ms of
    Nothing -> Inline <$> parseJSON js
    Just s  -> Ref <$> parseRef s
  where
    parseRef s = do
      case Text.stripPrefix prefix s of
        Nothing     -> fail $ "expected $ref of the form \"" <> Text.unpack prefix <> "*\", but got " <> show s
        Just suffix -> pure (Reference suffix)
referencedParseJSON _ _ = fail "referenceParseJSON: not an object"
instance FromJSON (Referenced Schema)   where parseJSON = referencedParseJSON "#/components/schemas/"
instance FromJSON (Referenced Param)    where parseJSON = referencedParseJSON "#/components/parameters/"
instance FromJSON (Referenced Response) where parseJSON = referencedParseJSON "#/components/responses/"
instance FromJSON (Referenced RequestBody) where parseJSON = referencedParseJSON "#/components/requestBodies/"
instance FromJSON (Referenced Example)  where parseJSON = referencedParseJSON "#/components/examples/"
instance FromJSON (Referenced Header)   where parseJSON = referencedParseJSON "#/components/headers/"
instance FromJSON (Referenced Link)     where parseJSON = referencedParseJSON "#/components/links/"
instance FromJSON (Referenced Callback) where parseJSON = referencedParseJSON "#/components/callbacks/"
instance FromJSON Xml where
  parseJSON = genericParseJSON (jsonPrefix "xml")
instance FromJSON AdditionalProperties where
  parseJSON (Bool b) = pure $ AdditionalPropertiesAllowed b
  parseJSON js = AdditionalPropertiesSchema <$> parseJSON js
instance FromJSON ExpressionOrValue where
  parseJSON (String expr) = pure $ Expression expr
  parseJSON v = pure $ Value v
instance FromJSON Callback where
  parseJSON = fmap Callback . parseJSON
instance HasSwaggerAesonOptions Server where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "server"
instance HasSwaggerAesonOptions Components where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "components"
instance HasSwaggerAesonOptions Header where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "header"
instance AesonDefaultValue p => HasSwaggerAesonOptions (OAuth2Flow p) where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "oauth2" & saoSubObject ?~ "params"
instance HasSwaggerAesonOptions OAuth2Flows where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "oauth2Flows"
instance HasSwaggerAesonOptions Operation where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "operation"
instance HasSwaggerAesonOptions Param where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "param"
instance HasSwaggerAesonOptions PathItem where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "pathItem"
instance HasSwaggerAesonOptions Response where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "response"
instance HasSwaggerAesonOptions RequestBody where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "requestBody"
instance HasSwaggerAesonOptions MediaTypeObject where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "mediaTypeObject"
instance HasSwaggerAesonOptions Responses where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "responses" & saoSubObject ?~ "responses"
instance HasSwaggerAesonOptions SecurityScheme where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "securityScheme" & saoSubObject ?~ "type"
instance HasSwaggerAesonOptions Schema where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "schema" & saoSubObject ?~ "paramSchema"
instance HasSwaggerAesonOptions OpenApi where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "swagger" & saoAdditionalPairs .~ [("openapi", "3.0.0")]
instance HasSwaggerAesonOptions Example where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "example"
instance HasSwaggerAesonOptions Encoding where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "encoding"
instance HasSwaggerAesonOptions Link where
  swaggerAesonOptions _ = mkSwaggerAesonOptions "link"
instance AesonDefaultValue Server
instance AesonDefaultValue Components
instance AesonDefaultValue OAuth2ImplicitFlow
instance AesonDefaultValue OAuth2PasswordFlow
instance AesonDefaultValue OAuth2ClientCredentialsFlow
instance AesonDefaultValue OAuth2AuthorizationCodeFlow
instance AesonDefaultValue p => AesonDefaultValue (OAuth2Flow p)
instance AesonDefaultValue Responses
instance AesonDefaultValue SecuritySchemeType
instance AesonDefaultValue OpenApiType
instance AesonDefaultValue MimeList where defaultValue = Just mempty
instance AesonDefaultValue Info
instance AesonDefaultValue ParamLocation
instance AesonDefaultValue Link