{-# LANGUAGE DuplicateRecordFields #-}

-- | The abstract syntax tree of FTL, the <https://projectfluent.org Project Fluent> file format.
--
-- The documentation of each type links to the relevant chapter of the
-- <https://projectfluent.org/fluent/guide/ Fluent Syntax Guide>.
--
-- The normative reference is the <https://github.com/projectfluent/fluent/blob/master/spec/fluent.ebnf grammar>.
module Language.Fluent.AST where

import Data.Hashable (Hashable)
import Data.List.NonEmpty (NonEmpty)
import Data.Text (Text)
import GHC.Generics (Generic)
import Prelude

-- | An entire FTL file
newtype Resource = Resource {Resource -> [Entry]
entries :: [Entry]}
    deriving stock ((forall x. Resource -> Rep Resource x)
-> (forall x. Rep Resource x -> Resource) -> Generic Resource
forall x. Rep Resource x -> Resource
forall x. Resource -> Rep Resource x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Resource -> Rep Resource x
from :: forall x. Resource -> Rep Resource x
$cto :: forall x. Rep Resource x -> Resource
to :: forall x. Rep Resource x -> Resource
Generic, Resource -> Resource -> Bool
(Resource -> Resource -> Bool)
-> (Resource -> Resource -> Bool) -> Eq Resource
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Resource -> Resource -> Bool
== :: Resource -> Resource -> Bool
$c/= :: Resource -> Resource -> Bool
/= :: Resource -> Resource -> Bool
Eq, Int -> Resource -> ShowS
[Resource] -> ShowS
Resource -> String
(Int -> Resource -> ShowS)
-> (Resource -> String) -> ([Resource] -> ShowS) -> Show Resource
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Resource -> ShowS
showsPrec :: Int -> Resource -> ShowS
$cshow :: Resource -> String
show :: Resource -> String
$cshowList :: [Resource] -> ShowS
showList :: [Resource] -> ShowS
Show)

-- | A top-level element of a t'Resource'
data Entry
    = -- | A t'Message': @hello = Hello, world!@
      MessageEntry Message
    | -- | A t'Term': @-brand-name = Fluent@
      TermEntry Term
    | -- | A standalone @#@ comment, not attached to a t'Message' or t'Term'.
      CommentEntry Comment
    | -- | A @##@ comment, describing the group of entries that follows it.
      GroupCommentEntry Comment
    | -- | A @###@ comment, describing the whole t'Resource'.
      ResourceCommentEntry Comment
    | -- | Source text which could not be parsed, preserved verbatim.
      -- See <https://projectfluent.org/fluent/guide/ the guide> on error recovery.
      JunkEntry Text
    deriving stock ((forall x. Entry -> Rep Entry x)
-> (forall x. Rep Entry x -> Entry) -> Generic Entry
forall x. Rep Entry x -> Entry
forall x. Entry -> Rep Entry x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Entry -> Rep Entry x
from :: forall x. Entry -> Rep Entry x
$cto :: forall x. Rep Entry x -> Entry
to :: forall x. Rep Entry x -> Entry
Generic, Entry -> Entry -> Bool
(Entry -> Entry -> Bool) -> (Entry -> Entry -> Bool) -> Eq Entry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Entry -> Entry -> Bool
== :: Entry -> Entry -> Bool
$c/= :: Entry -> Entry -> Bool
/= :: Entry -> Entry -> Bool
Eq, Int -> Entry -> ShowS
[Entry] -> ShowS
Entry -> String
(Int -> Entry -> ShowS)
-> (Entry -> String) -> ([Entry] -> ShowS) -> Show Entry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Entry -> ShowS
showsPrec :: Int -> Entry -> ShowS
$cshow :: Entry -> String
show :: Entry -> String
$cshowList :: [Entry] -> ShowS
showList :: [Entry] -> ShowS
Show)

-- | A translation unit. Either the @value@ or the @attributes@ must be present.
data Message = Message
    { Message -> Identifier
id :: Identifier
    -- ^ The name by which the message is referenced, e.g. @hello@.
    , Message -> Maybe Pattern
value :: Maybe Pattern
    -- ^ The translation itself.
    , Message -> [Attribute]
attributes :: [Attribute]
    -- ^ Additional translations belonging to this message.
    , Message -> Maybe Comment
comment :: Maybe Comment
    -- ^ The @#@ comment directly above the message, if any.
    }
    deriving stock ((forall x. Message -> Rep Message x)
-> (forall x. Rep Message x -> Message) -> Generic Message
forall x. Rep Message x -> Message
forall x. Message -> Rep Message x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Message -> Rep Message x
from :: forall x. Message -> Rep Message x
$cto :: forall x. Rep Message x -> Message
to :: forall x. Rep Message x -> Message
Generic, Message -> Message -> Bool
(Message -> Message -> Bool)
-> (Message -> Message -> Bool) -> Eq Message
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Message -> Message -> Bool
== :: Message -> Message -> Bool
$c/= :: Message -> Message -> Bool
/= :: Message -> Message -> Bool
Eq, Int -> Message -> ShowS
[Message] -> ShowS
Message -> String
(Int -> Message -> ShowS)
-> (Message -> String) -> ([Message] -> ShowS) -> Show Message
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Message -> ShowS
showsPrec :: Int -> Message -> ShowS
$cshow :: Message -> String
show :: Message -> String
$cshowList :: [Message] -> ShowS
showList :: [Message] -> ShowS
Show)

-- | A translation unit which is only ever referenced by other translations.
-- See <https://projectfluent.org/fluent/guide/terms.html Terms>.
data Term = Term
    { Term -> Identifier
id :: Identifier
    -- ^ The name by which the term is referenced, without the leading @-@.
    -- e.g. @brand-name@ in @-brand-name@.
    , Term -> Pattern
value :: Pattern
    -- ^ The translation itself; unlike a t'Message', a term always has one.
    , Term -> [Attribute]
attributes :: [Attribute]
    -- ^ Additional translations belonging to this term, often grammatical
    -- properties such as gender or case.
    , Term -> Maybe Comment
comment :: Maybe Comment
    -- ^ The @#@ comment directly above the term, if any.
    }
    deriving stock ((forall x. Term -> Rep Term x)
-> (forall x. Rep Term x -> Term) -> Generic Term
forall x. Rep Term x -> Term
forall x. Term -> Rep Term x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Term -> Rep Term x
from :: forall x. Term -> Rep Term x
$cto :: forall x. Rep Term x -> Term
to :: forall x. Rep Term x -> Term
Generic, Term -> Term -> Bool
(Term -> Term -> Bool) -> (Term -> Term -> Bool) -> Eq Term
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Term -> Term -> Bool
== :: Term -> Term -> Bool
$c/= :: Term -> Term -> Bool
/= :: Term -> Term -> Bool
Eq, Int -> Term -> ShowS
[Term] -> ShowS
Term -> String
(Int -> Term -> ShowS)
-> (Term -> String) -> ([Term] -> ShowS) -> Show Term
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Term -> ShowS
showsPrec :: Int -> Term -> ShowS
$cshow :: Term -> String
show :: Term -> String
$cshowList :: [Term] -> ShowS
showList :: [Term] -> ShowS
Show)

-- | The text of a comment, with the @#@ prefixes and the space following them removed.
-- See <https://projectfluent.org/fluent/guide/comments.html Comments>.
newtype Comment = Comment Text
    deriving stock ((forall x. Comment -> Rep Comment x)
-> (forall x. Rep Comment x -> Comment) -> Generic Comment
forall x. Rep Comment x -> Comment
forall x. Comment -> Rep Comment x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Comment -> Rep Comment x
from :: forall x. Comment -> Rep Comment x
$cto :: forall x. Rep Comment x -> Comment
to :: forall x. Rep Comment x -> Comment
Generic, Comment -> Comment -> Bool
(Comment -> Comment -> Bool)
-> (Comment -> Comment -> Bool) -> Eq Comment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Comment -> Comment -> Bool
== :: Comment -> Comment -> Bool
$c/= :: Comment -> Comment -> Bool
/= :: Comment -> Comment -> Bool
Eq, Int -> Comment -> ShowS
[Comment] -> ShowS
Comment -> String
(Int -> Comment -> ShowS)
-> (Comment -> String) -> ([Comment] -> ShowS) -> Show Comment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Comment -> ShowS
showsPrec :: Int -> Comment -> ShowS
$cshow :: Comment -> String
show :: Comment -> String
$cshowList :: [Comment] -> ShowS
showList :: [Comment] -> ShowS
Show)

-- | A named t'Pattern' belonging to a t'Message' or a t'Term', written as
-- @.key = value@ on a line of its own.
-- See <https://projectfluent.org/fluent/guide/attributes.html Attributes>.
data Attribute = Attribute Identifier Pattern
    deriving stock ((forall x. Attribute -> Rep Attribute x)
-> (forall x. Rep Attribute x -> Attribute) -> Generic Attribute
forall x. Rep Attribute x -> Attribute
forall x. Attribute -> Rep Attribute x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Attribute -> Rep Attribute x
from :: forall x. Attribute -> Rep Attribute x
$cto :: forall x. Rep Attribute x -> Attribute
to :: forall x. Rep Attribute x -> Attribute
Generic, Attribute -> Attribute -> Bool
(Attribute -> Attribute -> Bool)
-> (Attribute -> Attribute -> Bool) -> Eq Attribute
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Attribute -> Attribute -> Bool
== :: Attribute -> Attribute -> Bool
$c/= :: Attribute -> Attribute -> Bool
/= :: Attribute -> Attribute -> Bool
Eq, Int -> Attribute -> ShowS
[Attribute] -> ShowS
Attribute -> String
(Int -> Attribute -> ShowS)
-> (Attribute -> String)
-> ([Attribute] -> ShowS)
-> Show Attribute
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Attribute -> ShowS
showsPrec :: Int -> Attribute -> ShowS
$cshow :: Attribute -> String
show :: Attribute -> String
$cshowList :: [Attribute] -> ShowS
showList :: [Attribute] -> ShowS
Show)

-- | The value of a t'Message', t'Term', t'Attribute' or t'Variant': text interspersed
-- with placeables.
-- See <https://projectfluent.org/fluent/guide/text.html Writing Text>.
newtype Pattern = Pattern (NonEmpty PatternElement)
    deriving stock ((forall x. Pattern -> Rep Pattern x)
-> (forall x. Rep Pattern x -> Pattern) -> Generic Pattern
forall x. Rep Pattern x -> Pattern
forall x. Pattern -> Rep Pattern x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Pattern -> Rep Pattern x
from :: forall x. Pattern -> Rep Pattern x
$cto :: forall x. Rep Pattern x -> Pattern
to :: forall x. Rep Pattern x -> Pattern
Generic, Pattern -> Pattern -> Bool
(Pattern -> Pattern -> Bool)
-> (Pattern -> Pattern -> Bool) -> Eq Pattern
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Pattern -> Pattern -> Bool
== :: Pattern -> Pattern -> Bool
$c/= :: Pattern -> Pattern -> Bool
/= :: Pattern -> Pattern -> Bool
Eq, Int -> Pattern -> ShowS
[Pattern] -> ShowS
Pattern -> String
(Int -> Pattern -> ShowS)
-> (Pattern -> String) -> ([Pattern] -> ShowS) -> Show Pattern
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Pattern -> ShowS
showsPrec :: Int -> Pattern -> ShowS
$cshow :: Pattern -> String
show :: Pattern -> String
$cshowList :: [Pattern] -> ShowS
showList :: [Pattern] -> ShowS
Show)

-- | A single piece of a t'Pattern'.
data PatternElement
    = -- | Text on the first line of the pattern, or following a t'Placeable'.
      InlineText Text
    | -- | Text on a continuation line, already dedented according to the
      -- <https://projectfluent.org/fluent/guide/multiline.html multiline> rules.
      BlockText Text
    | Placeable Placeable
    deriving stock ((forall x. PatternElement -> Rep PatternElement x)
-> (forall x. Rep PatternElement x -> PatternElement)
-> Generic PatternElement
forall x. Rep PatternElement x -> PatternElement
forall x. PatternElement -> Rep PatternElement x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. PatternElement -> Rep PatternElement x
from :: forall x. PatternElement -> Rep PatternElement x
$cto :: forall x. Rep PatternElement x -> PatternElement
to :: forall x. Rep PatternElement x -> PatternElement
Generic, PatternElement -> PatternElement -> Bool
(PatternElement -> PatternElement -> Bool)
-> (PatternElement -> PatternElement -> Bool) -> Eq PatternElement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PatternElement -> PatternElement -> Bool
== :: PatternElement -> PatternElement -> Bool
$c/= :: PatternElement -> PatternElement -> Bool
/= :: PatternElement -> PatternElement -> Bool
Eq, Int -> PatternElement -> ShowS
[PatternElement] -> ShowS
PatternElement -> String
(Int -> PatternElement -> ShowS)
-> (PatternElement -> String)
-> ([PatternElement] -> ShowS)
-> Show PatternElement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PatternElement -> ShowS
showsPrec :: Int -> PatternElement -> ShowS
$cshow :: PatternElement -> String
show :: PatternElement -> String
$cshowList :: [PatternElement] -> ShowS
showList :: [PatternElement] -> ShowS
Show)

-- | An 'Expression' embedded in a t'Pattern' between braces, e.g. @{ $userName }@.
-- See <https://projectfluent.org/fluent/guide/placeables.html Placeables>.
data Placeable
    = -- | A placeable on the same line as the text preceding it.
      InlinePlaceable Expression
    | -- | A placeable on a continuation line, together with its indentation in
      -- columns, which takes part in computing the common indent of the t'Pattern'.
      BlockPlaceable Int Expression
    deriving stock ((forall x. Placeable -> Rep Placeable x)
-> (forall x. Rep Placeable x -> Placeable) -> Generic Placeable
forall x. Rep Placeable x -> Placeable
forall x. Placeable -> Rep Placeable x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Placeable -> Rep Placeable x
from :: forall x. Placeable -> Rep Placeable x
$cto :: forall x. Rep Placeable x -> Placeable
to :: forall x. Rep Placeable x -> Placeable
Generic, Placeable -> Placeable -> Bool
(Placeable -> Placeable -> Bool)
-> (Placeable -> Placeable -> Bool) -> Eq Placeable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Placeable -> Placeable -> Bool
== :: Placeable -> Placeable -> Bool
$c/= :: Placeable -> Placeable -> Bool
/= :: Placeable -> Placeable -> Bool
Eq, Int -> Placeable -> ShowS
[Placeable] -> ShowS
Placeable -> String
(Int -> Placeable -> ShowS)
-> (Placeable -> String)
-> ([Placeable] -> ShowS)
-> Show Placeable
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Placeable -> ShowS
showsPrec :: Int -> Placeable -> ShowS
$cshow :: Placeable -> String
show :: Placeable -> String
$cshowList :: [Placeable] -> ShowS
showList :: [Placeable] -> ShowS
Show)

-- | The 'Expression' of a t'Placeable', whether inline or block.
placeableExpression :: Placeable -> Expression
placeableExpression :: Placeable -> Expression
placeableExpression (InlinePlaceable Expression
e) = Expression
e
placeableExpression (BlockPlaceable Int
_ Expression
e) = Expression
e

-- | A choice between several t'Variant's, made by matching the selector, an
-- 'InlineExpression', against the t'VariantKey's: @{ $count -> ... }@.
-- See <https://projectfluent.org/fluent/guide/selectors.html Selectors>.
data SelectExpression = SelectExpression InlineExpression VariantList
    deriving stock ((forall x. SelectExpression -> Rep SelectExpression x)
-> (forall x. Rep SelectExpression x -> SelectExpression)
-> Generic SelectExpression
forall x. Rep SelectExpression x -> SelectExpression
forall x. SelectExpression -> Rep SelectExpression x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SelectExpression -> Rep SelectExpression x
from :: forall x. SelectExpression -> Rep SelectExpression x
$cto :: forall x. Rep SelectExpression x -> SelectExpression
to :: forall x. Rep SelectExpression x -> SelectExpression
Generic, SelectExpression -> SelectExpression -> Bool
(SelectExpression -> SelectExpression -> Bool)
-> (SelectExpression -> SelectExpression -> Bool)
-> Eq SelectExpression
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SelectExpression -> SelectExpression -> Bool
== :: SelectExpression -> SelectExpression -> Bool
$c/= :: SelectExpression -> SelectExpression -> Bool
/= :: SelectExpression -> SelectExpression -> Bool
Eq, Int -> SelectExpression -> ShowS
[SelectExpression] -> ShowS
SelectExpression -> String
(Int -> SelectExpression -> ShowS)
-> (SelectExpression -> String)
-> ([SelectExpression] -> ShowS)
-> Show SelectExpression
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SelectExpression -> ShowS
showsPrec :: Int -> SelectExpression -> ShowS
$cshow :: SelectExpression -> String
show :: SelectExpression -> String
$cshowList :: [SelectExpression] -> ShowS
showList :: [SelectExpression] -> ShowS
Show)

-- | An expression which yields a value.
data InlineExpression
    = StringLiteralExpression StringLiteral
    | NumberLiteralExpression NumberLiteral
    | -- | A call of a built-in or implementation-provided function, e.g.
      -- @NUMBER($ratio, minimumFractionDigits: 2)@.
      -- See <https://projectfluent.org/fluent/guide/builtins.html Built-in Functions>
      -- and <https://projectfluent.org/fluent/guide/functions.html Functions>.
      FunctionReference Identifier CallArguments
    | -- | A reference to another t'Message' or one of its attributes.
      -- See <https://projectfluent.org/fluent/guide/references.html Referencing Messages>.
      MessageReference Identifier (Maybe AttributeAccessor)
    | -- | A reference to a t'Term' or one of its attributes, with optional arguments to
      -- parameterise it.
      -- See <https://projectfluent.org/fluent/guide/terms.html Terms>.
      TermReference Identifier (Maybe AttributeAccessor) (Maybe CallArguments)
    | -- | A reference to an argument passed in by the application, e.g. @$userName@.
      -- See <https://projectfluent.org/fluent/guide/variables.html Variables>.
      VariableReference Identifier
    | -- | A placeable nested inside another placeable, used for grouping.
      PlaceableExpression Expression
    deriving stock ((forall x. InlineExpression -> Rep InlineExpression x)
-> (forall x. Rep InlineExpression x -> InlineExpression)
-> Generic InlineExpression
forall x. Rep InlineExpression x -> InlineExpression
forall x. InlineExpression -> Rep InlineExpression x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. InlineExpression -> Rep InlineExpression x
from :: forall x. InlineExpression -> Rep InlineExpression x
$cto :: forall x. Rep InlineExpression x -> InlineExpression
to :: forall x. Rep InlineExpression x -> InlineExpression
Generic, InlineExpression -> InlineExpression -> Bool
(InlineExpression -> InlineExpression -> Bool)
-> (InlineExpression -> InlineExpression -> Bool)
-> Eq InlineExpression
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InlineExpression -> InlineExpression -> Bool
== :: InlineExpression -> InlineExpression -> Bool
$c/= :: InlineExpression -> InlineExpression -> Bool
/= :: InlineExpression -> InlineExpression -> Bool
Eq, Int -> InlineExpression -> ShowS
[InlineExpression] -> ShowS
InlineExpression -> String
(Int -> InlineExpression -> ShowS)
-> (InlineExpression -> String)
-> ([InlineExpression] -> ShowS)
-> Show InlineExpression
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InlineExpression -> ShowS
showsPrec :: Int -> InlineExpression -> ShowS
$cshow :: InlineExpression -> String
show :: InlineExpression -> String
$cshowList :: [InlineExpression] -> ShowS
showList :: [InlineExpression] -> ShowS
Show)

-- | The @.key@ suffix of a reference, selecting an t'Attribute' of the referent.
-- See <https://projectfluent.org/fluent/guide/attributes.html Attributes>.
newtype AttributeAccessor = AttributeAccessor Identifier
    deriving stock ((forall x. AttributeAccessor -> Rep AttributeAccessor x)
-> (forall x. Rep AttributeAccessor x -> AttributeAccessor)
-> Generic AttributeAccessor
forall x. Rep AttributeAccessor x -> AttributeAccessor
forall x. AttributeAccessor -> Rep AttributeAccessor x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AttributeAccessor -> Rep AttributeAccessor x
from :: forall x. AttributeAccessor -> Rep AttributeAccessor x
$cto :: forall x. Rep AttributeAccessor x -> AttributeAccessor
to :: forall x. Rep AttributeAccessor x -> AttributeAccessor
Generic, AttributeAccessor -> AttributeAccessor -> Bool
(AttributeAccessor -> AttributeAccessor -> Bool)
-> (AttributeAccessor -> AttributeAccessor -> Bool)
-> Eq AttributeAccessor
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AttributeAccessor -> AttributeAccessor -> Bool
== :: AttributeAccessor -> AttributeAccessor -> Bool
$c/= :: AttributeAccessor -> AttributeAccessor -> Bool
/= :: AttributeAccessor -> AttributeAccessor -> Bool
Eq, Int -> AttributeAccessor -> ShowS
[AttributeAccessor] -> ShowS
AttributeAccessor -> String
(Int -> AttributeAccessor -> ShowS)
-> (AttributeAccessor -> String)
-> ([AttributeAccessor] -> ShowS)
-> Show AttributeAccessor
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AttributeAccessor -> ShowS
showsPrec :: Int -> AttributeAccessor -> ShowS
$cshow :: AttributeAccessor -> String
show :: AttributeAccessor -> String
$cshowList :: [AttributeAccessor] -> ShowS
showList :: [AttributeAccessor] -> ShowS
Show)

-- | The contents of a t'Placeable'.
-- See <https://projectfluent.org/fluent/guide/placeables.html Placeables>.
data Expression
    = Select SelectExpression
    | Inline InlineExpression
    deriving stock ((forall x. Expression -> Rep Expression x)
-> (forall x. Rep Expression x -> Expression) -> Generic Expression
forall x. Rep Expression x -> Expression
forall x. Expression -> Rep Expression x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Expression -> Rep Expression x
from :: forall x. Expression -> Rep Expression x
$cto :: forall x. Rep Expression x -> Expression
to :: forall x. Rep Expression x -> Expression
Generic, Expression -> Expression -> Bool
(Expression -> Expression -> Bool)
-> (Expression -> Expression -> Bool) -> Eq Expression
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Expression -> Expression -> Bool
== :: Expression -> Expression -> Bool
$c/= :: Expression -> Expression -> Bool
/= :: Expression -> Expression -> Bool
Eq, Int -> Expression -> ShowS
[Expression] -> ShowS
Expression -> String
(Int -> Expression -> ShowS)
-> (Expression -> String)
-> ([Expression] -> ShowS)
-> Show Expression
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Expression -> ShowS
showsPrec :: Int -> Expression -> ShowS
$cshow :: Expression -> String
show :: Expression -> String
$cshowList :: [Expression] -> ShowS
showList :: [Expression] -> ShowS
Show)

-- | One branch of a t'SelectExpression', written as @[key] value@ on a line of its own.
-- See <https://projectfluent.org/fluent/guide/selectors.html Selectors>.
data Variant = Variant
    { Variant -> VariantKey
key :: VariantKey
    -- ^ The value or plural category.
    , Variant -> Pattern
value :: Pattern
    -- ^ The translation for this variant.
    , Variant -> Bool
isDefault :: Bool
    -- ^ Whether the variant is marked as default with @*@.
    -- A default variant is used when no key matches.
    }
    deriving stock ((forall x. Variant -> Rep Variant x)
-> (forall x. Rep Variant x -> Variant) -> Generic Variant
forall x. Rep Variant x -> Variant
forall x. Variant -> Rep Variant x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Variant -> Rep Variant x
from :: forall x. Variant -> Rep Variant x
$cto :: forall x. Rep Variant x -> Variant
to :: forall x. Rep Variant x -> Variant
Generic, Variant -> Variant -> Bool
(Variant -> Variant -> Bool)
-> (Variant -> Variant -> Bool) -> Eq Variant
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Variant -> Variant -> Bool
== :: Variant -> Variant -> Bool
$c/= :: Variant -> Variant -> Bool
/= :: Variant -> Variant -> Bool
Eq, Int -> Variant -> ShowS
[Variant] -> ShowS
Variant -> String
(Int -> Variant -> ShowS)
-> (Variant -> String) -> ([Variant] -> ShowS) -> Show Variant
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Variant -> ShowS
showsPrec :: Int -> Variant -> ShowS
$cshow :: Variant -> String
show :: Variant -> String
$cshowList :: [Variant] -> ShowS
showList :: [Variant] -> ShowS
Show)

-- | The key of a t'Variant': either a number, or a plural category such as @one@ or @other@.
-- See <https://projectfluent.org/fluent/guide/selectors.html Selectors>.
newtype VariantKey = VariantKey (Either NumberLiteral Identifier)
    deriving stock ((forall x. VariantKey -> Rep VariantKey x)
-> (forall x. Rep VariantKey x -> VariantKey) -> Generic VariantKey
forall x. Rep VariantKey x -> VariantKey
forall x. VariantKey -> Rep VariantKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. VariantKey -> Rep VariantKey x
from :: forall x. VariantKey -> Rep VariantKey x
$cto :: forall x. Rep VariantKey x -> VariantKey
to :: forall x. Rep VariantKey x -> VariantKey
Generic, VariantKey -> VariantKey -> Bool
(VariantKey -> VariantKey -> Bool)
-> (VariantKey -> VariantKey -> Bool) -> Eq VariantKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VariantKey -> VariantKey -> Bool
== :: VariantKey -> VariantKey -> Bool
$c/= :: VariantKey -> VariantKey -> Bool
/= :: VariantKey -> VariantKey -> Bool
Eq, Int -> VariantKey -> ShowS
[VariantKey] -> ShowS
VariantKey -> String
(Int -> VariantKey -> ShowS)
-> (VariantKey -> String)
-> ([VariantKey] -> ShowS)
-> Show VariantKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VariantKey -> ShowS
showsPrec :: Int -> VariantKey -> ShowS
$cshow :: VariantKey -> String
show :: VariantKey -> String
$cshowList :: [VariantKey] -> ShowS
showList :: [VariantKey] -> ShowS
Show)

-- | The t'Variant's of a t'SelectExpression'. Exactly one of them is the default.
-- See <https://projectfluent.org/fluent/guide/selectors.html Selectors>.
newtype VariantList = VariantList (NonEmpty Variant)
    deriving stock ((forall x. VariantList -> Rep VariantList x)
-> (forall x. Rep VariantList x -> VariantList)
-> Generic VariantList
forall x. Rep VariantList x -> VariantList
forall x. VariantList -> Rep VariantList x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. VariantList -> Rep VariantList x
from :: forall x. VariantList -> Rep VariantList x
$cto :: forall x. Rep VariantList x -> VariantList
to :: forall x. Rep VariantList x -> VariantList
Generic, VariantList -> VariantList -> Bool
(VariantList -> VariantList -> Bool)
-> (VariantList -> VariantList -> Bool) -> Eq VariantList
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VariantList -> VariantList -> Bool
== :: VariantList -> VariantList -> Bool
$c/= :: VariantList -> VariantList -> Bool
/= :: VariantList -> VariantList -> Bool
Eq, Int -> VariantList -> ShowS
[VariantList] -> ShowS
VariantList -> String
(Int -> VariantList -> ShowS)
-> (VariantList -> String)
-> ([VariantList] -> ShowS)
-> Show VariantList
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VariantList -> ShowS
showsPrec :: Int -> VariantList -> ShowS
$cshow :: VariantList -> String
show :: VariantList -> String
$cshowList :: [VariantList] -> ShowS
showList :: [VariantList] -> ShowS
Show)

-- | The parenthesised arguments of a 'FunctionReference' or 'TermReference'.
-- Positional arguments must precede named ones.
-- See <https://projectfluent.org/fluent/guide/functions.html Functions>.
newtype CallArguments = CallArguments [Either NamedArgument InlineExpression]
    deriving stock ((forall x. CallArguments -> Rep CallArguments x)
-> (forall x. Rep CallArguments x -> CallArguments)
-> Generic CallArguments
forall x. Rep CallArguments x -> CallArguments
forall x. CallArguments -> Rep CallArguments x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CallArguments -> Rep CallArguments x
from :: forall x. CallArguments -> Rep CallArguments x
$cto :: forall x. Rep CallArguments x -> CallArguments
to :: forall x. Rep CallArguments x -> CallArguments
Generic, CallArguments -> CallArguments -> Bool
(CallArguments -> CallArguments -> Bool)
-> (CallArguments -> CallArguments -> Bool) -> Eq CallArguments
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallArguments -> CallArguments -> Bool
== :: CallArguments -> CallArguments -> Bool
$c/= :: CallArguments -> CallArguments -> Bool
/= :: CallArguments -> CallArguments -> Bool
Eq, Int -> CallArguments -> ShowS
[CallArguments] -> ShowS
CallArguments -> String
(Int -> CallArguments -> ShowS)
-> (CallArguments -> String)
-> ([CallArguments] -> ShowS)
-> Show CallArguments
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallArguments -> ShowS
showsPrec :: Int -> CallArguments -> ShowS
$cshow :: CallArguments -> String
show :: CallArguments -> String
$cshowList :: [CallArguments] -> ShowS
showList :: [CallArguments] -> ShowS
Show)

-- | An argument passed by name, e.g. @minimumFractionDigits: 2@.
-- See <https://projectfluent.org/fluent/guide/functions.html Functions>.
data NamedArgument = NamedArgument Identifier (Either StringLiteral NumberLiteral)
    deriving stock ((forall x. NamedArgument -> Rep NamedArgument x)
-> (forall x. Rep NamedArgument x -> NamedArgument)
-> Generic NamedArgument
forall x. Rep NamedArgument x -> NamedArgument
forall x. NamedArgument -> Rep NamedArgument x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NamedArgument -> Rep NamedArgument x
from :: forall x. NamedArgument -> Rep NamedArgument x
$cto :: forall x. Rep NamedArgument x -> NamedArgument
to :: forall x. Rep NamedArgument x -> NamedArgument
Generic, NamedArgument -> NamedArgument -> Bool
(NamedArgument -> NamedArgument -> Bool)
-> (NamedArgument -> NamedArgument -> Bool) -> Eq NamedArgument
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NamedArgument -> NamedArgument -> Bool
== :: NamedArgument -> NamedArgument -> Bool
$c/= :: NamedArgument -> NamedArgument -> Bool
/= :: NamedArgument -> NamedArgument -> Bool
Eq, Int -> NamedArgument -> ShowS
[NamedArgument] -> ShowS
NamedArgument -> String
(Int -> NamedArgument -> ShowS)
-> (NamedArgument -> String)
-> ([NamedArgument] -> ShowS)
-> Show NamedArgument
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NamedArgument -> ShowS
showsPrec :: Int -> NamedArgument -> ShowS
$cshow :: NamedArgument -> String
show :: NamedArgument -> String
$cshowList :: [NamedArgument] -> ShowS
showList :: [NamedArgument] -> ShowS
Show)

-- | The name of a t'Message', t'Term', t'Attribute', variable, function, or named argument.
newtype Identifier = Identifier Text
    deriving newtype (Int -> Identifier -> ShowS
[Identifier] -> ShowS
Identifier -> String
(Int -> Identifier -> ShowS)
-> (Identifier -> String)
-> ([Identifier] -> ShowS)
-> Show Identifier
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Identifier -> ShowS
showsPrec :: Int -> Identifier -> ShowS
$cshow :: Identifier -> String
show :: Identifier -> String
$cshowList :: [Identifier] -> ShowS
showList :: [Identifier] -> ShowS
Show, Identifier -> Identifier -> Bool
(Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool) -> Eq Identifier
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Identifier -> Identifier -> Bool
== :: Identifier -> Identifier -> Bool
$c/= :: Identifier -> Identifier -> Bool
/= :: Identifier -> Identifier -> Bool
Eq, Eq Identifier
Eq Identifier =>
(Identifier -> Identifier -> Ordering)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Bool)
-> (Identifier -> Identifier -> Identifier)
-> (Identifier -> Identifier -> Identifier)
-> Ord Identifier
Identifier -> Identifier -> Bool
Identifier -> Identifier -> Ordering
Identifier -> Identifier -> Identifier
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 :: Identifier -> Identifier -> Ordering
compare :: Identifier -> Identifier -> Ordering
$c< :: Identifier -> Identifier -> Bool
< :: Identifier -> Identifier -> Bool
$c<= :: Identifier -> Identifier -> Bool
<= :: Identifier -> Identifier -> Bool
$c> :: Identifier -> Identifier -> Bool
> :: Identifier -> Identifier -> Bool
$c>= :: Identifier -> Identifier -> Bool
>= :: Identifier -> Identifier -> Bool
$cmax :: Identifier -> Identifier -> Identifier
max :: Identifier -> Identifier -> Identifier
$cmin :: Identifier -> Identifier -> Identifier
min :: Identifier -> Identifier -> Identifier
Ord, Eq Identifier
Eq Identifier =>
(Int -> Identifier -> Int)
-> (Identifier -> Int) -> Hashable Identifier
Int -> Identifier -> Int
Identifier -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Identifier -> Int
hashWithSalt :: Int -> Identifier -> Int
$chash :: Identifier -> Int
hash :: Identifier -> Int
Hashable)

