{-# 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
(Int -> LicenseExpression -> ShowS)
-> (LicenseExpression -> String)
-> ([LicenseExpression] -> ShowS)
-> Show LicenseExpression
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LicenseExpression -> ShowS
showsPrec :: Int -> LicenseExpression -> ShowS
$cshow :: LicenseExpression -> String
show :: LicenseExpression -> String
$cshowList :: [LicenseExpression] -> ShowS
showList :: [LicenseExpression] -> ShowS
Show, ReadPrec [LicenseExpression]
ReadPrec LicenseExpression
Int -> ReadS LicenseExpression
ReadS [LicenseExpression]
(Int -> ReadS LicenseExpression)
-> ReadS [LicenseExpression]
-> ReadPrec LicenseExpression
-> ReadPrec [LicenseExpression]
-> Read LicenseExpression
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS LicenseExpression
readsPrec :: Int -> ReadS LicenseExpression
$creadList :: ReadS [LicenseExpression]
readList :: ReadS [LicenseExpression]
$creadPrec :: ReadPrec LicenseExpression
readPrec :: ReadPrec LicenseExpression
$creadListPrec :: ReadPrec [LicenseExpression]
readListPrec :: ReadPrec [LicenseExpression]
Read, LicenseExpression -> LicenseExpression -> Bool
(LicenseExpression -> LicenseExpression -> Bool)
-> (LicenseExpression -> LicenseExpression -> Bool)
-> Eq LicenseExpression
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: LicenseExpression -> LicenseExpression -> Bool
== :: LicenseExpression -> LicenseExpression -> Bool
$c/= :: LicenseExpression -> LicenseExpression -> Bool
/= :: LicenseExpression -> LicenseExpression -> Bool
Eq, Eq LicenseExpression
Eq LicenseExpression =>
(LicenseExpression -> LicenseExpression -> Ordering)
-> (LicenseExpression -> LicenseExpression -> Bool)
-> (LicenseExpression -> LicenseExpression -> Bool)
-> (LicenseExpression -> LicenseExpression -> Bool)
-> (LicenseExpression -> LicenseExpression -> Bool)
-> (LicenseExpression -> LicenseExpression -> LicenseExpression)
-> (LicenseExpression -> LicenseExpression -> LicenseExpression)
-> Ord 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
$ccompare :: LicenseExpression -> LicenseExpression -> Ordering
compare :: LicenseExpression -> LicenseExpression -> Ordering
$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
>= :: LicenseExpression -> LicenseExpression -> Bool
$cmax :: LicenseExpression -> LicenseExpression -> LicenseExpression
max :: LicenseExpression -> LicenseExpression -> LicenseExpression
$cmin :: LicenseExpression -> LicenseExpression -> LicenseExpression
min :: LicenseExpression -> LicenseExpression -> LicenseExpression
Ord, Typeable, Typeable LicenseExpression
Typeable LicenseExpression =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g)
 -> LicenseExpression
 -> c LicenseExpression)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c LicenseExpression)
-> (LicenseExpression -> Constr)
-> (LicenseExpression -> DataType)
-> (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))
-> ((forall b. Data b => b -> b)
    -> LicenseExpression -> LicenseExpression)
-> (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 u.
    (forall d. Data d => d -> u) -> LicenseExpression -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u)
-> (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 (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> LicenseExpression -> m LicenseExpression)
-> Data LicenseExpression
LicenseExpression -> Constr
LicenseExpression -> DataType
(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)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> LicenseExpression -> c LicenseExpression
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LicenseExpression
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c LicenseExpression
$ctoConstr :: LicenseExpression -> Constr
toConstr :: LicenseExpression -> Constr
$cdataTypeOf :: LicenseExpression -> DataType
dataTypeOf :: LicenseExpression -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c LicenseExpression)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LicenseExpression)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c LicenseExpression)
$cgmapT :: (forall b. Data b => b -> b)
-> LicenseExpression -> LicenseExpression
gmapT :: (forall b. Data b => b -> b)
-> LicenseExpression -> LicenseExpression
$cgmapQl :: 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
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> LicenseExpression -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> LicenseExpression -> [u]
$cgmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> LicenseExpression -> u
$cgmapM :: forall (m :: * -> *).
Monad 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
$cgmapMp :: 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
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> LicenseExpression -> m LicenseExpression
Data, (forall x. LicenseExpression -> Rep LicenseExpression x)
-> (forall x. Rep LicenseExpression x -> LicenseExpression)
-> Generic LicenseExpression
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
$cfrom :: forall x. LicenseExpression -> Rep LicenseExpression x
from :: forall x. LicenseExpression -> Rep LicenseExpression x
$cto :: forall x. Rep LicenseExpression x -> LicenseExpression
to :: forall x. Rep LicenseExpression x -> LicenseExpression
Generic)

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

