public Evaluator buildEvaluator()

in nifi-commons/nifi-expression-language/src/main/java/org/apache/nifi/attribute/expression/language/compile/ExpressionCompiler.java [1136:1294]


    public Evaluator<?> buildEvaluator(final Tree tree) {
        switch (tree.getType()) {
            case EXPRESSION: {
                return buildExpressionEvaluator(tree);
            }
            case PARAMETER_REFERENCE: {
                final String parameterName = tree.getChild(0).getText();
                final ParameterEvaluator parameterEvaluator = new ParameterEvaluator(parameterName);
                evaluators.add(parameterEvaluator);
                return parameterEvaluator;
            }
            case ATTRIBUTE_REFERENCE: {
                final Evaluator<?> childEvaluator = buildEvaluator(tree.getChild(0));
                if (childEvaluator instanceof MultiAttributeEvaluator) {
                    return childEvaluator;
                }
                final AttributeEvaluator eval = new AttributeEvaluator(toStringEvaluator(childEvaluator));
                evaluators.add(eval);
                return eval;
            }
            case MULTI_ATTRIBUTE_REFERENCE: {

                final Tree functionTypeTree = tree.getChild(0);
                final int multiAttrType = functionTypeTree.getType();
                if (multiAttrType == ANY_DELINEATED_VALUE || multiAttrType == ALL_DELINEATED_VALUES) {
                    final Evaluator<String> delineatedValueEvaluator = toStringEvaluator(buildEvaluator(tree.getChild(1)));
                    final Evaluator<String> delimiterEvaluator = toStringEvaluator(buildEvaluator(tree.getChild(2)));

                    final String token = (multiAttrType == ANY_DELINEATED_VALUE) ? "anyDelineatedValue" : "allDelineatedValues";
                    return addToken(new DelineatedAttributeEvaluator(delineatedValueEvaluator, delimiterEvaluator, multiAttrType), token);
                }

                final List<String> attributeNames = new ArrayList<>();
                for (int i = 1; i < tree.getChildCount(); i++) {  // skip the first child because that's the name of the multi-attribute function
                    attributeNames.add(newStringLiteralEvaluator(tree.getChild(i).getText()).evaluate(new StandardEvaluationContext(Collections.emptyMap())).getValue());
                }

                switch (multiAttrType) {
                    case ALL_ATTRIBUTES:
                        for (final String attributeName : attributeNames) {
                            try {
                                FlowFile.KeyValidator.validateKey(attributeName);
                            } catch (final IllegalArgumentException iae) {
                                throw new AttributeExpressionLanguageParsingException("Invalid Attribute Name: " + attributeName + ". " + iae.getMessage());
                            }
                        }

                        return addToken(new MultiNamedAttributeEvaluator(attributeNames, ALL_ATTRIBUTES), "allAttributes");
                    case ALL_MATCHING_ATTRIBUTES:
                        return addToken(new MultiMatchAttributeEvaluator(attributeNames, ALL_MATCHING_ATTRIBUTES), "allMatchingAttributes");
                    case ANY_ATTRIBUTE:
                        for (final String attributeName : attributeNames) {
                            try {
                                FlowFile.KeyValidator.validateKey(attributeName);
                            } catch (final IllegalArgumentException iae) {
                                throw new AttributeExpressionLanguageParsingException("Invalid Attribute Name: " + attributeName + ". " + iae.getMessage());
                            }
                        }

                        return addToken(new MultiNamedAttributeEvaluator(attributeNames, ANY_ATTRIBUTE), "anyAttribute");
                    case ANY_MATCHING_ATTRIBUTE:
                        return addToken(new MultiMatchAttributeEvaluator(attributeNames, ANY_MATCHING_ATTRIBUTE), "anyMatchingAttribute");
                    default:
                        throw new AssertionError("Illegal Multi-Attribute Reference: " + functionTypeTree.toString());
                }
            }
            case ATTR_NAME: {
                return newStringLiteralEvaluator(tree.getChild(0).getText());
            }
            case WHOLE_NUMBER: {
                return addToken(new WholeNumberLiteralEvaluator(tree.getText()), "wholeNumber");
            }
            case STRING_LITERAL: {
                return newStringLiteralEvaluator(tree.getText());
            }
            case DECIMAL: {
                return addToken(new DecimalLiteralEvaluator(tree.getText()), "decimal");
            }
            case TRUE:
            case FALSE:
                return buildBooleanEvaluator(tree);
            case NULL:
                return newStringLiteralEvaluator(null);
            case UUID: {
                return addToken(new UuidEvaluator(), "uuid");
            }
            case NOW: {
                return addToken(new NowEvaluator(), "now");
            }
            case TO_LITERAL: {
                final Evaluator<?> argEvaluator = buildEvaluator(tree.getChild(0));
                return addToken(new ToLiteralEvaluator(argEvaluator), "toLiteral");
            }
            case IP: {
                try {
                    return addToken(new IPEvaluator(), "ip");
                } catch (final UnknownHostException e) {
                    throw new AttributeExpressionLanguageException(e);
                }
            }
            case THREAD:
                return addToken(new ThreadEvaluator(), "thread");
            case HOSTNAME: {
                if (tree.getChildCount() == 0) {
                    try {
                        return addToken(new HostnameEvaluator(false), "hostname");
                    } catch (final UnknownHostException e) {
                        throw new AttributeExpressionLanguageException(e);
                    }
                } else if (tree.getChildCount() == 1) {
                    final Tree childTree = tree.getChild(0);
                    try {
                        switch (childTree.getType()) {
                            case TRUE:
                                return addToken(new HostnameEvaluator(true), "hostname");
                            case FALSE:
                                return addToken(new HostnameEvaluator(false), "hostname");
                            default:
                                throw new AttributeExpressionLanguageParsingException("Call to hostname() must take 0 or 1 (boolean) parameter");
                        }
                    } catch (final UnknownHostException e) {
                        throw new AttributeExpressionLanguageException(e);
                    }
                } else {
                    throw new AttributeExpressionLanguageParsingException("Call to hostname() must take 0 or 1 (boolean) parameter");
                }
            }
            case NEXT_INT: {
                return addToken(new OneUpSequenceEvaluator(), "nextInt");
            }
            case RANDOM: {
                return addToken(new RandomNumberGeneratorEvaluator(), "random");
            }
            case MATH: {
                if (tree.getChildCount() == 1) {
                    return addToken(new MathEvaluator(null, toStringEvaluator(buildEvaluator(tree.getChild(0))), null), "math");
                } else {
                    throw new AttributeExpressionLanguageParsingException("Call to math() as the subject must take exactly 1 parameter");
                }
            }
            case GET_STATE_VALUE: {
                final Tree childTree = tree.getChild(0);
                final Evaluator<?> argEvaluator = buildEvaluator(childTree);
                final Evaluator<String> stringEvaluator = toStringEvaluator(argEvaluator);
                final GetStateVariableEvaluator eval = new GetStateVariableEvaluator(stringEvaluator);
                evaluators.add(eval);
                return eval;
            }
            case GET_URI: {
                List<Evaluator<String>> uriArgs = Stream.iterate(0, i -> i + 1)
                        .limit(tree.getChildCount())
                        .map(num -> toStringEvaluator(buildEvaluator(tree.getChild(num))))
                        .collect(Collectors.toList());
                return addToken(new GetUriEvaluator(uriArgs), "getUri");
            }
            default:
                throw new AttributeExpressionLanguageParsingException("Unexpected token: " + tree.toString());
        }
    }