module EVM.StorageLayout where

-- Figures out the layout of storage slots for Solidity contracts.

import EVM.Dapp (DappInfo(..))
import EVM.Solidity (SolcContract, creationSrcmap, SlotType(..))
import EVM.ABI (AbiType (..), parseTypeName)

import Optics.Core
import Data.Aeson (Value (..))
import Data.Aeson.Optics
import Data.Foldable (toList)
import Data.List.NonEmpty qualified as NonEmpty
import Data.Map qualified as Map
import Data.Maybe (fromMaybe, isJust)
import Data.Sequence qualified as Seq
import Data.Text (Text, unpack, pack, words)

import Prelude hiding (words)

-- A contract has all the slots of its inherited contracts.
--
-- The slot order is determined by the inheritance linearization order,
-- so we first have to calculate that.
--
-- This information is available in the abstract syntax tree.

findContractDefinition :: DappInfo -> SolcContract -> Maybe Value
findContractDefinition :: DappInfo -> SolcContract -> Maybe Value
findContractDefinition DappInfo
dapp SolcContract
solc =
  -- The first source mapping in the contract's creation code
  -- corresponds to the source field of the contract definition.
  case forall (a :: OpticKind). Seq a -> ViewL a
Seq.viewl SolcContract
solc.creationSrcmap of
    SrcMap
firstSrcMap Seq.:< Seq SrcMap
_ ->
      DappInfo
dapp.astSrcMap SrcMap
firstSrcMap
    ViewL SrcMap
_ ->
      forall (a :: OpticKind). Maybe a
Nothing

storageLayout :: DappInfo -> SolcContract -> [Text]
storageLayout :: DappInfo -> SolcContract -> [Text]
storageLayout DappInfo
dapp SolcContract
solc =
  let
    root :: Value
    root :: Value
root =
      forall (a :: OpticKind). a -> Maybe a -> a
fromMaybe Value
Null
        (DappInfo -> SolcContract -> Maybe Value
findContractDefinition DappInfo
dapp SolcContract
solc)
  in
    case forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview ( forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"attributes"
                 forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"linearizedBaseContracts"
                 forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t (Vector Value)
_Array
                 ) Value
root of
      Maybe (Vector Value)
Nothing ->
        []
      Just ((forall (a :: OpticKind). [a] -> [a]
reverse forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (t :: OpticKind -> OpticKind) (a :: OpticKind).
Foldable t =>
t a -> [a]
toList) -> [Value]
linearizedBaseContracts) ->
        forall (a :: OpticKind) (b :: OpticKind) (c :: OpticKind).
(a -> b -> c) -> b -> a -> c
flip forall (t :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Foldable t =>
(a -> [b]) -> t a -> [b]
concatMap [Value]
linearizedBaseContracts
          (\case
             Number Scientific
i -> forall (a :: OpticKind). a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => [Char] -> a
error [Char]
"malformed AST JSON") forall (a :: OpticKind) b. (a -> b) -> a -> b
$
               Value -> Maybe [Text]
storageVariablesForContract forall (m :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Monad m =>
(a -> m b) -> m a -> m b
=<<
                 forall (k :: OpticKind) (a :: OpticKind).
Ord k =>
k -> Map k a -> Maybe a
Map.lookup (forall (a :: OpticKind) (b :: OpticKind).
(RealFrac a, Integral b) =>
a -> b
floor Scientific
i) DappInfo
dapp.astIdMap
             Value
_ ->
               forall a. HasCallStack => [Char] -> a
error [Char]
"malformed AST JSON")

storageVariablesForContract :: Value -> Maybe [Text]
storageVariablesForContract :: Value -> Maybe [Text]
storageVariablesForContract Value
node = do
  Text
name <- forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (m :: OpticKind).
Ixed m =>
Index m -> Optic' (IxKind m) NoIx m (IxValue m)
ix Key
"attributes" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"name" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
node
  [Value]
vars <-
    forall (f :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Functor f =>
(a -> b) -> f a -> f b
fmap
      (forall (a :: OpticKind). (a -> Bool) -> [a] -> [a]
filter Value -> Bool
isStorageVariableDeclaration forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (t :: OpticKind -> OpticKind) (a :: OpticKind).
Foldable t =>
t a -> [a]
toList)
      (forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (m :: OpticKind).
Ixed m =>
Index m -> Optic' (IxKind m) NoIx m (IxValue m)
ix Key
"children" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t (Vector Value)
_Array) Value
node)

  forall (f :: OpticKind -> OpticKind) (a :: OpticKind).
Applicative f =>
a -> f a
pure forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. forall (a :: OpticKind) (b :: OpticKind) (c :: OpticKind).
(a -> b -> c) -> b -> a -> c
flip forall (a :: OpticKind) (b :: OpticKind). (a -> b) -> [a] -> [b]
map [Value]
vars forall (a :: OpticKind) b. (a -> b) -> a -> b
$
    \Value
x ->
      case forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"attributes" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"name" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
x of
        Just Text
variableName ->
          forall (a :: OpticKind). Monoid a => [a] -> a
mconcat
            [ Text
variableName
            , Text
" (", Text
name, Text
")"
            , Text
"\n", Text
"  Type: "
            , [Char] -> Text
pack forall (a :: OpticKind) b. (a -> b) -> a -> b
$ forall (a :: OpticKind). Show a => a -> [Char]
show (Value -> SlotType
slotTypeForDeclaration Value
x)
            ]
        Maybe Text
Nothing ->
          forall a. HasCallStack => [Char] -> a
error [Char]
"malformed variable declaration"

nodeIs :: Text -> Value -> Bool
nodeIs :: Text -> Value -> Bool
nodeIs Text
t Value
x = Bool
isSourceNode Bool -> Bool -> Bool
&& Bool
hasRightName
  where
    isSourceNode :: Bool
isSourceNode =
      forall (a :: OpticKind). Maybe a -> Bool
isJust (forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"src") Value
x)
    hasRightName :: Bool
