-- 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 Control.Exception (assert)
import qualified Data.Binary.Put as Bi
import qualified Data.Bits as Bits
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 Michelson.Text
import Michelson.Typed
import Michelson.Untyped.Annotation
  (Annotation(..), FieldAnn, TypeAnn, VarAnn, convAnn, 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.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 = "\x05"

-- | Serialize a value given to @PACK@ instruction.
packValue :: PackedValScope t => Value t -> LByteString
packValue :: Value t -> LByteString
packValue x :: 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 val :: Value t
val = case (Value t
val, SingI t => Sing t
forall k (a :: k). SingI a => Sing a
sing @t) of
  (VKey s :: PublicKey
s, _) -> LByteString -> LByteString
encodeBytes (LByteString -> LByteString)
-> (ByteString -> LByteString) -> ByteString -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> LByteString
LBS.fromStrict (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ case PublicKey
s of
    PublicKeyEd25519 pk :: PublicKey
pk -> "\x00" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
Ed25519.publicKeyToBytes PublicKey
pk
    PublicKeySecp256k1 pk :: PublicKey
pk -> "\x01" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
Secp256k1.publicKeyToBytes PublicKey
pk
    PublicKeyP256 pk :: PublicKey
pk -> "\x02" ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
P256.publicKeyToBytes PublicKey
pk
  (VUnit, _) -> "\x03\x0b"
  (VSignature x :: Signature
x, _) -> LByteString -> LByteString
encodeBytes (LByteString -> LByteString)
-> (ByteString -> LByteString) -> ByteString -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> LByteString
LBS.fromStrict (ByteString -> LByteString) -> ByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ Signature -> ByteString
forall ba. ByteArray ba => Signature -> ba
signatureToBytes Signature
x
  (VChainId x :: ChainId
x, _) ->
    LByteString -> LByteString
encodeBytes (LByteString -> LByteString)
-> (ByteString -> LByteString) -> ByteString -> LByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> LByteString
LBS.fromStrict (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 x :: Value' Instr t
x), STOption _) -> "\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 Nothing, _) -> "\x03\x06"
  (VList xs :: [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 xs :: 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
    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 addr :: Address
addr sepc :: SomeEntrypointCallT arg
sepc, _) -> 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 (v1 :: Value' Instr l
v1, v2 :: 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
      OpAbsent -> "\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 v :: 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
      OpAbsent -> "\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 v :: 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
      OpAbsent-> "\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 lam :: RemFail Instr '[inp] '[out]
lam, _) -> 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 m :: 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
    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 m :: 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
    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 x :: Integer
x, STInt) -> Integer -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric Integer
x
  (VNat x :: Natural
x, STNat) -> Natural -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric Natural
x
  (VString text :: MText
text, STString) -> MText -> LByteString
encodeString MText
text
  (VBytes bytes :: ByteString
bytes, STBytes) -> LByteString -> LByteString
encodeBytes (ByteString -> LByteString
LBS.fromStrict ByteString
bytes)
  (VMutez x :: Mutez
x, STMutez) -> Word64 -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Mutez -> Word64
unMutez Mutez
x)
  (VBool True, STBool) -> "\x03\x0a"
  (VBool False, STBool) -> "\x03\x03"
  (VKeyHash kh :: KeyHash
kh, STKeyHash) -> LByteString -> LByteString
encodeBytes (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ KeyHash -> LByteString
encodeKeyHashRaw KeyHash
kh
  (VTimestamp x :: Timestamp
x, STTimestamp) -> Integer -> LByteString
forall i. Integral i => i -> LByteString
encodeNumeric (Timestamp -> Integer
forall a. Integral a => Timestamp -> a
timestampToSeconds @Integer Timestamp
x)
  (VAddress addr :: EpAddress
addr, 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 bs :: 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 encodeElem :: a -> LByteString
encodeElem l :: [a]
l = "\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 text :: MText
text = "\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 bs :: LByteString
bs =
  "\x0a" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> LByteString -> LByteString
encodeAsList LByteString
bs

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

-- | 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 m :: Map (Value k) (Value v)
m =
  ((Value k, Value v) -> LByteString)
-> [(Value k, Value v)] -> LByteString
forall a. (a -> LByteString) -> [a] -> LByteString
encodeList (\(k :: Value k
k, v :: Value v
v) -> "\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 kh :: 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
    KeyHashEd25519 -> "\x00"
    KeyHashSecp256k1 -> "\x01"
    KeyHashP256 -> "\x02"

encodeAddress :: Address -> LByteString
encodeAddress :: Address -> LByteString
encodeAddress = \case
  KeyAddress keyHash :: KeyHash
keyHash ->
    "\x00" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> (KeyHash -> LByteString
encodeKeyHashRaw KeyHash
keyHash)
  ContractAddress (ContractHash address :: ByteString
address) ->
    "\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
<> "\x00"

encodeEpAddress :: EpAddress -> LByteString
encodeEpAddress :: EpAddress -> LByteString
encodeEpAddress (EpAddress addr :: Address
addr epName :: 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
. Bool -> Integer -> NonEmpty Word8
doEncode Bool
True
  where
    {- Numbers are represented as follows:

    byte 0:         1              _         ______   ||  lowest digits
            has continuation  is negative   payload   ||
                                                      ||
    byte 1:         1                       _______   ||
    ...             1                       _______   ||
    byte n:         0                       _______   ||
            has continuation                payload   \/  highest digits
    -}
    doEncode :: Bool -> Integer -> NonEmpty Word8
    doEncode :: Bool -> Integer -> NonEmpty Word8
doEncode isFirst :: Bool
isFirst a :: Integer
a
      | Integer
a Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
byteWeight =
          let (hi :: Integer
hi, lo :: Integer
lo) = Integer
a Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` Integer
byteWeight
              byte :: Word8
byte = Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
Bits.setBit (Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral @_ @Word8 Integer
lo) 7
          in Word8
byte Word8 -> [Word8] -> NonEmpty Word8
forall a. a -> [a] -> NonEmpty a
:| NonEmpty Word8 -> [Element (NonEmpty Word8)]
forall t. Container t => t -> [Element t]
toList (Bool -> Integer -> NonEmpty Word8
doEncode Bool
False Integer
hi)
      | Integer
a Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= 0 =
          OneItem (NonEmpty Word8) -> NonEmpty Word8
forall x. One x => OneItem x -> x
one (Integer -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral @_ @Word8 Integer
a)
      | Bool
otherwise = Bool -> NonEmpty Word8 -> NonEmpty Word8
forall a. (?callStack::CallStack) => Bool -> a -> a
assert Bool
isFirst (NonEmpty Word8 -> NonEmpty Word8)
-> NonEmpty Word8 -> NonEmpty Word8
forall a b. (a -> b) -> a -> b
$
          let h :: Word8
h :| t :: [Word8]
t = Bool -> Integer -> NonEmpty Word8
doEncode Bool
True (-Integer
a)
          in Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
Bits.setBit Word8
h 6 Word8 -> [Word8] -> NonEmpty Word8
forall a. a -> [a] -> NonEmpty a
:| [Word8]
t
      where
        byteWeight :: Integer
byteWeight = if Bool
isFirst then 64 else 128

-- | Encode an int-like value.
encodeNumeric :: Integral i => i -> LByteString
encodeNumeric :: i -> LByteString
encodeNumeric i :: i
i = "\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 _ i :: Instr inp out
i ->
    Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
i
  InstrWithNotes n :: PackedNotes out
n a :: Instr inp out
a ->
    Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
forall (inp :: [T]) (out :: [T]).
Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
encodeNotedInstr Instr inp out
a PackedNotes out
n []
  InstrWithVarNotes varNotes :: NonEmpty VarAnn
varNotes a :: Instr inp out
a ->
    Instr inp out -> NonEmpty VarAnn -> LByteString
forall (inp :: [T]) (out :: [T]).
Instr inp out -> NonEmpty VarAnn -> LByteString
encodeVarNotedInstr Instr inp out
a NonEmpty VarAnn
varNotes
  FrameInstr _ i :: Instr a b
i ->
    Instr a b -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr a b
i
  Seq a :: Instr inp b
a b :: 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
  Nop ->
    LByteString
forall a. Monoid a => a
mempty
  Nested i :: Instr inp out
i ->
    Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr inp out
i
  DocGroup _ i :: Instr inp out
i ->
    Instr inp out -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstrs Instr inp out
i
  Ext _ ->
    ""
  DROP ->
    "\x03\x20"
  DROPN s :: Sing n
s ->
    "\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)
  DUP ->
    "\x03\x21"
  SWAP ->
    "\x03\x4c"
  DIG s :: Sing n
s ->
    "\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 s :: Sing n
s ->
    "\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) ->
    "\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
  SOME ->
    "\x03\x46"
  NONE | _ :: Proxy ('TOption t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\x05\x3e" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  UNIT ->
    "\x03\x4f"
  IF_NONE a :: Instr s out
a b :: Instr (a : s) out
b ->
    "\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 tn :: TypeAnn
tn fn1 :: Annotation FieldTag
fn1 fn2 :: Annotation FieldTag
fn2 ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [] "\x03\x42"
  (AnnCAR fn :: Annotation FieldTag
fn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [Annotation FieldTag
fn] [] "\x03\x16"
  (AnnCDR fn :: Annotation FieldTag
fn) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [Annotation FieldTag
fn] [] "\x03\x17"
  LEFT | _ :: Proxy ('TOr l r ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\x05\x33" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI b => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @r
  RIGHT | _ :: Proxy ('TOr l r ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\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 a :: Instr (a : s) out
a b :: Instr (b : s) out
b ->
    "\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
  NIL | _ :: Proxy ('TList t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\x05\x3d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI p => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  CONS ->
    "\x03\x1b"
  IF_CONS a :: Instr (a : 'TList a : s) out
a b :: Instr s out
b ->
    "\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
  SIZE ->
    "\x03\x45"
  EMPTY_SET | _ :: Proxy ('TSet t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\x05\x24" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI e => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  EMPTY_MAP | _ :: Proxy ('TMap k v ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\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
  EMPTY_BIG_MAP | _ :: Proxy ('TBigMap k v ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\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 a :: Instr (MapOpInp c : s) (b : s)
a ->
    "\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 a :: Instr (IterOpEl c : out) out
a ->
    "\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
  MEM ->
    "\x03\x39"
  GET ->
    "\x03\x29"
  UPDATE ->
    "\x03\x50"
  IF a :: Instr s out
a b :: Instr s out
b ->
    "\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 a :: Instr out ('TBool : out)
a ->
    "\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 a :: Instr (a : s) ('TOr a b : s)
a ->
    "\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)) ->
    "\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 0  -- encoding of a Variable Annotation (that we don't support)
  EXEC ->
    "\x03\x26"
  APPLY ->
    "\x03\x73"
  DIP a :: Instr a c
a ->
    "\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 s :: Sing n
s a :: Instr s s'
a ->
    "\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
  FAILWITH ->
    "\x03\x27"
  CAST | _ :: Proxy (t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\x05\x57" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  RENAME ->
    "\x03\x58"
  PACK ->
    "\x03\x0c"
  UNPACK | _ :: Proxy ('TOption t ': s) <- Proxy out
forall k (t :: k). Proxy t
Proxy @out ->
    "\x05\x0d" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> SingI a => LByteString
forall (t :: T). SingI t => LByteString
encodeT' @t
  CONCAT ->
    "\x03\x1a"
  CONCAT' ->
    "\x03\x1a"
  SLICE ->
    "\x03\x6f"
  ISNAT ->
    "\x03\x56"
  ADD ->
    "\x03\x12"
  SUB ->
    "\x03\x4b"
  MUL ->
    "\x03\x3a"
  EDIV ->
    "\x03\x22"
  ABS ->
    "\x03\x11"
  NEG ->
    "\x03\x3b"
  LSL ->
    "\x03\x35"
  LSR ->
    "\x03\x36"
  OR ->
    "\x03\x41"
  AND ->
    "\x03\x14"
  XOR ->
    "\x03\x51"
  NOT ->
    "\x03\x3f"
  COMPARE ->
    "\x03\x19"
  EQ ->
    "\x03\x25"
  NEQ ->
    "\x03\x3c"
  LT ->
    "\x03\x37"
  GT ->
    "\x03\x2a"
  LE ->
    "\x03\x32"
  GE ->
    "\x03\x28"
  INT ->
    "\x03\x30"
  SELF sepc :: SomeEntrypointCallT arg
sepc ->
    case SomeEntrypointCallT arg -> EpName
forall (arg :: T). SomeEntrypointCallT arg -> EpName
sepcName SomeEntrypointCallT arg
sepc of
      DefEpName ->  "\x03\x49"
      epName :: EpName
epName -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [EpName -> Annotation FieldTag
epNameToRefAnn EpName
epName] [] "\x03\x49"
  CONTRACT ns :: Notes p
ns ep :: 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
$ "\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
  TRANSFER_TOKENS ->
    "\x03\x4d"
  SET_DELEGATE ->
    "\x03\x4e"
  CREATE_CONTRACT contract :: Contract p g
contract@Contract{..}
    | 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
            (\np :: ParamNotes p
np -> "\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)
            (\ng :: Notes g
ng -> "\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)
            (\instr :: ContractCode p g
instr -> "\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 "\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
  IMPLICIT_ACCOUNT ->
   "\x03\x1e"
  NOW ->
   "\x03\x40"
  AMOUNT ->
   "\x03\x13"
  BALANCE ->
   "\x03\x15"
  CHECK_SIGNATURE ->
   "\x03\x18"
  SHA256 ->
   "\x03\x0f"
  SHA512 ->
   "\x03\x10"
  BLAKE2B ->
   "\x03\x0e"
  HASH_KEY ->
   "\x03\x2b"
  SOURCE ->
   "\x03\x47"
  SENDER ->
   "\x03\x48"
  ADDRESS ->
   "\x03\x54"
  CHAIN_ID ->
   "\x03\x75"

-- | 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 tns :: [TypeAnn]
tns fns :: [Annotation FieldTag]
fns vns :: [VarAnn]
vns encodedInput :: 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 = (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
encodeVarNotedInstr :: Instr inp out -> NonEmpty VarAnn -> LByteString
encodeVarNotedInstr i :: Instr inp out
i vns :: NonEmpty VarAnn
vns = case Instr inp out
i of
  InstrWithNotes n :: PackedNotes out
n a :: Instr inp out
a -> Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
forall (inp :: [T]) (out :: [T]).
Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
encodeNotedInstr Instr inp out
a PackedNotes out
n (NonEmpty VarAnn -> [Element (NonEmpty VarAnn)]
forall t. Container t => t -> [Element t]
toList NonEmpty VarAnn
vns)
  _ -> [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [] [] (NonEmpty VarAnn -> [Element (NonEmpty VarAnn)]
forall t. Container t => t -> [Element t]
toList NonEmpty 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. Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
encodeNotedInstr :: Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
encodeNotedInstr a :: Instr inp out
a (PackedNotes n :: Notes a
n) vns :: [VarAnn]
vns = case (Instr inp out
a, Proxy out
forall k (t :: k). Proxy t
Proxy @out, Notes a
n) of
  (WithLoc _ a0 :: Instr inp out
a0, _, _) ->
    Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
forall (inp :: [T]) (out :: [T]).
Instr inp out -> PackedNotes out -> [VarAnn] -> LByteString
encodeNotedInstr Instr inp out
a0 (Notes a -> PackedNotes (a : s)
forall (a :: T) (s :: [T]).
SingI a =>
Notes a -> PackedNotes (a : s)
PackedNotes Notes a
n) [VarAnn]
vns
  (SOME, _, NTOption tn :: TypeAnn
tn _ns :: Notes t
_ns) ->
    [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
a
  (NONE, _ :: Proxy ('TOption t ': s), NTOption tn :: TypeAnn
tn ns :: Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ "\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
  (UNIT, _, NTUnit tn :: TypeAnn
tn) ->
    [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
a
  (LEFT, _ :: Proxy ('TOr l r ': s), NTOr tn :: TypeAnn
tn fn1 :: Annotation FieldTag
fn1 fn2 :: Annotation FieldTag
fn2 _ns1 :: Notes p
_ns1 ns2 :: Notes q
ns2) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ "\x05\x33" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes b -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @r Notes b
Notes q
ns2
  (RIGHT, _ :: Proxy ('TOr l r ': s), NTOr tn :: TypeAnn
tn fn1 :: Annotation FieldTag
fn1 fn2 :: Annotation FieldTag
fn2 ns1 :: Notes p
ns1 _ns2 :: Notes q
_ns2) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [Annotation FieldTag
fn1, Annotation FieldTag
fn2] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ "\x05\x44" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> Notes a -> LByteString
forall (t :: T). SingI t => Notes t -> LByteString
encodeNotedT' @l Notes a
Notes p
ns1
  (NIL, _ :: Proxy ('TList t ': s), NTList tn :: TypeAnn
tn ns :: Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ "\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
  (EMPTY_SET, _ :: Proxy ('TSet t ': s), NTSet tn :: TypeAnn
tn ns :: Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ "\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
  (EMPTY_MAP, _ :: Proxy ('TMap k v ': s), NTMap tn1 :: TypeAnn
tn1 nk :: Notes k
nk ns :: Notes v
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn1] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      "\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
  (EMPTY_BIG_MAP, _ :: Proxy ('TBigMap k v ': s), NTBigMap tn1 :: TypeAnn
tn1 nk :: Notes k
nk ns :: Notes v
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn1] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$
      "\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), _, tn :: Notes a
tn) ->
    "\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 a
Notes t
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)), _, NTLambda _tn :: TypeAnn
_tn ns1 :: Notes p
ns1 ns2 :: Notes q
ns2) ->
    "\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 0  -- encoding of a Variable Annotation (that we don't support)
  (CAST, _ :: Proxy (t ': s), tn :: Notes a
tn) ->
    "\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
tn
  (UNPACK, _ :: Proxy ('TOption t ': s), NTOption tn :: TypeAnn
tn ns :: Notes t
ns) ->
    [TypeAnn]
-> [Annotation FieldTag] -> [VarAnn] -> LByteString -> LByteString
encodeWithAnns [TypeAnn
tn] [] [VarAnn]
vns (LByteString -> LByteString) -> LByteString -> LByteString
forall a b. (a -> b) -> a -> b
$ "\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 -> LByteString
forall (inp :: [T]) (out :: [T]). Instr inp out -> LByteString
encodeInstr Instr inp out
a

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{..} = 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) (RootAnn -> Annotation FieldTag
forall k1 k2 (tag1 :: k1) (tag2 :: k2).
Annotation tag1 -> Annotation tag2
convAnn RootAnn
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 st :: Sing t
st fn :: Annotation FieldTag
fn n :: Notes t
n = case (Sing t
SingT t
st, Notes t
n) of
  (STInt, NTInt tn :: 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)
  (STNat, NTNat tn :: 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)
  (STString, NTString tn :: 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)
  (STBytes, NTBytes tn :: 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)
  (STMutez, NTMutez tn :: 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)
  (STBool, NTBool tn :: 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)
  (STKeyHash, NTKeyHash tn :: 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)
  (STTimestamp, NTTimestamp tn :: 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)
  (STAddress, NTAddress tn :: 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)

  (STKey, NTKey tn :: 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
$ "\x03\x5c"
  (STUnit, NTUnit tn :: 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
$ "\x03\x6c"
  (STSignature, NTSignature tn :: 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
$ "\x03\x67"
  (STChainId, NTChainId tn :: 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
$ "\x03\x74"
  (STOption a :: Sing a
a, NTOption tn :: TypeAnn
tn ns :: 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
$ "\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 a :: Sing a
a, NTList tn :: TypeAnn
tn ns :: 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
$ "\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 a :: Sing a
a, NTSet tn :: TypeAnn
tn ns :: 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
$ "\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
  (STOperation, NTOperation tn :: 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
$ "\x03\x6d"
  (STContract a :: Sing a
a, NTContract tn :: TypeAnn
tn ns :: 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
$ "\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 a :: Sing a
a b :: Sing b
b, NTPair tn :: TypeAnn
tn fn1 :: Annotation FieldTag
fn1 fn2 :: Annotation FieldTag
fn2 ns1 :: Notes p
ns1 ns2 :: 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
$
      "\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 a :: Sing a
a b :: Sing b
b, NTOr tn :: TypeAnn
tn fn1 :: Annotation FieldTag
fn1 fn2 :: Annotation FieldTag
fn2 ns1 :: Notes p
ns1 ns2 :: 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
$
      "\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 a :: Sing a
a r :: Sing b
r, NTLambda tn :: TypeAnn
tn ns1 :: Notes p
ns1 ns2 :: 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
$
      "\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 k :: Sing a
k v :: Sing b
v, NTMap tn :: TypeAnn
tn nk :: Notes k
nk nv :: 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
$
      "\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 k :: Sing a
k v :: Sing b
v, NTBigMap tn :: TypeAnn
tn nk :: Notes k
nk nv :: 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
$
      "\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
  TKey  -> "\x03\x5c"
  TUnit -> "\x03\x6c"
  TSignature -> "\x03\x67"
  TChainId -> "\x03\x74"
  TOption t :: T
t -> "\x05\x63" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  TList t :: T
t -> "\x05\x5f" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  TSet t :: T
t -> "\x05\x66" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  TOperation -> "\x03\x6d"
  TContract t :: T
t -> "\x05\x5a" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> T -> LByteString
encodeT T
t
  TPair a :: T
a b :: T
b -> "\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 a :: T
a b :: T
b -> "\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 a :: T
a r :: T
r -> "\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 k :: T
k v :: T
v -> "\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 k :: T
k v :: T
v -> "\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
  TInt -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x5b"
  TNat -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x62"
  TString -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x68"
  TBytes -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x69"
  TMutez -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x6a"
  TBool -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x59"
  TKeyHash -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x5d"
  TTimestamp -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\x6b"
  TAddress -> "\x03" LByteString -> LByteString -> LByteString
forall a. Semigroup a => a -> a -> a
<> "\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)