-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

{-# LANGUAGE UndecidableSuperClasses #-}

-- | Type and field annotations for Lorentz types.
module Lorentz.Annotation
  ( FollowEntrypointFlag (..)
  , GenerateFieldAnnFlag (..)
  , HasAnnotation (..)
  , GHasAnnotation (..)
  , gGetAnnotationNoField
  , insertTypeAnn
  ) where

import qualified GHC.Generics as G
import Named (NamedF)

import Lorentz.Entrypoints.Helpers (ctorNameToAnn)
import Michelson.Text
import Michelson.Typed
  (BigMap, ContractRef(..), EpAddress, KnownIsoT, Notes(..), Operation, ToT, insertTypeAnn,
  starNotes)
import Michelson.Typed.Haskell.Value (GValueType)
import Michelson.Untyped (FieldAnn, TypeAnn, ann, noAnn)
import Tezos.Address
import Tezos.Core
import Tezos.Crypto
import Util.TypeLits

-- | Used in `GHasAnnotation` and `HasAnnotation` as a flag to track
-- whether or not it directly follows an entrypoint to avoid introducing
-- extra entrypoints.
data FollowEntrypointFlag = FollowEntrypoint | NotFollowEntrypoint

-- | Used in `GHasAnnotation` as a flag to track whether or not field/constructor
-- annotations should be generated.
data GenerateFieldAnnFlag = GenerateFieldAnn | NotGenerateFieldAnn

-- | Use this in the instance of @HasAnnotation@ when field annotations
-- should not be generated.
gGetAnnotationNoField
    :: forall a. (GHasAnnotation (G.Rep a), GValueType (G.Rep a) ~ ToT a)
    => FollowEntrypointFlag -> Notes (ToT a)
gGetAnnotationNoField :: FollowEntrypointFlag -> Notes (ToT a)
gGetAnnotationNoField = \_ -> (Notes (ToT a), FieldAnn) -> Notes (ToT a)
forall a b. (a, b) -> a
fst ((Notes (ToT a), FieldAnn) -> Notes (ToT a))
-> (Notes (ToT a), FieldAnn) -> Notes (ToT a)
forall a b. (a -> b) -> a -> b
$ FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType (Rep a)), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @(G.Rep a) FollowEntrypointFlag
NotFollowEntrypoint GenerateFieldAnnFlag
NotGenerateFieldAnn

-- | This class defines the type and field annotations for a given type. Right now
-- the type annotations come from names in a named field, and field annotations are
-- generated from the record fields.
class HasAnnotation a where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT a)
  default getAnnotation
    :: (GHasAnnotation (G.Rep a), GValueType (G.Rep a) ~ ToT a)
    => FollowEntrypointFlag
    -> Notes (ToT a)
  getAnnotation b :: FollowEntrypointFlag
b = (Notes (ToT a), FieldAnn) -> Notes (ToT a)
forall a b. (a, b) -> a
fst ((Notes (ToT a), FieldAnn) -> Notes (ToT a))
-> (Notes (ToT a), FieldAnn) -> Notes (ToT a)
forall a b. (a -> b) -> a -> b
$ FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType (Rep a)), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @(G.Rep a) FollowEntrypointFlag
b GenerateFieldAnnFlag
GenerateFieldAnn

instance (HasAnnotation a, KnownSymbol name)
  => HasAnnotation (NamedF Identity a name) where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT (NamedF Identity a name))
getAnnotation b :: FollowEntrypointFlag
b = TypeAnn -> Notes (ToT a) -> Notes (ToT a)
forall (b :: T). TypeAnn -> Notes b -> Notes b
insertTypeAnn (KnownSymbol name => TypeAnn
forall (s :: Symbol). KnownSymbol s => TypeAnn
symbolAnn @name) (Notes (ToT a) -> Notes (ToT (NamedF Identity a name)))
-> Notes (ToT a) -> Notes (ToT (NamedF Identity a name))
forall a b. (a -> b) -> a -> b
$
    FollowEntrypointFlag -> Notes (ToT a)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @a FollowEntrypointFlag