hasRightName =
      forall (a :: OpticKind). a -> Maybe a
Just Text
t forall (a :: OpticKind). Eq a => a -> a -> Bool
== forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"name" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
x

isStorageVariableDeclaration :: Value -> Bool
isStorageVariableDeclaration :: Value -> Bool
isStorageVariableDeclaration Value
x =
  Text -> Value -> Bool
nodeIs Text
"VariableDeclaration" Value
x
    Bool -> Bool -> Bool
&& forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"attributes" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"constant" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Bool
_Bool) Value
x forall (a :: OpticKind). Eq a => a -> a -> Bool
/= forall (a :: OpticKind). a -> Maybe a
Just Bool
True

slotTypeForDeclaration :: Value -> SlotType
slotTypeForDeclaration :: Value -> SlotType
slotTypeForDeclaration Value
node =
  case forall (t :: OpticKind -> OpticKind) (a :: OpticKind).
Foldable t =>
t a -> [a]
toList forall (f :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Functor f =>
(a -> b) -> f a -> f b
<$> forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"children" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t (Vector Value)
_Array) Value
node of
    Just (Value
x:[Value]
_) ->
      Value -> SlotType
grokDeclarationType Value
x
    Maybe [Value]
_ ->
      forall a. HasCallStack => [Char] -> a
error [Char]
"malformed AST"

grokDeclarationType :: Value -> SlotType
grokDeclarationType :: Value -> SlotType
grokDeclarationType Value
x =
  case forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"name" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
x of
    Just Text
"Mapping" ->
      case forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"children" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t (Vector Value)
_Array) Value
x of
        Just (forall (t :: OpticKind -> OpticKind) (a :: OpticKind).
Foldable t =>
t a -> [a]
toList -> [Value]
xs) ->
          [Value] -> SlotType
grokMappingType [Value]
xs
        Maybe (Vector Value)
_ ->
          forall a. HasCallStack => [Char] -> a
error [Char]
"malformed AST"
    Just Text
_ ->
      AbiType -> SlotType
StorageValue (Value -> AbiType
grokValueType Value
x)
    Maybe Text
_ ->
      forall a. HasCallStack => [Char] -> a
error ([Char]
"malformed AST " forall (a :: OpticKind). [a] -> [a] -> [a]
++ forall (a :: OpticKind). Show a => a -> [Char]
show Value
x)

grokMappingType :: [Value] -> SlotType
grokMappingType :: [Value] -> SlotType
grokMappingType [Value
s, Value
t] =
  case (Value -> SlotType
grokDeclarationType Value
s, Value -> SlotType
grokDeclarationType Value
t) of
    (StorageValue AbiType
s', StorageMapping NonEmpty AbiType
t' AbiType
x) ->
      NonEmpty AbiType -> AbiType -> SlotType
