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

-- | Module, carrying logic of @PACK@ instruction.
--
-- This is nearly symmetric to adjacent Unpack.hs module.
module Michelson.Interpret.Pack
  ( packCode'
  , packT'
  , packValue
  , packValue'
  , packValuePrefix
    -- * Serializers used in morley-client
  , encodeValue'
  , encodeValue
  , packNotedT'
    -- * Internals
  , encodeIntPayload
  , encodeKeyHashRaw
  , encodeEpAddress
  ) where

import Prelude hiding (EQ, GT, LT)

import qualified Data.Binary.Put as Bi
import qualified Data.ByteArray as ByteArray
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Map as Map
import Data.Singletons (Sing, demote)
import Data.Vinyl (Rec(..))
import Util.Type (type (++))

import Michelson.Interpret.Utils
import Michelson.Text
import Michelson.Typed
import Michelson.Untyped.Annotation
  (Annotation(..), FieldAnn, TypeAnn, VarAnn, fullAnnSet, isNoAnnSet, noAnn)
import Tezos.Address (Address(..), ContractHash(..))
import Tezos.Core (ChainId(..), Mutez(..), timestampToSeconds)
import Tezos.Crypto (KeyHash(..), KeyHashTag(..), PublicKey(..), signatureToBytes)
import qualified Tezos.Crypto.BLS12381 as BLS
import qualified Tezos.Crypto.Ed25519 as Ed25519
import qualified Tezos.Crypto.P256 as P256
import qualified Tezos.Crypto.Secp256k1 as Secp256k1
import Util.Peano (peanoValSing)

-- | Prefix prepended to the binary representation of a value.
packValuePrefix :: IsString s => s
packValuePrefix :: s
packValuePrefix = s
"\x05"

-- | Serialize a value given to @PACK@ instruction.
packValue :: PackedValScope t => Value t -> LByteString
packValue :: Value t -> LByteString
packValue Value t
x = LByteString
forall s. IsString s => s
packValuePrefix LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value t -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value t
x

-- | Same as 'packValue', for strict bytestring.
packValue' :: PackedValScope t => Value t -> ByteString
packValue' :: Value t -> ByteString
packValue' = LByteString -> ByteString
LBS.toStrict (LByteString -> ByteString)
-> (Value t -> LByteString) -> Value t -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value t -> LByteString
forall (t :: T). PackedValScope t => Value t -> LByteString
packValue

encodeValue' :: (SingI t, HasNoOp t) => Value t -> ByteString
encodeValue' :: Value t -> ByteString
encodeValue' = LByteString -> ByteString
LBS.toStrict (LByteString -> ByteString)
-> (Value t -> LByteString) -> Value t -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value t -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue

packT' :: forall (t :: T). SingI t => ByteString
packT' :: ByteString
packT' = LByteString -> ByteString
LBS.toStrict (LByteString -> ByteString) -> LByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ SingI t => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t

packCode' :: Instr inp out -> ByteString
packCode' :: Instr inp out -> ByteString
packCode' = LByteString -> ByteString
LBS.toStrict (LByteString -> ByteString)
-> (Instr inp out -> LByteString) -> Instr inp out -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs

