package org.scribble.ast.name.simple; import org.antlr.runtime.tree.CommonTree; import org.scribble.ast.AstFactoryImpl; import org.scribble.ast.MessageNode; import org.scribble.ast.NonRoleArgNode; import org.scribble.ast.name.PayloadElemNameNode; import org.scribble.sesstype.Arg; import org.scribble.sesstype.Message; import org.scribble.sesstype.kind.DataTypeKind; import org.scribble.sesstype.kind.Kind; import org.scribble.sesstype.kind.NonRoleParamKind; import org.scribble.sesstype.kind.SigKind; import org.scribble.sesstype.name.DataType; import org.scribble.sesstype.name.MessageSigName; import org.scribble.sesstype.name.Name; import org.scribble.sesstype.name.PayloadType; import org.scribble.visit.Substitutor; // An unambiguous kinded parameter (ambiguous parameters handled by disambiguation) that isn't a role -- e.g. DataType/MessageSigName param //public class NonRoleParamNode<K extends NonRoleParamKind> extends SimpleNameNode<K> implements MessageNode, PayloadElemNameNode //public class NonRoleParamNode<K extends NonRoleParamKind> extends SimpleNameNode<K> implements MessageNode, PayloadElemNameNode<PayloadTypeKind> public class NonRoleParamNode<K extends NonRoleParamKind> extends SimpleNameNode<K> implements MessageNode, PayloadElemNameNode<DataTypeKind> // As a payload, can only be a DataType (so hardcode) { public final K kind; public NonRoleParamNode(CommonTree source, K kind, String identifier) { super(source, identifier); this.kind = kind; } @Override public MessageNode project() // MessageSigName params { return this; } @Override protected NonRoleParamNode<K> copy() { return new NonRoleParamNode<>(this.source, this.kind, getIdentifier()); } @Override public NonRoleParamNode<K> clone() { return AstFactoryImpl.FACTORY.NonRoleParamNode(this.source, this.kind, getIdentifier()); } @Override public NonRoleArgNode substituteNames(Substitutor subs) { Arg<K> arg = toArg(); NonRoleArgNode an; if (this.kind.equals(SigKind.KIND) || this.kind.equals(DataTypeKind.KIND)) //if (this.kind instanceof NonRoleParamKind) // Would additionally include other payloadtype kinds { an = subs.getArgumentSubstitution(arg); // getArgumentSubstitution returns a clone } else { throw new RuntimeException("TODO: " + this); } // Effectively a reconstruct: use the dels/envs made by the subprotocolvisitor cloning, cf. RoleNode an = (NonRoleArgNode) an.del(del()); return an; } @Override public Name<K> toName() { String id = getIdentifier(); if (this.kind.equals(SigKind.KIND)) { return Kind.castName(this.kind, new MessageSigName(id)); } else if (this.kind.equals(DataTypeKind.KIND)) { return Kind.castName(this.kind, new DataType(id)); } else { throw new RuntimeException("Shouldn't get in here: " + this.kind); } } @Override public boolean isParamNode() { return true; } @Override public Arg<K> toArg() { Arg<? extends Kind> arg; if (this.kind.equals(DataTypeKind.KIND)) // FIXME: as a payload kind, currently hardcorded to data type kinds (protocol payloads not supported) { arg = toPayloadType(); } else if (this.kind.equals(SigKind.KIND)) { arg = toMessage(); } else { throw new RuntimeException("Shouldn't get here: " + this); } @SuppressWarnings("unchecked") Arg<K> tmp = (Arg<K>) arg; return tmp; } @Override public Message toMessage() { if (!this.kind.equals(SigKind.KIND)) { throw new RuntimeException("Not a sig kind parameter: " + this); } return (Message) toName(); } @Override //public PayloadType<? extends PayloadTypeKind> toPayloadType() public PayloadType<DataTypeKind> toPayloadType() // Currently can assume the only possible kind for NonRoleParamNode is DataTypeKind //public PayloadType<? extends PayloadTypeKind> toPayloadType() { if (this.kind.equals(DataTypeKind.KIND)) // As a payload, NonRoleParamNode can only be a DataType { return (DataType) toName(); } /*else if (this.kind.equals(Local.KIND)) // Protocol params not supported { return (Local) toName(); }*/ throw new RuntimeException("Not a payload kind parameter: " + this); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof NonRoleParamNode)) { return false; } NonRoleParamNode<? extends NonRoleParamKind> n = (NonRoleParamNode<?>) o; return n.canEqual(this) && this.kind.equals(n.kind) && super.equals(o); } @Override public boolean canEqual(Object o) { return o instanceof NonRoleParamNode; } @Override public int hashCode() { int hash = 317; hash = 31 * super.hashCode(); return hash; } }