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();
}
}