private Item instantiatePhraseItem(String field, OperatorNode<ExpressionOperator> ast) {
        assertHasFunctionName(ast, PHRASE);

        if (getAnnotation(ast, ORIGIN, Map.class, null, ORIGIN_DESCRIPTION, false) != null) {
            return instantiatePhraseSegmentItem(field, ast, false);
        }

        PhraseItem phrase = new PhraseItem();
        phrase.setIndexName(field);
        phrase.setExplicit(true);
        for (OperatorNode<ExpressionOperator> word : ast.<List<OperatorNode<ExpressionOperator>>> getArgument(1)) {
            if (word.getOperator() == ExpressionOperator.CALL) {
                List<String> names = word.getArgument(0);
                switch (names.get(0)) {
                case PHRASE:
                    if (getAnnotation(word, ORIGIN, Map.class, null, ORIGIN_DESCRIPTION, false) == null) {
                        phrase.addItem(instantiatePhraseItem(field, word));
                    } else {
                        phrase.addItem(instantiatePhraseSegmentItem(field, word, true));
                    }
                    break;
                case ALTERNATIVES:
                    phrase.addItem(instantiateWordAlternativesItem(field, word));
                    break;
                default:
                    throw new IllegalArgumentException("Expected phrase or word alternatives, got " + names.get(0));
                }
            } else {
                phrase.addItem(instantiateWordItem(field, word, phrase.getClass()));
            }
        }
        return leafStyleSettings(ast, phrase);
    }
The YQL query language.

This class <em>must</em> be kept in lockstep with {@link VespaSerializer}.
Adding anything here will usually require a corresponding addition in
VespaSerializer.

@author Steinar Knutsen
@author Stian Kristoffersen
@author Simon Thoresen Hult
container-search/src/main/java/com/yahoo/search/yql/YqlParser.java