    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE DeriveGeneric      #-}
    module Distribution.SPDX.LicenseExpression (
        LicenseExpression (..),
        SimpleLicenseExpression (..),
        simpleLicenseExpression,
        ) where

    import Distribution.Compat.Prelude
    import Prelude ()

    import Distribution.Parsec
    import Distribution.Pretty
    import Distribution.SPDX.LicenseExceptionId
    import Distribution.SPDX.LicenseId
    import Distribution.SPDX.LicenseListVersion
    import Distribution.SPDX.LicenseReference
    import Distribution.Utils.Generic           (isAsciiAlphaNum)

    import qualified Distribution.Compat.CharParsing as P
    import qualified Text.PrettyPrint                as Disp

    -- | SPDX License Expression.
    --
    -- @
    -- idstring              = 1*(ALPHA \/ DIGIT \/ "-" \/ "." )
    -- license id            = \<short form license identifier inAppendix I.1>
    -- license exception id  = \<short form license exception identifier inAppendix I.2>
    -- license ref           = [\"DocumentRef-"1*(idstring)":"]\"LicenseRef-"1*(idstring)
    --
    -- simple expression     = license id \/ license id"+" \/ license ref
    --
    -- compound expression   = 1*1(simple expression \/
    --                         simple expression \"WITH" license exception id \/
    --                         compound expression \"AND" compound expression \/
    --                         compound expression \"OR" compound expression ) \/
    --                         "(" compound expression ")" )
    --
    -- license expression    = 1*1(simple expression / compound expression)
    -- @
    data LicenseExpression
        = ELicense !SimpleLicenseExpression !(Maybe LicenseExceptionId)
        | EAnd !LicenseExpression !LicenseExpression
        | EOr !LicenseExpression !LicenseExpression
        deriving (Int -> LicenseExpression -> ShowS
    [LicenseExpression] -> ShowS
    LicenseExpression -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [LicenseExpression] -> ShowS
    $cshowList :: [LicenseExpression] -> ShowS
    show :: LicenseExpression -> String
    $cshow :: LicenseExpression -> String
    showsPrec :: Int -> LicenseExpression -> ShowS
    $cshowsPrec :: Int -> LicenseExpression -> ShowS
    Show, ReadPrec [LicenseExpression]
    ReadPrec LicenseExpression
    Int -> ReadS LicenseExpression
    ReadS [LicenseExpression]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [LicenseExpression]
    $creadListPrec :: ReadPrec [LicenseExpression]
    readPrec :: ReadPrec LicenseExpression
    $creadPrec :: ReadPrec LicenseExpression
    readList :: ReadS [LicenseExpression]
    $creadList :: ReadS [LicenseExpression]
    readsPrec :: Int -> ReadS LicenseExpression
    $creadsPrec :: Int -> ReadS LicenseExpression
    Read, LicenseExpression -> LicenseExpression -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: LicenseExpression -> LicenseExpression -> Bool
    $c/= :: LicenseExpression -> LicenseExpression -> Bool
    == :: LicenseExpression -> LicenseExpression -> Bool
    $c== :: LicenseExpression -> LicenseExpression -> Bool
    Eq, Eq LicenseExpression
    LicenseExpression -> LicenseExpression -> Bool
    LicenseExpression -> LicenseExpression -> Ordering
    LicenseExpression -> LicenseExpression -> LicenseExpression
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: LicenseExpression -> LicenseExpression -> LicenseExpression
    $cmin :: LicenseExpression -> LicenseExpression -> LicenseExpression
    max :: LicenseExpression -> LicenseExpression -> LicenseExpression
    $cmax :: LicenseExpression -> LicenseExpression -> LicenseExpression
    >= :: LicenseExpression -> LicenseExpression -> Bool
    $c>= :: LicenseExpression -> LicenseExpression -> Bool
    > :: LicenseExpression -> LicenseExpression -> Bool
    $c> :: LicenseExpression -> LicenseExpression -> Bool
    <= :: LicenseExpression -> LicenseExpression -> Bool
    $c<= :: LicenseExpression -> LicenseExpression -> Bool
    < :: LicenseExpression -> LicenseExpression -> Bool
    $c< :: LicenseExpression -> LicenseExpression -> Bool
    compare :: LicenseExpression -> LicenseExpression -> Ordering
    $ccompare :: LicenseExpression -> LicenseExpression -> Ordering
    Ord, Typeable, Typeable LicenseExpression
    LicenseExpression -> DataType
    LicenseExpression -> Constr
    (forall b. Data b => b -> b)
    -> LicenseExpression -> LicenseExpression
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
    forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LicenseExpression
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c LicenseExpression)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
    gmapT :: (forall b. Data b => b -> b)
    -> LicenseExpression -> LicenseExpression
    $cgmapT :: (forall b. Data b => b -> b)
    -> LicenseExpression -> LicenseExpression
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c LicenseExpression)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c LicenseExpression)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
    dataTypeOf :: LicenseExpression -> DataType
    $cdataTypeOf :: LicenseExpression -> DataType
    toConstr :: LicenseExpression -> Constr
    $ctoConstr :: LicenseExpression -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LicenseExpression
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LicenseExpression
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
    Data, forall x. Rep LicenseExpression x -> LicenseExpression
    forall x. LicenseExpression -> Rep LicenseExpression x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cto :: forall x. Rep LicenseExpression x -> LicenseExpression
    $cfrom :: forall x. LicenseExpression -> Rep LicenseExpression x
    Generic)

    -- | Simple License Expressions.
    data SimpleLicenseExpression
        = ELicenseId LicenseId
          -- ^ An SPDX License List Short Form Identifier. For example: @GPL-2.0-only@
        | ELicenseIdPlus LicenseId
          -- ^ An SPDX License List Short Form Identifier with a unary"+" operator suffix to represent the current version of the license or any later version.  For example: @GPL-2.0+@
        | ELicenseRef LicenseRef
          -- ^ A SPDX user defined license reference: For example: @LicenseRef-23@, @LicenseRef-MIT-Style-1@, or @DocumentRef-spdx-tool-1.2:LicenseRef-MIT-Style-2@
        deriving (Int -> SimpleLicenseExpression -> ShowS
    [SimpleLicenseExpression] -> ShowS
    SimpleLicenseExpression -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [SimpleLicenseExpression] -> ShowS
    $cshowList :: [SimpleLicenseExpression] -> ShowS
    show :: SimpleLicenseExpression -> String
    $cshow :: SimpleLicenseExpression -> String
    showsPrec :: Int -> SimpleLicenseExpression -> ShowS
    $cshowsPrec :: Int -> SimpleLicenseExpression -> ShowS
    Show, ReadPrec [SimpleLicenseExpression]
    ReadPrec SimpleLicenseExpression
    Int -> ReadS SimpleLicenseExpression
    ReadS [SimpleLicenseExpression]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [SimpleLicenseExpression]
    $creadListPrec :: ReadPrec [SimpleLicenseExpression]
    readPrec :: ReadPrec SimpleLicenseExpression
    $creadPrec :: ReadPrec SimpleLicenseExpression
    readList :: ReadS [SimpleLicenseExpression]
    $creadList :: ReadS [SimpleLicenseExpression]
    readsPrec :: Int -> ReadS SimpleLicenseExpression
    $creadsPrec :: Int -> ReadS SimpleLicenseExpression
    Read, SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    $c/= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    == :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    $c== :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    Eq, Eq SimpleLicenseExpression
    SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    SimpleLicenseExpression -> SimpleLicenseExpression -> Ordering
    SimpleLicenseExpression
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: SimpleLicenseExpression
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    $cmin :: SimpleLicenseExpression
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    max :: SimpleLicenseExpression
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    $cmax :: SimpleLicenseExpression
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    >= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    $c>= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    > :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    $c> :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    <= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    $c<= :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    < :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    $c< :: SimpleLicenseExpression -> SimpleLicenseExpression -> Bool
    compare :: SimpleLicenseExpression -> SimpleLicenseExpression -> Ordering
    $ccompare :: SimpleLicenseExpression -> SimpleLicenseExpression -> Ordering
    Ord, Typeable, Typeable SimpleLicenseExpression
    SimpleLicenseExpression -> DataType
    SimpleLicenseExpression -> Constr
    (forall b. Data b => b -> b)
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> SimpleLicenseExpression -> u
    forall u.
    (forall d. Data d => d -> u) -> SimpleLicenseExpression -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r
    -> (forall d. Data d => d -> r')
    -> SimpleLicenseExpression
    -> r
    forall r r'.
    (r' -> r -> r)
    -> r
    -> (forall d. Data d => d -> r')
    -> SimpleLicenseExpression
    -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SimpleLicenseExpression
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> SimpleLicenseExpression
    -> c SimpleLicenseExpression
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SimpleLicenseExpression)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c SimpleLicenseExpression)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> SimpleLicenseExpression -> m SimpleLicenseExpression
    gmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> SimpleLicenseExpression -> u
    $cgmapQi :: forall u.
    Int -> (forall d. Data d => d -> u) -> SimpleLicenseExpression -> u
    gmapQ :: forall u.
    (forall d. Data d => d -> u) -> SimpleLicenseExpression -> [u]
    $cgmapQ :: forall u.
    (forall d. Data d => d -> u) -> SimpleLicenseExpression -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r
    -> (forall d. Data d => d -> r')
    -> SimpleLicenseExpression
    -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r
    -> (forall d. Data d => d -> r')
    -> SimpleLicenseExpression
    -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r
    -> (forall d. Data d => d -> r')
    -> SimpleLicenseExpression
    -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r
    -> (forall d. Data d => d -> r')
    -> SimpleLicenseExpression
    -> r
    gmapT :: (forall b. Data b => b -> b)
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    $cgmapT :: (forall b. Data b => b -> b)
    -> SimpleLicenseExpression -> SimpleLicenseExpression
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c SimpleLicenseExpression)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c SimpleLicenseExpression)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SimpleLicenseExpression)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SimpleLicenseExpression)
    dataTypeOf :: SimpleLicenseExpression -> DataType
    $cdataTypeOf :: SimpleLicenseExpression -> DataType
    toConstr :: SimpleLicenseExpression -> Constr
    $ctoConstr :: SimpleLicenseExpression -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SimpleLicenseExpression
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SimpleLicenseExpression
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> SimpleLicenseExpression
    -> c SimpleLicenseExpression
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> SimpleLicenseExpression
    -> c SimpleLicenseExpression
    Data, forall x. Rep SimpleLicenseExpression x -> SimpleLicenseExpression
    forall x. SimpleLicenseExpression -> Rep SimpleLicenseExpression x
    forall a.
    (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
    $cto :: forall x. Rep SimpleLicenseExpression x -> SimpleLicenseExpression
    $cfrom :: forall x. SimpleLicenseExpression -> Rep SimpleLicenseExpression x
    Generic)

    simpleLicenseExpression :: LicenseId -> LicenseExpression
    simpleLicenseExpression :: LicenseId -> LicenseExpression
    simpleLicenseExpression LicenseId
    i = SimpleLicenseExpression
    -> Maybe LicenseExceptionId -> LicenseExpression
    ELicense (LicenseId -> SimpleLicenseExpression
    ELicenseId LicenseId
    i) forall a. Maybe a
    Nothing

    instance Binary LicenseExpression
    instance Binary SimpleLicenseExpression
    instance Structured SimpleLicenseExpression
    instance Structured LicenseExpression

    instance Pretty LicenseExpression where
        pretty :: LicenseExpression -> Doc
    pretty = Int -> LicenseExpression -> Doc
    go Int
    0
          where
            go :: Int -> LicenseExpression -> Disp.Doc
            go :: Int -> LicenseExpression -> Doc
    go Int
    _ (ELicense SimpleLicenseExpression
    lic Maybe LicenseExceptionId
    exc) =
                let doc :: Doc
    doc = forall a. Pretty a => a -> Doc
    pretty SimpleLicenseExpression
    lic
                in forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. a -> a
    id (\LicenseExceptionId
    e Doc
    d -> Doc
    d Doc -> Doc -> Doc
    <+> String -> Doc
    Disp.text String
    "WITH" Doc -> Doc -> Doc
    <+> forall a. Pretty a => a -> Doc
    pretty LicenseExceptionId
    e) Maybe LicenseExceptionId
    exc Doc
    doc
            go Int
    d (EAnd LicenseExpression
    e1 LicenseExpression
    e2) = Bool -> Doc -> Doc
    parens (Int
    d forall a. Ord a => a -> a -> Bool
    < Int
    0) forall a b. (a -> b) -> a -> b
    $ Int -> LicenseExpression -> Doc
    go Int
    0 LicenseExpression
    e1 Doc -> Doc -> Doc
    <+> String -> Doc
    Disp.text String
    "AND" Doc -> Doc -> Doc
    <+> Int -> LicenseExpression -> Doc
    go Int
    0 LicenseExpression
    e2
            go Int
    d (EOr  LicenseExpression
    e1 LicenseExpression
    e2) = Bool -> Doc -> Doc
    parens (Int
    d forall a. Ord a => a -> a -> Bool
    < Int
    1) forall a b. (a -> b) -> a -> b
    $ Int -> LicenseExpression -> Doc
    go Int
    1 LicenseExpression
    e1 Doc -> Doc -> Doc
    <+> String -> Doc
    Disp.text String
    "OR" Doc -> Doc -> Doc
    <+> Int -> LicenseExpression -> Doc
    go Int
    1 LicenseExpression
    e2

            parens :: Bool -> Doc -> Doc
    parens Bool
    False Doc
    doc = Doc
    doc
            parens Bool
    True  Doc
    doc = Doc -> Doc
    Disp.parens Doc
    doc

    instance Pretty SimpleLicenseExpression where
        pretty :: SimpleLicenseExpression -> Doc
    pretty (ELicenseId LicenseId
    i)     = forall a. Pretty a => a -> Doc
    pretty LicenseId
    i
        pretty (ELicenseIdPlus LicenseId
    i) = forall a. Pretty a => a -> Doc
    pretty LicenseId
    i Doc -> Doc -> Doc
    <<>> Char -> Doc
    Disp.char Char
    '+'
        pretty (ELicenseRef LicenseRef
    r)    = forall a. Pretty a => a -> Doc
    pretty LicenseRef
    r

    instance Parsec SimpleLicenseExpression where
        parsec :: forall (m :: * -> *). CabalParsing m => m SimpleLicenseExpression
    parsec = forall (m :: * -> *). CharParsing m => m String
    idstring forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= forall {m :: * -> *}.
    CabalParsing m =>
    String -> m SimpleLicenseExpression
    simple where
            simple :: String -> m SimpleLicenseExpression
    simple String
    n
                | Just String
    l <- String
    "LicenseRef-" forall a. Eq a => [a] -> [a] -> Maybe [a]
    `isPrefixOfMaybe` String
    n =
                    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
    fail forall a b. (a -> b) -> a -> b
    $ String
    "Incorrect LicenseRef format: " forall a. [a] -> [a] -> [a]
    ++ String
    n) (forall (m :: * -> *) a. Monad m => a -> m a
    return forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LicenseRef -> SimpleLicenseExpression
    ELicenseRef) forall a b. (a -> b) -> a -> b
    $ Maybe String -> String -> Maybe LicenseRef
    mkLicenseRef forall a. Maybe a
    Nothing String
    l
                | Just String
    d <- String
    "DocumentRef-" forall a. Eq a => [a] -> [a] -> Maybe [a]
    `isPrefixOfMaybe` String
    n = do
                    String
    _ <- forall (m :: * -> *). CharParsing m => String -> m String
    P.string String
    ":LicenseRef-"
                    String
    l <- forall (m :: * -> *). CharParsing m => m String
    idstring
                    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
    fail forall a b. (a -> b) -> a -> b
    $ String
    "Incorrect LicenseRef format:" forall a. [a] -> [a] -> [a]
    ++ String
    n) (forall (m :: * -> *) a. Monad m => a -> m a
    return forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LicenseRef -> SimpleLicenseExpression
    ELicenseRef) forall a b. (a -> b) -> a -> b
    $ Maybe String -> String -> Maybe LicenseRef
    mkLicenseRef (forall a. a -> Maybe a
    Just String
    d) String
    l
                | Bool
    otherwise = do
                    CabalSpecVersion
    v <- forall (m :: * -> *). CabalParsing m => m CabalSpecVersion
    askCabalSpecVersion
                    LicenseId
    l <- forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (forall (m :: * -> *) a. MonadFail m => String -> m a
    fail forall a b. (a -> b) -> a -> b
    $ String
    "Unknown SPDX license identifier: '" forall a. [a] -> [a] -> [a]
    ++  String
    n forall a. [a] -> [a] -> [a]
    ++ String
    "' " forall a. [a] -> [a] -> [a]
    ++ ShowS
    licenseIdMigrationMessage String
    n) forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $
                        LicenseListVersion -> String -> Maybe LicenseId
    mkLicenseId (CabalSpecVersion -> LicenseListVersion
    cabalSpecVersionToSPDXListVersion CabalSpecVersion
    v) String
    n
                    Bool
    orLater <- forall a. Maybe a -> Bool
    isJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    P.optional (forall (m :: * -> *). CharParsing m => Char -> m Char
    P.char Char
    '+')
                    if Bool
    orLater
                    then forall (m :: * -> *) a. Monad m => a -> m a
    return (LicenseId -> SimpleLicenseExpression
    ELicenseIdPlus LicenseId
    l)
                    else forall (m :: * -> *) a. Monad m => a -> m a
    return (LicenseId -> SimpleLicenseExpression
    ELicenseId LicenseId
    l)

    idstring :: P.CharParsing m => m String
    idstring :: forall (m :: * -> *). CharParsing m => m String
    idstring = forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m String
    P.munch1 forall a b. (a -> b) -> a -> b
    $ \Char
    c -> Char -> Bool
    isAsciiAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '-' Bool -> Bool -> Bool
    || Char
    c forall a. Eq a => a -> a -> Bool
    == Char
    '.'

    -- returns suffix part
    isPrefixOfMaybe :: Eq a => [a] -> [a] -> Maybe [a]
    isPrefixOfMaybe :: forall a. Eq a => [a] -> [a] -> Maybe [a]
    isPrefixOfMaybe [a]
    pfx [a]
    s
        | [a]
    pfx forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` [a]
    s = forall a. a -> Maybe a
    Just (forall a. Int -> [a] -> [a]
    drop (forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    pfx) [a]
    s)
        | Bool
    otherwise          = forall a. Maybe a
    Nothing

    instance Parsec LicenseExpression where
        parsec :: forall (m :: * -> *). CabalParsing m => m LicenseExpression
    parsec = m LicenseExpression
    expr
          where
            expr :: m LicenseExpression
    expr = m LicenseExpression
    compoundOr

            simple :: m LicenseExpression
    simple = do
                SimpleLicenseExpression
    s <- forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
    parsec
                Maybe LicenseExceptionId
    exc <- m (Maybe LicenseExceptionId)
    exception
                forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $ SimpleLicenseExpression
    -> Maybe LicenseExceptionId -> LicenseExpression
    ELicense SimpleLicenseExpression
    s Maybe LicenseExceptionId
    exc

            exception :: m (Maybe LicenseExceptionId)
    exception = forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    P.optional forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *) a. Parsing m => m a -> m a
    P.try (m ()
    spaces1 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> forall (m :: * -> *). CharParsing m => String -> m String
    P.string String
    "WITH" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> m ()
    spaces1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
    parsec

            compoundOr :: m LicenseExpression
    compoundOr = do
                LicenseExpression
    x <- m LicenseExpression
    compoundAnd
                Maybe LicenseExpression
    l <- forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    P.optional forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *) a. Parsing m => m a -> m a
    P.try (m ()
    spaces1 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> forall (m :: * -> *). CharParsing m => String -> m String
    P.string String
    "OR" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> m ()
    spaces1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> m LicenseExpression
    compoundOr
                forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $ forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. a -> a
    id (forall a b c. (a -> b -> c) -> b -> a -> c
    flip LicenseExpression -> LicenseExpression -> LicenseExpression
    EOr) Maybe LicenseExpression
    l LicenseExpression
    x

            compoundAnd :: m LicenseExpression
    compoundAnd = do
                LicenseExpression
    x <- m LicenseExpression
    compound
                Maybe LicenseExpression
    l <- forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
    P.optional forall a b. (a -> b) -> a -> b
    $ forall (m :: * -> *) a. Parsing m => m a -> m a
    P.try (m ()
    spaces1 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> forall (m :: * -> *). CharParsing m => String -> m String
    P.string String
    "AND" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> m ()
    spaces1) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> m LicenseExpression
    compoundAnd
                forall (m :: * -> *) a. Monad m => a -> m a
    return forall a b. (a -> b) -> a -> b
    $ forall b a. b -> (a -> b) -> Maybe a -> b
    maybe forall a. a -> a
    id (forall a b c. (a -> b -> c) -> b -> a -> c
    flip LicenseExpression -> LicenseExpression -> LicenseExpression
    EAnd) Maybe LicenseExpression
    l LicenseExpression
    x

            compound :: m LicenseExpression
    compound = m LicenseExpression
    braces forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> m LicenseExpression
    simple

            -- NOTE: we require that there's a space around AND & OR operators,
            -- i.e. @(MIT)AND(MIT)@ will cause parse-error.
            braces :: m LicenseExpression
    braces = do
                Char
    _ <- forall (m :: * -> *). CharParsing m => Char -> m Char
    P.char Char
    '('
                ()
    _ <- forall (m :: * -> *). CharParsing m => m ()
    P.spaces
                LicenseExpression
    x <- m LicenseExpression
    expr
                Char
    _ <- forall (m :: * -> *). CharParsing m => Char -> m Char
    P.char Char
    ')'
                forall (m :: * -> *) a. Monad m => a -> m a
    return LicenseExpression
    x

            spaces1 :: m ()
    spaces1 = forall (m :: * -> *). CharParsing m => m Char
    P.space forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> forall (m :: * -> *). CharParsing m => m ()
    P.spaces

    -- notes:
    --
    -- There MUST NOT be whitespace between a licenseid and any following "+".  This supports easy parsing and
    -- backwards compatibility.  There MUST be whitespace on either side of the operator "WITH".  There MUST be
    -- whitespace and/or parentheses on either side of the operators "AND" and "OR".
    --
    -- We handle that by having greedy 'idstring' parser, so MITAND would parse as invalid license identifier.

    instance NFData LicenseExpression where
        rnf :: LicenseExpression -> ()
    rnf (ELicense SimpleLicenseExpression
    s Maybe LicenseExceptionId
    e) = forall a. NFData a => a -> ()
    rnf SimpleLicenseExpression
    s seq :: forall a b. a -> b -> b
    `seq` forall a. NFData a => a -> ()
    rnf Maybe LicenseExceptionId
    e
        rnf (EAnd LicenseExpression
    x LicenseExpression
    y)     = forall a. NFData a => a -> ()
    rnf LicenseExpression
    x seq :: forall a b. a -> b -> b
    `seq` forall a. NFData a => a -> ()
    rnf LicenseExpression
    y
        rnf (EOr LicenseExpression
    x LicenseExpression
    y)      = forall a. NFData a => a -> ()
    rnf LicenseExpression
    x seq :: forall a b. a -> b -> b
    `seq` forall a. NFData a => a -> ()
    rnf LicenseExpression
    y

    instance NFData SimpleLicenseExpression where
        rnf :: SimpleLicenseExpression -> ()
    rnf (ELicenseId LicenseId
    i)     = forall a. NFData a => a -> ()
    rnf LicenseId
    i
        rnf (ELicenseIdPlus LicenseId
    i) = forall a. NFData a => a -> ()
    rnf LicenseId
    i
        rnf (ELicenseRef LicenseRef
    r)    = forall a. NFData a => a -> ()
    rnf LicenseRef
    r