package ameba.db.dsl; import ameba.db.dsl.QueryExprMeta.Val; import com.google.common.collect.Lists; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.tree.ParseTreeProperty; import java.util.Collections; import java.util.List; /** * <p>QueryExprListener class.</p> * * @author icode * */ public class QueryExprListener extends QueryBaseListener { private ParseTreeProperty<QueryExprMeta> infoMap = new ParseTreeProperty<>(); private List<QueryExprMeta> queryExprMetaList = Lists.newArrayList(); private QueryExprMeta queryExprMeta; /** * <p>Getter for the field <code>queryExprMetaList</code>.</p> * * @return a {@link java.util.List} object. */ public List<QueryExprMeta> getQueryExprMetaList() { return queryExprMetaList; } /** * {@inheritDoc} */ @Override public void exitSourceElements(QueryParser.SourceElementsContext ctx) { infoMap = null; queryExprMeta = null; queryExprMetaList = Collections.unmodifiableList(queryExprMetaList); } /** {@inheritDoc} */ @Override public void exitSourceElement(QueryParser.SourceElementContext ctx) { if (queryExprMeta != null) { String op = queryExprMeta.operator(); if (op == null) { String co = queryExprMeta.field(); if (co != null && queryExprMeta.arguments() == null) { int offset = co.lastIndexOf('.'); if (offset == -1) { if (queryExprMeta.parent() == null) { queryExprMeta.operator(co); queryExprMeta.field(null); } else { List<Val<?>> args = queryExprMeta.parent().arguments(); int argOffset = -1; for (int i = 0; i < args.size(); i++) { Val val = args.get(i); if (queryExprMeta.equals(val.object())) { argOffset = i; break; } } if (argOffset != -1) { args.set(argOffset, Val.of(co)); queryExprMeta = null; } } } else { queryExprMeta.field(co.substring(0, offset)); queryExprMeta.operator(co.substring(offset + 1)); } } } } } /** {@inheritDoc} */ @Override public void enterSourceElement(QueryParser.SourceElementContext ctx) { queryExprMeta = QueryExprMeta.create(); infoMap.put(ctx, queryExprMeta); // root source element if (ctx.getParent() instanceof QueryParser.SourceElementsContext) { queryExprMetaList.add(queryExprMeta); } else { QueryExprMeta parentInfo = infoMap.get(getParentSourceElement(ctx)).arguments(queryExprMeta); queryExprMeta.parent(parentInfo); } } /** {@inheritDoc} */ @Override public void exitIdentifierName(QueryParser.IdentifierNameContext ctx) { queryExprMeta.operator(ctx.getText()); } /** {@inheritDoc} */ @Override public void exitFieldExpression(QueryParser.FieldExpressionContext ctx) { queryExprMeta.field(ctx.getText()); } /** {@inheritDoc} */ @Override public void exitLiteral(QueryParser.LiteralContext ctx) { String text = ctx.getText(); if (ctx.NullLiteral() != null) { queryExprMeta.arguments(Val.of()); } else if (ctx.BooleanLiteral() != null) { queryExprMeta.arguments(Val.ofBool(text)); } else if (ctx.DecimalLiteral() != null) { queryExprMeta.arguments(Val.ofDecimal(text)); } else { queryExprMeta.arguments(Val.of(text)); } } /** {@inheritDoc} */ @Override public void exitIdentifierVal(QueryParser.IdentifierValContext ctx) { queryExprMeta.arguments(Val.of(ctx.getText())); } /** * <p>getParentSourceElement.</p> * * @param node a {@link org.antlr.v4.runtime.ParserRuleContext} object. * @return a {@link org.antlr.v4.runtime.ParserRuleContext} object. */ protected ParserRuleContext getParentSourceElement(ParserRuleContext node) { if (node == null) return null; ParserRuleContext parent = node.getParent(); if (parent instanceof QueryParser.SourceElementContext) { return parent; } return getParentSourceElement(parent); } }