b
    where
      symbolAnn :: forall s. KnownSymbol s => TypeAnn
      symbolAnn :: TypeAnn
symbolAnn = Text -> TypeAnn
forall k (a :: k). HasCallStack => Text -> Annotation a
ann (Text -> TypeAnn) -> Text -> TypeAnn
forall a b. (a -> b) -> a -> b
$ KnownSymbol s => Text
forall (s :: Symbol). KnownSymbol s => Text
symbolValT' @s

instance (HasAnnotation (Maybe a), KnownSymbol name)
  => HasAnnotation (NamedF Maybe a name) where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT (NamedF Maybe a name))
getAnnotation b :: FollowEntrypointFlag
b = FollowEntrypointFlag
-> Notes (ToT (NamedF Identity (Maybe a) name))
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @(NamedF Identity (Maybe a) name) FollowEntrypointFlag
b

-- Primitive instances
instance (HasAnnotation a) => HasAnnotation (Maybe a) where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT (Maybe a))
getAnnotation _ = TypeAnn -> Notes (ToT a) -> Notes ('TOption (ToT a))
forall (t1 :: T). TypeAnn -> Notes t1 -> Notes ('TOption t1)
NTOption TypeAnn
forall k (a :: k). Annotation a
noAnn (FollowEntrypointFlag -> Notes (ToT a)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @a FollowEntrypointFlag
NotFollowEntrypoint)

instance HasAnnotation ()

instance HasAnnotation Integer where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Integer)
getAnnotation _ = Notes (ToT Integer)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation Natural where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Natural)
getAnnotation _ = Notes (ToT Natural)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation MText where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT MText)
getAnnotation _ = Notes (ToT MText)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation Bool where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Bool)
getAnnotation _ = Notes (ToT Bool)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation ByteString where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT ByteString)
getAnnotation _ = Notes (ToT ByteString)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation Mutez where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Mutez)
getAnnotation _ = Notes (ToT Mutez)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation Address where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Address)
getAnnotation _ = Notes (ToT Address)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation EpAddress where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT EpAddress)
getAnnotation _ = Notes (ToT EpAddress)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation KeyHash where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT KeyHash)
getAnnotation _ = Notes (ToT KeyHash)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation Timestamp where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Timestamp)
getAnnotation _ = Notes (ToT Timestamp)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation PublicKey where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT PublicKey)
getAnnotation _ = Notes (ToT PublicKey)
forall (t :: T). SingI t => Notes t
starNotes

instance HasAnnotation Signature where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Signature)
getAnnotation _ = Notes (ToT Signature)
forall (t :: T). SingI t => Notes t
starNotes

