Skip to content

Commit

Permalink
java representation for value GenMap (digital-asset#3515)
Browse files Browse the repository at this point in the history
  • Loading branch information
remyhaemmerle-da authored and mergify[bot] committed Nov 19, 2019
1 parent 3d960c7 commit 027d63a
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) 2019 The DAML Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.ledger.javaapi.data;

import com.digitalasset.ledger.api.v1.ValueOuterClass;
import org.checkerframework.checker.nullness.qual.NonNull;

import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;

public class DamlGenMap extends Value {

private static DamlGenMap EMPTY = new DamlGenMap(Collections.EMPTY_MAP);

private final java.util.Map<Value, Value> value;

public DamlGenMap(java.util.Map<Value, Value> value) {
this.value = value;
}

public @Nonnull
java.util.Map<Value, Value> getMap() { return value; }

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DamlGenMap optional = (DamlGenMap) o;
return Objects.equals(value, optional.value);
}

@Override
public int hashCode() {
return value.hashCode();
}

@Override
public @NonNull String toString() {
StringJoiner sj = new StringJoiner(", ", "GenMap{", "}");
value.forEach((key, value) -> sj.add(key.toString()+ " -> " + value.toString()));
return sj.toString();
}

@Override
public @Nonnull ValueOuterClass.Value toProto() {
ValueOuterClass.GenMap.Builder mb = ValueOuterClass.GenMap.newBuilder();
value.forEach((key, value) ->
mb.addEntries(ValueOuterClass.GenMap.Entry.newBuilder()
.setKey(key.toProto())
.setValue(value.toProto())
));
return ValueOuterClass.Value.newBuilder().setGenMap(mb).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ public final Optional<DamlMap> asMap() {
return (this instanceof DamlMap) ? Optional.of((DamlMap) this) : Optional.empty();
}

public final Optional<DamlGenMap> asGenMap() {
return (this instanceof DamlGenMap) ? Optional.of((DamlGenMap) this) : Optional.empty();
}

public abstract ValueOuterClass.Value toProto();
}

Expand Down
4 changes: 1 addition & 3 deletions language-support/java/codegen/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,7 @@ test_daml_lf_target_versions = [
"1.3",
"1.6",
"1.7",
# FIXME https://github.com/digital-asset/daml/issues/2256
# reactivate dev once codegen handle GenMap
# "1.dev",
"1.dev",
]