simpleLicenseExpression :: LicenseId -> LicenseExpression
simpleLicenseExpression :: LicenseId -> LicenseExpression
simpleLicenseExpression LicenseId
i = SimpleLicenseExpression
-> Maybe LicenseExceptionId -> LicenseExpression
ELicense (LicenseId -> SimpleLicenseExpression
ELicenseId LicenseId
i) Maybe LicenseExceptionId
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 = SimpleLicenseExpression -> Doc
forall a. Pretty a => a -> Doc
pretty SimpleLicenseExpression
lic
         in (Doc -> Doc)
-> (LicenseExceptionId -> Doc -> Doc)
-> Maybe LicenseExceptionId
-> Doc
-> Doc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc -> Doc
forall a. a -> a
id (\LicenseExceptionId
e Doc
d -> Doc
d Doc -> Doc -> Doc
<+> String -> Doc
Disp.text String
"WITH" Doc -> Doc -> Doc
<+> LicenseExceptionId -> 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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (Doc -> Doc) -> Doc -> Doc
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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1) (Doc -> Doc) -> Doc -> Doc
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) = LicenseId -> Doc
forall a. Pretty a => a -> Doc
pretty LicenseId
i
  pretty (ELicenseIdPlus LicenseId
i) = LicenseId -> Doc
forall a. Pretty a => a -> Doc
pretty LicenseId
i Doc -> Doc -> Doc
<<>> Char -> Doc
Disp.char Char
'+'
  pretty (ELicenseRef LicenseRef
r) = LicenseRef -> Doc
forall a. Pretty a => a -> Doc
pretty LicenseRef
r

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

idstring :: P.CharParsing m => m String
idstring :: forall (m :: * -> *). CharParsing m => m String
idstring = (Char -> Bool) -> m String
forall (m :: * -> *). CharParsing m => (Char -> Bool) -> m String
P.munch1 ((Char -> Bool) -> m String) -> (Char -> Bool) -> m String
forall a b. (a -> b) -> a -> b
$ \Char
c -> Char -> Bool
isAsciiAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-' Bool -> Bool -> Bool
|| Char
c Char -> Char -> Bool
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 [a] -> [a] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [a]
s = [a] -> Maybe [a]
forall a. a -> Maybe a
Just (Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
pfx) [a]
s)
  | Bool
otherwise = Maybe [a]
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
        s <- m SimpleLicenseExpression
forall a (m :: * -> *). (Parsec a, CabalParsing m) => m a
forall (m :: * -> *). CabalParsing m => m SimpleLicenseExpression
parsec
        exc <- exception
        return $ ELicense s exc

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

      compoundOr :: m LicenseExpression
compoundOr = do
        x <- m LicenseExpression
compoundAnd
        l <- P.optional $ P.try (spaces1 *> P.string "OR" *> spaces1) *> compoundOr
        return $ maybe id (flip EOr) l x

      compoundAnd :: m LicenseExpression
compoundAnd = do
        x <- m LicenseExpression
compound
        l <- P.optional $ P.try (spaces1 *> P.string "AND" *> spaces1) *> compoundAnd
        return $ maybe id (flip EAnd) l x

      compound :: m LicenseExpression
compound = m LicenseExpression
braces m LicenseExpression -> m LicenseExpression -> m LicenseExpression
forall a. m a -> m a -> m a
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 -> m Char
forall (m :: * -> *). CharParsing m => Char -> m Char
P.char Char
'('
        _ <- P.spaces
        x <- expr
        _ <- P.char ')'
        return x

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

-- notes:
--
-- There MUST NOT be whitespace between a license­id 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) = SimpleLicenseExpression -> ()
forall a. NFData a => a -> ()
rnf SimpleLicenseExpression
s () -> () -> ()
forall a b. a -> b -> b
`seq` Maybe LicenseExceptionId -> ()
forall a. NFData a => a -> ()
rnf Maybe LicenseExceptionId
e
  rnf (EAnd LicenseExpression
x LicenseExpression
y) = LicenseExpression -> ()
forall a. NFData a => a -> ()
rnf LicenseExpression
x () -> () -> ()
forall a b. a -> b -> b
`seq` LicenseExpression -> ()
forall a. NFData a => a -> ()
rnf LicenseExpression
y
  rnf (EOr LicenseExpression
x LicenseExpression
y) = LicenseExpression -> ()
forall a. NFData a => a -> ()
rnf LicenseExpression
x () -> () -> ()
forall a b. a -> b -> b
`seq` LicenseExpression -> ()
forall a. NFData a => a -> ()
rnf LicenseExpression
y

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