instance (HasAnnotation a) => HasAnnotation (ContractRef a) where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT (ContractRef a))
getAnnotation _ = TypeAnn -> Notes (ToT a) -> Notes ('TContract (ToT a))
forall (t1 :: T). TypeAnn -> Notes t1 -> Notes ('TContract t1)
NTContract TypeAnn
forall k (a :: k). Annotation a
noAnn (FollowEntrypointFlag -> Notes (ToT a)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @a FollowEntrypointFlag
NotFollowEntrypoint)

instance (HasAnnotation k, HasAnnotation v) => HasAnnotation (Map k v) where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT (Map k v))
getAnnotation _ = TypeAnn
-> Notes (ToT k) -> Notes (ToT v) -> Notes ('TMap (ToT k) (ToT v))
forall (k :: T) (v :: T).
TypeAnn -> Notes k -> Notes v -> Notes ('TMap k v)
NTMap TypeAnn
forall k (a :: k). Annotation a
noAnn (FollowEntrypointFlag -> Notes (ToT k)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @k FollowEntrypointFlag
NotFollowEntrypoint) (FollowEntrypointFlag -> Notes (ToT v)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @v FollowEntrypointFlag
NotFollowEntrypoint)

instance (HasAnnotation k, HasAnnotation v) => HasAnnotation (BigMap k v) where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT (BigMap k v))
getAnnotation _ = TypeAnn
-> Notes (ToT k)
-> Notes (ToT v)
-> Notes ('TBigMap (ToT k) (ToT v))
forall (k :: T) (v :: T).
TypeAnn -> Notes k -> Notes v -> Notes ('TBigMap k v)
NTBigMap TypeAnn
forall k (a :: k). Annotation a
noAnn (FollowEntrypointFlag -> Notes (ToT k)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @k FollowEntrypointFlag
NotFollowEntrypoint) (FollowEntrypointFlag -> Notes (ToT v)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @v FollowEntrypointFlag
NotFollowEntrypoint)

instance (KnownIsoT v) => HasAnnotation (Set v) where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT (Set v))
getAnnotation _ = Notes (ToT (Set v))
forall (t :: T). SingI t => Notes t
starNotes

instance (HasAnnotation a) => HasAnnotation [a] where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT [a])
getAnnotation _ = TypeAnn -> Notes (ToT a) -> Notes ('TList (ToT a))
forall (t1 :: T). TypeAnn -> Notes t1 -> Notes ('TList t1)
NTList TypeAnn
forall k (a :: k). Annotation a
noAnn (FollowEntrypointFlag -> Notes (ToT a)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @a FollowEntrypointFlag
NotFollowEntrypoint)

instance HasAnnotation Operation where
  getAnnotation :: FollowEntrypointFlag -> Notes (ToT Operation)
getAnnotation _ = Notes (ToT Operation)
forall (t :: T). SingI t => Notes t
starNotes

instance (HasAnnotation a, HasAnnotation b) => HasAnnotation (a, b)
instance (HasAnnotation a, HasAnnotation b, HasAnnotation c) => HasAnnotation (a, b, c)
instance (HasAnnotation a, HasAnnotation b, HasAnnotation c, HasAnnotation d) => HasAnnotation (a, b, c, d)
instance (HasAnnotation a, HasAnnotation b, HasAnnotation c, HasAnnotation d, HasAnnotation e)
  => HasAnnotation (a, b, c, d, e)
instance (HasAnnotation a, HasAnnotation b, HasAnnotation c, HasAnnotation d, HasAnnotation e, HasAnnotation f)
  => HasAnnotation (a, b, c, d, e, f)
instance
  ( HasAnnotation a, HasAnnotation b, HasAnnotation c, HasAnnotation d, HasAnnotation e
  , HasAnnotation f, HasAnnotation g)
  => HasAnnotation (a, b, c, d, e, f, g)

-- | A Generic @HasAnnotation@ implementation
class GHasAnnotation a where
  gGetAnnotation :: FollowEntrypointFlag -> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)

instance GHasAnnotation G.U1 where
  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType U1), FieldAnn)
gGetAnnotation _ _ = (Notes (GValueType U1)
forall (t :: T). SingI t => Notes t
starNotes, FieldAnn
forall k (a :: k). Annotation a
noAnn)

instance (GHasAnnotation x)
  => GHasAnnotation (G.M1 G.S ('G.MetaSel 'Nothing b c d) x)
  where
  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag
-> (Notes (GValueType (M1 S ('MetaSel 'Nothing b c d) x)),
    FieldAnn)
gGetAnnotation b :: FollowEntrypointFlag
b b2 :: GenerateFieldAnnFlag
b2 = FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType x), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @x FollowEntrypointFlag
b GenerateFieldAnnFlag
b2

instance (GHasAnnotation x, KnownSymbol a)
  => GHasAnnotation (G.M1 G.S ('G.MetaSel ('Just a) b c d) x)
  where
  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag
-> (Notes (GValueType (M1 S ('MetaSel ('Just a) b c d) x)),
    FieldAnn)