-- | Generic serializer.
--
-- We don't require @HasNoBigMap@ constraint here since the big_map serialization
-- is only prohibited in @PACK@ instructions, however, we still want to be able to
-- serialize big_map e.g. in order to transform typed value to low-level Micheline
-- representation.
-- TODO: Serialize chain operations properly as well since they actually also have
-- byte representation.
encodeValue :: forall t. (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue :: Value t -> LByteString
encodeValue Value t
val = case (Value t
val, SingI t => Sing t
forall k (a :: k). SingI a => Sing a
sing @t) of
  (VKey PublicKey
s, SingT t
_) -> ByteString -> LByteString
encodeBytes' (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ case PublicKey
s of
    PublicKeyEd25519 PublicKey
pk -> ByteString
"\x00" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
Ed25519.publicKeyToBytes PublicKey
pk
    PublicKeySecp256k1 PublicKey
pk -> ByteString
"\x01" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
Secp256k1.publicKeyToBytes PublicKey
pk
    PublicKeyP256 PublicKey
pk -> ByteString
"\x02" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
P256.publicKeyToBytes PublicKey
pk
  (Value t
VUnit, SingT t
_) -> LByteString
"\x03\x0b"
  (VSignature Signature
x, SingT t
_) -> ByteString -> LByteString
encodeBytes' (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Signature -> ByteString
forall ba. ByteArray ba => Signature -> ba
signatureToBytes Signature
x
  (VChainId ChainId
x, SingT t
_) ->
    ByteString -> LByteString
encodeBytes' (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
ByteArray.convert (ChainId -> ByteString
unChainId ChainId
x)
  (VOption (Just Value' Instr t
x), STOption _) -> LByteString
"\x05\x09" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value' Instr t -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value' Instr t
x
  (VOption Maybe (Value' Instr t)
Nothing, SingT t
_) -> LByteString
"\x03\x06"
  (VList [Value' Instr t]
xs, STList _) -> (Value' Instr t -> LByteString) -> [Value' Instr t] -> LByteString
forall a. (a -> LByteString) -> [a] -> LByteString
encodeList Value' Instr t -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue [Value' Instr t]
xs
  (VSet Set (Value' Instr t)
xs, (STSet (st :: Sing st))) -> case Sing t -> OpPresence t
forall (ty :: T). Sing ty -> OpPresence ty
checkOpPresence Sing t
st of
    OpPresence t
OpAbsent -> (Value' Instr t -> LByteString) -> [Value' Instr t] -> LByteString
forall a. (a -> LByteString) -> [a] -> LByteString
encodeList Value' Instr t -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue (Set (Value' Instr t) -> [Element (Set (Value' Instr t))]
forall t. Container t => t -> [Element t]
toList Set (Value' Instr t)
xs)
  (VContract Address
addr SomeEntrypointCallT arg
sepc, SingT t
_) -> EpAddress -> LByteString
encodeEpAddress (EpAddress -> LByteString) -> EpAddress -> LByteString
forall a b. (a -> b) -> a -> b
$ Address -> EpName -> EpAddress
EpAddress Address
addr (SomeEntrypointCallT arg -> EpName
forall (arg :: T). SomeEntrypointCallT arg -> EpName
sepcName SomeEntrypointCallT arg
sepc)
  (VPair (Value' Instr l
v1, Value' Instr r
v2), STPair l _) ->
    case Sing l -> OpPresence l
forall (ty :: T). Sing ty -> OpPresence ty
checkOpPresence Sing l
Sing a
l of
      OpPresence l
OpAbsent -> LByteString
"\x07\x07" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value' Instr l -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value' Instr l
v1 LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value' Instr r -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value' Instr r
v2
  (VOr (Left Value' Instr l
v), STOr l _) ->
    case Sing l -> OpPresence l
forall (ty :: T). Sing ty -> OpPresence ty
checkOpPresence Sing l
Sing a
l of
      OpPresence l
OpAbsent -> LByteString
"\x05\x05" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value' Instr l -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value' Instr l
v
  (VOr (Right Value' Instr r
v), STOr l _) ->
    case Sing l -> OpPresence l
forall (ty :: T). Sing ty -> OpPresence ty
checkOpPresence Sing l
Sing a
l of
      OpPresence l
OpAbsent-> LByteString
"\x05\x08" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value' Instr r -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value' Instr r
v
  (VLam RemFail Instr '[inp] '[out]
lam, SingT t
_) -> Instr '[inp] '[out] -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs (Instr '[inp] '[out] -> LByteString)
-> Instr '[inp] '[out] -> LByteString
forall a b. (a -> b) -> a -> b
$ RemFail Instr '[inp] '[out] -> Instr '[inp] '[out]
forall k (instr :: k -> k -> *) (i :: k) (o :: k).
RemFail instr i o -> instr i o
rfAnyInstr RemFail Instr '[inp] '[out]
lam
  (VMap Map (Value' Instr k) (Value' Instr v)
m, STMap sk _) -> case Sing k -> OpPresence k
forall (ty :: T). Sing ty -> OpPresence ty
checkOpPresence Sing k
Sing a
sk of
    OpPresence k
OpAbsent -> Map (Value' Instr k) (Value' Instr v) -> LByteString
forall (v :: T) (k :: T).
(SingI v, HasNoOp v, SingI k, HasNoOp k) =>
Map (Value k) (Value v) -> LByteString
encodeMap Map (Value' Instr k) (Value' Instr v)
m
  (VBigMap Map (Value' Instr k) (Value' Instr v)
m, STBigMap sk _) -> case Sing k -> OpPresence k
forall (ty :: T). Sing ty -> OpPresence ty
checkOpPresence Sing k
Sing a
sk of
    OpPresence k
OpAbsent -> Map (Value' Instr k) (Value' Instr v) -> LByteString
forall (v :: T) (k :: T).
(SingI v, HasNoOp v, SingI k, HasNoOp k) =>
Map (Value k) (Value v) -> LByteString
encodeMap Map (Value' Instr k) (Value' Instr v)
m
  (VInt Integer
x, SingT t
STInt) -> Integer -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric Integer
x
  (VNat Natural
x, SingT t
STNat) -> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric Natural
x
  (VString MText
text, SingT t
STString) -> MText -> LByteString
encodeString MText
text
  (VBytes ByteString
bytes, SingT t
STBytes) -> ByteString -> LByteString
encodeBytes' ByteString
bytes
  (VMutez Mutez
x, SingT t
STMutez) -> Word64 -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Mutez -> Word64
unMutez Mutez
x)
  (VBool Bool
True, SingT t
STBool) -> LByteString
"\x03\x0a"
  (VBool Bool
False, SingT t
STBool) -> LByteString
"\x03\x03"
  (VKeyHash KeyHash
kh, SingT t
STKeyHash) -> LByteString -> LByteString
encodeBytes (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ KeyHash -> LByteString
encodeKeyHashRaw KeyHash
kh
  (VBls12381Fr Bls12381Fr
v, SingT t
STBls12381Fr) -> ByteString -> LByteString
encodeBytes' (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Bls12381Fr -> ByteString
forall a. CurveObject a => a -> ByteString
BLS.toMichelsonBytes Bls12381Fr
v
  (VBls12381G1 Bls12381G1
v, SingT t
STBls12381G1) -> ByteString -> LByteString
encodeBytes' (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Bls12381G1 -> ByteString
forall a. CurveObject a => a -> ByteString
BLS.toMichelsonBytes Bls12381G1
v
  (VBls12381G2 Bls12381G2
v, SingT t
STBls12381G2) -> ByteString -> LByteString
encodeBytes' (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Bls12381G2 -> ByteString
forall a. CurveObject a => a -> ByteString
BLS.toMichelsonBytes Bls12381G2
v
  (VTimestamp Timestamp
x, SingT t
STTimestamp) -> Integer -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Timestamp -> Integer
forall a. Integral a => Timestamp -> a
timestampToSeconds @Integer Timestamp
x)
  (VAddress EpAddress
addr, SingT t
STAddress) -> EpAddress -> LByteString
encodeEpAddress EpAddress
addr

encodeLength :: Int -> LByteString
encodeLength :: Int -> LByteString
encodeLength = Put -> LByteString
Bi.runPut (Put -> LByteString) -> (Int -> Put) -> Int -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> Put
Bi.putWord32be (Word32 -> Put) -> (Int -> Word32) -> Int -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral

-- | Lift encoded list content to an entire encoded list.
encodeAsList :: LByteString -> LByteString
encodeAsList :: LByteString -> LByteString
encodeAsList LByteString
bs = Int -> LByteString
encodeLength (LByteString -> Int
forall t. Container t => t -> Int
length LByteString
bs) LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
bs

-- | Encode a list-like structure.
encodeList :: (a -> LByteString) -> [a] -> LByteString
encodeList :: (a -> LByteString) -> [a] -> LByteString
encodeList a -> LByteString
encodeElem [a]
l = LByteString
"\x02" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString -> LByteString
encodeAsList ([LByteString] -> LByteString
LBS.concat ([LByteString] -> LByteString) -> [LByteString] -> LByteString
forall a b. (a -> b) -> a -> b
$ (a -> LByteString) -> [a] -> [LByteString]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map a -> LByteString
encodeElem [a]
l)

-- | Encode a text.
encodeString :: MText -> LByteString
encodeString :: MText -> LByteString
encodeString MText
text = LByteString
"\x01" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString -> LByteString
encodeAsList (Text -> LByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 (Text -> LByteString) -> Text -> LByteString
forall a b. (a -> b) -> a -> b
$ MText -> Text
unMText MText
text)

-- | Encode some raw data.
encodeBytes :: LByteString -> LByteString
encodeBytes :: LByteString -> LByteString
encodeBytes LByteString
bs =
  LByteString
"\x0a" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString -> LByteString
encodeAsList LByteString
bs

-- | Version of 'encodeBytes' that accepts a strict bytestring.
encodeBytes' :: ByteString -> LByteString
encodeBytes' :: ByteString -> LByteString
encodeBytes' = LByteString -> LByteString
encodeBytes (LByteString -> LByteString)
-> (ByteString -> LByteString) -> ByteString -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> LByteString
LBS.fromStrict

encodeEpName :: EpName -> LByteString
encodeEpName :: EpName -> LByteString
encodeEpName = Text -> LByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 (Text -> LByteString) -> (EpName -> Text) -> EpName -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Annotation FieldTag -> Text
forall k (tag :: k). Annotation tag -> Text
unAnnotation (Annotation FieldTag -> Text)
-> (EpName -> Annotation FieldTag) -> EpName -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EpName -> Annotation FieldTag
epNameToRefAnn (EpName -> Annotation FieldTag)
-> (EpName -> EpName) -> EpName -> Annotation FieldTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EpName -> EpName
canonicalize
  where
    canonicalize :: EpName -> EpName
    canonicalize :: EpName -> EpName
canonicalize (EpNameUnsafe Text
"default") = EpName
DefEpName
    canonicalize EpName
epName                   = EpName
epName

-- | Encode some map.
encodeMap :: (SingI v, HasNoOp v, SingI k, HasNoOp k) => Map (Value k) (Value v) -> LByteString
encodeMap :: Map (Value k) (Value v) -> LByteString
encodeMap Map (Value k) (Value v)
m =
  ((Value k, Value v) -> LByteString)
-> [(Value k, Value v)] -> LByteString
forall a. (a -> LByteString) -> [a] -> LByteString
encodeList (\(Value k
k, Value v
v) -> LByteString
"\x07\x04" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value k -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value k
k LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value v -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value v
v) (Map (Value k) (Value v) -> [(Value k, Value v)]
forall k a. Map k a -> [(k, a)]
Map.toList Map (Value k) (Value v)
m)

encodeKeyHashRaw :: KeyHash -> LByteString
encodeKeyHashRaw :: KeyHash -> LByteString
encodeKeyHashRaw KeyHash
kh = (LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> ByteString -> LByteString
LBS.fromStrict (KeyHash -> ByteString
khBytes KeyHash
kh)) (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
  case KeyHash -> KeyHashTag
khTag KeyHash
kh of
    KeyHashTag
KeyHashEd25519 -> LByteString
"\x00"
    KeyHashTag
KeyHashSecp256k1 -> LByteString
"\x01"
    KeyHashTag
KeyHashP256 -> LByteString
"\x02"

encodeAddress :: Address -> LByteString
encodeAddress :: Address -> LByteString
encodeAddress = \case
  KeyAddress KeyHash
keyHash ->
    LByteString
"\x00" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> (KeyHash -> LByteString
encodeKeyHashRaw KeyHash
keyHash)
  ContractAddress (ContractHash ByteString
address) ->
    LByteString
"\x01" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> ByteString -> LByteString
LBS.fromStrict ByteString
address LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x00"

encodeEpAddress :: EpAddress -> LByteString
encodeEpAddress :: EpAddress -> LByteString
encodeEpAddress (EpAddress Address
addr EpName
epName) =
  LByteString -> LByteString
encodeBytes (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Address -> LByteString
encodeAddress Address
addr LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> EpName -> LByteString
encodeEpName EpName
epName

-- | Encode contents of a given number.
encodeIntPayload :: Integer -> LByteString
encodeIntPayload :: Integer -> LByteString
encodeIntPayload = [Word8] -> LByteString
LBS.pack ([Word8] -> LByteString)
-> (Integer -> [Word8]) -> Integer -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty Word8 -> [Word8]
forall t. Container t => t -> [Element t]
toList (NonEmpty Word8 -> [Word8])
-> (Integer -> NonEmpty Word8) -> Integer -> [Word8]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> NonEmpty Word8
encodeZarithNumber

-- | Encode an int-like value.
encodeNumeric :: Integral i => i -> LByteString
encodeNumeric :: i -> LByteString
encodeNumeric i
i = LByteString
"\x00" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Integer -> LByteString
encodeIntPayload (i -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral i
i)

-- | Encode a code block.
encodeInstrs :: Instr inp out -> LByteString
encodeInstrs :: Instr inp out -> LByteString
encodeInstrs = (LByteString -> LByteString) -> [LByteString] -> LByteString
forall a. (a -> LByteString) -> [a] -> LByteString
encodeList LByteString -> LByteString
forall a. a -> a
id ([LByteString] -> LByteString)
-> (Instr inp out -> [LByteString]) -> Instr inp out -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LByteString -> [LByteString]
forall x. One x => OneItem x -> x
one (LByteString -> [LByteString])
-> (Instr inp out -> LByteString) -> Instr inp out -> [LByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr

-- | Encode an instruction.
encodeInstr :: forall inp out. Instr inp out -> LByteString
encodeInstr :: Instr inp out -> LByteString
encodeInstr = \case
  WithLoc InstrCallStack
_ Instr inp out
i ->
    Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
i
  InstrWithNotes Proxy s
proxy Rec Notes topElems
notes Instr inp (topElems ++ s)
instr ->
    Proxy s
-> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
forall (inp :: [T]) (out :: [T]) (topElems :: [T]) (rest :: [T]).
(out ~ (topElems ++ rest)) =>
Proxy rest
-> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
encodeNotedInstr Proxy s
proxy Instr inp out
Instr inp (topElems ++ s)
instr Rec Notes topElems
notes []
  InstrWithVarNotes NonEmpty VarAnn
varNotes Instr inp out
a -> case Instr inp out
a of
    AnnLEFT{} | _ :: Proxy ('TOr l r ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
      Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
forall (inp :: [T]) (out :: [T]).
Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
encodeVarNotedInstr Instr inp out
a NonEmpty VarAnn
varNotes (SingI b => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @r)
    AnnRIGHT{} | _ :: Proxy ('TOr l r ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
      Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
forall (inp :: [T]) (out :: [T]).
Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
encodeVarNotedInstr Instr inp out
a NonEmpty VarAnn
varNotes (SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @l)
    Instr inp out
_ -> Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
forall (inp :: [T]) (out :: [T]).
Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
encodeVarNotedInstr Instr inp out
a NonEmpty VarAnn
varNotes LByteString
""
  InstrWithVarAnns VarAnns
_ Instr inp out
a ->
    Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
a
  FrameInstr Proxy s
_ Instr a b
i ->
    Instr a b -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr a b
i
  Seq Instr inp b
a Instr b out
b ->
    Instr inp b -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp b
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr b out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr b out
b
  Instr inp out
Nop ->
    LByteString
forall a. Monoid a => a
mempty
  Nested Instr inp out
i ->
    Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr inp out
i
  DocGroup DocGrouping
_ Instr inp out
i ->
    Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr inp out
i
  Ext ExtInstr inp
_ ->
    LByteString
""
  Instr inp out
DROP ->
    LByteString
"\x03\x20"
  DROPN Sing n
s ->
    LByteString
"\x05\x20" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing n -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing n
s)
  Instr inp out
DUP ->
    LByteString
"\x03\x21"
  DUPN Sing n
s ->
    LByteString
"\x05\x21" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing n -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing n
s)
  Instr inp out
SWAP ->
    LByteString
"\x03\x4c"
  DIG Sing n
s ->
    LByteString
"\x05\x70" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing n -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing n
s)
  DUG Sing n
s ->
    LByteString
"\x05\x71" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing n -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing n
s)
  PUSH (Value t
a :: Value t) ->
    LByteString
"\x07\x43" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI t => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value t -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value t
a
  Instr inp out
SOME ->
    LByteString
"\x03\x46"
  Instr inp out
NONE | _ :: Proxy ('TOption t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    LByteString
"\x05\x3e" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  Instr inp out
UNIT ->
    LByteString
"\x03\x4f"
  IF_NONE Instr s out
a Instr (a : s) out
b ->
    LByteString
"\x07\x2f" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr s out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr s out
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr (a : s) out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr (a : s) out
b
  AnnPAIR TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2 ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [] LByteString
"\x03\x42"
  PAIRN Sing n
n ->
    LByteString
"\x05\x42" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing n -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing n
n)
  UNPAIRN Sing n
n ->
    LByteString
"\x05\x7a" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing n -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing n
n)
  (AnnCAR Annotation FieldTag
fn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [Annotation FieldTag
fn] [] LByteString
"\x03\x16"
  (AnnCDR Annotation FieldTag
fn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [Annotation FieldTag
fn] [] LByteString
"\x03\x17"
  (AnnLEFT TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2) | _ :: Proxy ('TOr l r ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x33" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI b => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @r
  (AnnRIGHT TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2) | _ :: Proxy ('TOr l r ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x44" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @l
  IF_LEFT Instr (a : s) out
a Instr (b : s) out
b ->
    LByteString
"\x07\x2e" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr (a : s) out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr (a : s) out
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr (b : s) out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr (b : s) out
b
  Instr inp out
NIL | _ :: Proxy ('TList t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    LByteString
"\x05\x3d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI p => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  Instr inp out
CONS ->
    LByteString
"\x03\x1b"
  IF_CONS Instr (a : 'TList a : s) out
a Instr s out
b ->
    LByteString
"\x07\x2d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr (a : 'TList a : s) out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr (a : 'TList a : s) out
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr s out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr s out
b
  Instr inp out
SIZE ->
    LByteString
"\x03\x45"
  Instr inp out
EMPTY_SET | _ :: Proxy ('TSet t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    LByteString
"\x05\x24" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI e => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  Instr inp out
EMPTY_MAP | _ :: Proxy ('TMap k v ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    LByteString
"\x07\x23" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @k LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI b => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @v
  Instr inp out
EMPTY_BIG_MAP | _ :: Proxy ('TBigMap k v ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    LByteString
"\x07\x72" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @k LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI b => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @v
  MAP Instr (MapOpInp c : s) (b : s)
a ->
    LByteString
"\x05\x38" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr (MapOpInp c : s) (b : s) -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr (MapOpInp c : s) (b : s)
a
  ITER Instr (IterOpEl c : out) out
a ->
    LByteString
"\x05\x52" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr (IterOpEl c : out) out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr (IterOpEl c : out) out
a
  Instr inp out
MEM ->
    LByteString
"\x03\x39"
  Instr inp out
GET ->
    LByteString
"\x03\x29"
  GETN Sing ix
n ->
    LByteString
"\x05\x29" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing ix -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing ix
n)
  Instr inp out
UPDATE ->
    LByteString
"\x03\x50"
  UPDATEN Sing ix
n ->
    LByteString
"\x05\x50" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing ix -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing ix
n)
  Instr inp out
GET_AND_UPDATE ->
    LByteString
"\x03\x8c"
  IF Instr s out
a Instr s out
b ->
    LByteString
"\x07\x2c" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr s out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr s out
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr s out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr s out
b
  LOOP Instr out ('TBool : out)
a ->
    LByteString
"\x05\x34" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr out ('TBool : out) -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr out ('TBool : out)
a
  LOOP_LEFT Instr (a : s) ('TOr a b : s)
a ->
    LByteString
"\x05\x53" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr (a : s) ('TOr a b : s) -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr (a : s) ('TOr a b : s)
a
  LAMBDA (Value ('TLambda i o)
v :: Value ('TLambda i o)) ->
    LByteString
"\x09\x31" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<>
    LByteString -> LByteString
encodeAsList (SingI i => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @i LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI o => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @o LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value ('TLambda i o) -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value ('TLambda i o)
v) LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<>
    Int -> LByteString
encodeLength Int
0  -- encoding of a Variable Annotation (that we don't support)
  Instr inp out
EXEC ->
    LByteString
"\x03\x26"
  Instr inp out
APPLY ->
    LByteString
"\x03\x73"
  DIP Instr a c
a ->
    LByteString
"\x05\x1f" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr a c -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr a c
a
  DIPN Sing n
s Instr s s'
a ->
    LByteString
"\x07\x1f" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Sing n -> Natural
forall (n :: Peano). KnownPeano n => Sing n -> Natural
peanoValSing Sing n
s) LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Instr s s' -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr s s'
a
  Instr inp out
FAILWITH ->
    LByteString
"\x03\x27"
  Instr inp out
CAST | _ :: Proxy (t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    LByteString
"\x05\x57" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  Instr inp out
RENAME ->
    LByteString
"\x03\x58"
  Instr inp out
PACK ->
    LByteString
"\x03\x0c"
  Instr inp out
UNPACK | _ :: Proxy ('TOption t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    LByteString
"\x05\x0d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  Instr inp out
CONCAT ->
    LByteString
"\x03\x1a"
  Instr inp out
CONCAT' ->
    LByteString
"\x03\x1a"
  Instr inp out
SLICE ->
    LByteString
"\x03\x6f"
  Instr inp out
ISNAT ->
    LByteString
"\x03\x56"
  Instr inp out
ADD ->
    LByteString
"\x03\x12"
  Instr inp out
SUB ->
    LByteString
"\x03\x4b"
  Instr inp out
MUL ->
    LByteString
"\x03\x3a"
  Instr inp out
EDIV ->
    LByteString
"\x03\x22"
  Instr inp out
ABS ->
    LByteString
"\x03\x11"
  Instr inp out
NEG ->
    LByteString
"\x03\x3b"
  Instr inp out
LSL ->
    LByteString
"\x03\x35"
  Instr inp out
LSR ->
    LByteString
"\x03\x36"
  Instr inp out
OR ->
    LByteString
"\x03\x41"
  Instr inp out
AND ->
    LByteString
"\x03\x14"
  Instr inp out
XOR ->
    LByteString
"\x03\x51"
  Instr inp out
NOT ->
    LByteString
"\x03\x3f"
  Instr inp out
COMPARE ->
    LByteString
"\x03\x19"
  Instr inp out
EQ ->
    LByteString
"\x03\x25"
  Instr inp out
NEQ ->
    LByteString
"\x03\x3c"
  Instr inp out
LT ->
    LByteString
"\x03\x37"
  Instr inp out
GT ->
    LByteString
"\x03\x2a"
  Instr inp out
LE ->
    LByteString
"\x03\x32"
  Instr inp out
GE ->
    LByteString
"\x03\x28"
  Instr inp out
INT ->
    LByteString
"\x03\x30"
  SELF SomeEntrypointCallT arg
sepc ->
    case SomeEntrypointCallT arg -> EpName
forall (arg :: T). SomeEntrypointCallT arg -> EpName
sepcName SomeEntrypointCallT arg
sepc of
      EpName
DefEpName ->  LByteString
"\x03\x49"
      EpName
epName -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [EpName -> Annotation FieldTag
epNameToRefAnn EpName
epName] [] LByteString
"\x03\x49"
  CONTRACT Notes p
ns EpName
ep | _ :: Proxy ('TOption ('TContract t) ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [EpName -> Annotation FieldTag
epNameToRefAnn EpName
ep] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x55" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes p -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @t Notes p
ns
  Instr inp out
TRANSFER_TOKENS ->
    LByteString
"\x03\x4d"
  Instr inp out
SET_DELEGATE ->
    LByteString
"\x03\x4e"
  CREATE_CONTRACT contract :: Contract p g
contract@Contract{EntriesOrder
Notes g
ParamNotes p
ContractCode p g
cEntriesOrder :: forall (cp :: T) (st :: T). Contract cp st -> EntriesOrder
cStoreNotes :: forall (cp :: T) (st :: T). Contract cp st -> Notes st
cParamNotes :: forall (cp :: T) (st :: T). Contract cp st -> ParamNotes cp
cCode :: forall (cp :: T) (st :: T). Contract cp st -> ContractCode cp st
cEntriesOrder :: EntriesOrder
cStoreNotes :: Notes g
cParamNotes :: ParamNotes p
cCode :: ContractCode p g
..}
    | ContractCode p g
_ :: Instr '[ 'TPair p g ] '[ 'TPair ('TList 'TOperation) g ] <- ContractCode p g
cCode ->
    let contents :: [LByteString]
contents = Contract p g
-> (ParamNotes p -> LByteString)
-> (Notes g -> LByteString)
-> (ContractCode p g -> LByteString)
-> [LByteString]
forall (cp :: T) (st :: T) a.
Contract cp st
-> (ParamNotes cp -> a)
-> (Notes st -> a)
-> (ContractCode cp st -> a)
-> [a]
mapEntriesOrdered Contract p g
contract
            (\ParamNotes p
np -> LByteString
"\x05\x00" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> ParamNotes p -> LByteString
forall (t :: T). SingI t => ParamNotes t -> LByteString
encodeParamNotes' @p ParamNotes p
np)
            (\Notes g
ng -> LByteString
"\x05\x01" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes g -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @g Notes g
ng)
            (\ContractCode p g
instr -> LByteString
"\x05\x02" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> ContractCode p g -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs ContractCode p g
instr)
    in LByteString
"\x05\x1d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> (LByteString -> LByteString) -> [LByteString] -> LByteString
forall a. (a -> LByteString) -> [a] -> LByteString
encodeList LByteString -> LByteString
forall a. a -> a
id [LByteString]
contents
  Instr inp out
IMPLICIT_ACCOUNT ->
   LByteString
"\x03\x1e"
  Instr inp out
NOW ->
   LByteString
"\x03\x40"
  Instr inp out
AMOUNT ->
   LByteString
"\x03\x13"
  Instr inp out
BALANCE ->
   LByteString
"\x03\x15"
  Instr inp out
VOTING_POWER ->
   LByteString
"\x03\x7b"
  Instr inp out
TOTAL_VOTING_POWER ->
   LByteString
"\x03\x7c"
  Instr inp out
CHECK_SIGNATURE ->
   LByteString
"\x03\x18"
  Instr inp out
SHA256 ->
   LByteString
"\x03\x0f"
  Instr inp out
SHA512 ->
   LByteString
"\x03\x10"
  Instr inp out
BLAKE2B ->
   LByteString
"\x03\x0e"
  Instr inp out
SHA3 ->
   LByteString
"\x03\x7e"
  Instr inp out
KECCAK ->
   LByteString
"\x03\x7d"
  Instr inp out
HASH_KEY ->
   LByteString
"\x03\x2b"
  Instr inp out
PAIRING_CHECK ->
   LByteString
"\x03\x7f"
  Instr inp out
SOURCE ->
   LByteString
"\x03\x47"
  Instr inp out
SENDER ->
   LByteString
"\x03\x48"
  Instr inp out
ADDRESS ->
   LByteString
"\x03\x54"
  Instr inp out
CHAIN_ID ->
   LByteString
"\x03\x75"
  Instr inp out
LEVEL ->
   LByteString
"\x03\x76"
  Instr inp out
SELF_ADDRESS ->
   LByteString
"\x03\x77"
  Instr inp out
NEVER ->
   LByteString
"\x03\x79"


-- | Iff there are non-empty annotations it increments the value's tag and
-- appends the encoded annotations.
encodeWithAnns :: [TypeAnn] -> [FieldAnn] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns :: [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn]
tns [Annotation FieldTag]
fns [VarAnn]
vns LByteString
encodedInput
  | LByteString -> Bool
forall t. Container t => t -> Bool
null LByteString
encodedInput = LByteString
encodedInput
  | AnnotationSet -> Bool
isNoAnnSet AnnotationSet
annSet = LByteString
encodedInput
  | Bool
otherwise = LByteString
inputIncrem LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
encodedAnns
  where
    annSet :: AnnotationSet
annSet = [TypeAnn] -> [Annotation FieldTag] -> [VarAnn] -> AnnotationSet
fullAnnSet [TypeAnn]
tns [Annotation FieldTag]
fns [VarAnn]
vns
    encodedAnns :: LByteString
encodedAnns = LByteString -> LByteString
encodeAsList (LByteString -> LByteString)
-> (Text -> LByteString) -> Text -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> LByteString
forall a b. ConvertUtf8 a b => a -> b
encodeUtf8 (Text -> LByteString) -> Text -> LByteString
forall a b. (a -> b) -> a -> b
$ AnnotationSet -> Text
forall b a. (Show a, IsString b) => a -> b
show @Text AnnotationSet
annSet
    inputIncrem :: LByteString
inputIncrem = (Word8
1 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+ LByteString -> Word8
LBS.head LByteString
encodedInput) Word8 -> LByteString -> LByteString
`LBS.cons` LByteString -> LByteString
LBS.tail LByteString
encodedInput

-- | Encode an instruction with variable annotations
encodeVarNotedInstr :: Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
encodeVarNotedInstr :: Instr inp out -> NonEmpty VarAnn -> LByteString -> LByteString
encodeVarNotedInstr Instr inp out
i vns' :: NonEmpty VarAnn
vns'@(NonEmpty VarAnn -> [Element (NonEmpty VarAnn)]
forall t. Container t => t -> [Element t]
toList -> [Element (NonEmpty VarAnn)]
vns) LByteString
encodedType = case Instr inp out
i of
  InstrWithNotes Proxy s
proxy Rec Notes topElems
n Instr inp (topElems ++ s)
a -> Proxy s
-> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
forall (inp :: [T]) (out :: [T]) (topElems :: [T]) (rest :: [T]).
(out ~ (topElems ++ rest)) =>
Proxy rest
-> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
encodeNotedInstr Proxy s
proxy Instr inp out
Instr inp (topElems ++ s)
a Rec Notes topElems
n [Element (NonEmpty VarAnn)]
[VarAnn]
vns
  InstrWithVarAnns VarAnns
_ Instr inp out
a -> Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr (Instr inp out -> LByteString) -> Instr inp out -> LByteString
forall a b. (a -> b) -> a -> b
$ NonEmpty VarAnn -> Instr inp out -> Instr inp out
forall (a :: [T]) (b :: [T]).
NonEmpty VarAnn -> Instr a b -> Instr a b
InstrWithVarNotes NonEmpty VarAnn
vns' Instr inp out
a
  -- AnnPAIR, AnnCAR, AnnCDR and AnnLEFT, AnnRIGHT are checked here because
  -- their cases on `encodeInstr` increment them to \x04 and to \x05 respectively
  -- when they have a field annotation, but they would also get increment due to
  -- variable annotations, resulting in incorrect \x05 and \x06 codes respectively.
  AnnPAIR TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2 -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [Element (NonEmpty VarAnn)]
[VarAnn]
vns LByteString
"\x03\x42"
  AnnCAR Annotation FieldTag
fn -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [Annotation FieldTag
fn] [Element (NonEmpty VarAnn)]
[VarAnn]
vns LByteString
"\x03\x16"
  AnnCDR Annotation FieldTag
fn -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [Annotation FieldTag
fn] [Element (NonEmpty VarAnn)]
[VarAnn]
vns LByteString
"\x03\x17"
  AnnLEFT TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2 -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [Element (NonEmpty VarAnn)]
[VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x33" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
encodedType
  AnnRIGHT TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2 -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [Element (NonEmpty VarAnn)]
[VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x44" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
encodedType
  Instr inp out
_ -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [] [Element (NonEmpty VarAnn)]
[VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
i

-- | Encode an instruction with Annotations
encodeNotedInstr
  :: forall inp out topElems rest.
     out ~ (topElems ++ rest)
  => Proxy rest -> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
encodeNotedInstr :: Proxy rest
-> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
encodeNotedInstr Proxy rest
proxy Instr inp out
instr Rec Notes topElems
notes [VarAnn]
vns = case (Instr inp out
instr, Proxy out
forall k (t :: k). Proxy t
Proxy @out, Rec Notes topElems
notes) of
  (WithLoc InstrCallStack
_ Instr inp out
instr', Proxy out
_, Rec Notes topElems
_) ->
    Proxy rest
-> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
forall (inp :: [T]) (out :: [T]) (topElems :: [T]) (rest :: [T]).
(out ~ (topElems ++ rest)) =>
Proxy rest
-> Instr inp out -> Rec Notes topElems -> [VarAnn] -> LByteString
encodeNotedInstr Proxy rest
proxy Instr inp out
instr' Rec Notes topElems
notes [VarAnn]
vns
  (Instr inp out
SOME, Proxy out
_, NTOption TypeAnn
tn Notes t
_ns :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
instr
  (Instr inp out
NONE, _ :: Proxy ('TOption t ': s), NTOption TypeAnn
tn Notes t
ns :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x3e" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes a -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @t Notes a
Notes t
ns
  (Instr inp out
UNIT, Proxy out
_, NTUnit TypeAnn
tn :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
instr
  (Instr inp out
NIL, _ :: Proxy ('TList t ': s), NTList TypeAnn
tn Notes t
ns :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x3d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes p -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @t Notes p
Notes t
ns
  (Instr inp out
EMPTY_SET, _ :: Proxy ('TSet t ': s), NTSet TypeAnn
tn Notes t
ns :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x24" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes e -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @t Notes e
Notes t
ns
  (Instr inp out
EMPTY_MAP, _ :: Proxy ('TMap k v ': s), NTMap TypeAnn
tn1 Notes k
nk Notes v
ns :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn1] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      LByteString
"\x07\x23" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes a -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @k Notes a
Notes k
nk LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes b -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @v Notes b
Notes v
ns
  (Instr inp out
EMPTY_BIG_MAP, _ :: Proxy ('TBigMap k v ': s), NTBigMap TypeAnn
tn1 Notes k
nk Notes v
ns :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn1] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      LByteString
"\x07\x72" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes a -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @k Notes a
Notes k
nk LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes b -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @v Notes b
Notes v
ns
  (PUSH (Value t
v :: Value t), Proxy out
_, Notes r
tn :& Rec Notes rs
_) ->
    LByteString
"\x07\x43" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes t -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @t Notes t
Notes r
tn LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value t -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value t
v
  (LAMBDA (Value ('TLambda i o)
v :: Value ('TLambda i o)), Proxy out
_, NTLambda TypeAnn
_tn Notes p
ns1 Notes q
ns2 :& Rec Notes rs
_) ->
    LByteString
"\x09\x31" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<>
    LByteString -> LByteString
encodeAsList (Notes i -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @i Notes i
Notes p
ns1 LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes o -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @o Notes o
Notes q
ns2 LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Value ('TLambda i o) -> LByteString
forall (t :: T). (SingI t, HasNoOp t) => Value t -> LByteString
encodeValue Value ('TLambda i o)
v) LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<>
    Int -> LByteString
encodeLength Int
0  -- encoding of a Variable Annotation (that we don't support)
  (Instr inp out
CAST, _ :: Proxy (t ': s), Notes r
tn :& Rec Notes rs
_) ->
    LByteString
"\x05\x57" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes a -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @t Notes a
Notes r
tn
  (Instr inp out
UNPACK, _ :: Proxy ('TOption t ': s), NTOption TypeAnn
tn Notes t
ns :& Rec Notes rs
_) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x0d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes a -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @t Notes a
Notes t
ns
  -- NOTE: `CONTRACT` may be part of an `InstrWithNotes` with `NTOption`, but is
  -- taken care of in `encodeInstr` anyway (because it contains the note itself)
  (Instr inp out, Proxy out, Rec Notes topElems)
_ -> Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
instr

packNotedT' :: forall (t :: T). SingI t => Notes t -> ByteString
packNotedT' :: Notes t -> ByteString
packNotedT' = LByteString -> ByteString
LBS.toStrict (LByteString -> ByteString)
-> (Notes t -> LByteString) -> Notes t -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Notes t -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT'

encodeNotedT' :: forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' :: Notes t -> LByteString
encodeNotedT' = Sing t -> Annotation FieldTag -> Notes t -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST (SingI t => Sing t
forall k (a :: k). SingI a => Sing a
sing @t) Annotation FieldTag
forall k (a :: k). Annotation a
noAnn

encodeParamNotes' ::
  forall (t :: T). SingI t => ParamNotes t -> LByteString
encodeParamNotes' :: ParamNotes t -> LByteString
encodeParamNotes' ParamNotesUnsafe{Annotation FieldTag
Notes t
pnRootAnn :: forall (t :: T). ParamNotes t -> Annotation FieldTag
pnNotes :: forall (t :: T). ParamNotes t -> Notes t
pnRootAnn :: Annotation FieldTag
pnNotes :: Notes t
..} = Sing t -> Annotation FieldTag -> Notes t -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST (SingI t => Sing t
forall k (a :: k). SingI a => Sing a
sing @t) Annotation FieldTag
pnRootAnn Notes t
pnNotes

-- Note: to encode field annotations we have to accept them as an additional
-- parameter because they are stored in the parent's `Notes t`, e.g. see STPair.
encodeNotedST :: Sing t -> FieldAnn -> Notes t -> LByteString
encodeNotedST :: Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing t
st Annotation FieldTag
fn Notes t
n = case (Sing t
SingT t
st, Notes t
n) of
  (SingT t
STInt, NTInt TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TInt -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TInt
st)
  (SingT t
STNat, NTNat TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TNat -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TNat
st)
  (SingT t
STString, NTString TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TString -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TString
st)
  (SingT t
STBytes, NTBytes TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TBytes -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TBytes
st)
  (SingT t
STMutez, NTMutez TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TMutez -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TMutez
st)
  (SingT t
STBool, NTBool TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TBool -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TBool
st)
  (SingT t
STKeyHash, NTKeyHash TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TKeyHash -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TKeyHash
st)
  (SingT t
STBls12381Fr, NTBls12381Fr TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TBls12381Fr -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TBls12381Fr
st)
  (SingT t
STBls12381G1, NTBls12381G1 TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TBls12381G1 -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TBls12381G1
st)
  (SingT t
STBls12381G2, NTBls12381G2 TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TBls12381G2 -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TBls12381G2
st)
  (SingT t
STTimestamp, NTTimestamp TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TTimestamp -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TTimestamp
st)
  (SingT t
STAddress, NTAddress TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ T -> LByteString
encodeT (Sing 'TAddress -> T
forall (a :: T). Sing a -> T
fromSingT Sing t
Sing 'TAddress
st)

  (SingT t
STKey, NTKey TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x03\x5c"
  (SingT t
STUnit, NTUnit TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x03\x6c"
  (SingT t
STNever, NTNever TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x03\x78"
  (SingT t
STSignature, NTSignature TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x03\x67"
  (SingT t
STChainId, NTChainId TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x03\x74"
  (STOption Sing a
a, NTOption TypeAnn
tn Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x63" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing t -> Annotation FieldTag -> Notes t -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing t
a Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes t
ns
  (STList Sing a
a, NTList TypeAnn
tn Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x5f" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing t -> Annotation FieldTag -> Notes t -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing t
a Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes t
ns
  (STSet Sing a
a, NTSet TypeAnn
tn Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x66" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing t -> Annotation FieldTag -> Notes t -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing t
a Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes t
ns
  (SingT t
STOperation, NTOperation TypeAnn
tn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x03\x6d"
  (STContract Sing a
a, NTContract TypeAnn
tn Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ LByteString
"\x05\x5a" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing t -> Annotation FieldTag -> Notes t -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing t
a Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes t
ns
  (STPair Sing a
a Sing b
b, NTPair TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2 VarAnn
_vn1 VarAnn
_vn2 Notes p
ns1 Notes q
ns2) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      LByteString
"\x07\x65" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing p -> Annotation FieldTag -> Notes p -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing p
a Annotation FieldTag
fn1 Notes p
ns1 LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing q -> Annotation FieldTag -> Notes q -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing b
Sing q
b Annotation FieldTag
fn2 Notes q
ns2
  (STOr Sing a
a Sing b
b, NTOr TypeAnn
tn Annotation FieldTag
fn1 Annotation FieldTag
fn2 Notes p
ns1 Notes q
ns2) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      LByteString
"\x07\x64" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing p -> Annotation FieldTag -> Notes p -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing p
a Annotation FieldTag
fn1 Notes p
ns1 LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing q -> Annotation FieldTag -> Notes q -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing b
Sing q
b Annotation FieldTag
fn2 Notes q
ns2
  (STLambda Sing a
a Sing b
r, NTLambda TypeAnn
tn Notes p
ns1 Notes q
ns2) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      LByteString
"\x07\x5e" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing p -> Annotation FieldTag -> Notes p -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing p
a Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes p
ns1 LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing q -> Annotation FieldTag -> Notes q -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing b
Sing q
r Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes q
ns2
  (STMap Sing a
k Sing b
v, NTMap TypeAnn
tn Notes k
nk Notes v
nv) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      LByteString
"\x07\x60" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing k -> Annotation FieldTag -> Notes k -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing k
k Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes k
nk LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing v -> Annotation FieldTag -> Notes v -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing b
Sing v
v Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes v
nv
  (STBigMap Sing a
k Sing b
v, NTBigMap TypeAnn
tn Notes k
nk Notes v
nv) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn] [] (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      LByteString
"\x07\x61" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing k -> Annotation FieldTag -> Notes k -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing a
Sing k
k Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes k
nk LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Sing v -> Annotation FieldTag -> Notes v -> LByteString
forall (t :: T).
Sing t -> Annotation FieldTag -> Notes t -> LByteString
encodeNotedST Sing b
Sing v
v Annotation FieldTag
forall k (a :: k). Annotation a
noAnn Notes v
nv

encodeT :: T -> LByteString
encodeT :: T -> LByteString
encodeT = \case
  T
TKey  -> LByteString
"\x03\x5c"
  T
TUnit -> LByteString
"\x03\x6c"
  T
TNever -> LByteString
"\x03\x78"
  T
TSignature -> LByteString
"\x03\x67"
  T
TChainId -> LByteString
"\x03\x74"
  TOption T
t -> LByteString
"\x05\x63" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  TList T
t -> LByteString
"\x05\x5f" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  TSet T
t -> LByteString
"\x05\x66" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  T
TOperation -> LByteString
"\x03\x6d"
  TContract T
t -> LByteString
"\x05\x5a" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  TPair T
a T
b -> LByteString
"\x07\x65" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
b
  TOr T
a T
b -> LByteString
"\x07\x64" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
b
  TLambda T
a T
r -> LByteString
"\x07\x5e" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
a LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
r
  TMap T
k T
v -> LByteString
"\x07\x60" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
k LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
v
  TBigMap T
k T
v -> LByteString
"\x07\x61" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
k LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
v
  T
TInt -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x5b"
  T
TNat -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x62"
  T
TString -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x68"
  T
TBytes -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x69"
  T
TMutez -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x6a"
  T
TBool -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x59"
  T
TKeyHash -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x5d"
  T
TBls12381Fr -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x82"
  T
TBls12381G1 -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x80"
  T
TBls12381G2 -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x81"
  T
TTimestamp -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x6b"
  T
TAddress -> LByteString
"\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString
"\x6e"

encodeT' :: forall (t :: T). SingI t => LByteString
encodeT' :: LByteString
encodeT' = T -> LByteString
encodeT ((SingKind T, SingI t) => Demote T
forall k (a :: k). (SingKind k, SingI a) => Demote k
demote @t)