{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Data.Morpheus.Parsing.Request.Operation
  ( parseOperation,
  )
where

import Data.Morpheus.Internal.Utils
  ( empty,
  )
import Data.Morpheus.Parsing.Internal.Internal
  ( Parser,
    getLocation,
  )
import Data.Morpheus.Parsing.Internal.Pattern
  ( optionalDirectives,
    parseOperationType,
  )
import Data.Morpheus.Parsing.Internal.Terms
  ( colon,
    parseName,
    parseType,
    uniqTupleOpt,
    varName,
  )
import Data.Morpheus.Parsing.Internal.Value
  ( parseDefaultValue,
  )
import Data.Morpheus.Parsing.Request.Selection
  ( parseSelectionSet,
  )
import Data.Morpheus.Types.Internal.AST
  ( Operation (..),
    OperationType (..),
    RAW,
    Variable (..),
    VariableContent (..),
  )
import Relude hiding (empty)
import Text.Megaparsec
  ( label,
    (<?>),
  )

-- Variables :  https://graphql.github.io/graphql-spec/June2018/#VariableDefinition
--
--  VariableDefinition
--    Variable : Type DefaultValue(opt)
--
variableDefinition :: Parser (Variable RAW)
variableDefinition :: Parser (Variable RAW)
variableDefinition =
  String -> Parser (Variable RAW) -> Parser (Variable RAW)
forall a.
String
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult a
forall e s (m :: * -> *) a.
MonadParsec e s m =>
String -> m a -> m a
label String
"VariableDefinition" (Parser (Variable RAW) -> Parser (Variable RAW))
-> Parser (Variable RAW) -> Parser (Variable RAW)
forall a b. (a -> b) -> a -> b
$
    Position
-> FieldName
-> TypeRef
-> VariableContent (CONST_OR_VALID RAW)
-> Variable RAW
Position
-> FieldName -> TypeRef -> VariableContent CONST -> Variable RAW
forall (stage :: Stage).
Position
-> FieldName
-> TypeRef
-> VariableContent (CONST_OR_VALID stage)
-> Variable stage
Variable
      (Position
 -> FieldName -> TypeRef -> VariableContent CONST -> Variable RAW)
-> ParsecT Void ByteString GQLResult Position
-> ParsecT
     Void
     ByteString
     GQLResult
     (FieldName -> TypeRef -> VariableContent CONST -> Variable RAW)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void ByteString GQLResult Position
getLocation
      ParsecT
  Void
  ByteString
  GQLResult
  (FieldName -> TypeRef -> VariableContent CONST -> Variable RAW)
-> ParsecT Void ByteString GQLResult FieldName
-> ParsecT
     Void
     ByteString
     GQLResult
     (TypeRef -> VariableContent CONST -> Variable RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (ParsecT Void ByteString GQLResult FieldName
varName ParsecT Void ByteString GQLResult FieldName
-> ParsecT Void ByteString GQLResult ()
-> ParsecT Void ByteString GQLResult FieldName
forall a b.
ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
-> ParsecT Void ByteString GQLResult a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Void ByteString GQLResult ()
colon)
      ParsecT
  Void
  ByteString
  GQLResult
  (TypeRef -> VariableContent CONST -> Variable RAW)
-> ParsecT Void ByteString GQLResult TypeRef
-> ParsecT
     Void ByteString GQLResult (VariableContent CONST -> Variable RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void ByteString GQLResult TypeRef
parseType
      ParsecT
  Void ByteString GQLResult (VariableContent CONST -> Variable RAW)
-> ParsecT Void ByteString GQLResult (VariableContent CONST)
-> Parser (Variable RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Maybe ResolvedValue -> VariableContent CONST
DefaultValue (Maybe ResolvedValue -> VariableContent CONST)
-> ParsecT Void ByteString GQLResult (Maybe ResolvedValue)
-> ParsecT Void ByteString GQLResult (VariableContent CONST)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void ByteString GQLResult ResolvedValue
-> ParsecT Void ByteString GQLResult (Maybe ResolvedValue)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void ByteString GQLResult ResolvedValue
forall (s :: Stage). Parser (Value s)
parseDefaultValue)

-- Operations : https://graphql.github.io/graphql-spec/June2018/#sec-Language.Operations
--
-- OperationDefinition
--   OperationType Name(opt) VariableDefinitions(opt) Directives(opt) SelectionSet
--
--   OperationType: one of
--     query, mutation,    subscription
parseOperationDefinition :: Parser (Operation RAW)
parseOperationDefinition :: Parser (Operation RAW)
parseOperationDefinition =
  String -> Parser (Operation RAW) -> Parser (Operation RAW)
forall a.
String
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult a
forall e s (m :: * -> *) a.
MonadParsec e s m =>
String -> m a -> m a
label String
"OperationDefinition" (Parser (Operation RAW) -> Parser (Operation RAW))
-> Parser (Operation RAW) -> Parser (Operation RAW)
forall a b. (a -> b) -> a -> b
$
    Position
-> OperationType
-> Maybe FieldName
-> VariableDefinitions RAW
-> Directives RAW
-> MergeMap 'True FieldName (Selection RAW)
-> Operation RAW
Position
-> OperationType
-> Maybe FieldName
-> VariableDefinitions RAW
-> Directives RAW
-> SelectionSet RAW
-> Operation RAW
forall (s :: Stage).
Position
-> OperationType
-> Maybe FieldName
-> VariableDefinitions s
-> Directives s
-> SelectionSet s
-> Operation s
Operation
      (Position
 -> OperationType
 -> Maybe FieldName
 -> VariableDefinitions RAW
 -> Directives RAW
 -> MergeMap 'True FieldName (Selection RAW)
 -> Operation RAW)
-> ParsecT Void ByteString GQLResult Position
-> ParsecT
     Void
     ByteString
     GQLResult
     (OperationType
      -> Maybe FieldName
      -> VariableDefinitions RAW
      -> Directives RAW
      -> MergeMap 'True FieldName (Selection RAW)
      -> Operation RAW)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void ByteString GQLResult Position
getLocation
      ParsecT
  Void
  ByteString
  GQLResult
  (OperationType
   -> Maybe FieldName
   -> VariableDefinitions RAW
   -> Directives RAW
   -> MergeMap 'True FieldName (Selection RAW)
   -> Operation RAW)
-> ParsecT Void ByteString GQLResult OperationType
-> ParsecT
     Void
     ByteString
     GQLResult
     (Maybe FieldName
      -> VariableDefinitions RAW
      -> Directives RAW
      -> MergeMap 'True FieldName (Selection RAW)
      -> Operation RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void ByteString GQLResult OperationType
parseOperationType
      ParsecT
  Void
  ByteString
  GQLResult
  (Maybe FieldName
   -> VariableDefinitions RAW
   -> Directives RAW
   -> MergeMap 'True FieldName (Selection RAW)
   -> Operation RAW)
-> ParsecT Void ByteString GQLResult (Maybe FieldName)
-> ParsecT
     Void
     ByteString
     GQLResult
     (VariableDefinitions RAW
      -> Directives RAW
      -> MergeMap 'True FieldName (Selection RAW)
      -> Operation RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void ByteString GQLResult FieldName
-> ParsecT Void ByteString GQLResult (Maybe FieldName)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void ByteString GQLResult FieldName
forall (t :: NAME). Parser (Name t)
parseName
      ParsecT
  Void
  ByteString
  GQLResult
  (VariableDefinitions RAW
   -> Directives RAW
   -> MergeMap 'True FieldName (Selection RAW)
   -> Operation RAW)
-> ParsecT Void ByteString GQLResult (VariableDefinitions RAW)
-> ParsecT
     Void
     ByteString
     GQLResult
     (Directives RAW
      -> MergeMap 'True FieldName (Selection RAW) -> Operation RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Variable RAW)
-> ParsecT Void ByteString GQLResult (VariableDefinitions RAW)
forall (map :: * -> * -> *) k a.
(FromList GQLResult map k a, Empty (map k a), KeyOf k a) =>
Parser a -> Parser (map k a)
uniqTupleOpt Parser (Variable RAW)
variableDefinition
      ParsecT
  Void
  ByteString
  GQLResult
  (Directives RAW
   -> MergeMap 'True FieldName (Selection RAW) -> Operation RAW)
-> ParsecT Void ByteString GQLResult (Directives RAW)
-> ParsecT
     Void
     ByteString
     GQLResult
     (MergeMap 'True FieldName (Selection RAW) -> Operation RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Void ByteString GQLResult (Directives RAW)
forall (s :: Stage). Parse (Value s) => Parser (Directives s)
optionalDirectives
      ParsecT
  Void
  ByteString
  GQLResult
  (MergeMap 'True FieldName (Selection RAW) -> Operation RAW)
-> ParsecT
     Void
     ByteString
     GQLResult
     (MergeMap 'True FieldName (Selection RAW))
-> Parser (Operation RAW)
forall a b.
ParsecT Void ByteString GQLResult (a -> b)
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT
  Void
  ByteString
  GQLResult
  (MergeMap 'True FieldName (Selection RAW))
Parser (SelectionSet RAW)
parseSelectionSet

parseAnonymousQuery :: Parser (Operation RAW)
parseAnonymousQuery :: Parser (Operation RAW)
parseAnonymousQuery = String -> Parser (Operation RAW) -> Parser (Operation RAW)
forall a.
String
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult a
forall e s (m :: * -> *) a.
MonadParsec e s m =>
String -> m a -> m a
label String
"AnonymousQuery" (Parser (Operation RAW) -> Parser (Operation RAW))
-> Parser (Operation RAW) -> Parser (Operation RAW)
forall a b. (a -> b) -> a -> b
$ do
  Position
operationPosition <- ParsecT Void ByteString GQLResult Position
getLocation
  MergeMap 'True FieldName (Selection RAW)
operationSelection <- ParsecT
  Void
  ByteString
  GQLResult
  (MergeMap 'True FieldName (Selection RAW))
Parser (SelectionSet RAW)
parseSelectionSet
  Operation RAW -> Parser (Operation RAW)
forall a. a -> ParsecT Void ByteString GQLResult a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    ( Operation
        { operationName :: Maybe FieldName
operationName = Maybe FieldName
forall a. Maybe a
Nothing,
          operationType :: OperationType
operationType = OperationType
OPERATION_QUERY,
          operationArguments :: VariableDefinitions RAW
operationArguments = VariableDefinitions RAW
forall coll. Empty coll => coll
empty,
          operationDirectives :: Directives RAW
operationDirectives = Directives RAW
forall coll. Empty coll => coll
empty,
          MergeMap 'True FieldName (Selection RAW)
SelectionSet RAW
Position
operationPosition :: Position
operationSelection :: MergeMap 'True FieldName (Selection RAW)
operationPosition :: Position
operationSelection :: SelectionSet RAW
..
        }
    )
    Parser (Operation RAW) -> String -> Parser (Operation RAW)
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"can't parse AnonymousQuery"

parseOperation :: Parser (Operation RAW)
parseOperation :: Parser (Operation RAW)
parseOperation = Parser (Operation RAW)
parseAnonymousQuery Parser (Operation RAW)
-> Parser (Operation RAW) -> Parser (Operation RAW)
forall a.
ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult a
-> ParsecT Void ByteString GQLResult a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Operation RAW)
parseOperationDefinition