gGetAnnotation b :: FollowEntrypointFlag
b b2 :: GenerateFieldAnnFlag
b2 = case GenerateFieldAnnFlag
b2 of
    GenerateFieldAnn -> ((Notes (GValueType x), FieldAnn)
-> Notes (GValueType (M1 S ('MetaSel ('Just a) b c d) x))
forall a b. (a, b) -> a
fst ((Notes (GValueType x), FieldAnn)
 -> Notes (GValueType (M1 S ('MetaSel ('Just a) b c d) x)))
-> (Notes (GValueType x), FieldAnn)
-> Notes (GValueType (M1 S ('MetaSel ('Just a) b c d) x))
forall a b. (a -> b) -> a -> b
$ FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType x), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @x FollowEntrypointFlag
b GenerateFieldAnnFlag
b2, (KnownSymbol a, HasCallStack) => FieldAnn
forall (ctor :: Symbol).
(KnownSymbol ctor, HasCallStack) =>
FieldAnn
ctorNameToAnn @a)
    NotGenerateFieldAnn -> ((Notes (GValueType x), FieldAnn)
-> Notes (GValueType (M1 S ('MetaSel ('Just a) b c d) x))
forall a b. (a, b) -> a
fst ((Notes (GValueType x), FieldAnn)
 -> Notes (GValueType (M1 S ('MetaSel ('Just a) b c d) x)))
-> (Notes (GValueType x), FieldAnn)
-> Notes (GValueType (M1 S ('MetaSel ('Just a) b c d) x))
forall a b. (a -> b) -> a -> b
$ FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType x), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @x FollowEntrypointFlag
b GenerateFieldAnnFlag
b2, FieldAnn
forall k (a :: k). Annotation a
noAnn)