[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ object Types {
val apiUnit = ClassName.get(classOf[javaapi.data.Unit])
val apiContractId = ClassName.get(classOf[javaapi.data.ContractId])
val apiMap = ClassName.get(classOf[javaapi.data.DamlMap])
val apiGenMap = ClassName.get(classOf[javaapi.data.DamlGenMap])

// All the types part of the Java platform to which API types will be mapped to
val javaNativeBoolean = TypeName.get(java.lang.Boolean.TYPE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,24 +212,69 @@ private[inner] object FromValueGenerator extends StrictLogging {
val entryArg = args.next()
CodeBlock
.builder()
.add(CodeBlock.of("$L.asMap().map($L -> ", accessor, optMapArg))
.add(CodeBlock.of(
"$L.getMap().entrySet().stream().collect($T.<java.util.Map.Entry<String,Value>,String,$L>toMap(",
"""$L.asMap().map(
| $L -> $L.getMap().entrySet().stream().collect(
| $T.<java.util.Map.Entry<String,Value>,String,$L>toMap(
| java.util.Map.Entry::getKey,
| $L ->
| $L
| )
| )
|)""".stripMargin,
accessor,
optMapArg,
optMapArg,
classOf[Collectors],
toJavaTypeName(param, packagePrefixes)
toJavaTypeName(param, packagePrefixes),
entryArg,
extractor(
param,
entryArg,
CodeBlock.of("$L.getValue()", entryArg),
args,
packagePrefixes)
))
.add(orElseThrow(apiType, field))
.build()

case TypePrim(PrimTypeGenMap, ImmArraySeq(keyType, valueType)) =>
val optMapArg = args.next()
val entryArg = args.next()
CodeBlock
.builder()
.add(CodeBlock.of(
"""$L.asGenMap().map(
| $L -> $L.getMap().entrySet().stream().collect(
| $T.<java.util.Map.Entry<Value,Value>,$L,$L>toMap(
| $L ->
| $L,
| $L ->
| $L
| )
| )
|)""".stripMargin,
accessor,
optMapArg,
optMapArg,
classOf[Collectors],
toJavaTypeName(keyType, packagePrefixes),
toJavaTypeName(valueType, packagePrefixes),
entryArg,
extractor(
keyType,
entryArg,
CodeBlock.of("$L.getKey()", entryArg),
args,
packagePrefixes),
entryArg,
extractor(
valueType,
entryArg,
CodeBlock.of("$L.getValue()", entryArg),
args,
packagePrefixes)
))
.add(CodeBlock.of("java.util.Map.Entry::getKey,$L -> ", entryArg))
.add(
CodeBlock.of(
"$L",
extractor(
param,
entryArg,
CodeBlock.of("$L.getValue()", entryArg),
args,
packagePrefixes)))
.add(CodeBlock.of(")))"))
.add(orElseThrow(apiType, field))
.build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,34 @@ object ToValueGenerator {
extractor
)

case TypePrim(PrimTypeGenMap, ImmArraySeq(keyType, valueType)) =>
val arg = args.next()
val keyExtractor = CodeBlock.of(
"$L -> $L",
arg,
generateToValueConverter(keyType, CodeBlock.of("$L.getKey()", arg), args, packagePrefixes)
)
val valueExtractor = CodeBlock.of(
"$L -> $L",
arg,
generateToValueConverter(
valueType,
CodeBlock.of("$L.getValue()", arg),
args,
packagePrefixes)
)
CodeBlock.of(
"new $T($L.entrySet().stream().collect($T.<$T<$L,$L>,Value,Value>toMap($L, $L)))",
apiGenMap,
accessor,
classOf[Collectors],
classOf[java.util.Map.Entry[_, _]],
toJavaTypeName(keyType, packagePrefixes),
toJavaTypeName(valueType, packagePrefixes),
keyExtractor,
valueExtractor
)

case TypePrim(PrimTypeContractId, _) | TypeCon(_, Seq()) =>
CodeBlock.of("$L.toValue()", accessor)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.util

import com.daml.ledger.javaapi
import com.daml.ledger.javaapi.data.codegen.ContractId
import com.daml.ledger.javaapi.data.{DamlList, DamlMap, DamlOptional}
import com.daml.ledger.javaapi.data.{DamlGenMap, DamlList, DamlMap, DamlOptional}
import com.digitalasset.daml.lf.data.ImmArray.ImmArraySeq
import com.digitalasset.daml.lf.data.Ref.{Identifier, PackageId, QualifiedName}
import com.digitalasset.daml.lf.iface._
Expand Down Expand Up @@ -80,6 +80,11 @@ package object inner {
ClassName.get(classOf[java.util.Map[String, _]]),
ClassName.get(classOf[java.lang.String]) +:
typeParameters.map(toJavaTypeName(_, packagePrefixes)): _*)
case TypePrim(PrimTypeGenMap, typeParameters) =>
ParameterizedTypeName
.get(
ClassName.get(classOf[java.util.Map[_, _]]),
typeParameters.map(toJavaTypeName(_, packagePrefixes)): _*)
case TypePrim(PrimTypeUnit, _) => ClassName.get(classOf[javaapi.data.Unit])
case TypeVar(name) => TypeVariableName.get(JavaEscaper.escapeString(name))
}
Expand All @@ -102,8 +107,7 @@ package object inner {
case TypePrim(PrimTypeMap, _) =>
ClassName.get(classOf[DamlMap])
case TypePrim(PrimTypeGenMap, _) =>
// FIXME https://github.com/digital-asset/daml/issues/2256
sys.error("GenMap not supported")
ClassName.get(classOf[DamlGenMap])
case TypePrim(PrimTypeUnit, _) =>
ClassName.get(classOf[javaapi.data.Unit])
case TypeCon(_, _) | TypeVar(_) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
@Suite.SuiteClasses({
DecimalTestForAll.class,
EnumTestFor1_6AndFor1_7.class,
NumericTestFor1_7.class,
NumericTestFor1_7AndFor1_dev.class,
})
public class AllTestsFor1_7{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2019 The DAML Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.digitalasset.testing;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

import java.math.BigDecimal;

@RunWith(Suite.class)
@Suite.SuiteClasses({
DecimalTestForAll.class,
NumericTestFor1_7AndFor1_dev.class,
GenMapTestFor1_dev.class,
})
public class AllTestsFor1_dev { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) 2019 The DAML Authors. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.digitalasset.testing;


import com.daml.ledger.javaapi.data.*;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import test.genmapmod.Box;
import test.recordmod.Pair;
import test.variantmod.Either;
import test.variantmod.either.*;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

@RunWith(JUnitPlatform.class)
public class GenMapTestFor1_dev {

private BigDecimal bg1 = new BigDecimal("1.0000000000");
private BigDecimal bg2 = new BigDecimal("-2.2222222222");
private BigDecimal bg3 = new BigDecimal("3.3333333333");

@Test
void genMap2Value2GenMap() {
HashMap<Pair<Long, BigDecimal>, Either<Long, BigDecimal>> map = new HashMap<>();
map.put(new Pair<>(1L, bg1), new Right<>(bg1));
map.put(new Pair<>(2L, bg2), new Left<>(2L));
map.put(new Pair<>(3L, bg3), new Right<>(bg3));
Box b = new Box(map, "alice");
assertEquals(Box.fromValue(b.toValue()), b);
}

private Record pair(Long fst, BigDecimal snd) {
return new Record(
new Record.Field("fst", new Int64(fst)),
new Record.Field("snd", new Numeric(snd))
);
}

private Variant left(Long l) {
return new Variant("Left", new Int64(l));
}

private Variant right(BigDecimal r) {
return new Variant("Right", new Numeric(r));
}

@Test
void value2GenMap2value() {
Map<Value, Value> value = new HashMap<Value, Value>();
value.put(pair(1L, bg1), left(1L));
value.put(pair(-2L,bg2 ), right(bg2));
value.put(pair(3L, bg3), left(3L));
Value map = new DamlGenMap(value);
Record b = new Record(
new Record.Field("x", map),
new Record.Field("party", new Party("alice"))
);
assertEquals(Box.fromValue(b).toValue(), b);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

@RunWith(JUnitPlatform.class)
public class NumericTestFor1_7 {
public class NumericTestFor1_7AndFor1_dev {

@Test
void numeric2Value2Numeric() {
Expand Down

0 comments on commit 027d63a

Please sign in to comment.