mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 09:17:43 +03:00
This reverts commit 68e4453324
.
This commit is contained in:
parent
156edf7432
commit
449500bad8
@ -67,18 +67,10 @@ featureAnyTemplate = Feature
|
||||
, featureCppFlag = "DAML_ANY_TEMPLATE"
|
||||
}
|
||||
|
||||
featureStringInterning :: Feature
|
||||
featureStringInterning = Feature
|
||||
{ featureName = "String interning"
|
||||
, featureMinVersion = version1_7
|
||||
, featureCppFlag = "DAML_STRING_INTERNING"
|
||||
}
|
||||
|
||||
allFeatures :: [Feature]
|
||||
allFeatures =
|
||||
[ featureNumeric
|
||||
, featureAnyTemplate
|
||||
, featureStringInterning
|
||||
]
|
||||
|
||||
allFeaturesForVersion :: Version -> [Feature]
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
{-# LANGUAGE ConstraintKinds #-}
|
||||
{-# LANGUAGE MultiWayIf #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
|
||||
module DA.Daml.LF.Proto3.DecodeV1
|
||||
( decodePackage
|
||||
@ -12,11 +11,10 @@ module DA.Daml.LF.Proto3.DecodeV1
|
||||
|
||||
import DA.Daml.LF.Ast as LF
|
||||
import DA.Daml.LF.Proto3.Error
|
||||
import qualified DA.Daml.LF.Proto3.Util as Util
|
||||
import Control.Monad
|
||||
import Control.Monad.Except
|
||||
import Control.Monad.Reader
|
||||
import Data.Int
|
||||
import Data.Word
|
||||
import Text.Read
|
||||
import Data.List
|
||||
import DA.Daml.LF.Mangling
|
||||
@ -28,9 +26,8 @@ import qualified Data.Vector as V
|
||||
import qualified Proto3.Suite as Proto
|
||||
|
||||
|
||||
data DecodeEnv = DecodeEnv
|
||||
{ internedStrings :: !(V.Vector T.Text)
|
||||
, internedDottedNames :: !(V.Vector [T.Text])
|
||||
newtype DecodeEnv = DecodeEnv
|
||||
{ internedStrings :: V.Vector T.Text
|
||||
}
|
||||
|
||||
newtype Decode a = Decode{unDecode :: ReaderT DecodeEnv (Except Error) a}
|
||||
@ -39,21 +36,15 @@ newtype Decode a = Decode{unDecode :: ReaderT DecodeEnv (Except Error) a}
|
||||
runDecode :: DecodeEnv -> Decode a -> Either Error a
|
||||
runDecode env act = runExcept $ runReaderT (unDecode act) env
|
||||
|
||||
lookupInterned :: V.Vector a -> (Int32 -> Error) -> Int32 -> Decode a
|
||||
lookupInterned interned mkError id = do
|
||||
case interned V.!? fromIntegral id of
|
||||
Nothing -> throwError $ mkError id
|
||||
Just x -> pure x
|
||||
|
||||
lookupString :: Int32 -> Decode T.Text
|
||||
lookupString strId = do
|
||||
lookupString :: Word64 -> Decode T.Text
|
||||
lookupString strIdW = do
|
||||
let strIdI = toInteger strIdW
|
||||
when (strIdI > toInteger (maxBound :: Int)) $
|
||||
throwError $ MissingPackageRefId strIdW
|
||||
DecodeEnv{internedStrings} <- ask
|
||||
lookupInterned internedStrings BadStringId strId
|
||||
|
||||
lookupDottedName :: Int32 -> Decode [T.Text]
|
||||
lookupDottedName id = do
|
||||
DecodeEnv{internedDottedNames} <- ask
|
||||
lookupInterned internedDottedNames BadDottedNameId id
|
||||
case internedStrings V.!? fromInteger strIdI of
|
||||
Nothing -> throwError $ MissingPackageRefId strIdW
|
||||
Just str -> pure str
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- Decodings of things related to string interning
|
||||
@ -65,30 +56,15 @@ decodeString :: TL.Text -> T.Text
|
||||
decodeString = TL.toStrict
|
||||
|
||||
-- | Decode a string that will be interned in DAML-LF 1.7 and onwards.
|
||||
-- At the protobuf level, we represent internable non-empty lists of strings
|
||||
-- by a repeatable string and a number. If there's at least one string,
|
||||
-- then the number must not be set, i.e. zero. If there are no strings,
|
||||
-- then the number is treated as an index into the interning table.
|
||||
decodeInternableStrings :: V.Vector TL.Text -> Int32 -> Decode [T.Text]
|
||||
decodeInternableStrings strs id
|
||||
| V.null strs = lookupDottedName id
|
||||
| id == 0 = pure $ map decodeString (V.toList strs)
|
||||
| otherwise = throwError $ ParseError "items and interned id both set for string list"
|
||||
decodeInternableString :: TL.Text -> Decode T.Text
|
||||
decodeInternableString = pure . decodeString
|
||||
|
||||
-- | Decode the name of a syntactic object, e.g., a variable or a data
|
||||
-- constructor. These strings are mangled to escape special characters. All
|
||||
-- names will be interned in DAML-LF 1.7 and onwards.
|
||||
decodeName
|
||||
:: Util.EitherLike TL.Text Int32 e
|
||||
=> (T.Text -> a) -> Maybe e -> Decode a
|
||||
decodeName wrapName mbStrOrId = mayDecode "name" mbStrOrId $ \strOrId -> do
|
||||
mangled <- case Util.toEither strOrId of
|
||||
Left str -> pure $ decodeString str
|
||||
Right strId -> lookupString strId
|
||||
decodeNameString wrapName mangled
|
||||
|
||||
decodeNameString :: (T.Text -> a) -> T.Text -> Decode a
|
||||
decodeNameString wrapName mangled =
|
||||
decodeName :: (T.Text -> a) -> TL.Text -> Decode a
|
||||
decodeName wrapName mangled = do
|
||||
mangled <- decodeInternableString mangled
|
||||
case unmangleIdentifier mangled of
|
||||
Left err -> throwError $ ParseError $ "Could not unmangle name " ++ show mangled ++ ": " ++ err
|
||||
Right unmangled -> pure $ wrapName unmangled
|
||||
@ -97,31 +73,29 @@ decodeNameString wrapName mangled =
|
||||
-- constructor. All compononents are mangled. Dotted names will be interned
|
||||
-- in DAML-LF 1.7 and onwards.
|
||||
decodeDottedName :: ([T.Text] -> a) -> LF1.DottedName -> Decode a
|
||||
decodeDottedName wrapDottedName (LF1.DottedName mangled dnId) =
|
||||
wrapDottedName <$> (decodeInternableStrings mangled dnId >>= mapM (decodeNameString id))
|
||||
decodeDottedName wrapDottedName (LF1.DottedName mangled) = do
|
||||
wrapDottedName <$> mapM (decodeName id) (V.toList mangled)
|
||||
|
||||
-- | Decode the name of a top-level value. The name is mangled and will be
|
||||
-- interned in DAML-LF 1.7 and onwards.
|
||||
decodeValueName :: String -> V.Vector TL.Text -> Int32 -> Decode ExprValName
|
||||
decodeValueName ident mangledV dnId = do
|
||||
mangled <- decodeInternableStrings mangledV dnId
|
||||
case mangled of
|
||||
[] -> throwError $ MissingField ident
|
||||
[unmangled] -> do
|
||||
mangled <- decodeNameString id unmangled
|
||||
case unmangleIdentifier mangled of
|
||||
Right unmangled -> pure $ ExprValName unmangled
|
||||
-- NOTE(MH): This is an ugly hack to keep backwards compatibility.
|
||||
-- We need to fix this in DAML-LF 2.
|
||||
Left _ -> pure $ ExprValName mangled
|
||||
_ -> throwError $ ParseError $ "Unexpected multi-segment def name: " ++ show mangledV ++ "//" ++ show mangled
|
||||
decodeValueName :: String -> V.Vector TL.Text -> Decode ExprValName
|
||||
decodeValueName ident mangledV = case V.length mangledV of
|
||||
0 -> throwError $ MissingField ident
|
||||
1 -> do
|
||||
mangled <- decodeInternableString $ V.head mangledV
|
||||
case unmangleIdentifier mangled of
|
||||
Right unmangled -> pure $ ExprValName unmangled
|
||||
-- NOTE(MH): This is an ugly hack to keep backwards compatibility.
|
||||
-- We need to fix this in DAML-LF 2.
|
||||
Left _ -> pure $ ExprValName mangled
|
||||
_ -> throwError $ ParseError $ "Unexpected multi-segment def name: " ++ show mangledV
|
||||
|
||||
-- | Decode a reference to a top-level value. The name is mangled and will be
|
||||
-- interned in DAML-LF 1.7 and onwards.
|
||||
decodeValName :: LF1.ValName -> Decode (Qualified ExprValName)
|
||||
decodeValName LF1.ValName{..} = do
|
||||
(pref, mname) <- mayDecode "valNameModule" valNameModule decodeModuleRef
|
||||
name <- decodeValueName "valNameName" valNameName valNameNameInternedId
|
||||
name <- decodeValueName "valNameName" valNameName
|
||||
pure $ Qualified pref mname name
|
||||
|
||||
-- | Decode a reference to a package. Package names are not mangled. Package
|
||||
@ -139,8 +113,7 @@ decodePackageRef (LF1.PackageRef pref) =
|
||||
|
||||
decodeVersion :: T.Text -> Either Error Version
|
||||
decodeVersion minorText = do
|
||||
let unsupported :: Either Error a
|
||||
unsupported = throwError (UnsupportedMinorVersion minorText)
|
||||
let unsupported = throwError (UnsupportedMinorVersion minorText)
|
||||
-- we translate "no version" to minor version 0, since we introduced
|
||||
-- minor versions once DAML-LF v1 was already out, and we want to be
|
||||
-- able to parse packages that were compiled before minor versions
|
||||
@ -152,19 +125,12 @@ decodeVersion minorText = do
|
||||
let version = V1 minor
|
||||
if version `elem` LF.supportedInputVersions then pure version else unsupported
|
||||
|
||||
decodeInternedDottedName :: LF1.InternedDottedName -> Decode [T.Text]
|
||||
decodeInternedDottedName (LF1.InternedDottedName ids) =
|
||||
mapM lookupString $ V.toList ids
|
||||
|
||||
decodePackage :: TL.Text -> LF1.Package -> Either Error Package
|
||||
decodePackage minorText (LF1.Package mods internedStringsV internedDottedNamesV) = do
|
||||
decodePackage minorText (LF1.Package mods internedList) = do
|
||||
version <- decodeVersion (decodeString minorText)
|
||||
let internedStrings = V.map decodeString internedStringsV
|
||||
let internedDottedNames = V.empty
|
||||
let env0 = DecodeEnv{..}
|
||||
internedDottedNames <- runDecode env0 $ mapM decodeInternedDottedName internedDottedNamesV
|
||||
let env = DecodeEnv{..}
|
||||
runDecode env $ do
|
||||
let internedStrings = V.map decodeString internedList
|
||||
let env = DecodeEnv{internedStrings}
|
||||
runDecode env $
|
||||
Package version <$> decodeNM DuplicateModule decodeModule mods
|
||||
|
||||
decodeModule :: LF1.Module -> Decode Module
|
||||
@ -201,16 +167,12 @@ decodeDataCons = \case
|
||||
DataRecord <$> mapM (decodeFieldWithType FieldName) (V.toList fs)
|
||||
LF1.DefDataTypeDataConsVariant (LF1.DefDataType_Fields fs) ->
|
||||
DataVariant <$> mapM (decodeFieldWithType VariantConName) (V.toList fs)
|
||||
LF1.DefDataTypeDataConsEnum (LF1.DefDataType_EnumConstructors cs cIds) -> do
|
||||
mangled <- if
|
||||
| V.null cIds -> pure $ map decodeString (V.toList cs)
|
||||
| V.null cs -> mapM lookupString (V.toList cIds)
|
||||
| otherwise -> throwError $ ParseError "strings and interned string ids both set for enum constructor"
|
||||
DataEnum <$> mapM (decodeNameString VariantConName) mangled
|
||||
LF1.DefDataTypeDataConsEnum (LF1.DefDataType_EnumConstructors cs) ->
|
||||
DataEnum <$> mapM (decodeName VariantConName) (V.toList cs)
|
||||
|
||||
decodeDefValueNameWithType :: LF1.DefValue_NameWithType -> Decode (ExprValName, Type)
|
||||
decodeDefValueNameWithType LF1.DefValue_NameWithType{..} = (,)
|
||||
<$> decodeValueName "defValueName" defValue_NameWithTypeName defValue_NameWithTypeNameInternedId
|
||||
<$> decodeValueName "defValueName" defValue_NameWithTypeName
|
||||
<*> mayDecode "defValueType" defValue_NameWithTypeType decodeType
|
||||
|
||||
decodeDefValue :: LF1.DefValue -> Decode DefValue
|
||||
@ -409,8 +371,7 @@ decodeExpr (LF1.Expr mbLoc exprSum) = case mbLoc of
|
||||
|
||||
decodeExprSum :: Maybe LF1.ExprSum -> Decode Expr
|
||||
decodeExprSum exprSum = mayDecode "exprSum" exprSum $ \case
|
||||
LF1.ExprSumVar var -> EVar <$> decodeNameString ExprVarName (decodeString var)
|
||||
LF1.ExprSumVarInternedId strId -> EVar <$> (lookupString strId >>= decodeNameString ExprVarName)
|
||||
LF1.ExprSumVar var -> EVar <$> decodeName ExprVarName var
|
||||
LF1.ExprSumVal val -> EVal <$> decodeValName val
|
||||
LF1.ExprSumBuiltin (Proto.Enumerated (Right bi)) -> EBuiltin <$> decodeBuiltinFunction bi
|
||||
LF1.ExprSumBuiltin (Proto.Enumerated (Left num)) -> throwError (UnknownEnum "ExprSumBuiltin" num)
|
||||
@ -628,15 +589,11 @@ decodeVarWithType LF1.VarWithType{..} =
|
||||
decodePrimLit :: LF1.PrimLit -> Decode BuiltinExpr
|
||||
decodePrimLit (LF1.PrimLit mbSum) = mayDecode "primLitSum" mbSum $ \case
|
||||
LF1.PrimLitSumInt64 sInt -> pure $ BEInt64 sInt
|
||||
LF1.PrimLitSumDecimal sDec -> decodeDecimalLit $ decodeString sDec
|
||||
LF1.PrimLitSumDecimalInternedId strId -> lookupString strId >>= decodeDecimalLit
|
||||
LF1.PrimLitSumNumeric sNum -> decodeNumericLit $ decodeString sNum
|
||||
LF1.PrimLitSumNumericInternedId strId -> lookupString strId >>= decodeNumericLit
|
||||
LF1.PrimLitSumDecimal sDec -> decodeInternableString sDec >>= decodeDecimalLit
|
||||
LF1.PrimLitSumNumeric sNum -> decodeInternableString sNum >>= decodeNumericLit
|
||||
LF1.PrimLitSumTimestamp sTime -> pure $ BETimestamp sTime
|
||||
LF1.PrimLitSumText x -> pure $ BEText $ decodeString x
|
||||
LF1.PrimLitSumTextInternedId strId -> BEText <$> lookupString strId
|
||||
LF1.PrimLitSumParty p -> pure $ BEParty $ PartyLiteral $ decodeString p
|
||||
LF1.PrimLitSumPartyInternedId strId -> BEParty . PartyLiteral <$> lookupString strId
|
||||
LF1.PrimLitSumText x -> BEText <$> decodeInternableString x
|
||||
LF1.PrimLitSumParty p -> BEParty . PartyLiteral <$> decodeInternableString p
|
||||
LF1.PrimLitSumDate days -> pure $ BEDate days
|
||||
|
||||
decodeDecimalLit :: T.Text -> Decode BuiltinExpr
|
||||
|
@ -1,8 +1,7 @@
|
||||
-- Copyright (c) 2019 The DAML Authors. All rights reserved.
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
|
||||
-- | Encoding of the LF package into LF version 1 format.
|
||||
module DA.Daml.LF.Proto3.EncodeV1
|
||||
( encodeModuleWithoutInterning
|
||||
@ -13,20 +12,17 @@ import Control.Lens ((^.), matching)
|
||||
import Control.Lens.Ast (rightSpine)
|
||||
import Control.Monad.State.Strict
|
||||
|
||||
import Data.Coerce
|
||||
import Data.Functor.Identity
|
||||
import qualified Data.HashMap.Strict as HMS
|
||||
import qualified Data.List as L
|
||||
import qualified Data.NameMap as NM
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Lazy as TL
|
||||
import qualified Data.Vector as V
|
||||
import Data.Int
|
||||
import Data.Word
|
||||
|
||||
import DA.Pretty
|
||||
import DA.Daml.LF.Ast
|
||||
import DA.Daml.LF.Mangling
|
||||
import qualified DA.Daml.LF.Proto3.Util as Util
|
||||
import qualified Da.DamlLf1 as P
|
||||
|
||||
import qualified Proto3.Suite as P (Enumerated (..))
|
||||
@ -43,52 +39,24 @@ newtype WithInterning = WithInterning{getWithInterning :: Bool}
|
||||
data EncodeEnv = EncodeEnv
|
||||
{ version :: !Version
|
||||
, withInterning :: !WithInterning
|
||||
, internedStrings :: !(HMS.HashMap T.Text Int32)
|
||||
, nextInternedStringId :: !Int32
|
||||
-- ^ We track the size of `internedStrings` explicitly since `HMS.size` is `O(n)`.
|
||||
, internedDottedNames :: !(HMS.HashMap [Int32] Int32)
|
||||
, nextInternedDottedNameId :: !Int32
|
||||
-- ^ We track the size of `internedDottedNames` explicitly since `HMS.size` is `O(n)`.
|
||||
, internedStrings :: !(HMS.HashMap T.Text Word64)
|
||||
}
|
||||
|
||||
initEncodeEnv :: Version -> WithInterning -> EncodeEnv
|
||||
initEncodeEnv version withInterning =
|
||||
EncodeEnv
|
||||
{ nextInternedStringId = 0
|
||||
, internedStrings = HMS.empty
|
||||
, internedDottedNames = HMS.empty
|
||||
, nextInternedDottedNameId = 0
|
||||
, ..
|
||||
}
|
||||
initEncodeEnv version withInterning = EncodeEnv{internedStrings = HMS.empty, ..}
|
||||
|
||||
-- | Find or allocate a string in the interning table. Return the index of
|
||||
-- the string in the resulting interning table.
|
||||
allocString :: T.Text -> Encode Int32
|
||||
allocString :: T.Text -> Encode Word64
|
||||
allocString t = do
|
||||
env@EncodeEnv{internedStrings, nextInternedStringId = n} <- get
|
||||
env@EncodeEnv{internedStrings} <- get
|
||||
case t `HMS.lookup` internedStrings of
|
||||
Just n -> pure n
|
||||
Nothing -> do
|
||||
when (n == maxBound) $
|
||||
error "String interning table grew too large"
|
||||
put $! env
|
||||
{ internedStrings = HMS.insert t n internedStrings
|
||||
, nextInternedStringId = n + 1
|
||||
}
|
||||
pure n
|
||||
|
||||
allocDottedName :: [Int32] -> Encode Int32
|
||||
allocDottedName ids = do
|
||||
env@EncodeEnv{internedDottedNames, nextInternedDottedNameId = n} <- get
|
||||
case ids `HMS.lookup` internedDottedNames of
|
||||
Just n -> pure n
|
||||
Nothing -> do
|
||||
when (n == maxBound) $
|
||||
error "Dotted name interning table grew too large"
|
||||
put $! env
|
||||
{ internedDottedNames = HMS.insert ids n internedDottedNames
|
||||
, nextInternedDottedNameId = n + 1
|
||||
}
|
||||
-- NOTE(MH): We assumie that the number of interned strings fits
|
||||
-- in a `Word64`. (More than that would require A LOT of memory.)
|
||||
let n = fromIntegral (HMS.size internedStrings)
|
||||
put $! env{internedStrings = HMS.insert t n internedStrings}
|
||||
pure n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
@ -101,54 +69,23 @@ encodeString :: T.Text -> TL.Text
|
||||
encodeString = TL.fromStrict
|
||||
|
||||
-- | Encode a string that will be interned in DAML-LF 1.7 and onwards.
|
||||
encodeInternableString :: T.Text -> Encode (Either TL.Text Int32)
|
||||
encodeInternableString = coerce (encodeInternableStrings @Identity)
|
||||
|
||||
-- | Encode a string that will be interned in DAML-LF 1.7 and onwards.
|
||||
encodeInternableStrings :: Traversable t => t T.Text -> Encode (Either (t TL.Text) (t Int32))
|
||||
encodeInternableStrings strs = do
|
||||
EncodeEnv{..} <- get
|
||||
if getWithInterning withInterning && version `supports` featureStringInterning
|
||||
then Right <$> mapM allocString strs
|
||||
else pure $ Left $ fmap encodeString strs
|
||||
encodeInternableString :: T.Text -> Encode TL.Text
|
||||
encodeInternableString = pure . encodeString
|
||||
|
||||
-- | Encode the name of a syntactic object, e.g., a variable or a data
|
||||
-- constructor. These strings are mangled to escape special characters. All
|
||||
-- names will be interned in DAML-LF 1.7 and onwards.
|
||||
encodeName
|
||||
:: Util.EitherLike TL.Text Int32 e
|
||||
=> (a -> T.Text) -> a -> Encode (Just e)
|
||||
encodeName unwrapName = fmap Just . encodeName' unwrapName
|
||||
|
||||
encodeName'
|
||||
:: Util.EitherLike TL.Text Int32 e
|
||||
=> (a -> T.Text) -> a -> Encode e
|
||||
encodeName' unwrapName (unwrapName -> unmangled) = do
|
||||
Util.fromEither @TL.Text @Int32 <$> coerce (encodeNames @Identity) unmangled
|
||||
|
||||
encodeNames :: Traversable t => t T.Text -> Encode (Either (t TL.Text) (t Int32))
|
||||
encodeNames = encodeInternableStrings . fmap mangleName
|
||||
where
|
||||
mangleName :: T.Text -> T.Text
|
||||
mangleName unmangled = case mangleIdentifier unmangled of
|
||||
Left err -> error $ "IMPOSSIBLE: could not mangle name " ++ show unmangled ++ ": " ++ err
|
||||
Right mangled -> mangled
|
||||
encodeName :: (a -> T.Text) -> a -> Encode TL.Text
|
||||
encodeName unwrapName (unwrapName -> unmangled) = case mangleIdentifier unmangled of
|
||||
Left err -> error $ "IMPOSSIBLE: could not mangle name " ++ show unmangled ++ ": " ++ err
|
||||
Right mangled -> encodeInternableString mangled
|
||||
|
||||
-- | Encode the multi-component name of a syntactic object, e.g., a type
|
||||
-- constructor. All compononents are mangled. Dotted names will be interned
|
||||
-- in DAML-LF 1.7 and onwards.
|
||||
encodeDottedName :: (a -> [T.Text]) -> a -> Encode (Just P.DottedName)
|
||||
encodeDottedName unwrapDottedName (unwrapDottedName -> unmangled) =
|
||||
Just . uncurry P.DottedName <$> encodeDottedName' unmangled
|
||||
|
||||
encodeDottedName' :: [T.Text] -> Encode (V.Vector TL.Text, Int32)
|
||||
encodeDottedName' unmangled = do
|
||||
mangledAndInterned <- encodeNames unmangled
|
||||
case mangledAndInterned of
|
||||
Left mangled -> pure (V.fromList mangled, 0)
|
||||
Right ids -> do
|
||||
id <- allocDottedName ids
|
||||
pure (V.empty, id)
|
||||
encodeDottedName unwrapDottedName =
|
||||
fmap (Just . P.DottedName) . encodeList (encodeName id) . unwrapDottedName
|
||||
|
||||
-- | Encode the name of a top-level value. The name is mangled and will be
|
||||
-- interned in DAML-LF 1.7 and onwards.
|
||||
@ -158,8 +95,8 @@ encodeDottedName' unmangled = do
|
||||
-- because currently GenDALF generates weird names like `.` that we'd
|
||||
-- have to handle separatedly. So for now, considering that we do not
|
||||
-- use values in codegen, just mangle the entire thing.
|
||||
encodeValueName :: ExprValName -> Encode (V.Vector TL.Text, Int32)
|
||||
encodeValueName valName = encodeDottedName' [unExprValName valName]
|
||||
encodeValueName :: ExprValName -> Encode (V.Vector TL.Text)
|
||||
encodeValueName = fmap V.singleton . encodeName unExprValName
|
||||
|
||||
-- | Encode a reference to a package. Package names are not mangled. Package
|
||||
-- name are interned since DAML-LF 1.6.
|
||||
@ -312,19 +249,11 @@ encodeTypeConApp (TypeConApp tycon args) = do
|
||||
encodeBuiltinExpr :: BuiltinExpr -> Encode P.ExprSum
|
||||
encodeBuiltinExpr = \case
|
||||
BEInt64 x -> pureLit $ P.PrimLitSumInt64 x
|
||||
BEDecimal dec ->
|
||||
lit . either P.PrimLitSumDecimal P.PrimLitSumDecimalInternedId
|
||||
<$> encodeInternableString (T.pack (show dec))
|
||||
BENumeric n ->
|
||||
lit . either P.PrimLitSumNumeric P.PrimLitSumNumericInternedId
|
||||
<$> encodeInternableString (T.pack (show n))
|
||||
BEText x ->
|
||||
lit . either P.PrimLitSumText P.PrimLitSumTextInternedId
|
||||
<$> encodeInternableString x
|
||||
BEDecimal dec -> lit . P.PrimLitSumDecimal <$> encodeInternableString (T.pack (show dec))
|
||||
BENumeric n -> lit . P.PrimLitSumNumeric <$> encodeInternableString (T.pack (show n))
|
||||
BEText x -> lit . P.PrimLitSumText <$> encodeInternableString x
|
||||
BETimestamp x -> pureLit $ P.PrimLitSumTimestamp x
|
||||
BEParty x ->
|
||||
lit . either P.PrimLitSumParty P.PrimLitSumPartyInternedId
|
||||
<$> encodeInternableString (unPartyLiteral x)
|
||||
BEParty x -> lit . P.PrimLitSumParty <$> encodeInternableString (unPartyLiteral x)
|
||||
BEDate x -> pureLit $ P.PrimLitSumDate x
|
||||
|
||||
BEUnit -> pure $ P.ExprSumPrimCon $ P.Enumerated $ Right P.PrimConCON_UNIT
|
||||
@ -461,10 +390,10 @@ encodeBuiltinExpr = \case
|
||||
|
||||
encodeExpr' :: Expr -> Encode P.Expr
|
||||
encodeExpr' = \case
|
||||
EVar v -> expr . either P.ExprSumVar P.ExprSumVarInternedId <$> encodeName' unExprVarName v
|
||||
EVar v -> expr . P.ExprSumVar <$> encodeName unExprVarName v
|
||||
EVal (Qualified pkgRef modName val) -> do
|
||||
valNameModule <- encodeModuleRef pkgRef modName
|
||||
(valNameName, valNameNameInternedId) <- encodeValueName val
|
||||
valNameName <- encodeValueName val
|
||||
pureExpr $ P.ExprSumVal P.ValName{..}
|
||||
EBuiltin bi -> expr <$> encodeBuiltinExpr bi
|
||||
ERecCon{..} -> do
|
||||
@ -694,10 +623,7 @@ encodeDefDataType DefDataType{..} = do
|
||||
defDataType_FieldsFields <- encodeFieldsWithTypes unVariantConName fs
|
||||
pure $ P.DefDataTypeDataConsVariant P.DefDataType_Fields{..}
|
||||
DataEnum cs -> do
|
||||
mangledAndInterned <- encodeNames (map unVariantConName cs)
|
||||
let (defDataType_EnumConstructorsConstructors, defDataType_EnumConstructorsConstructorsInternedIds) = case mangledAndInterned of
|
||||
Left mangled -> (V.fromList mangled, V.empty)
|
||||
Right mangledIds -> (V.empty, V.fromList mangledIds)
|
||||
defDataType_EnumConstructorsConstructors <- encodeList (encodeName unVariantConName) cs
|
||||
pure $ P.DefDataTypeDataConsEnum P.DefDataType_EnumConstructors{..}
|
||||
let defDataTypeSerializable = getIsSerializable dataSerializable
|
||||
defDataTypeLocation <- traverse encodeSourceLoc dataLocation
|
||||
@ -705,7 +631,7 @@ encodeDefDataType DefDataType{..} = do
|
||||
|
||||
encodeDefValue :: DefValue -> Encode P.DefValue
|
||||
encodeDefValue DefValue{..} = do
|
||||
(defValue_NameWithTypeName, defValue_NameWithTypeNameInternedId) <- encodeValueName (fst dvalBinder)
|
||||
defValue_NameWithTypeName <- encodeValueName (fst dvalBinder)
|
||||
defValue_NameWithTypeType <- encodeType (snd dvalBinder)
|
||||
let defValueNameWithType = Just P.DefValue_NameWithType{..}
|
||||
defValueExpr <- encodeExpr dvalBody
|
||||
@ -774,12 +700,9 @@ encodeModule Module{..} = do
|
||||
encodePackage :: Package -> P.Package
|
||||
encodePackage (Package version mods) =
|
||||
let env = initEncodeEnv version (WithInterning True)
|
||||
(packageModules, EncodeEnv{internedStrings, internedDottedNames}) =
|
||||
runState (encodeNameMap encodeModule mods) env
|
||||
packageInternedStrings =
|
||||
(packageModules, EncodeEnv{internedStrings}) = runState (encodeNameMap encodeModule mods) env
|
||||
packageInternedPackageIds =
|
||||
V.fromList $ map (encodeString . fst) $ L.sortOn snd $ HMS.toList internedStrings
|
||||
packageInternedDottedNames =
|
||||
V.fromList $ map (P.InternedDottedName . V.fromList . fst) $ L.sortOn snd $ HMS.toList internedDottedNames
|
||||
in
|
||||
P.Package{..}
|
||||
|
||||
|
@ -7,6 +7,7 @@ module DA.Daml.LF.Proto3.Error
|
||||
|
||||
import qualified Data.Text as T
|
||||
import Data.Int (Int32)
|
||||
import Data.Word (Word64)
|
||||
|
||||
import DA.Daml.LF.Ast
|
||||
|
||||
@ -20,7 +21,6 @@ data Error
|
||||
| EDuplicateTemplate TypeConName
|
||||
| DuplicateChoice ChoiceName
|
||||
| UnsupportedMinorVersion T.Text
|
||||
| BadStringId Int32
|
||||
| BadDottedNameId Int32
|
||||
| MissingPackageRefId Word64
|
||||
| ExpectedTCon Type
|
||||
deriving (Show, Eq)
|
||||
|
@ -1,63 +0,0 @@
|
||||
-- Copyright (c) 2019 The DAML Authors. All rights reserved.
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
{-# LANGUAGE DefaultSignatures #-}
|
||||
{-# LANGUAGE FlexibleInstances #-}
|
||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
{-# LANGUAGE TypeOperators #-}
|
||||
module DA.Daml.LF.Proto3.Util (
|
||||
EitherLike,
|
||||
toEither,
|
||||
fromEither,
|
||||
) where
|
||||
|
||||
import Data.Int
|
||||
import qualified Data.Text.Lazy as TL
|
||||
import GHC.Generics
|
||||
|
||||
import qualified Da.DamlLf1 as P
|
||||
|
||||
class EitherLike a b e where
|
||||
toEither :: e -> Either a b
|
||||
fromEither :: Either a b -> e
|
||||
|
||||
default toEither
|
||||
:: (Generic e, Rep e ~ D1 m1 (C1 m2 (S1 m3 (Rec0 a)) :+: C1 m4 (S1 m5 (Rec0 b))))
|
||||
=> e -> Either a b
|
||||
toEither e =
|
||||
case unM1 $ from e of
|
||||
L1 x -> Left $ unK1 $ unM1 $ unM1 x
|
||||
R1 y -> Right $ unK1 $ unM1 $ unM1 y
|
||||
default fromEither
|
||||
:: (Generic e, Rep e ~ D1 m1 (C1 m2 (S1 m3 (Rec0 a)) :+: C1 m4 (S1 m5 (Rec0 b))))
|
||||
=> Either a b -> e
|
||||
fromEither = to . M1 . either (L1 . M1 . M1 . K1) (R1 . M1 . M1 . K1)
|
||||
|
||||
instance EitherLike a b (Either a b) where
|
||||
toEither = id
|
||||
fromEither = id
|
||||
|
||||
instance EitherLike TL.Text Int32 P.CaseAlt_ConsVarHead
|
||||
instance EitherLike TL.Text Int32 P.CaseAlt_ConsVarTail
|
||||
instance EitherLike TL.Text Int32 P.CaseAlt_EnumConstructor
|
||||
instance EitherLike TL.Text Int32 P.CaseAlt_OptionalSomeVarBody
|
||||
instance EitherLike TL.Text Int32 P.CaseAlt_VariantBinder
|
||||
instance EitherLike TL.Text Int32 P.CaseAlt_VariantVariant
|
||||
instance EitherLike TL.Text Int32 P.DefTemplateParam
|
||||
instance EitherLike TL.Text Int32 P.Expr_EnumConEnumCon
|
||||
instance EitherLike TL.Text Int32 P.Expr_RecProjField
|
||||
instance EitherLike TL.Text Int32 P.Expr_RecUpdField
|
||||
instance EitherLike TL.Text Int32 P.Expr_TupleProjField
|
||||
instance EitherLike TL.Text Int32 P.Expr_TupleUpdField
|
||||
instance EitherLike TL.Text Int32 P.Expr_VariantConVariantCon
|
||||
instance EitherLike TL.Text Int32 P.FieldWithExprField
|
||||
instance EitherLike TL.Text Int32 P.FieldWithTypeField
|
||||
instance EitherLike TL.Text Int32 P.KeyExpr_ProjectionField
|
||||
instance EitherLike TL.Text Int32 P.KeyExpr_RecordFieldField
|
||||
instance EitherLike TL.Text Int32 P.TemplateChoiceName
|
||||
instance EitherLike TL.Text Int32 P.TemplateChoiceSelfBinder
|
||||
instance EitherLike TL.Text Int32 P.Type_VarVar
|
||||
instance EitherLike TL.Text Int32 P.TypeVarWithKindVar
|
||||
instance EitherLike TL.Text Int32 P.Update_ExerciseChoice
|
||||
instance EitherLike TL.Text Int32 P.VarWithTypeVar
|
@ -1,9 +1,6 @@
|
||||
-- Copyright (c) 2019 The DAML Authors. All rights reserved.
|
||||
-- SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
-- Check that the interning tables don't contain duplicates:
|
||||
-- @QUERY-LF .interned_strings // [] | (unique | length == length)
|
||||
-- @QUERY-LF .interned_dotted_names // [] | (unique | length == length)
|
||||
daml 1.2
|
||||
module Test where
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
-- Check that enum types get translated to DAML-LF's enum types.
|
||||
-- @SINCE-LF 1.6
|
||||
-- @QUERY-LF .modules[] | .data_types[] | select(.name | lf::get_dotted_name($pkg) == ["Color"]) | has("enum")
|
||||
-- @QUERY-LF .modules[] | .values[] | select(.name_with_type | lf::get_value_name($pkg) == ["red"]) | .expr | has("enum_con")
|
||||
-- @QUERY-LF .modules[] | .values[] | select(.name_with_type | lf::get_value_name($pkg) == ["isRed"]) | .expr.abs.body.case.alts | .[0] | has("enum")
|
||||
-- @QUERY-LF .modules[] | .values[] | select(.name_with_type | lf::get_name($pkg) == ["red"]) | .expr | has("enum_con")
|
||||
-- @QUERY-LF .modules[] | .values[] | select(.name_with_type | lf::get_name($pkg) == ["isRed"]) | .expr.abs.body.case.alts | .[0] | has("enum")
|
||||
-- @QUERY-LF .modules[] | .data_types[] | select(.name | lf::get_dotted_name($pkg) == ["Tag"]) | (has("enum") | not)
|
||||
daml 1.2
|
||||
module EnumLF where
|
||||
|
@ -6,7 +6,7 @@
|
||||
-- uses actors as a sanity check.
|
||||
|
||||
-- @SINCE-LF 1.5
|
||||
-- @QUERY-LF [.modules[] | .values[] | select(.name_with_type | lf::get_value_name($pkg) == ["$$fFooInstance"]) | .expr | .. | objects | select(has("exercise")) | .exercise | has("actor") | not] | (length > 0 and all)
|
||||
-- @QUERY-LF [.modules[] | .values[] | select(.name_with_type | lf::get_name($pkg) == ["$$fFooInstance"]) | .expr | .. | objects | select(has("exercise")) | .exercise | has("actor") | not] | all
|
||||
daml 1.2
|
||||
module ExerciseWithoutActors where
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
-- All rights reserved.
|
||||
|
||||
-- @ SINCE-LF 1.6
|
||||
-- @QUERY-LF [.modules[] | .values[] | .expr.val.module.package_ref | select(has("interned_id"))] | length == 2
|
||||
-- @QUERY-LF .interned_strings | length >= 2
|
||||
-- @QUERY-LF [ .modules[] | .values[] | .expr.val.module.package_ref.interned_id ] | sort == ["0", "1"]
|
||||
-- @QUERY-LF .interned_package_ids | length == 2
|
||||
|
||||
-- We test that interning of package ids works. The two packages we reference are
|
||||
-- daml-prim and daml-stdlib.
|
||||
|
@ -173,7 +173,7 @@ testCase args version getService outdir registerTODO (name, file) = singleTest n
|
||||
for_ [file ++ ", " ++ x | Todo x <- anns] (registerTODO . TODO)
|
||||
resDiag <- checkDiagnostics log [fields | DiagnosticFields fields <- anns] $
|
||||
[ideErrorText "" $ T.pack $ show e | Left e <- [ex], not $ "_IGNORE_" `isInfixOf` show e] ++ diags
|
||||
resQueries <- runJqQuery log version outdir file [q | QueryLF q <- anns]
|
||||
resQueries <- runJqQuery log outdir file [q | QueryLF q <- anns]
|
||||
let failures = catMaybes $ resDiag : resQueries
|
||||
case failures of
|
||||
err : _others -> pure $ testFailed err
|
||||
@ -185,19 +185,15 @@ testCase args version getService outdir registerTODO (name, file) = singleTest n
|
||||
UntilLF maxVersion -> version > maxVersion
|
||||
_ -> False
|
||||
|
||||
runJqQuery :: (String -> IO ()) -> LF.Version -> FilePath -> FilePath -> [String] -> IO [Maybe String]
|
||||
runJqQuery log version outdir file qs = do
|
||||
runJqQuery :: (String -> IO ()) -> FilePath -> FilePath -> [String] -> IO [Maybe String]
|
||||
runJqQuery log outdir file qs = do
|
||||
let proj = takeBaseName file
|
||||
forM qs $ \q -> do
|
||||
log $ "running jq query: " ++ q
|
||||
let jqKey = "external" </> "jq_dev_env" </> "bin" </> if isWindows then "jq.exe" else "jq"
|
||||
jq <- locateRunfiles $ mainWorkspace </> jqKey
|
||||
queryLfDir <- locateRunfiles $ mainWorkspace </> "compiler/damlc/tests/src"
|
||||
let queryLfMod
|
||||
| version `supports` featureStringInterning = "query-lf-interned"
|
||||
| otherwise = "query-lf-non-interned"
|
||||
let fullQuery = "import \"./" ++ queryLfMod ++ "\" as lf; . as $pkg | " ++ q
|
||||
out <- readProcess jq ["-L", queryLfDir, fullQuery, outdir </> proj <.> "json"] ""
|
||||
queryLfLib <- locateRunfiles $ mainWorkspace </> "compiler/damlc/tests/src"
|
||||
out <- readProcess jq ["-L", queryLfLib, "import \"./query-lf-non-interned\" as lf; . as $pkg | " ++ q, outdir </> proj <.> "json"] ""
|
||||
case trim out of
|
||||
"true" -> pure Nothing
|
||||
other -> pure $ Just $ "jq query failed: got " ++ other
|
||||
|
@ -1,9 +0,0 @@
|
||||
def get_value_name(pkg): pkg.interned_dotted_names[.name_interned_id] | .segment_ids | map(pkg.interned_strings[.]);
|
||||
|
||||
def get_int64(pkg): .int64;
|
||||
|
||||
def get_dotted_name(pkg): pkg.interned_dotted_names[.segments_interned_id // 0] | .segment_ids | map(pkg.interned_strings[.]);
|
||||
|
||||
def get_field(pkg): pkg.interned_strings[.interned_id];
|
||||
|
||||
def get_name(pkg): .name;
|
@ -4,6 +4,6 @@ def get_int64(pkg): .int64;
|
||||
|
||||
def get_dotted_name(pkg): .segments;
|
||||
|
||||
def get_field(pkg): .name;
|
||||
def get_field(pkg): .field;
|
||||
|
||||
def get_name(pkg): .name;
|
||||
|
@ -6,7 +6,6 @@ load("//bazel_tools:pkg.bzl", "pkg_tar")
|
||||
load("//bazel_tools:proto.bzl", "proto_gen")
|
||||
load(
|
||||
"//bazel_tools:scala.bzl",
|
||||
"da_scala_binary",
|
||||
"da_scala_library",
|
||||
"da_scala_test_suite",
|
||||
"lf_scalacopts",
|
||||
@ -227,16 +226,3 @@ pkg_tar(
|
||||
package_dir = "daml-lf-archive-protos/protobuf/da",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# An ad-hoc tool for testing, benchmarking and profiling package decoding performance in isolation.
|
||||
da_scala_binary(
|
||||
name = "decode-tester",
|
||||
srcs = ["src/test/scala/com/digitalasset/daml/lf/archive/DecodeMain.scala"],
|
||||
main_class = "com.digitalasset.daml.lf.archive.DecodeMain",
|
||||
deps = [
|
||||
":daml_lf_archive_scala",
|
||||
":daml_lf_java_proto",
|
||||
"//daml-lf/data",
|
||||
"//daml-lf/language",
|
||||
],
|
||||
)
|
||||
|
@ -36,7 +36,6 @@
|
||||
// 2019-07-29: Add nat kind and Nat types, Numeric types and Numeric builtins
|
||||
// 2019-09-17: Add Any type and, To_Any and From_Any builtins
|
||||
// 2019-09-17: Drop support for Decimal
|
||||
// 2019-09-30: Add interning of strings and dotted names
|
||||
|
||||
syntax = "proto3";
|
||||
package daml_lf_1;
|
||||
@ -63,17 +62,16 @@ message PackageRef {
|
||||
|
||||
// An index into `interned_package_ids` of the Package containing
|
||||
// this reference.
|
||||
int32 interned_id = 3; // *Available in versions >= 1.6*
|
||||
uint64 interned_id = 3; // *Available in versions >= 1.6*
|
||||
}
|
||||
}
|
||||
|
||||
// A `name`, e.g. Util.Either.isLeft
|
||||
message DottedName {
|
||||
// *Must be a non-empty list of a valid identifiers unless `segments_interned_id` is set.*
|
||||
|
||||
// *Must be a non-empty list of a valid identifiers*
|
||||
repeated string segments = 1;
|
||||
|
||||
// *Must be set if and only if `segments` is an empty list.*
|
||||
int32 segments_interned_id = 2; // *Available in versions >= 1.dev*
|
||||
}
|
||||
|
||||
// A fully qualified module reference
|
||||
@ -104,11 +102,8 @@ message ValName {
|
||||
// Module where the value is defined
|
||||
ModuleRef module = 1;
|
||||
|
||||
// *Must be a non-empty list of a valid identifiers unless `interned_id` is set.*
|
||||
// value name.
|
||||
repeated string name = 2;
|
||||
|
||||
// *Must be set if and only if `segments` is an empty list.*
|
||||
int32 name_interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
|
||||
// A field name definition in a record or a variant associated with a type.
|
||||
@ -116,10 +111,7 @@ message FieldWithType {
|
||||
|
||||
// Name of the field .
|
||||
// *Must be a valid identifier*
|
||||
oneof field {
|
||||
string name = 1;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string field = 1;
|
||||
|
||||
// Type associated
|
||||
Type type = 2;
|
||||
@ -130,10 +122,7 @@ message VarWithType {
|
||||
|
||||
// Name of the bound expression variable.
|
||||
// *Must be a valid identifier*
|
||||
oneof var {
|
||||
string name = 1;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string var = 1;
|
||||
|
||||
// Type of the bound variable
|
||||
Type type = 2;
|
||||
@ -143,11 +132,7 @@ message VarWithType {
|
||||
message TypeVarWithKind {
|
||||
// Name of the bound expression variable
|
||||
// *Must be a valid identifier*
|
||||
oneof var {
|
||||
string name = 1;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
|
||||
string var = 1;
|
||||
// Kind of the bound variable
|
||||
Kind kind = 2;
|
||||
}
|
||||
@ -156,11 +141,7 @@ message TypeVarWithKind {
|
||||
message FieldWithExpr {
|
||||
// Name of the field
|
||||
// *Must be a valid identifier*
|
||||
oneof field {
|
||||
string name = 1;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
|
||||
string field = 1;
|
||||
// Value of the field
|
||||
Expr expr = 2;
|
||||
}
|
||||
@ -268,10 +249,7 @@ message Type {
|
||||
|
||||
// Name of the variable.
|
||||
// *Must be a valid identifier*
|
||||
oneof var {
|
||||
string var_name = 1;
|
||||
int32 var_interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string var = 1;
|
||||
|
||||
// Types to which the variable is applied
|
||||
repeated Type args = 2;
|
||||
@ -495,11 +473,9 @@ message PrimLit {
|
||||
// one. so, string it is. note that we can't store the whole and
|
||||
// decimal part in two numbers either, because 10^28 > 2^63.
|
||||
string decimal = 2; // *Available in versions < 1.dev*
|
||||
int32 decimal_interned_id = 10; // *Available in versions >= 1.dev*
|
||||
|
||||
// Unicode string literal ('LitText')
|
||||
string text = 4;
|
||||
int32 text_interned_id = 11; // *Available in versions >= 1.dev*
|
||||
|
||||
// UTC timestamp literal ('LitTimestamp')
|
||||
//
|
||||
@ -516,7 +492,6 @@ message PrimLit {
|
||||
// Party literal ('LitParty')
|
||||
// *Must be a PartyId string*
|
||||
string party = 7;
|
||||
int32 party_interned_id = 12; // *Available in versions >= 1.dev*
|
||||
|
||||
// Date literal ('Date')
|
||||
// Serialization of the number of days since the unix epoch. can go backwards.
|
||||
@ -533,7 +508,6 @@ message PrimLit {
|
||||
//
|
||||
// The number of decimal digits indicate the scale of the number.
|
||||
string numeric = 9; // *Available in versions >= 1.dev*
|
||||
int32 numeric_interned_id = 13; // *Available in versions >= 1.dev*
|
||||
}
|
||||
|
||||
reserved 3; // This was char.
|
||||
@ -577,10 +551,7 @@ message Expr {
|
||||
|
||||
// Name of the record field to be projected on.
|
||||
// *must be a valid Identifier*
|
||||
oneof field {
|
||||
string name = 2;
|
||||
int32 interned_id = 4; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string field = 2;
|
||||
|
||||
// projected expression
|
||||
Expr record = 3;
|
||||
@ -594,10 +565,7 @@ message Expr {
|
||||
|
||||
// Name of the updated field.
|
||||
// *must be a valid identifier*
|
||||
oneof field {
|
||||
string name = 2;
|
||||
int32 interned_id = 5; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string field = 2;
|
||||
|
||||
// Actual record being updated
|
||||
Expr record = 3;
|
||||
@ -614,10 +582,7 @@ message Expr {
|
||||
|
||||
// name of the variant constructor
|
||||
// *Must be a valid identifier*
|
||||
oneof variant_con {
|
||||
string name = 2;
|
||||
int32 interned_id = 4; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string variant_con = 2;
|
||||
|
||||
// Argument of the variant.
|
||||
Expr variant_arg = 3;
|
||||
@ -632,10 +597,7 @@ message Expr {
|
||||
|
||||
// name of the enum constructor
|
||||
// *Must be a valid identifier*
|
||||
oneof enum_con {
|
||||
string name = 2;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string enum_con = 2;
|
||||
}
|
||||
|
||||
// Tuple Construction ('ExpTupleCon')
|
||||
@ -649,10 +611,7 @@ message Expr {
|
||||
|
||||
// Name of the field to be projected on.
|
||||
// *Must be a valid Identifier*
|
||||
oneof field {
|
||||
string name = 1;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string field = 1;
|
||||
|
||||
// tuple to be projected.
|
||||
Expr tuple = 2;
|
||||
@ -663,10 +622,7 @@ message Expr {
|
||||
|
||||
// Name of the updated field.
|
||||
// *must be a valid identifier*.
|
||||
oneof field {
|
||||
string name = 1;
|
||||
int32 interned_id = 4; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string field = 1;
|
||||
|
||||
// Actual tuple being updated.
|
||||
Expr tuple = 2;
|
||||
@ -787,7 +743,6 @@ message Expr {
|
||||
// Expression variable ('ExpVar')
|
||||
// *must be a valid identifier*
|
||||
string var = 1;
|
||||
int32 var_interned_id = 31; // *Available in versions >= 1.dev*
|
||||
|
||||
// Defined value ('ExpVal')
|
||||
ValName val = 2;
|
||||
@ -887,17 +842,11 @@ message CaseAlt {
|
||||
|
||||
// name of the variant constructor
|
||||
// *Must be a valid identifier*
|
||||
oneof variant {
|
||||
string variant_name = 2;
|
||||
int32 variant_interned_id = 4; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string variant = 2;
|
||||
|
||||
// name of the variant binder
|
||||
// *Must be a valid identifier*
|
||||
oneof binder {
|
||||
string binder_name = 3;
|
||||
int32 binder_interned_id = 5; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string binder = 3;
|
||||
}
|
||||
|
||||
// Enum pattern
|
||||
@ -909,36 +858,24 @@ message CaseAlt {
|
||||
|
||||
// name of the variant constructor
|
||||
// *Must be a valid identifier*
|
||||
oneof constructor {
|
||||
string name = 2;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string constructor = 2;
|
||||
}
|
||||
|
||||
// Non empty list pattern
|
||||
message Cons {
|
||||
// name of the binder for the head
|
||||
// *Must be a valid identifier*
|
||||
oneof var_head {
|
||||
string var_head_name = 1;
|
||||
int32 var_head_interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string var_head = 1;
|
||||
|
||||
// name of the binder for the tail
|
||||
// *Must be a valid identifier*
|
||||
oneof var_tail {
|
||||
string var_tail_name = 2;
|
||||
int32 var_tail_interned_id = 4; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string var_tail = 2;
|
||||
}
|
||||
|
||||
// Non empty option patterm
|
||||
// *Available in versions >= 1.1*
|
||||
message OptionalSome {
|
||||
oneof var_body {
|
||||
string name = 1;
|
||||
int32 interned_id = 2; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string var_body = 1;
|
||||
}
|
||||
|
||||
oneof Sum {
|
||||
@ -990,10 +927,7 @@ message Update {
|
||||
// Template type
|
||||
TypeConName template = 1;
|
||||
// name of the exercised template choice
|
||||
oneof choice {
|
||||
string name = 2;
|
||||
int32 interned_id = 6; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string choice = 2;
|
||||
// contract id
|
||||
Expr cid = 3;
|
||||
// actors
|
||||
@ -1012,7 +946,7 @@ message Update {
|
||||
reserved 3; // was actor, we thought we'd need this, but we don't
|
||||
}
|
||||
|
||||
// Embedded Expression Update
|
||||
// Embeded Exression Update
|
||||
message EmbedExpr {
|
||||
// Expression type
|
||||
Type type = 1;
|
||||
@ -1084,10 +1018,7 @@ message Scenario {
|
||||
message TemplateChoice {
|
||||
|
||||
// *Must be a valid identifier*
|
||||
oneof name {
|
||||
string choice_name = 1;
|
||||
int32 choice_interned_id = 9; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string name = 1;
|
||||
|
||||
// Choice type
|
||||
bool consuming = 2;
|
||||
@ -1109,10 +1040,7 @@ message TemplateChoice {
|
||||
Expr update = 6;
|
||||
|
||||
// Name to bind the ContractId of the contract this choice is exercised on to.
|
||||
oneof self_binder {
|
||||
string self_binder_name = 7;
|
||||
int32 self_binder_interned_id = 10; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string self_binder = 7;
|
||||
|
||||
Location location = 8;
|
||||
}
|
||||
@ -1121,10 +1049,7 @@ message TemplateChoice {
|
||||
message KeyExpr {
|
||||
message Projection {
|
||||
Type.Con tycon = 1; // Always fully applied
|
||||
oneof field {
|
||||
string name = 2;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string field = 2;
|
||||
}
|
||||
|
||||
// note that the projection is always referring to the template parameter.
|
||||
@ -1133,10 +1058,7 @@ message KeyExpr {
|
||||
}
|
||||
|
||||
message RecordField {
|
||||
oneof field {
|
||||
string name = 1;
|
||||
int32 interned_id = 3; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string field = 1;
|
||||
KeyExpr expr = 2;
|
||||
}
|
||||
|
||||
@ -1171,10 +1093,7 @@ message DefTemplate {
|
||||
DottedName tycon = 1;
|
||||
|
||||
// Name to which the template argument is bound.
|
||||
oneof param {
|
||||
string param_name = 2;
|
||||
int32 param_interned_id = 11; // *Available in versions >= 1.dev*
|
||||
}
|
||||
string param = 2;
|
||||
|
||||
// NOTE(MH): The new runtime authorization check for DAML 1.0 does not rely
|
||||
// on the stakeholder signatures produced by the obligables computation
|
||||
@ -1218,7 +1137,6 @@ message DefDataType {
|
||||
// *Available in versions >= 1.6*
|
||||
message EnumConstructors {
|
||||
repeated string constructors = 1;
|
||||
repeated int32 constructors_interned_ids = 2; // *Available in versions >= 1.dev*
|
||||
}
|
||||
|
||||
// name of the defined data type
|
||||
@ -1255,9 +1173,7 @@ message DefValue {
|
||||
|
||||
// Name of the value
|
||||
// *each element of name must be a valid identifier*
|
||||
// `name` can be empty if and only if `name_interned_id` is set.
|
||||
repeated string name = 1;
|
||||
int32 name_interned_id = 6; // *Available in versions >= 1.dev*
|
||||
|
||||
// Type of the value
|
||||
Type type = 2;
|
||||
@ -1298,12 +1214,7 @@ message Module {
|
||||
repeated DefTemplate templates = 7;
|
||||
}
|
||||
|
||||
message InternedDottedName {
|
||||
repeated int32 segment_ids = 1; // *Available in versions >= 1.dev*
|
||||
}
|
||||
|
||||
message Package {
|
||||
repeated Module modules = 1;
|
||||
repeated string interned_strings = 2; // *Available in versions >= 1.6*
|
||||
repeated InternedDottedName interned_dotted_names = 3; // *Available in versions >= 1.dev*
|
||||
repeated string interned_package_ids = 2; // *Available in versions >= 1.6*
|
||||
}
|
||||
|
@ -24,28 +24,17 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
|
||||
private val languageVersion = LV(LV.Major.V1, minor)
|
||||
|
||||
private def name(s: String): Name = eitherToParseError(Name.fromString(s))
|
||||
|
||||
override def decodePackage(
|
||||
packageId: PackageId,
|
||||
lfPackage: PLF.Package,
|
||||
onlySerializableDataDefs: Boolean
|
||||
): Package = {
|
||||
val internedStrings: ImmArraySeq[String] = ImmArraySeq(
|
||||
lfPackage.getInternedStringsList.asScala: _*)
|
||||
if (internedStrings.nonEmpty)
|
||||
assertSince(LV.Features.internedPackageId, "interned strings table")
|
||||
|
||||
val internedDottedNames: ImmArraySeq[DottedName] =
|
||||
decodeInternedDottedNames(lfPackage.getInternedDottedNamesList.asScala, internedStrings)
|
||||
|
||||
val interned = decodeInternedPackageIds(lfPackage.getInternedPackageIdsList.asScala)
|
||||
Package(
|
||||
lfPackage.getModulesList.asScala
|
||||
.map(
|
||||
ModuleDecoder(
|
||||
packageId,
|
||||
internedStrings,
|
||||
internedDottedNames,
|
||||
_,
|
||||
onlySerializableDataDefs).decode))
|
||||
.map(ModuleDecoder(packageId, interned, _, onlySerializableDataDefs).decode))
|
||||
}
|
||||
|
||||
type ProtoModule = PLF.Module
|
||||
@ -54,29 +43,15 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
PLF.Module.parser().parseFrom(cis)
|
||||
|
||||
override def decodeScenarioModule(packageId: PackageId, lfModule: ProtoModule): Module =
|
||||
ModuleDecoder(
|
||||
packageId,
|
||||
ImmArraySeq.empty,
|
||||
ImmArraySeq.empty,
|
||||
lfModule,
|
||||
onlySerializableDataDefs = false).decode()
|
||||
ModuleDecoder(packageId, ImmArraySeq.empty, lfModule, onlySerializableDataDefs = false).decode()
|
||||
|
||||
private[this] def decodeInternedDottedNames(
|
||||
internedList: Seq[PLF.InternedDottedName],
|
||||
internedStrings: ImmArraySeq[String]): ImmArraySeq[DottedName] = {
|
||||
private[this] def eitherToParseError[A](x: Either[String, A]): A =
|
||||
x.fold(err => throw new ParseError(err), identity)
|
||||
|
||||
private[this] def decodeInternedPackageIds(internedList: Seq[String]): ImmArraySeq[PackageId] = {
|
||||
if (internedList.nonEmpty)
|
||||
assertSince(LV.Features.internedDottedNames, "interned dotted names table")
|
||||
|
||||
def outOfRange(id: Int) =
|
||||
ParseError(s"invalid string table index $id")
|
||||
|
||||
internedList
|
||||
.map(
|
||||
idn =>
|
||||
decodeSegments(
|
||||
idn.getSegmentIdsList.asScala
|
||||
.map(id => internedStrings.lift(id).getOrElse(throw outOfRange(id)))(breakOut))
|
||||
)(breakOut)
|
||||
assertSince(LV.Features.internedIds, "interned package ID table")
|
||||
internedList.map(s => eitherToParseError(PackageId.fromString(s)))(breakOut)
|
||||
}
|
||||
|
||||
private[this] def decodeSegments(segments: ImmArray[String]): DottedName =
|
||||
@ -87,16 +62,16 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
|
||||
case class ModuleDecoder(
|
||||
packageId: PackageId,
|
||||
internedStrings: ImmArraySeq[String],
|
||||
internedDottedNames: ImmArraySeq[DottedName],
|
||||
internedPackageIds: ImmArraySeq[PackageId],
|
||||
lfModule: PLF.Module,
|
||||
onlySerializableDataDefs: Boolean
|
||||
) {
|
||||
|
||||
val moduleName: ModuleName =
|
||||
decodeDottedName(lfModule.getName)
|
||||
val moduleName = eitherToParseError(
|
||||
ModuleName.fromSegments(lfModule.getName.getSegmentsList.asScala))
|
||||
|
||||
private var currentDefinitionRef: Option[DefinitionRef] = None
|
||||
// FIXME(JM): rewrite.
|
||||
var currentDefinitionRef: Option[DefinitionRef] = None
|
||||
|
||||
def decode(): Module = {
|
||||
val defs = mutable.ArrayBuffer[(DottedName, Definition)]()
|
||||
@ -106,7 +81,8 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
lfModule.getDataTypesList.asScala
|
||||
.filter(!onlySerializableDataDefs || _.getSerializable)
|
||||
.foreach { defn =>
|
||||
val defName = decodeDottedName(defn.getName)
|
||||
val defName =
|
||||
eitherToParseError(DottedName.fromSegments(defn.getName.getSegmentsList.asScala))
|
||||
currentDefinitionRef = Some(DefinitionRef(packageId, QualifiedName(moduleName, defName)))
|
||||
val d = decodeDefDataType(defn)
|
||||
defs += (defName -> d)
|
||||
@ -115,14 +91,8 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
if (!onlySerializableDataDefs) {
|
||||
// collect values
|
||||
lfModule.getValuesList.asScala.foreach { defn =>
|
||||
val nameWithType = defn.getNameWithType
|
||||
val defName =
|
||||
if (nameWithType.getNameCount == 0) {
|
||||
assertSince(LV.Features.internedDottedNames, "interned dotted names table")
|
||||
getInternedDottedName(nameWithType.getNameInternedId)
|
||||
} else {
|
||||
decodeSegments(ImmArray(nameWithType.getNameList.asScala))
|
||||
}
|
||||
decodeSegments(ImmArray(defn.getNameWithType.getNameList.asScala))
|
||||
currentDefinitionRef = Some(DefinitionRef(packageId, QualifiedName(moduleName, defName)))
|
||||
val d = decodeDefValue(defn)
|
||||
defs += (defName -> d)
|
||||
@ -131,7 +101,8 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
|
||||
// collect templates
|
||||
lfModule.getTemplatesList.asScala.foreach { defn =>
|
||||
val defName = decodeDottedName(defn.getTycon)
|
||||
val defName =
|
||||
eitherToParseError(DottedName.fromSegments(defn.getTycon.getSegmentsList.asScala))
|
||||
currentDefinitionRef = Some(DefinitionRef(packageId, QualifiedName(moduleName, defName)))
|
||||
templates += ((defName, decodeTemplate(defn)))
|
||||
}
|
||||
@ -140,53 +111,6 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
private[this] def getInternedString(id: Int) =
|
||||
internedStrings.lift(id).getOrElse {
|
||||
throw ParseError(s"invalid internedString table index $id")
|
||||
}
|
||||
|
||||
private[this] def getInternedPackageId(id: Int): PackageId = {
|
||||
assertSince(LV.Features.internedPackageId, "interned PackageId")
|
||||
toPackageId(getInternedString(id))
|
||||
}
|
||||
|
||||
private[this] def getInternedName(id: Int): Name = {
|
||||
assertSince(LV.Features.internedStrings, "interned Name")
|
||||
toName(getInternedString(id))
|
||||
}
|
||||
|
||||
private[this] def getInternedText(id: Int): PLText = {
|
||||
assertSince(LV.Features.internedStrings, "interned Text")
|
||||
PLText(getInternedString(id))
|
||||
}
|
||||
|
||||
private[this] def getInternedNumeric(id: Int): PrimLit = {
|
||||
assertSince(LV.Features.internedStrings, "interned Numeric")
|
||||
toNumericLiteral(getInternedString(id))
|
||||
}
|
||||
|
||||
private[this] def getInternedDecimal(id: Int): PLNumeric = {
|
||||
assertSince(LV.Features.internedStrings, "interned Decimal")
|
||||
toDecimalLiteral(getInternedString(id))
|
||||
}
|
||||
|
||||
private[this] def getInternedParty(id: Int): PLParty = {
|
||||
assertSince(LV.Features.internedStrings, "interned Party")
|
||||
toPartyLiteral(getInternedString(id))
|
||||
}
|
||||
|
||||
private[this] def getInternedDottedName(id: Int): DottedName =
|
||||
internedDottedNames.lift(id).getOrElse {
|
||||
assertSince(LV.Features.internedDottedNames, "interned DottedNames")
|
||||
throw ParseError(s"invalid dotted name table index $id")
|
||||
}
|
||||
|
||||
private[this] def decodeDottedName(name: PLF.DottedName): DottedName =
|
||||
if (name.getSegmentsCount == 0) {
|
||||
getInternedDottedName(name.getSegmentsInternedId)
|
||||
} else {
|
||||
decodeSegments(ImmArray(name.getSegmentsList.asScala))
|
||||
}
|
||||
|
||||
private[this] def decodeFeatureFlags(flags: PLF.FeatureFlags): FeatureFlags = {
|
||||
// NOTE(JM, #157): We disallow loading packages with these flags because they impact the Ledger API in
|
||||
@ -212,7 +136,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
case PLF.DefDataType.DataConsCase.ENUM =>
|
||||
assertSince(LV.Features.enum, "DefDataType.DataCons.Enum")
|
||||
assertEmpty(params.toSeq, "params")
|
||||
DataEnum(decodeEnumCon(lfDataType.getEnum))
|
||||
DataEnum(decodeEnumCons(ImmArray(lfDataType.getEnum.getConstructorsList.asScala)))
|
||||
case PLF.DefDataType.DataConsCase.DATACONS_NOT_SET =>
|
||||
throw ParseError("DefDataType.DATACONS_NOT_SET")
|
||||
|
||||
@ -220,46 +144,14 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def decodeFieldWithType(lfFieldWithType: PLF.FieldWithType): (Name, Type) =
|
||||
(lfFieldWithType.getFieldCase match {
|
||||
case PLF.FieldWithType.FieldCase.NAME =>
|
||||
toName(lfFieldWithType.getName)
|
||||
case PLF.FieldWithType.FieldCase.INTERNED_ID =>
|
||||
getInternedName(lfFieldWithType.getInternedId)
|
||||
case PLF.FieldWithType.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("FieldWithType.FIELD_NOT_SET")
|
||||
}) -> decodeType(lfFieldWithType.getType)
|
||||
|
||||
private[this] def decodeFields(lfFields: ImmArray[PLF.FieldWithType]): ImmArray[(Name, Type)] =
|
||||
lfFields.map(decodeFieldWithType)
|
||||
lfFields.map(field => name(field.getField) -> decodeType(field.getType))
|
||||
|
||||
private[this] def decodeFieldWithExpr(
|
||||
lfFieldWithExpr: PLF.FieldWithExpr,
|
||||
definition: String
|
||||
): (Name, Expr) =
|
||||
(lfFieldWithExpr.getFieldCase match {
|
||||
case PLF.FieldWithExpr.FieldCase.NAME => toName(lfFieldWithExpr.getName)
|
||||
case PLF.FieldWithExpr.FieldCase.INTERNED_ID =>
|
||||
getInternedName(lfFieldWithExpr.getInternedId)
|
||||
case PLF.FieldWithExpr.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("FieldWithExpr.FIELD_NOT_SET")
|
||||
}) -> decodeExpr(lfFieldWithExpr.getExpr, definition)
|
||||
|
||||
private[this] def decodeEnumCon(
|
||||
enumCon: PLF.DefDataType.EnumConstructors): ImmArray[EnumConName] =
|
||||
if (enumCon.getConstructorsCount == 0)
|
||||
enumCon.getConstructorsInternedIdsList.asScala
|
||||
.map(id => getInternedName(id))(breakOut)
|
||||
else
|
||||
enumCon.getConstructorsList.asScala.map(toName)(breakOut)
|
||||
private[this] def decodeEnumCons(cons: ImmArray[String]): ImmArray[EnumConName] =
|
||||
cons.map(name)
|
||||
|
||||
private[this] def decodeDefValue(lfValue: PLF.DefValue): DValue = {
|
||||
val nameWithType = lfValue.getNameWithType
|
||||
val definition =
|
||||
if (nameWithType.getNameCount == 0)
|
||||
getInternedDottedName(nameWithType.getNameInternedId).segments.toSeq.mkString(".")
|
||||
else
|
||||
nameWithType.getNameList.asScala.mkString(".")
|
||||
val definition = lfValue.getNameWithType.getNameList.asScala.mkString(".")
|
||||
DValue(
|
||||
typ = decodeType(lfValue.getNameWithType.getType),
|
||||
noPartyLiterals = lfValue.getNoPartyLiterals,
|
||||
@ -290,7 +182,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
}
|
||||
|
||||
private[this] def decodeTemplateKey(
|
||||
tpl: DottedName,
|
||||
tpl: String,
|
||||
key: PLF.DefTemplate.DefKey,
|
||||
tplVar: ExprVarName): TemplateKey = {
|
||||
assertSince(LV.Features.contractKeys, "DefTemplate.DefKey")
|
||||
@ -318,32 +210,13 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
ERecCon(
|
||||
tycon = decodeTypeConApp(recCon.getTycon),
|
||||
fields = ImmArray(recCon.getFieldsList.asScala).map(field =>
|
||||
(field.getFieldCase match {
|
||||
case PLF.KeyExpr.RecordField.FieldCase.NAME =>
|
||||
toName(field.getName)
|
||||
case PLF.KeyExpr.RecordField.FieldCase.INTERNED_ID =>
|
||||
getInternedName(field.getInternedId)
|
||||
case PLF.KeyExpr.RecordField.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("KeyExpr.Record.Field.FIELD_NOT_SET")
|
||||
|
||||
}) -> decodeKeyExpr(field.getExpr, tplVar))
|
||||
name(field.getField) -> decodeKeyExpr(field.getExpr, tplVar))
|
||||
)
|
||||
|
||||
case PLF.KeyExpr.SumCase.PROJECTIONS =>
|
||||
val lfProjs = expr.getProjections.getProjectionsList.asScala
|
||||
lfProjs.foldLeft(EVar(tplVar): Expr)(
|
||||
(acc, lfProj) =>
|
||||
ERecProj(
|
||||
decodeTypeConApp(lfProj.getTycon),
|
||||
lfProj.getFieldCase match {
|
||||
case PLF.KeyExpr.Projection.FieldCase.NAME => toName(lfProj.getName)
|
||||
case PLF.KeyExpr.Projection.FieldCase.INTERNED_ID =>
|
||||
getInternedName(lfProj.getInternedId)
|
||||
case PLF.KeyExpr.Projection.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("KeyExpr.Projection.Field.FIELD_NOT_SET")
|
||||
},
|
||||
acc
|
||||
))
|
||||
lfProjs.foldLeft(EVar(tplVar): Expr)((acc, lfProj) =>
|
||||
ERecProj(decodeTypeConApp(lfProj.getTycon), name(lfProj.getField), acc))
|
||||
|
||||
case PLF.KeyExpr.SumCase.SUM_NOT_SET =>
|
||||
throw ParseError("KeyExpr.SUM_NOT_SET")
|
||||
@ -351,17 +224,10 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
}
|
||||
|
||||
private[this] def decodeTemplate(lfTempl: PLF.DefTemplate): Template = {
|
||||
val tpl = decodeDottedName(lfTempl.getTycon)
|
||||
val paramName = lfTempl.getParamCase match {
|
||||
case PLF.DefTemplate.ParamCase.PARAM_NAME =>
|
||||
toName(lfTempl.getParamName)
|
||||
case PLF.DefTemplate.ParamCase.PARAM_INTERNED_ID =>
|
||||
getInternedName(lfTempl.getParamInternedId)
|
||||
case PLF.DefTemplate.ParamCase.PARAM_NOT_SET =>
|
||||
throw ParseError("DefTemplate.PARAM_NOT_SET")
|
||||
}
|
||||
val tpl = lfTempl.getTycon.getSegmentsList.asScala.mkString(".")
|
||||
|
||||
Template(
|
||||
param = paramName,
|
||||
param = name(lfTempl.getParam),
|
||||
precond = if (lfTempl.hasPrecond) decodeExpr(lfTempl.getPrecond, s"$tpl:ensure") else ETrue,
|
||||
signatories = decodeExpr(lfTempl.getSignatories, s"$tpl.signatory"),
|
||||
agreementText = decodeExpr(lfTempl.getAgreement, s"$tpl:agreement"),
|
||||
@ -370,38 +236,20 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
.map(ch => (ch.name, ch)),
|
||||
observers = decodeExpr(lfTempl.getObservers, s"$tpl:observer"),
|
||||
key =
|
||||
if (lfTempl.hasKey) Some(decodeTemplateKey(tpl, lfTempl.getKey, paramName))
|
||||
if (lfTempl.hasKey) Some(decodeTemplateKey(tpl, lfTempl.getKey, name(lfTempl.getParam)))
|
||||
else None
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def decodeChoice(
|
||||
tpl: DottedName,
|
||||
lfChoice: PLF.TemplateChoice): TemplateChoice = {
|
||||
private[this] def decodeChoice(tpl: String, lfChoice: PLF.TemplateChoice): TemplateChoice = {
|
||||
val (v, t) = decodeBinder(lfChoice.getArgBinder)
|
||||
val chName: Name = lfChoice.getNameCase match {
|
||||
case PLF.TemplateChoice.NameCase.CHOICE_NAME =>
|
||||
toName(lfChoice.getChoiceName)
|
||||
case PLF.TemplateChoice.NameCase.CHOICE_INTERNED_ID =>
|
||||
getInternedName(lfChoice.getChoiceInternedId)
|
||||
case PLF.TemplateChoice.NameCase.NAME_NOT_SET =>
|
||||
throw ParseError("TemplateChoice.NAME_NOT_SET")
|
||||
|
||||
}
|
||||
val selfBinder: Name = lfChoice.getSelfBinderCase match {
|
||||
case PLF.TemplateChoice.SelfBinderCase.SELF_BINDER_NAME =>
|
||||
toName(lfChoice.getSelfBinderName)
|
||||
case PLF.TemplateChoice.SelfBinderCase.SELF_BINDER_INTERNED_ID =>
|
||||
getInternedName(lfChoice.getSelfBinderInternedId)
|
||||
case PLF.TemplateChoice.SelfBinderCase.SELFBINDER_NOT_SET =>
|
||||
throw ParseError("TemplateChoice.SELFBINDER_NOT_SET")
|
||||
}
|
||||
val chName = lfChoice.getName
|
||||
|
||||
TemplateChoice(
|
||||
name = chName,
|
||||
name = name(chName),
|
||||
consuming = lfChoice.getConsuming,
|
||||
controllers = decodeExpr(lfChoice.getControllers, s"$tpl:$chName:controller"),
|
||||
selfBinder = selfBinder,
|
||||
selfBinder = name(lfChoice.getSelfBinder),
|
||||
argBinder = Some(v) -> t,
|
||||
returnType = decodeType(lfChoice.getRetType),
|
||||
update = decodeExpr(lfChoice.getUpdate, s"$tpl:$chName:choice")
|
||||
@ -427,16 +275,8 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
lfType.getSumCase match {
|
||||
case PLF.Type.SumCase.VAR =>
|
||||
val tvar = lfType.getVar
|
||||
val varName = tvar.getVarCase match {
|
||||
case PLF.Type.Var.VarCase.VAR_NAME =>
|
||||
toName(tvar.getVarName)
|
||||
case PLF.Type.Var.VarCase.VAR_INTERNED_ID =>
|
||||
getInternedName(tvar.getVarInternedId)
|
||||
case PLF.Type.Var.VarCase.VAR_NOT_SET =>
|
||||
throw ParseError("Type.VAR_NOT_SET")
|
||||
}
|
||||
tvar.getArgsList.asScala
|
||||
.foldLeft[Type](TVar(varName))((typ, arg) => TApp(typ, decodeType(arg)))
|
||||
.foldLeft[Type](TVar(name(tvar.getVar)))((typ, arg) => TApp(typ, decodeType(arg)))
|
||||
case PLF.Type.SumCase.NAT =>
|
||||
assertSince(LV.Features.numeric, "Type.NAT")
|
||||
Numeric.Scale
|
||||
@ -479,23 +319,33 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
val tuple = lfType.getTuple
|
||||
val fields = tuple.getFieldsList.asScala
|
||||
assertNonEmpty(fields, "fields")
|
||||
TTuple(fields.map(decodeFieldWithType)(breakOut))
|
||||
TTuple(
|
||||
ImmArray(fields.map(ft => name(ft.getField) -> decodeType(ft.getType)))
|
||||
)
|
||||
|
||||
case PLF.Type.SumCase.SUM_NOT_SET =>
|
||||
throw ParseError("Type.SUM_NOT_SET")
|
||||
}
|
||||
|
||||
private[this] def decodeModuleRef(lfRef: PLF.ModuleRef): (PackageId, ModuleName) = {
|
||||
val modName = decodeDottedName(lfRef.getModuleName)
|
||||
val modName = eitherToParseError(
|
||||
ModuleName.fromSegments(lfRef.getModuleName.getSegmentsList.asScala))
|
||||
import PLF.PackageRef.{SumCase => SC}
|
||||
|
||||
val pkgId = lfRef.getPackageRef.getSumCase match {
|
||||
case SC.SELF =>
|
||||
this.packageId
|
||||
case SC.PACKAGE_ID =>
|
||||
toPackageId(lfRef.getPackageRef.getPackageId)
|
||||
val rawPid = lfRef.getPackageRef.getPackageId
|
||||
PackageId
|
||||
.fromString(rawPid)
|
||||
.getOrElse(throw ParseError(s"invalid packageId '$rawPid'"))
|
||||
case SC.INTERNED_ID =>
|
||||
getInternedPackageId(lfRef.getPackageRef.getInternedId)
|
||||
assertSince(LV.Features.internedIds, "interned package ID")
|
||||
val iidl = lfRef.getPackageRef.getInternedId
|
||||
def outOfRange = ParseError(s"invalid package ID table index $iidl")
|
||||
val iid = iidl.toInt
|
||||
if (iidl != iid.toLong) throw outOfRange
|
||||
internedPackageIds.lift(iid).getOrElse(throw outOfRange)
|
||||
case SC.SUM_NOT_SET =>
|
||||
throw ParseError("PackageRef.SUM_NOT_SET")
|
||||
}
|
||||
@ -504,18 +354,14 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
|
||||
private[this] def decodeValName(lfVal: PLF.ValName): ValueRef = {
|
||||
val (packageId, module) = decodeModuleRef(lfVal.getModule)
|
||||
val name: DottedName =
|
||||
if (lfVal.getNameCount == 0) {
|
||||
getInternedDottedName(lfVal.getNameInternedId)
|
||||
} else {
|
||||
decodeSegments(ImmArray(lfVal.getNameList.asScala))
|
||||
}
|
||||
val name = decodeSegments(ImmArray(lfVal.getNameList.asScala))
|
||||
ValueRef(packageId, QualifiedName(module, name))
|
||||
}
|
||||
|
||||
private[this] def decodeTypeConName(lfTyConName: PLF.TypeConName): TypeConName = {
|
||||
val (packageId, module) = decodeModuleRef(lfTyConName.getModule)
|
||||
val name = decodeDottedName(lfTyConName.getName)
|
||||
val name = eitherToParseError(
|
||||
DottedName.fromSegments(lfTyConName.getName.getSegmentsList.asScala))
|
||||
Identifier(packageId, QualifiedName(module, name))
|
||||
}
|
||||
|
||||
@ -534,10 +380,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
private[this] def decodeExprBody(lfExpr: PLF.Expr, definition: String): Expr =
|
||||
lfExpr.getSumCase match {
|
||||
case PLF.Expr.SumCase.VAR =>
|
||||
EVar(toName(lfExpr.getVar))
|
||||
|
||||
case PLF.Expr.SumCase.VAR_INTERNED_ID =>
|
||||
EVar(getInternedName(lfExpr.getVarInternedId))
|
||||
EVar(name(lfExpr.getVar))
|
||||
|
||||
case PLF.Expr.SumCase.VAL =>
|
||||
EVal(decodeValName(lfExpr.getVal))
|
||||
@ -567,36 +410,22 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
val recCon = lfExpr.getRecCon
|
||||
ERecCon(
|
||||
tycon = decodeTypeConApp(recCon.getTycon),
|
||||
fields = ImmArray(recCon.getFieldsList.asScala).map(decodeFieldWithExpr(_, definition))
|
||||
fields = ImmArray(recCon.getFieldsList.asScala).map(field =>
|
||||
name(field.getField) -> decodeExpr(field.getExpr, definition))
|
||||
)
|
||||
|
||||
case PLF.Expr.SumCase.REC_PROJ =>
|
||||
val recProj = lfExpr.getRecProj
|
||||
ERecProj(
|
||||
tycon = decodeTypeConApp(recProj.getTycon),
|
||||
field = recProj.getFieldCase match {
|
||||
case PLF.Expr.RecProj.FieldCase.NAME =>
|
||||
toName(recProj.getName)
|
||||
case PLF.Expr.RecProj.FieldCase.INTERNED_ID =>
|
||||
getInternedName(recProj.getInternedId)
|
||||
case PLF.Expr.RecProj.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("Expr.RecProj.FIELD_NOT_SET")
|
||||
},
|
||||
record = decodeExpr(recProj.getRecord, definition)
|
||||
)
|
||||
field = name(recProj.getField),
|
||||
record = decodeExpr(recProj.getRecord, definition))
|
||||
|
||||
case PLF.Expr.SumCase.REC_UPD =>
|
||||
val recUpd = lfExpr.getRecUpd
|
||||
ERecUpd(
|
||||
tycon = decodeTypeConApp(recUpd.getTycon),
|
||||
field = (recUpd.getFieldCase match {
|
||||
case PLF.Expr.RecUpd.FieldCase.NAME =>
|
||||
toName(recUpd.getName)
|
||||
case PLF.Expr.RecUpd.FieldCase.INTERNED_ID =>
|
||||
getInternedName(recUpd.getInternedId)
|
||||
case PLF.Expr.RecUpd.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("Expr.RecUpd.FIELD_NOT_SET")
|
||||
}),
|
||||
field = name(recUpd.getField),
|
||||
record = decodeExpr(recUpd.getRecord, definition),
|
||||
update = decodeExpr(recUpd.getUpdate, definition)
|
||||
)
|
||||
@ -605,66 +434,34 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
val varCon = lfExpr.getVariantCon
|
||||
EVariantCon(
|
||||
decodeTypeConApp(varCon.getTycon),
|
||||
varCon.getVariantConCase match {
|
||||
case PLF.Expr.VariantCon.VariantConCase.NAME =>
|
||||
toName(varCon.getName)
|
||||
case PLF.Expr.VariantCon.VariantConCase.INTERNED_ID =>
|
||||
getInternedName(varCon.getInternedId)
|
||||
case PLF.Expr.VariantCon.VariantConCase.VARIANTCON_NOT_SET =>
|
||||
throw ParseError("Expr.VariantCon.VARIANTCON_NOT_SET")
|
||||
},
|
||||
decodeExpr(varCon.getVariantArg, definition)
|
||||
)
|
||||
name(varCon.getVariantCon),
|
||||
decodeExpr(varCon.getVariantArg, definition))
|
||||
|
||||
case PLF.Expr.SumCase.ENUM_CON =>
|
||||
assertSince(LV.Features.enum, "Expr.Enum")
|
||||
val enumCon = lfExpr.getEnumCon
|
||||
EEnumCon(
|
||||
decodeTypeConName(enumCon.getTycon),
|
||||
enumCon.getEnumConCase match {
|
||||
case PLF.Expr.EnumCon.EnumConCase.NAME =>
|
||||
toName(enumCon.getName)
|
||||
case PLF.Expr.EnumCon.EnumConCase.INTERNED_ID =>
|
||||
getInternedName(enumCon.getInternedId)
|
||||
case PLF.Expr.EnumCon.EnumConCase.ENUMCON_NOT_SET =>
|
||||
throw ParseError("Expr.EnumCon.ENUMCON_NOT_SET")
|
||||
}
|
||||
name(enumCon.getEnumCon)
|
||||
)
|
||||
|
||||
case PLF.Expr.SumCase.TUPLE_CON =>
|
||||
val tupleCon = lfExpr.getTupleCon
|
||||
ETupleCon(
|
||||
ImmArray(tupleCon.getFieldsList.asScala).map(decodeFieldWithExpr(_, definition))
|
||||
ImmArray(tupleCon.getFieldsList.asScala).map(field =>
|
||||
name(field.getField) -> decodeExpr(field.getExpr, definition))
|
||||
)
|
||||
|
||||
case PLF.Expr.SumCase.TUPLE_PROJ =>
|
||||
val tupleProj = lfExpr.getTupleProj
|
||||
ETupleProj(
|
||||
tupleProj.getFieldCase match {
|
||||
case PLF.Expr.TupleProj.FieldCase.NAME =>
|
||||
toName(tupleProj.getName)
|
||||
case PLF.Expr.TupleProj.FieldCase.INTERNED_ID =>
|
||||
getInternedName(tupleProj.getInternedId)
|
||||
case PLF.Expr.TupleProj.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("Expr.TupleProj.FIELD_NOT_SET")
|
||||
},
|
||||
decodeExpr(tupleProj.getTuple, definition)
|
||||
)
|
||||
ETupleProj(name(tupleProj.getField), decodeExpr(tupleProj.getTuple, definition))
|
||||
|
||||
case PLF.Expr.SumCase.TUPLE_UPD =>
|
||||
val tupleUpd = lfExpr.getTupleUpd
|
||||
ETupleUpd(
|
||||
field = tupleUpd.getFieldCase match {
|
||||
case PLF.Expr.TupleUpd.FieldCase.NAME =>
|
||||
toName(tupleUpd.getName)
|
||||
case PLF.Expr.TupleUpd.FieldCase.INTERNED_ID =>
|
||||
getInternedName(tupleUpd.getInternedId)
|
||||
case PLF.Expr.TupleUpd.FieldCase.FIELD_NOT_SET =>
|
||||
throw ParseError("Expr.TupleUpd.FIELD_NOT_SET")
|
||||
},
|
||||
field = name(tupleUpd.getField),
|
||||
tuple = decodeExpr(tupleUpd.getTuple, definition),
|
||||
update = decodeExpr(tupleUpd.getUpdate, definition)
|
||||
)
|
||||
update = decodeExpr(tupleUpd.getUpdate, definition))
|
||||
|
||||
case PLF.Expr.SumCase.APP =>
|
||||
val app = lfExpr.getApp
|
||||
@ -769,61 +566,19 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
val variant = lfCaseAlt.getVariant
|
||||
CPVariant(
|
||||
decodeTypeConName(variant.getCon),
|
||||
variant.getVariantCase match {
|
||||
case PLF.CaseAlt.Variant.VariantCase.VARIANT_NAME =>
|
||||
toName(variant.getVariantName)
|
||||
case PLF.CaseAlt.Variant.VariantCase.VARIANT_INTERNED_ID =>
|
||||
getInternedName(variant.getVariantInternedId)
|
||||
case PLF.CaseAlt.Variant.VariantCase.VARIANT_NOT_SET =>
|
||||
throw ParseError("CaseAlt.Variant.VARIANT_NOT_SET")
|
||||
},
|
||||
variant.getBinderCase match {
|
||||
case PLF.CaseAlt.Variant.BinderCase.BINDER_NAME =>
|
||||
toName(variant.getBinderName)
|
||||
case PLF.CaseAlt.Variant.BinderCase.BINDER_INTERNED_ID =>
|
||||
getInternedName(variant.getBinderInternedId)
|
||||
case PLF.CaseAlt.Variant.BinderCase.BINDER_NOT_SET =>
|
||||
throw ParseError("CaseAlt.Variant.BINDER_NOT_SET")
|
||||
}
|
||||
)
|
||||
name(variant.getVariant),
|
||||
name(variant.getBinder))
|
||||
case PLF.CaseAlt.SumCase.ENUM =>
|
||||
assertSince(LV.Features.enum, "CaseAlt.Enum")
|
||||
val enum = lfCaseAlt.getEnum
|
||||
CPEnum(
|
||||
decodeTypeConName(enum.getCon),
|
||||
enum.getConstructorCase match {
|
||||
case PLF.CaseAlt.Enum.ConstructorCase.NAME =>
|
||||
toName(enum.getName)
|
||||
case PLF.CaseAlt.Enum.ConstructorCase.INTERNED_ID =>
|
||||
getInternedName(enum.getInternedId)
|
||||
case PLF.CaseAlt.Enum.ConstructorCase.CONSTRUCTOR_NOT_SET =>
|
||||
throw ParseError("CaseAlt.Enum.CONSTRUCTOR_NOT_SET")
|
||||
}
|
||||
)
|
||||
CPEnum(decodeTypeConName(enum.getCon), name(enum.getConstructor))
|
||||
case PLF.CaseAlt.SumCase.PRIM_CON =>
|
||||
CPPrimCon(decodePrimCon(lfCaseAlt.getPrimCon))
|
||||
case PLF.CaseAlt.SumCase.NIL =>
|
||||
CPNil
|
||||
case PLF.CaseAlt.SumCase.CONS =>
|
||||
val cons = lfCaseAlt.getCons
|
||||
CPCons(
|
||||
cons.getVarHeadCase match {
|
||||
case PLF.CaseAlt.Cons.VarHeadCase.VAR_HEAD_NAME =>
|
||||
toName(cons.getVarHeadName)
|
||||
case PLF.CaseAlt.Cons.VarHeadCase.VAR_HEAD_INTERNED_ID =>
|
||||
getInternedName(cons.getVarHeadInternedId)
|
||||
case PLF.CaseAlt.Cons.VarHeadCase.VARHEAD_NOT_SET =>
|
||||
throw ParseError("CaseAlt.Cons.VARHEAD_NOT_SET")
|
||||
},
|
||||
cons.getVarTailCase match {
|
||||
case PLF.CaseAlt.Cons.VarTailCase.VAR_TAIL_NAME =>
|
||||
toName(cons.getVarTailName)
|
||||
case PLF.CaseAlt.Cons.VarTailCase.VAR_TAIL_INTERNED_ID =>
|
||||
getInternedName(cons.getVarTailInternedId)
|
||||
case PLF.CaseAlt.Cons.VarTailCase.VARTAIL_NOT_SET =>
|
||||
throw ParseError("CaseAlt.Cons.VARTAIL_NOT_SET")
|
||||
}
|
||||
)
|
||||
CPCons(name(cons.getVarHead), name(cons.getVarTail))
|
||||
|
||||
case PLF.CaseAlt.SumCase.OPTIONAL_NONE =>
|
||||
assertSince(LV.Features.optional, "CaseAlt.OptionalNone")
|
||||
@ -831,14 +586,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
|
||||
case PLF.CaseAlt.SumCase.OPTIONAL_SOME =>
|
||||
assertSince(LV.Features.optional, "CaseAlt.OptionalSome")
|
||||
CPSome(lfCaseAlt.getOptionalSome.getVarBodyCase match {
|
||||
case PLF.CaseAlt.OptionalSome.VarBodyCase.NAME =>
|
||||
toName(lfCaseAlt.getOptionalSome.getName)
|
||||
case PLF.CaseAlt.OptionalSome.VarBodyCase.INTERNED_ID =>
|
||||
getInternedName(lfCaseAlt.getOptionalSome.getInternedId)
|
||||
case PLF.CaseAlt.OptionalSome.VarBodyCase.VARBODY_NOT_SET =>
|
||||
throw ParseError("CaseAlt.OptionalSome.VARBODY_NOT_SET")
|
||||
})
|
||||
CPSome(name(lfCaseAlt.getOptionalSome.getVarBody))
|
||||
|
||||
case PLF.CaseAlt.SumCase.SUM_NOT_SET =>
|
||||
throw ParseError("CaseAlt.SUM_NOT_SET")
|
||||
@ -878,14 +626,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
val exercise = lfUpdate.getExercise
|
||||
UpdateExercise(
|
||||
templateId = decodeTypeConName(exercise.getTemplate),
|
||||
choice = exercise.getChoiceCase match {
|
||||
case PLF.Update.Exercise.ChoiceCase.NAME =>
|
||||
toName(exercise.getName)
|
||||
case PLF.Update.Exercise.ChoiceCase.INTERNED_ID =>
|
||||
getInternedName(exercise.getInternedId)
|
||||
case PLF.Update.Exercise.ChoiceCase.CHOICE_NOT_SET =>
|
||||
throw ParseError("Update.Exercise.CHOICE_NOT_SET")
|
||||
},
|
||||
choice = name(exercise.getChoice),
|
||||
cidE = decodeExpr(exercise.getCid, definition),
|
||||
actorsE =
|
||||
if (exercise.hasActor)
|
||||
@ -969,15 +710,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
|
||||
private[this] def decodeTypeVarWithKind(
|
||||
lfTypeVarWithKind: PLF.TypeVarWithKind): (TypeVarName, Kind) =
|
||||
(lfTypeVarWithKind.getVarCase match {
|
||||
case PLF.TypeVarWithKind.VarCase.NAME =>
|
||||
toName(lfTypeVarWithKind.getName)
|
||||
case PLF.TypeVarWithKind.VarCase.INTERNED_ID =>
|
||||
getInternedName(lfTypeVarWithKind.getInternedId)
|
||||
case PLF.TypeVarWithKind.VarCase.VAR_NOT_SET =>
|
||||
throw ParseError("TypeVarWithKind.VAR_NOT_SET")
|
||||
|
||||
}) -> decodeKind(lfTypeVarWithKind.getKind)
|
||||
name(lfTypeVarWithKind.getVar) -> decodeKind(lfTypeVarWithKind.getKind)
|
||||
|
||||
private[this] def decodeBinding(lfBinding: PLF.Binding, definition: String): Binding = {
|
||||
val (binder, typ) = decodeBinder(lfBinding.getBinder)
|
||||
@ -985,14 +718,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
}
|
||||
|
||||
private[this] def decodeBinder(lfBinder: PLF.VarWithType): (ExprVarName, Type) =
|
||||
(lfBinder.getVarCase match {
|
||||
case PLF.VarWithType.VarCase.NAME =>
|
||||
toName(lfBinder.getName)
|
||||
case PLF.VarWithType.VarCase.INTERNED_ID =>
|
||||
getInternedName(lfBinder.getInternedId)
|
||||
case PLF.VarWithType.VarCase.VAR_NOT_SET =>
|
||||
throw ParseError("VarWithType.VAR_NOT_SET")
|
||||
}) -> decodeType(lfBinder.getType)
|
||||
name(lfBinder.getVar) -> decodeType(lfBinder.getType)
|
||||
|
||||
private[this] def decodePrimCon(lfPrimCon: PLF.PrimCon): PrimCon =
|
||||
lfPrimCon match {
|
||||
@ -1011,51 +737,50 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
PLInt64(lfPrimLit.getInt64)
|
||||
case PLF.PrimLit.SumCase.DECIMAL =>
|
||||
assertUntil(LV.Features.numeric, "PrimLit.decimal")
|
||||
toDecimalLiteral(lfPrimLit.getDecimal)
|
||||
Decimal
|
||||
.fromString(lfPrimLit.getDecimal)
|
||||
.flatMap(Numeric.fromBigDecimal(Decimal.scale, _))
|
||||
.fold(e => throw ParseError("error parsing decimal: " + e), PLNumeric)
|
||||
case PLF.PrimLit.SumCase.NUMERIC =>
|
||||
assertSince(LV.Features.numeric, "PrimLit.numeric")
|
||||
toNumericLiteral(lfPrimLit.getNumeric)
|
||||
Numeric
|
||||
.fromString(lfPrimLit.getNumeric)
|
||||
.fold(e => throw ParseError("error parsing numeric: " + e), PLNumeric)
|
||||
case PLF.PrimLit.SumCase.TEXT =>
|
||||
PLText(lfPrimLit.getText)
|
||||
case PLF.PrimLit.SumCase.PARTY =>
|
||||
toPartyLiteral(lfPrimLit.getParty)
|
||||
val p = Party
|
||||
.fromString(lfPrimLit.getParty)
|
||||
.getOrElse(throw ParseError(s"invalid party '${lfPrimLit.getParty}'"))
|
||||
PLParty(p)
|
||||
case PLF.PrimLit.SumCase.TIMESTAMP =>
|
||||
val t = Time.Timestamp.fromLong(lfPrimLit.getTimestamp)
|
||||
t.fold(e => throw ParseError("error decoding timestamp: " + e), PLTimestamp)
|
||||
case PLF.PrimLit.SumCase.DATE =>
|
||||
val d = Time.Date.fromDaysSinceEpoch(lfPrimLit.getDate)
|
||||
d.fold(e => throw ParseError("error decoding date: " + e), PLDate)
|
||||
case PLF.PrimLit.SumCase.TEXT_INTERNED_ID =>
|
||||
getInternedText(lfPrimLit.getTextInternedId)
|
||||
case PLF.PrimLit.SumCase.DECIMAL_INTERNED_ID =>
|
||||
assertUntil(LV.Features.numeric, "PrimLit.decimal")
|
||||
getInternedDecimal(lfPrimLit.getDecimalInternedId)
|
||||
case PLF.PrimLit.SumCase.NUMERIC_INTERNED_ID =>
|
||||
assertSince(LV.Features.numeric, "PrimLit.numeric")
|
||||
getInternedNumeric(lfPrimLit.getNumericInternedId)
|
||||
case PLF.PrimLit.SumCase.PARTY_INTERNED_ID =>
|
||||
getInternedParty(lfPrimLit.getPartyInternedId)
|
||||
case PLF.PrimLit.SumCase.SUM_NOT_SET =>
|
||||
throw ParseError("PrimLit.SUM_NOT_SET")
|
||||
case unknown =>
|
||||
throw ParseError("Unknown PrimLit: " + unknown.toString)
|
||||
}
|
||||
}
|
||||
|
||||
private def versionIsOlderThan(minVersion: LV): Boolean =
|
||||
LV.ordering.lt(languageVersion, minVersion)
|
||||
|
||||
private def assertUntil(maxVersion: LV, description: => String): Unit =
|
||||
private def assertUntil(maxVersion: LV, description: String): Unit =
|
||||
if (!versionIsOlderThan(maxVersion))
|
||||
throw ParseError(s"$description is not supported by DAML-LF 1.$minor")
|
||||
|
||||
private def assertSince(minVersion: LV, description: => String): Unit =
|
||||
private def assertSince(minVersion: LV, description: String): Unit =
|
||||
if (versionIsOlderThan(minVersion))
|
||||
throw ParseError(s"$description is not supported by DAML-LF 1.$minor")
|
||||
|
||||
private def assertNonEmpty(s: Seq[_], description: => String): Unit =
|
||||
private def assertNonEmpty(s: Seq[_], description: String): Unit =
|
||||
if (s.isEmpty) throw ParseError(s"Unexpected empty $description")
|
||||
|
||||
private def assertEmpty(s: Seq[_], description: => String): Unit =
|
||||
private def assertEmpty(s: Seq[_], description: String): Unit =
|
||||
if (s.nonEmpty) throw ParseError(s"Unexpected non-empty $description")
|
||||
|
||||
}
|
||||
|
||||
private[lf] object DecodeV1 {
|
||||
@ -1064,22 +789,6 @@ private[lf] object DecodeV1 {
|
||||
private def ntimes[A](n: Int, f: A => A, a: A): A =
|
||||
if (n == 0) a else ntimes(n - 1, f, f(a))
|
||||
|
||||
private def eitherToParseError[A](x: Either[String, A]): A =
|
||||
x.fold(err => throw new ParseError(err), identity)
|
||||
|
||||
private def toName(s: String): Name = eitherToParseError(Name.fromString(s))
|
||||
|
||||
private def toPackageId(s: String): PackageId = eitherToParseError(PackageId.fromString(s))
|
||||
|
||||
private def toNumericLiteral(s: String): PrimLit =
|
||||
PLNumeric(eitherToParseError(Numeric.fromString(s)))
|
||||
|
||||
private def toDecimalLiteral(s: String): PLNumeric =
|
||||
PLNumeric(eitherToParseError(Decimal.fromString(s)))
|
||||
|
||||
private def toPartyLiteral(s: String): PLParty =
|
||||
PLParty(eitherToParseError(Party.fromString(s)))
|
||||
|
||||
case class BuiltinTypeInfo(
|
||||
proto: PLF.PrimType,
|
||||
bTyp: BuiltinType,
|
||||
|
@ -1,43 +0,0 @@
|
||||
// Copyright (c) 2019 The DAML Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package com.digitalasset.daml.lf.archive
|
||||
|
||||
import java.io.File
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import com.digitalasset.daml.lf.data.Ref
|
||||
import com.digitalasset.daml.lf.language.Ast
|
||||
|
||||
/**
|
||||
* Test application for decoding DARs. Useful for testing decoder performance and memory usage.
|
||||
*/
|
||||
object DecodeMain extends App {
|
||||
if (args.length != 1) {
|
||||
println("usage: decode <dar file>")
|
||||
System.exit(1)
|
||||
}
|
||||
|
||||
def toMillis(a: Long, b: Long) = TimeUnit.NANOSECONDS.toMillis(b - a)
|
||||
|
||||
(1 to 3).foreach { _ =>
|
||||
val t0 = System.nanoTime()
|
||||
|
||||
val archives =
|
||||
DarReader().readArchiveFromFile(new File(args(0))).get
|
||||
val t1 = System.nanoTime()
|
||||
|
||||
val _: (Ref.PackageId, Ast.Package) =
|
||||
Decode.readArchivePayload(archives.main._1, archives.main._2)
|
||||
val t2 = System.nanoTime()
|
||||
|
||||
println(s"parseFrom in ${toMillis(t0, t1)}ms, decoded in ${toMillis(t1, t2)}ms.")
|
||||
|
||||
// Wait a while to allow for running e.g. jmap -heap etc.
|
||||
//val pid = Integer.parseInt(new File("/proc/self").getCanonicalFile.getName)
|
||||
//println(s"sleeping 5s, pid is $pid.")
|
||||
//Thread.sleep(5000)
|
||||
|
||||
System.gc()
|
||||
}
|
||||
}
|
@ -49,7 +49,6 @@ class DecodeV1Spec
|
||||
.ModuleDecoder(
|
||||
Ref.PackageId.assertFromString("noPkgId"),
|
||||
ImmArray.empty.toSeq,
|
||||
ImmArray.empty.toSeq,
|
||||
dummyModule,
|
||||
onlySerializableDataDefs = false)
|
||||
|
||||
@ -509,7 +508,7 @@ class DecodeV1Spec
|
||||
pr.getInternedId
|
||||
}
|
||||
.value
|
||||
dalf1.getInternedStringsList.asScala.lift(iix.toInt).value
|
||||
dalf1.getInternedPackageIdsList.asScala.lift(iix.toInt).value
|
||||
}
|
||||
|
||||
"take a dalf with interned IDs" in {
|
||||
|
@ -141,17 +141,13 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
@inline
|
||||
private implicit def encodeTypeBinder(binder: (String, Kind)): PLF.TypeVarWithKind = {
|
||||
val (varName, kind) = binder
|
||||
PLF.TypeVarWithKind
|
||||
.newBuilder()
|
||||
.setName(varName)
|
||||
.setKind(kind)
|
||||
.build()
|
||||
PLF.TypeVarWithKind.newBuilder().setVar(varName).setKind(kind).build()
|
||||
}
|
||||
|
||||
@inline
|
||||
private implicit def encodeFieldWithType(nameWithType: (String, Type)): PLF.FieldWithType = {
|
||||
val (name, typ) = nameWithType
|
||||
PLF.FieldWithType.newBuilder().setName(name).setType(typ).build()
|
||||
PLF.FieldWithType.newBuilder().setField(name).setType(typ).build()
|
||||
}
|
||||
|
||||
private val TForalls = RightRecMatcher[(TypeVarName, Kind), Type]({
|
||||
@ -181,7 +177,7 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
typ match {
|
||||
case TVar(varName) =>
|
||||
builder.setVar(
|
||||
PLF.Type.Var.newBuilder().setVarName(varName).accumulateLeft(args)(_ addArgs _))
|
||||
PLF.Type.Var.newBuilder().setVar(varName).accumulateLeft(args)(_ addArgs _))
|
||||
case TNat(n) =>
|
||||
assertSince(LV.Features.numeric, "Type.TNat")
|
||||
builder.setNat(n.toLong)
|
||||
@ -240,13 +236,13 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
@inline
|
||||
private implicit def encodeFieldWithExpr(fieldWithExpr: (Name, Expr)): PLF.FieldWithExpr = {
|
||||
val (name, expr) = fieldWithExpr
|
||||
PLF.FieldWithExpr.newBuilder().setName(name).setExpr(expr).build()
|
||||
PLF.FieldWithExpr.newBuilder().setField(name).setExpr(expr).build()
|
||||
}
|
||||
|
||||
@inline
|
||||
private implicit def encodeExprBinder(binder: (String, Type)): PLF.VarWithType = {
|
||||
val (varName, typ) = binder
|
||||
PLF.VarWithType.newBuilder().setName(varName).setType(typ).build()
|
||||
PLF.VarWithType.newBuilder().setVar(varName).setType(typ).build()
|
||||
}
|
||||
|
||||
private implicit def encodeLocation(loc: Location): PLF.Location = {
|
||||
@ -298,7 +294,7 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
PLF.Update.Exercise
|
||||
.newBuilder()
|
||||
.setTemplate(templateId)
|
||||
.setName(choice)
|
||||
.setChoice(choice)
|
||||
.setCid(cid)
|
||||
.accumulateLeft(actors)(_ setActor _)
|
||||
.setArg(arg)
|
||||
@ -373,26 +369,22 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
alt.pattern match {
|
||||
case CPVariant(tyCon, variant, binder) =>
|
||||
builder.setVariant(
|
||||
PLF.CaseAlt.Variant
|
||||
.newBuilder()
|
||||
.setCon(tyCon)
|
||||
.setVariantName(variant)
|
||||
.setBinderName(binder))
|
||||
PLF.CaseAlt.Variant.newBuilder().setCon(tyCon).setVariant(variant).setBinder(binder))
|
||||
case CPEnum(tyCon, con) =>
|
||||
assertSince(LV.Features.enum, "CaseAlt.Enum")
|
||||
builder.setEnum(PLF.CaseAlt.Enum.newBuilder().setCon(tyCon).setName(con))
|
||||
builder.setEnum(PLF.CaseAlt.Enum.newBuilder().setCon(tyCon).setConstructor(con))
|
||||
case CPPrimCon(primCon) =>
|
||||
builder.setPrimCon(primCon)
|
||||
case CPNil =>
|
||||
builder.setNil(unit)
|
||||
case CPCons(head, tail) =>
|
||||
builder.setCons(PLF.CaseAlt.Cons.newBuilder().setVarHeadName(head).setVarTailName(tail))
|
||||
builder.setCons(PLF.CaseAlt.Cons.newBuilder().setVarHead(head).setVarTail(tail))
|
||||
case CPNone =>
|
||||
assertSince(LV.Features.optional, "CaseAlt.OptionalNone")
|
||||
builder.setOptionalNone(unit)
|
||||
case CPSome(x) =>
|
||||
assertSince(LV.Features.optional, "CaseAlt.OptionalSome")
|
||||
builder.setOptionalSome(PLF.CaseAlt.OptionalSome.newBuilder().setName(x))
|
||||
builder.setOptionalSome(PLF.CaseAlt.OptionalSome.newBuilder().setVarBody(x))
|
||||
case CPDefault =>
|
||||
builder.setDefault(unit)
|
||||
}
|
||||
@ -437,13 +429,13 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
PLF.Expr.RecCon.newBuilder().setTycon(tyCon).accumulateLeft(fields)(_ addFields _))
|
||||
case ERecProj(tycon, field, expr) =>
|
||||
newBuilder.setRecProj(
|
||||
PLF.Expr.RecProj.newBuilder().setTycon(tycon).setName(field).setRecord(expr))
|
||||
PLF.Expr.RecProj.newBuilder().setTycon(tycon).setField(field).setRecord(expr))
|
||||
case ERecUpd(tyCon, field, expr, update) =>
|
||||
newBuilder.setRecUpd(
|
||||
PLF.Expr.RecUpd
|
||||
.newBuilder()
|
||||
.setTycon(tyCon)
|
||||
.setName(field)
|
||||
.setField(field)
|
||||
.setRecord(expr)
|
||||
.setUpdate(update))
|
||||
case EVariantCon(tycon, variant, arg) =>
|
||||
@ -451,19 +443,19 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
PLF.Expr.VariantCon
|
||||
.newBuilder()
|
||||
.setTycon(tycon)
|
||||
.setName(variant)
|
||||
.setVariantCon(variant)
|
||||
.setVariantArg(arg))
|
||||
case EEnumCon(tyCon, con) =>
|
||||
assertSince(LV.Features.enum, "Expr.Enum")
|
||||
newBuilder.setEnumCon(PLF.Expr.EnumCon.newBuilder().setTycon(tyCon).setName(con))
|
||||
newBuilder.setEnumCon(PLF.Expr.EnumCon.newBuilder().setTycon(tyCon).setEnumCon(con))
|
||||
case ETupleCon(fields) =>
|
||||
newBuilder.setTupleCon(
|
||||
PLF.Expr.TupleCon.newBuilder().accumulateLeft(fields)(_ addFields _))
|
||||
case ETupleProj(field, expr) =>
|
||||
newBuilder.setTupleProj(PLF.Expr.TupleProj.newBuilder().setName(field).setTuple(expr))
|
||||
newBuilder.setTupleProj(PLF.Expr.TupleProj.newBuilder().setField(field).setTuple(expr))
|
||||
case ETupleUpd(field, tuple, update) =>
|
||||
newBuilder.setTupleUpd(
|
||||
PLF.Expr.TupleUpd.newBuilder().setName(field).setTuple(tuple).setUpdate(update))
|
||||
PLF.Expr.TupleUpd.newBuilder().setField(field).setTuple(tuple).setUpdate(update))
|
||||
case EApps(fun, args) =>
|
||||
newBuilder.setApp(PLF.Expr.App.newBuilder().setFun(fun).accumulateLeft(args)(_ addArgs _))
|
||||
case ETyApps(expr, typs1) =>
|
||||
@ -559,13 +551,13 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
val (name, choice) = nameWithChoice
|
||||
PLF.TemplateChoice
|
||||
.newBuilder()
|
||||
.setChoiceName(name)
|
||||
.setName(name)
|
||||
.setConsuming(choice.consuming)
|
||||
.setControllers(choice.controllers)
|
||||
.setArgBinder(choice.argBinder._1.getOrElse("") -> choice.argBinder._2)
|
||||
.setRetType(choice.returnType)
|
||||
.setUpdate(choice.update)
|
||||
.setSelfBinderName(choice.selfBinder)
|
||||
.setSelfBinder(choice.selfBinder)
|
||||
.build()
|
||||
}
|
||||
|
||||
@ -583,7 +575,7 @@ private[digitalasset] class EncodeV1(val minor: LV.Minor) {
|
||||
PLF.DefTemplate
|
||||
.newBuilder()
|
||||
.setTycon(name)
|
||||
.setParamName(template.param)
|
||||
.setParam(template.param)
|
||||
.setPrecond(template.precond)
|
||||
.setSignatories(template.signatories)
|
||||
.setAgreement(template.agreementText)
|
||||
|
@ -17,15 +17,15 @@ sealed abstract class LanguageMajorVersion(
|
||||
with Product
|
||||
with Serializable {
|
||||
|
||||
final val maxSupportedStableMinorVersion: LanguageMinorVersion.Stable =
|
||||
val maxSupportedStableMinorVersion: LanguageMinorVersion.Stable =
|
||||
LanguageMinorVersion.Stable(stableAscending.last)
|
||||
|
||||
// do *not* use implicitly unless type `LanguageMinorVersion` becomes
|
||||
// indexed by the enclosing major version's singleton type --SC
|
||||
final val minorVersionOrdering: Ordering[LanguageMinorVersion] =
|
||||
final def minorVersionOrdering: Ordering[LanguageMinorVersion] =
|
||||
Ordering.by(acceptedVersions.zipWithIndex.toMap)
|
||||
|
||||
final val supportedMinorVersions: List[LanguageMinorVersion] =
|
||||
val supportedMinorVersions: List[LanguageMinorVersion] =
|
||||
acceptedVersions
|
||||
|
||||
final def supportsMinorVersion(fromLFFile: String): Boolean =
|
||||
|
@ -23,10 +23,10 @@ object LanguageVersion {
|
||||
private[lf] def apply(major: LanguageMajorVersion, minor: String): LanguageVersion =
|
||||
apply(major, Minor fromProtoIdentifier minor)
|
||||
|
||||
val default: LanguageVersion =
|
||||
def default: LanguageVersion =
|
||||
defaultV1
|
||||
|
||||
final val ordering: Ordering[LanguageVersion] =
|
||||
def ordering: Ordering[LanguageVersion] =
|
||||
(left, right) =>
|
||||
(left, right) match {
|
||||
case (LanguageVersion(leftMajor, leftMinor), LanguageVersion(rightMajor, rightMinor))
|
||||
@ -54,9 +54,7 @@ object LanguageVersion {
|
||||
val coerceContractId = v1_5
|
||||
val textPacking = v1_6
|
||||
val enum = v1_6
|
||||
val internedPackageId = v1_6
|
||||
val internedStrings = v1_dev
|
||||
val internedDottedNames = v1_dev
|
||||
val internedIds = v1_6
|
||||
val numeric = v1_dev
|
||||
val anyTemplate = v1_dev
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user