/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.internal.gosu.parser.expressions;
import gw.config.CommonServices;
import gw.internal.gosu.parser.Expression;
import gw.internal.gosu.parser.CannotExecuteGosuException;
import gw.internal.gosu.ir.transform.expression.EvalExpressionTransformer;
import gw.lang.parser.ICapturedSymbol;
import gw.lang.parser.IExpression;
import gw.lang.parser.expressions.IQueryExpression;
import gw.lang.parser.expressions.IQueryExpressionEvaluator;
import gw.lang.parser.expressions.IQueryPartAssembler;
import gw.lang.parser.expressions.ITypeVariableDefinition;
import gw.lang.parser.expressions.ILiteralExpression;
import gw.lang.reflect.IType;
import gw.lang.reflect.IFunctionType;
import java.util.List;
import java.util.Map;
import java.util.Iterator;
/**
* Represents a 'query' expression in the Gosu grammar:
* <pre>
* <i>query-expression</i>
* <b>find</b> <b>(</b> <identifier> <b>in</b> <query-path-expression> <b>where</b> <where-clause-expression> <b>)</b>
* </pre>
* <p/>
*
* @see gw.internal.gosu.parser.QueryExpressionParser
* @see gw.lang.parser.IGosuParser
*
* @deprecated
*/
public class QueryExpression extends Expression implements IQueryExpression
{
/**
* The type of objects this query expression returns
*/
private IType _entityType;
/**
* The (declared) Identifier part of the expression.
*/
protected String _strIdentifier;
/**
* The query path specifying the context for the query.
*/
private QueryPathExpression _qpe;
/**
* The conditional (test) expression specifying criteria for the query.
*/
private Expression _whereExpression;
private boolean _distinct = false;
private int _iNameOffset;
private List<ICapturedSymbol> _capturedForBytecode;
private Map<String, ITypeVariableDefinition> _capturedTypeVars;
public QueryExpression()
{
}
@Override
public IType getTypeImpl()
{
if( _type == null )
{
IQueryExpressionEvaluator evaluator = CommonServices.getEntityAccess().getQueryExpressionEvaluator( this );
_type = evaluator.getResultType();
}
return _type;
}
public IType getEntityType()
{
return _entityType;
}
public void setEntityType( IType entityType )
{
_entityType = entityType;
}
public String getIdentifier()
{
return _strIdentifier;
}
public void setIdentifier( String strIdentifier )
{
_strIdentifier = strIdentifier;
}
public QueryPathExpression getInExpression()
{
return _qpe;
}
public void setInExpression( QueryPathExpression qpe )
{
_qpe = qpe;
}
public Expression getWhereClauseExpression()
{
return _whereExpression;
}
public void setWhereClauseExpression( Expression whereExpression )
{
_whereExpression = whereExpression;
}
public void setCapturedSymbolsForBytecode( List<ICapturedSymbol> captured )
{
_capturedForBytecode = captured;
}
public List<ICapturedSymbol> getCapturedForBytecode()
{
return _capturedForBytecode;
}
public void setCapturedTypeVars( Map<String, ITypeVariableDefinition> typeVariables )
{
for( Iterator<ITypeVariableDefinition> iter = typeVariables.values().iterator(); iter.hasNext(); )
{
ITypeVariableDefinition tvd = iter.next();
if( !(tvd.getEnclosingType() instanceof IFunctionType) )
{
iter.remove();
}
}
_capturedTypeVars = typeVariables;
}
public Map<String, ITypeVariableDefinition> getCapturedTypeVars()
{
return _capturedTypeVars;
}
public Object evaluate()
{
if( !isCompileTimeConstant() )
{
return super.evaluate();
}
throw new CannotExecuteGosuException();
}
public void buildPrimaryQuery( IQueryExpressionEvaluator evaluator )
{
if( _whereExpression != null )
{
((IQueryPartAssembler)_whereExpression).assembleQueryPart( evaluator );
}
}
@Override
public String toString()
{
return "find( " + getIdentifier() + " in " + getInExpression().toString() +
(_whereExpression == null ? " )" : (" where " + _whereExpression.toString()) + " )" );
}
@Override
public int getNameOffset( String identifierName )
{
return _iNameOffset;
}
@Override
public void setNameOffset( int iOffset, String identifierName )
{
_iNameOffset = iOffset;
}
public boolean declares( String identifierName )
{
return identifierName.equals( getIdentifier() ) ||
identifierName.equals( getInExpression().getRootName() );
}
public String[] getDeclarations() {
return new String[] {getIdentifier()};
}
public void setDistinct( boolean distinct )
{
_distinct = distinct;
}
public boolean isDistinct()
{
return _distinct;
}
@Override
public Object evalRhsExpr( IExpression rhs, Object[] ctxArgs )
{
while( rhs instanceof TypeAsExpression )
{
rhs = ((TypeAsExpression)rhs).getLHS();
}
if( rhs instanceof EvalExpression )
{
return EvalExpressionTransformer.compileAndRunEvalSource( ((StringLiteral)((EvalExpression)rhs).getExpression()).getValue(), ctxArgs[0], (Object[])ctxArgs[1],
(IType[])ctxArgs[2], (IType)ctxArgs[3], (EvalExpression)rhs );
}
else if( rhs instanceof ILiteralExpression )
{
return rhs.evaluate();
}
else
{
throw new IllegalStateException( "Cannot evalute RHS in query of type " + rhs.getClass() + " with content " + rhs.toString() );
}
}
@Override
public boolean shouldClearParseInfo() {
return false;
}
}