StorageMapping (forall (a :: OpticKind). a -> NonEmpty a -> NonEmpty a
NonEmpty.cons AbiType
s' NonEmpty AbiType
t') AbiType
x
    (StorageValue AbiType
s', StorageValue AbiType
t') ->
      NonEmpty AbiType -> AbiType -> SlotType
StorageMapping (forall (f :: OpticKind -> OpticKind) (a :: OpticKind).
Applicative f =>
a -> f a
pure AbiType
s') AbiType
t'
    (StorageMapping NonEmpty AbiType
_ AbiType
_, SlotType
_) ->
      forall a. HasCallStack => [Char] -> a
error [Char]
"unexpected mapping as mapping key"
grokMappingType [Value]
_ =
  forall a. HasCallStack => [Char] -> a
error [Char]
"unexpected AST child count for mapping"

grokValueType :: Value -> AbiType
grokValueType :: Value -> AbiType
grokValueType Value
x =
  case ( forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"name" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
x
       , forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"children" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t (Vector Value)
_Array) Value
x
       , forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"attributes" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"type" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
x
       ) of
    (Just Text
"ElementaryTypeName", Maybe (Vector Value)
_, Just Text
typeName) ->
      forall (a :: OpticKind). a -> Maybe a -> a
fromMaybe (forall a. HasCallStack => [Char] -> a
error ([Char]
"ungrokked value type: " forall (a :: OpticKind). [a] -> [a] -> [a]
++ forall (a :: OpticKind). Show a => a -> [Char]
show Text
typeName))
        (Vector AbiType -> Text -> Maybe AbiType
parseTypeName forall (a :: OpticKind). Monoid a => a
mempty (forall (a :: OpticKind). [a] -> a
head (Text -> [Text]
words Text
typeName)))
    (Just Text
"UserDefinedTypeName", Maybe (Vector Value)
_, Maybe Text
_) ->
      AbiType
AbiAddressType
    (Just Text
"ArrayTypeName", forall (f :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Functor f =>
(a -> b) -> f a -> f b
fmap forall (t :: OpticKind -> OpticKind) (a :: OpticKind).
Foldable t =>
t a -> [a]
toList -> Just [Value
t], Maybe Text
_)->
      AbiType -> AbiType
AbiArrayDynamicType (Value -> AbiType
grokValueType Value
t)
    (Just Text
"ArrayTypeName", forall (f :: OpticKind -> OpticKind) (a :: OpticKind)
       (b :: OpticKind).
Functor f =>
(a -> b) -> f a -> f b
fmap forall (t :: OpticKind -> OpticKind) (a :: OpticKind).
Foldable t =>
t a -> [a]
toList -> Just [Value
t, Value
n], Maybe Text
_)->
      case ( forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"name" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
n
           , forall (k :: OpticKind) (is :: IxList) (s :: OpticKind)
       (a :: OpticKind).
Is k An_AffineFold =>
Optic' k is s a -> s -> Maybe a
preview (forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"attributes" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind).
AsValue t =>
Key -> AffineTraversal' t Value
key Key
"value" forall (k :: OpticKind) (l :: OpticKind) (m :: OpticKind)
       (is :: IxList) (js :: IxList) (ks :: IxList) (s :: OpticKind)
       (t :: OpticKind) (u :: OpticKind) (v :: OpticKind) (a :: OpticKind)
       (b :: OpticKind).
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall (t :: OpticKind). AsValue t => Prism' t Text
_String) Value
n
           ) of
        (Just Text
"Literal", Just ((forall (a :: OpticKind). Read a => [Char] -> a
read forall (b :: OpticKind) (c :: OpticKind) (a :: OpticKind).
(b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
unpack) -> Int
i)) ->
          Int -> AbiType -> AbiType
AbiArrayType Int
i (Value -> AbiType
grokValueType Value
t)
        (Maybe Text, Maybe Text)
_ ->
          forall a. HasCallStack => [Char] -> a
error [Char]
"malformed AST"
    (Maybe Text, Maybe (Vector Value), Maybe Text)
_ ->
      forall a. HasCallStack => [Char] -> a
error ([Char]
"unknown value type " forall (a :: OpticKind). [a] -> [a] -> [a]
++ forall (a :: OpticKind). Show a => a -> [Char]
show Value
x)