[MDSAL-740] Generate fields for all Identityrefs in an Union binding class. Created: 04/Apr/22  Updated: 13/Jun/22  Resolved: 13/Jun/22

Status: Resolved
Project: mdsal
Component/s: Binding codegen
Affects Version/s: None
Fix Version/s: 10.0.0

Type: Improvement Priority: Low
Reporter: Tibor Král Assignee: Oleksandr Zharov
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Blocks
is blocked by MDSAL-733 Change 'type identityref' Binding rep... Resolved

 Description   

Yang allows adding multiple identityrefs as possible types in an Union. For example:

identity compliance-code-identity {
  description
    "Base identity for reporting pluggable compliance codes per port.";
} 

identity network-phy-code-identity {
  description
    "base identity for network phy code.";
}
  
identity client-phy-code-identity {
  description
    "base identity for client phy code.";
}

type union {
  type identityref { base compliance-code-identity; }
  type identityref { base client-phy-code-identity; }
  type identityref { base network-phy-code-identity; }
  type uint64;
  type decimal64 {
    fraction-digits 8;
  } 
}

However when MDSAL generates binding class for this union, it only contains the first Identityref specified. In this case the compliance-code-identity.
Binding generator processes the "identityref" as an ordinary "type" and therefore it ignores multiple occurencies of it, just as it does for any other type. But Identityref isn't an ordinary type, so it should be processed differently.
The result is as follows:

public class ComplianceCodesUnion implements TypeObject, Serializable {
  private static final long serialVersionUID = -3780142905034216089L;
  private final Class<? extends ComplianceCodeIdentity> _identityref;
  private final BigInteger _uint64;
  private final BigDecimal _decimal64;

Modify the binding generator to include all the identityrefs.

 



 Comments   
Comment by Robert Varga [ 08/Apr/22 ]

This proposal cannot work with current mapping based on Java Language Specification. Most notably this proposal ignores pre-Java-1.5 world – and that aspect of the language is not going to change in foreseeable future.

Comment by Tibor Král [ 11/Apr/22 ]

Java won't allow us to simply generate one constructor for each idetityref like this:

public ComplianceCodesUnion(Class<? extends ComplianceCodeIdentity> _identityref) {...}
public ComplianceCodesUnion(Class<? extends ClientPhyCodeIdentity> _identityref) {...}
public ComplianceCodesUnion(Class<? extends NetworkPhyCodeIdentity> _identityref) {...}

because these constructors have the same signature. This means any solution which proposes a separate constructor for each Identityref will completely change the API and break backwards compatibility.

However there is a possible solution, which introduces an aggregare constructor for all identityrefs. It sacrifices a bit of type-safety, but should remain backwards-compatible:

ComplianceCodesUnion(Class<? extends BaseIdentity> identity) {
   if (isValidIdentity(identity, ComplianceCodeIdentity.class)) {
       _complianceCodeIdentity = (Class<? extends ComplianceCodeIdentity>) identity;
   } else if (isValidIdentity(identity, ClientPhyCodeIdentity.class)) {
       _clientPhyCodeIdentity = (Class<? extends ClientPhyCodeIdentity>) identity;
   } else if (isValidIdentity(identity, NetworkPhyCodeIdentity.class)) { 
       _networkPhyCodeIdentity = (Class<? extends NetworkPhyCodeIdentity>) identity; }
   else {
       throw new InvalidIdentityException("Missing identityref for identity " + identity.getName());
   }
}
Comment by Robert Varga [ 11/Apr/22 ]

Well, this completely drops compile-time safety. What about before-and-after class shape comparison?

Generated at Wed Feb 07 20:10:48 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.