-- | A decimal number with arbitrary precision.
newtype NumberLiteral = NumberLiteral Text
    deriving stock ((forall x. NumberLiteral -> Rep NumberLiteral x)
-> (forall x. Rep NumberLiteral x -> NumberLiteral)
-> Generic NumberLiteral
forall x. Rep NumberLiteral x -> NumberLiteral
forall x. NumberLiteral -> Rep NumberLiteral x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NumberLiteral -> Rep NumberLiteral x
from :: forall x. NumberLiteral -> Rep NumberLiteral x
$cto :: forall x. Rep NumberLiteral x -> NumberLiteral
to :: forall x. Rep NumberLiteral x -> NumberLiteral
Generic, NumberLiteral -> NumberLiteral -> Bool
(NumberLiteral -> NumberLiteral -> Bool)
-> (NumberLiteral -> NumberLiteral -> Bool) -> Eq NumberLiteral
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NumberLiteral -> NumberLiteral -> Bool
== :: NumberLiteral -> NumberLiteral -> Bool
$c/= :: NumberLiteral -> NumberLiteral -> Bool
/= :: NumberLiteral -> NumberLiteral -> Bool
Eq, Int -> NumberLiteral -> ShowS
[NumberLiteral] -> ShowS
NumberLiteral -> String
(Int -> NumberLiteral -> ShowS)
-> (NumberLiteral -> String)
-> ([NumberLiteral] -> ShowS)
-> Show NumberLiteral
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NumberLiteral -> ShowS
showsPrec :: Int -> NumberLiteral -> ShowS
$cshow :: NumberLiteral -> String
show :: NumberLiteral -> String
$cshowList :: [NumberLiteral] -> ShowS
showList :: [NumberLiteral] -> ShowS
Show)