instance (GHasAnnotation x, KnownSymbol a) => GHasAnnotation (G.M1 G.C ('G.MetaCons a _p _f) x) where
  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag
-> (Notes (GValueType (M1 C ('MetaCons a _p _f) x)), FieldAnn)
gGetAnnotation b :: FollowEntrypointFlag
b b2 :: GenerateFieldAnnFlag
b2 = ((Notes (GValueType x), FieldAnn)
-> Notes (GValueType (M1 C ('MetaCons a _p _f) x))
forall a b. (a, b) -> a
fst ((Notes (GValueType x), FieldAnn)
 -> Notes (GValueType (M1 C ('MetaCons a _p _f) x)))
-> (Notes (GValueType x), FieldAnn)
-> Notes (GValueType (M1 C ('MetaCons a _p _f) x))
forall a b. (a -> b) -> a -> b
$ FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType x), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @x FollowEntrypointFlag
b GenerateFieldAnnFlag
b2, (KnownSymbol a, HasCallStack) => FieldAnn
forall (ctor :: Symbol).
(KnownSymbol ctor, HasCallStack) =>
FieldAnn
ctorNameToAnn @a)

instance (GHasAnnotation x) => GHasAnnotation (G.M1 G.D i1 x) where
  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag
-> (Notes (GValueType (M1 D i1 x)), FieldAnn)
gGetAnnotation b :: FollowEntrypointFlag
b b2 :: GenerateFieldAnnFlag
b2 = FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType x), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @x FollowEntrypointFlag
b GenerateFieldAnnFlag
b2

instance
    ( GHasAnnotation x
    , GHasAnnotation y
    )
  =>
    GHasAnnotation (x G.:+: y)
  where

  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType (x :+: y)), FieldAnn)
gGetAnnotation followEntrypointFlag :: FollowEntrypointFlag
followEntrypointFlag generateAnnFlag :: GenerateFieldAnnFlag
generateAnnFlag =
    let (xTypeAnn :: Notes (GValueType x)
xTypeAnn, xFieldAnn :: FieldAnn
xFieldAnn) = FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType x), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @x FollowEntrypointFlag
followEntrypointFlag GenerateFieldAnnFlag
generateAnnFlag
        (yTypeAnn :: Notes (GValueType y)
yTypeAnn, yFieldAnn :: FieldAnn
yFieldAnn) = FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType y), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @y FollowEntrypointFlag
followEntrypointFlag GenerateFieldAnnFlag
generateAnnFlag
    in case (FollowEntrypointFlag
followEntrypointFlag, GenerateFieldAnnFlag
generateAnnFlag) of
          (NotFollowEntrypoint, GenerateFieldAnn) ->
            ( TypeAnn
-> FieldAnn
-> FieldAnn
-> Notes (GValueType x)
-> Notes (GValueType y)
-> Notes ('TOr (GValueType x) (GValueType y))
forall (p :: T) (q :: T).
TypeAnn
-> FieldAnn -> FieldAnn -> Notes p -> Notes q -> Notes ('TOr p q)
NTOr TypeAnn
forall k (a :: k). Annotation a
noAnn
                FieldAnn
xFieldAnn FieldAnn
yFieldAnn
                Notes (GValueType x)
xTypeAnn Notes (GValueType y)
yTypeAnn
            , FieldAnn
forall k (a :: k). Annotation a
noAnn
            )
          _ ->
            ( TypeAnn
-> FieldAnn
-> FieldAnn
-> Notes (GValueType x)
-> Notes (GValueType y)
-> Notes ('TOr (GValueType x) (GValueType y))
forall (p :: T) (q :: T).
TypeAnn
-> FieldAnn -> FieldAnn -> Notes p -> Notes q -> Notes ('TOr p q)
NTOr TypeAnn
forall k (a :: k). Annotation a
noAnn
                FieldAnn
forall k (a :: k). Annotation a
noAnn FieldAnn
forall k (a :: k). Annotation a
noAnn
                Notes (GValueType x)
xTypeAnn Notes (GValueType y)
yTypeAnn
            , FieldAnn
forall k (a :: k). Annotation a
noAnn
            )

instance
    ( GHasAnnotation x
    , GHasAnnotation y
    )
  =>
    GHasAnnotation (x G.:*: y)
  where
  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType (x :*: y)), FieldAnn)
gGetAnnotation _ b2 :: GenerateFieldAnnFlag
b2 =
    let  (xTypeAnn :: Notes (GValueType x)
xTypeAnn, xFieldAnn :: FieldAnn
xFieldAnn) = FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType x), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @x FollowEntrypointFlag
NotFollowEntrypoint GenerateFieldAnnFlag
b2
         (yTypeAnn :: Notes (GValueType y)
yTypeAnn, yFieldAnn :: FieldAnn
yFieldAnn) = FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType y), FieldAnn)
forall (a :: * -> *).
GHasAnnotation a =>
FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType a), FieldAnn)
gGetAnnotation @y FollowEntrypointFlag
NotFollowEntrypoint GenerateFieldAnnFlag
b2
    in
      ( TypeAnn
-> FieldAnn
-> FieldAnn
-> Notes (GValueType x)
-> Notes (GValueType y)
-> Notes ('TPair (GValueType x) (GValueType y))
forall (p :: T) (q :: T).
TypeAnn
-> FieldAnn -> FieldAnn -> Notes p -> Notes q -> Notes ('TPair p q)
NTPair TypeAnn
forall k (a :: k). Annotation a
noAnn
          FieldAnn
xFieldAnn FieldAnn
yFieldAnn
          Notes (GValueType x)
xTypeAnn Notes (GValueType y)
yTypeAnn
      , FieldAnn
forall k (a :: k). Annotation a
noAnn
      )

instance (HasAnnotation x) => GHasAnnotation (G.Rec0 x) where
  gGetAnnotation :: FollowEntrypointFlag
-> GenerateFieldAnnFlag -> (Notes (GValueType (Rec0 x)), FieldAnn)
gGetAnnotation b :: FollowEntrypointFlag
b _ = (FollowEntrypointFlag -> Notes (ToT x)
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @x FollowEntrypointFlag
b, FieldAnn
forall k (a :: k). Annotation a
noAnn)