Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interfaces: Do some TODOs #11231

Merged
merged 2 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions compiler/daml-lf-proto/src/DA/Daml/LF/Proto3/DecodeV1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Data.List
import DA.Daml.LF.Mangling
import qualified Com.Daml.DamlLfDev.DamlLf1 as LF1
import qualified Data.NameMap as NM
import qualified Data.HashSet as HS
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Vector.Extended as V
Expand Down Expand Up @@ -229,16 +230,18 @@ decodeModule (LF1.Module name flags synonyms dataTypes values templates exceptio
<*> decodeNM DuplicateInterface decodeDefInterface interfaces

decodeDefInterface :: LF1.DefInterface -> Decode DefInterface
decodeDefInterface LF1.DefInterface {..} =
DefInterface
<$> traverse decodeLocation defInterfaceLocation
<*> decodeDottedNameId TypeConName defInterfaceTyconInternedDname
<*> decodeNameId ExprVarName defInterfaceParamInternedStr
<*> decodeNM DuplicateChoice decodeInterfaceChoice defInterfaceChoices
<*> decodeNM DuplicateChoice decodeChoice defInterfaceFixedChoices
<*> decodeNM DuplicateMethod decodeInterfaceMethod defInterfaceMethods
-- TODO https://github.com/digital-asset/daml/issues/11137
-- maybe also check that choice names are unique between virtual choices & fixed choices
decodeDefInterface LF1.DefInterface {..} = do
intLocation <- traverse decodeLocation defInterfaceLocation
intName <- decodeDottedNameId TypeConName defInterfaceTyconInternedDname
intParam <- decodeNameId ExprVarName defInterfaceParamInternedStr
intVirtualChoices <- decodeNM DuplicateChoice decodeInterfaceChoice defInterfaceChoices
intFixedChoices <- decodeNM DuplicateChoice decodeChoice defInterfaceFixedChoices
intMethods <- decodeNM DuplicateMethod decodeInterfaceMethod defInterfaceMethods
unless (HS.null (NM.namesSet intFixedChoices `HS.intersection` NM.namesSet intVirtualChoices)) $
throwError $ ParseError $ unwords
[ "Interface", T.unpack (T.intercalate "." (unTypeConName intName))
, "has collision between fixed choice and virtual choice." ]
pure DefInterface {..}

decodeInterfaceChoice :: LF1.InterfaceChoice -> Decode InterfaceChoice
decodeInterfaceChoice LF1.InterfaceChoice {..} =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -724,12 +724,35 @@ private[daml] class EncodeV1(minor: LV.Minor) {
val (dottedName, interface) = nameWithDef
val builder = PLF.DefInterface.newBuilder()
builder.setTyconInternedDname(dottedNameTable.insert(dottedName))
builder.setParamInternedStr(stringsTable.insert(interface.param))
builder.accumulateLeft(interface.virtualChoices.sortByKey)(_ addChoices _)
// TODO https://github.com/digital-asset/daml/issues/11006
// encode interface methods as well
builder.accumulateLeft(interface.fixedChoices.sortByKey)(_ addFixedChoices _)
builder.accumulateLeft(interface.methods.sortByKey)(_ addMethods _)
builder.build()
}

private implicit def encodeInterfaceChoice(
nameWithChoice: (ChoiceName, InterfaceChoice)
): PLF.InterfaceChoice = {
val (name, choice) = nameWithChoice
val b = PLF.InterfaceChoice.newBuilder()
b.setNameInternedString(stringsTable.insert(name))
b.setConsuming(choice.consuming)
b.setArgType(choice.argType)
b.setRetType(choice.returnType)
b.build()
}

private implicit def encodeInterfaceMethod(
nameWithMethod: (MethodName, InterfaceMethod)
): PLF.InterfaceMethod = {
val (name, method) = nameWithMethod
val b = PLF.InterfaceMethod.newBuilder()
b.setMethodInternedName(stringsTable.insert(name))
b.setType(method.returnType)
b.build()
}

private implicit def encodeSynonymDef(nameWithDef: (DottedName, DTypeSyn)): PLF.DefTypeSyn = {
val (dottedName, typeSyn) = nameWithDef
val builder = PLF.DefTypeSyn.newBuilder()
Expand Down Expand Up @@ -783,18 +806,6 @@ private[daml] class EncodeV1(minor: LV.Minor) {
b.build()
}

private implicit def encodeInterfaceChoice(
nameWithChoice: (ChoiceName, InterfaceChoice)
): PLF.InterfaceChoice = {
val (name, choice) = nameWithChoice
val b = PLF.InterfaceChoice.newBuilder()
b.setNameInternedString(stringsTable.insert(name))
b.setConsuming(choice.consuming)
b.setArgType(choice.argType)
b.setRetType(choice.returnType)
b.build()
}

private implicit def encodeTemplateKey(key: TemplateKey): PLF.DefTemplate.DefKey =
PLF.DefTemplate.DefKey
.newBuilder()
Expand All @@ -816,17 +827,27 @@ private[daml] class EncodeV1(minor: LV.Minor) {
b.accumulateLeft(template.choices.sortByKey)(_ addChoices _)
b.setObservers(template.observers)
template.key.foreach(b.setKey(_))
b.accumulateLeft(template.implements.values)(_ addImplements encodeTemplateImplements(_))
b.accumulateLeft(template.implements.sortByKey)(_ addImplements _)
b.build()
}

// TODO https://github.com/digital-asset/daml/issues/11006
// encode rest of TemplateImplements
private implicit def encodeTemplateImplements(
impl: TemplateImplements
interfaceWithImplements: (TypeConName, TemplateImplements)
): PLF.DefTemplate.Implements = {
val (interface, implements) = interfaceWithImplements
val b = PLF.DefTemplate.Implements.newBuilder()
b.setInterface(impl.interface)
b.setInterface(interface)
b.accumulateLeft(implements.methods.sortByKey)(_ addMethods _)
b.build()
}

private implicit def encodeTemplateImplementsMethod(
nameWithMethod: (MethodName, TemplateImplementsMethod)
): PLF.DefTemplate.ImplementsMethod = {
val (name, method) = nameWithMethod
val b = PLF.DefTemplate.ImplementsMethod.newBuilder()
b.setMethodInternedName(stringsTable.insert(name))
b.setValue(method.value)
b.build()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,13 @@ private[validation] object ExprIterable {
choices,
observers,
key,
implements @ _, // TODO https://github.com/digital-asset/daml/issues/11006
implements,
) =>
Iterator(precond, signatories, agreementText) ++
choices.values.iterator.flatMap(iterator(_)) ++
Iterator(observers) ++
key.iterator.flatMap(iterator(_))
key.iterator.flatMap(iterator(_)) ++
implements.values.iterator.flatMap(iterator(_))
}

private[iterable] def iterator(x: TemplateChoice): Iterator[Expr] =
Expand All @@ -172,6 +173,43 @@ private[validation] object ExprIterable {
Iterator(body, maintainers)
}

private[iterable] def iterator(x: TemplateImplements): Iterator[Expr] =
x match {
case TemplateImplements(
interface @ _,
methods,
) =>
methods.values.iterator.flatMap(iterator(_))
}

private[iterable] def iterator(x: TemplateImplementsMethod): Iterator[Expr] =
x match {
case TemplateImplementsMethod(
name @ _,
value,
) =>
Iterator(value)
}

private[iterable] def iterator(x: DefException): Iterator[Expr] =
x match {
case DefException(
message
) =>
Iterator(message)
}

private[iterable] def iterator(x: DefInterface): Iterator[Expr] =
x match {
case DefInterface(
param @ _,
virtualChoices @ _,
fixedChoices,
methods @ _,
) =>
fixedChoices.values.iterator.flatMap(iterator(_))
}

def apply(expr: Expr): Iterable[Expr] =
new Iterable[Expr] {
override def iterator: Iterator[Expr] = ExprIterable.iterator(expr)
Expand All @@ -186,6 +224,8 @@ private[validation] object ExprIterable {
new Iterable[Expr] {
override def iterator: Iterator[Expr] =
module.definitions.values.iterator.flatMap(ExprIterable.iterator(_)) ++
module.exceptions.values.iterator.flatMap(ExprIterable.iterator(_)) ++
module.interfaces.values.iterator.flatMap(ExprIterable.iterator(_)) ++
module.templates.values.iterator.flatMap(ExprIterable.iterator(_))
}
}