-- | A quoted string, used to write characters which are otherwise
-- <https://projectfluent.org/fluent/guide/special.html special> in FTL.
data StringLiteral = StringLiteral
    { StringLiteral -> Text
raw :: Text
    -- ^ The source text between the quotes, with escape sequences unresolved.
    , StringLiteral -> Text
value :: Text
    -- ^ The text the literal denotes, with escape sequences resolved.
    }
    deriving stock ((forall x. StringLiteral -> Rep StringLiteral x)
-> (forall x. Rep StringLiteral x -> StringLiteral)
-> Generic StringLiteral
forall x. Rep StringLiteral x -> StringLiteral
forall x. StringLiteral -> Rep StringLiteral x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. StringLiteral -> Rep StringLiteral x
from :: forall x. StringLiteral -> Rep StringLiteral x
$cto :: forall x. Rep StringLiteral x -> StringLiteral
to :: forall x. Rep StringLiteral x -> StringLiteral
Generic, StringLiteral -> StringLiteral -> Bool
(StringLiteral -> StringLiteral -> Bool)
-> (StringLiteral -> StringLiteral -> Bool) -> Eq StringLiteral
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StringLiteral -> StringLiteral -> Bool
== :: StringLiteral -> StringLiteral -> Bool
$c/= :: StringLiteral -> StringLiteral -> Bool
/= :: StringLiteral -> StringLiteral -> Bool
Eq, Int -> StringLiteral -> ShowS
[StringLiteral] -> ShowS
StringLiteral -> String
(Int -> StringLiteral -> ShowS)
-> (StringLiteral -> String)
-> ([StringLiteral] -> ShowS)
-> Show StringLiteral
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StringLiteral -> ShowS
showsPrec :: Int -> StringLiteral -> ShowS
$cshow :: StringLiteral -> String
show :: StringLiteral -> String
$cshowList :: [StringLiteral] -> ShowS
showList :: [StringLiteral] -> ShowS
Show)