digital-asset / daml

The Daml smart contract language
https://www.digitalasset.com/developers
797 stars 201 forks source link

illustrate the phantom/nominal contract ID distinction in Java codegen, maybe work around #14299

Closed S11001001 closed 2 years ago

S11001001 commented 2 years ago

In Scala codegen, ContractId[T] = T.ContractId. However, in Java codegen, T.ContractId <: ContractId<T> but not vice versa, which means that (cidT: ContractId<T>).exerciseX(...) doesn't work, and ((T.ContractId) cidT) can fail too.

It's also possible that we can get ((T.ContractId) cidT) to work, but would require a significant redesign of the decoder path. #14313

Example fromValue illustrating the problem:

  public static <a> ParametrizedContractId<a> fromValue(Value value$, Function<Value, a> fromValuea)
      throws IllegalArgumentException {
    Value recordValue$ = value$;
    DamlRecord record$ = recordValue$.asRecord().orElseThrow(() -> new IllegalArgumentException("Contracts must be constructed from Records"));
    List<DamlRecord.Field> fields$ = record$.getFields();
    int numberOfFields = fields$.size();
    if (numberOfFields != 1) {
      throw new IllegalArgumentException("Expected 1 arguments, got " + numberOfFields);
    }
    ContractId<a> parametrizedContractId = new ContractId<a>(fields$.get(0).getValue().asContractId().orElseThrow(() -> new IllegalArgumentException("Expected parametrizedContractId to be of type com.daml.ledger.javaapi.data.ContractId")).getValue());
    return new tests.recordtest.ParametrizedContractId<a>(parametrizedContractId);
  }
chunlokling-da commented 2 years ago

static forwarder on the codegenned ContractId classes

I am making ContractId => T.ContractId utility available in ContractCompanion Can you elaborate more on "static forwarder" works in T.ContractId, in this context here? Thanks cc @ray-roestenburg-da

ray-roestenburg-da commented 2 years ago

A static forwarder in Scala is some generated code (for convenience) that provides Java users access to methods on a Scala object. this makes it possible for Java users to just call SomeObject.foo on class SomeObject where foo is a static method, instead of going through SomeObject$.MODULE$.foo (I think that is what @S11001001 is referring to, though conceptually).

ray-roestenburg-da commented 2 years ago

So in this case the generated ContractId class should get a static method that calls the ContractCompanion utility method.

chunlokling-da commented 2 years ago

Thanks, based on your information, I believe the "static forwarder" is referring to this

S11001001 commented 2 years ago

Thanks, based on your information, I believe the "static forwarder" is referring to this

That's right.