package edu.washington.escience.myria.expression; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import edu.washington.escience.myria.Type; import edu.washington.escience.myria.expression.evaluate.ExpressionOperatorParameter; /** * A conditional expression that uses the ternary operator. */ public class ConditionalExpression extends NAryExpression { /***/ private static final long serialVersionUID = 1L; /** * This is not really unused, it's used automagically by Jackson deserialization. */ @SuppressWarnings("unused") private ConditionalExpression() {} /** * Create a conditional expression using a ternary operator. * * @param condition a boolean expression * @param firstChoice the return value if the condition is true * @param secondChoice the return value if the condition is false */ public ConditionalExpression( final ExpressionOperator condition, final ExpressionOperator firstChoice, final ExpressionOperator secondChoice) { super(ImmutableList.of(condition, firstChoice, secondChoice)); } @Override public Type getOutputType(final ExpressionOperatorParameter parameters) { final Type type = getChild(0).getOutputType(parameters); Preconditions.checkArgument( type == Type.BOOLEAN_TYPE, "%s requires the first child [%s] to be a boolean expression but it is a %s", getClass().getSimpleName(), getChild(1), type); Type firstType = getChild(1).getOutputType(parameters); Type secondType = getChild(2).getOutputType(parameters); if (firstType == secondType) { return firstType; } ImmutableList<Type> validTypes = ImmutableList.of(Type.DOUBLE_TYPE, Type.FLOAT_TYPE, Type.LONG_TYPE, Type.INT_TYPE); int firstIdx = validTypes.indexOf(firstType); int secondIdx = validTypes.indexOf(secondType); Preconditions.checkArgument( firstIdx != -1, "%s cannot handle first choice [%s] of Type %s", getClass().getSimpleName(), getChild(1), firstType); Preconditions.checkArgument( secondIdx != -1, "%s cannot handle second choice [%s] of Type %s", getClass().getSimpleName(), getChild(2), secondType); return validTypes.get(Math.min(firstIdx, secondIdx)); } @Override public String getJavaString(final ExpressionOperatorParameter parameters) { return new StringBuilder("(") .append(getChild(0).getJavaString(parameters)) .append("?") .append(getChild(1).getJavaString(parameters)) .append(":") .append(getChild(2).getJavaString(parameters)) .append(")") .toString(); } }