All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kaazing.robot.lang.parser.ScriptParseStrategy Maven / Gradle / Ivy

/*
 * Copyright (c) 2014 "Kaazing Corporation," (www.kaazing.com)
 *
 * This file is part of Robot.
 *
 * Robot is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see .
 */

package org.kaazing.robot.lang.parser;

import static java.lang.Integer.parseInt;
import static org.kaazing.robot.lang.parser.ParserHelper.parseHexBytes;

import java.net.URI;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;

import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import org.antlr.v4.runtime.RecognitionException;
import org.kaazing.robot.lang.ast.AstAcceptNode;
import org.kaazing.robot.lang.ast.AstAcceptableNode;
import org.kaazing.robot.lang.ast.AstBarrierNode;
import org.kaazing.robot.lang.ast.AstBoundNode;
import org.kaazing.robot.lang.ast.AstChildClosedNode;
import org.kaazing.robot.lang.ast.AstChildOpenedNode;
import org.kaazing.robot.lang.ast.AstCloseNode;
import org.kaazing.robot.lang.ast.AstClosedNode;
import org.kaazing.robot.lang.ast.AstCommandNode;
import org.kaazing.robot.lang.ast.AstConnectNode;
import org.kaazing.robot.lang.ast.AstConnectedNode;
import org.kaazing.robot.lang.ast.AstDisconnectNode;
import org.kaazing.robot.lang.ast.AstDisconnectedNode;
import org.kaazing.robot.lang.ast.AstEventNode;
import org.kaazing.robot.lang.ast.AstNode;
import org.kaazing.robot.lang.ast.AstOpenedNode;
import org.kaazing.robot.lang.ast.AstOptionNode;
import org.kaazing.robot.lang.ast.AstReadAwaitNode;
import org.kaazing.robot.lang.ast.AstReadClosedNode;
import org.kaazing.robot.lang.ast.AstReadConfigNode;
import org.kaazing.robot.lang.ast.AstReadNotifyNode;
import org.kaazing.robot.lang.ast.AstReadOptionNode;
import org.kaazing.robot.lang.ast.AstReadValueNode;
import org.kaazing.robot.lang.ast.AstScriptNode;
import org.kaazing.robot.lang.ast.AstStreamNode;
import org.kaazing.robot.lang.ast.AstStreamableNode;
import org.kaazing.robot.lang.ast.AstUnbindNode;
import org.kaazing.robot.lang.ast.AstUnboundNode;
import org.kaazing.robot.lang.ast.AstWriteAwaitNode;
import org.kaazing.robot.lang.ast.AstWriteCloseNode;
import org.kaazing.robot.lang.ast.AstWriteConfigNode;
import org.kaazing.robot.lang.ast.AstWriteNotifyNode;
import org.kaazing.robot.lang.ast.AstWriteOptionNode;
import org.kaazing.robot.lang.ast.AstWriteValueNode;
import org.kaazing.robot.lang.ast.matcher.AstByteLengthBytesMatcher;
import org.kaazing.robot.lang.ast.matcher.AstExactBytesMatcher;
import org.kaazing.robot.lang.ast.matcher.AstExactTextMatcher;
import org.kaazing.robot.lang.ast.matcher.AstExpressionMatcher;
import org.kaazing.robot.lang.ast.matcher.AstFixedLengthBytesMatcher;
import org.kaazing.robot.lang.ast.matcher.AstIntLengthBytesMatcher;
import org.kaazing.robot.lang.ast.matcher.AstLongLengthBytesMatcher;
import org.kaazing.robot.lang.ast.matcher.AstRegexMatcher;
import org.kaazing.robot.lang.ast.matcher.AstShortLengthBytesMatcher;
import org.kaazing.robot.lang.ast.matcher.AstValueMatcher;
import org.kaazing.robot.lang.ast.matcher.AstVariableLengthBytesMatcher;
import org.kaazing.robot.lang.ast.value.AstExpressionValue;
import org.kaazing.robot.lang.ast.value.AstLiteralBytesValue;
import org.kaazing.robot.lang.ast.value.AstLiteralTextValue;
import org.kaazing.robot.lang.ast.value.AstValue;
import org.kaazing.robot.lang.el.ExpressionContext;
import org.kaazing.robot.lang.parser.v2.RobotBaseVisitor;
import org.kaazing.robot.lang.parser.v2.RobotParser;
import org.kaazing.robot.lang.parser.v2.RobotParser.AcceptNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.AcceptableNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.BarrierNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.BoundNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ChildClosedNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ChildOpenedNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.CloseNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ClosedNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.CommandNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ConnectNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ConnectedNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.DisconnectNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.DisconnectedNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.EventNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ExactBytesMatcherContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ExactTextMatcherContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ExpressionMatcherContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ExpressionValueContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.FixedLengthBytesMatcherContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.LiteralBytesContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.LiteralTextContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.MatcherContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.OpenedNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.OptionNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadAwaitNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadClosedNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadHttpHeaderNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadHttpMethodNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadHttpParameterNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadHttpStatusNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadHttpVersionNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadNotifyNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ReadOptionNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.RegexMatcherContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ScriptNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.ServerStreamableNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.StreamNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.StreamableNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.UnbindNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.UnboundNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.VariableLengthBytesMatcherContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteAwaitNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteCloseNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteHttpContentLengthNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteHttpHeaderNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteHttpMethodNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteHttpParameterNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteHttpStatusNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteHttpVersionNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteNotifyNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteOptionNodeContext;
import org.kaazing.robot.lang.parser.v2.RobotParser.WriteValueContext;
import org.kaazing.robot.lang.regex.NamedGroupPattern;

abstract class ScriptParseStrategy {

    public static final ScriptParseStrategy SCRIPT = new ScriptParseStrategy() {
        @Override
        public AstScriptNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstScriptNodeVisitor(elFactory, elContext).visit(parser.scriptNode());
        }
    };

    public static final ScriptParseStrategy STREAM = new ScriptParseStrategy() {
        @Override
        public AstStreamNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstStreamNodeVisitor(elFactory, elContext).visit(parser.streamNode());
        }
    };

    public static final ScriptParseStrategy STREAMABLE = new ScriptParseStrategy() {
        @Override
        public AstStreamableNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstStreamableNodeVisitor(elFactory, elContext).visit(parser.streamableNode());
        }
    };

    public static final ScriptParseStrategy EVENT = new ScriptParseStrategy() {
        @Override
        public AstEventNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstEventNodeVisitor(elFactory, elContext).visit(parser.eventNode());
        }
    };

    public static final ScriptParseStrategy COMMAND = new ScriptParseStrategy() {
        @Override
        public AstCommandNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstCommandNodeVisitor(elFactory, elContext).visit(parser.commandNode());
        }
    };

    public static final ScriptParseStrategy BARRIER = new ScriptParseStrategy() {
        @Override
        public AstBarrierNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstBarrierNodeVisitor(elFactory, elContext).visit(parser.barrierNode());
        }
    };

    public static final ScriptParseStrategy SERVER_STREAMABLE = new ScriptParseStrategy() {
        @Override
        public AstStreamableNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstStreamableNodeVisitor(elFactory, elContext).visit(parser.serverStreamableNode());
        }
    };

    public static final ScriptParseStrategy SERVER_EVENT = new ScriptParseStrategy() {
        @Override
        public AstEventNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstEventNodeVisitor(elFactory, elContext).visit(parser.serverEventNode());
        }
    };

    public static final ScriptParseStrategy SERVER_COMMAND = new ScriptParseStrategy() {
        @Override
        public AstCommandNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstCommandNodeVisitor(elFactory, elContext).visit(parser.serverCommandNode());
        }
    };

    public static final ScriptParseStrategy ACCEPT = new ScriptParseStrategy() {
        @Override
        public AstAcceptNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstAcceptNodeVisitor(elFactory, elContext).visit(parser.acceptNode());
        }
    };

    public static final ScriptParseStrategy ACCEPTABLE = new ScriptParseStrategy() {
        @Override
        public AstAcceptableNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstAcceptedNodeVisitor(elFactory, elContext).visit(parser.acceptableNode());
        }
    };

    public static final ScriptParseStrategy CONNECT = new ScriptParseStrategy() {
        @Override
        public AstConnectNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstConnectNodeVisitor(elFactory, elContext).visit(parser.connectNode());
        }
    };

    public static final ScriptParseStrategy CLOSE = new ScriptParseStrategy() {
        @Override
        public AstCloseNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstCloseNodeVisitor(elFactory, elContext).visit(parser.closeNode());
        }
    };

    public static final ScriptParseStrategy DISCONNECT = new ScriptParseStrategy() {
        @Override
        public AstDisconnectNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstDisconnectNodeVisitor(elFactory, elContext).visit(parser.disconnectNode());
        }
    };

    public static final ScriptParseStrategy UNBIND = new ScriptParseStrategy() {
        @Override
        public AstUnbindNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstUnbindNodeVisitor(elFactory, elContext).visit(parser.unbindNode());
        }
    };

    public static final ScriptParseStrategy WRITE = new ScriptParseStrategy() {
        @Override
        public AstWriteValueNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstWriteValueNodeVisitor(elFactory, elContext).visit(parser.writeNode());
        }
    };

    public static final ScriptParseStrategy CHILD_OPENED = new ScriptParseStrategy() {
        @Override
        public AstChildOpenedNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstChildOpenedNodeVisitor(elFactory, elContext).visit(parser.childOpenedNode());
        }
    };

    public static final ScriptParseStrategy CHILD_CLOSED = new ScriptParseStrategy() {
        @Override
        public AstChildClosedNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstChildClosedNodeVisitor(elFactory, elContext).visit(parser.childClosedNode());
        }
    };

    public static final ScriptParseStrategy BOUND = new ScriptParseStrategy() {
        @Override
        public AstBoundNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstBoundNodeVisitor(elFactory, elContext).visit(parser.boundNode());
        }
    };

    public static final ScriptParseStrategy CLOSED = new ScriptParseStrategy() {
        @Override
        public AstClosedNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstClosedNodeVisitor(elFactory, elContext).visit(parser.closedNode());
        }
    };

    public static final ScriptParseStrategy CONNECTED = new ScriptParseStrategy() {
        @Override
        public AstConnectedNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstConnectedNodeVisitor(elFactory, elContext).visit(parser.connectedNode());
        }
    };

    public static final ScriptParseStrategy DISCONNECTED = new ScriptParseStrategy() {
        @Override
        public AstDisconnectedNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstDisconnectedNodeVisitor(elFactory, elContext).visit(parser.disconnectedNode());
        }
    };

    public static final ScriptParseStrategy OPENED = new ScriptParseStrategy() {
        @Override
        public AstOpenedNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstOpenedNodeVisitor(elFactory, elContext).visit(parser.openedNode());
        }
    };

    public static final ScriptParseStrategy READ = new ScriptParseStrategy() {
        @Override
        public AstReadValueNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstReadValueNodeVisitor(elFactory, elContext).visit(parser.readNode());
        }
    };

    public static final ScriptParseStrategy READ_HTTP_HEADER = new ScriptParseStrategy() {
        @Override
        public AstReadConfigNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visit(parser.readHttpHeaderNode());
        }
    };

    public static final ScriptParseStrategy WRITE_HTTP_HEADER = new ScriptParseStrategy() {
        @Override
        public AstWriteConfigNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visit(parser.writeHttpHeaderNode());
        }
    };

    public static final ScriptParseStrategy WRITE_HTTP_CONTENT_LENGTH = new ScriptParseStrategy() {
        @Override
        public AstWriteConfigNode parse(RobotParser parser,
                                                   ExpressionFactory elFactory,
                                                   ExpressionContext elContext) throws RecognitionException {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visit(parser
                    .writeHttpContentLengthNode());
        }
    };

    public static final ScriptParseStrategy READ_HTTP_METHOD = new ScriptParseStrategy() {
        @Override
        public AstReadConfigNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visit(parser.readHttpMethodNode());
        }
    };

    public static final ScriptParseStrategy WRITE_HTTP_METHOD = new ScriptParseStrategy() {
        @Override
        public AstWriteConfigNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visit(parser.writeHttpMethodNode());
        }
    };

    public static final ScriptParseStrategy READ_HTTP_PARAMETER = new ScriptParseStrategy() {
        @Override
        public AstReadConfigNode parse(RobotParser parser,
                                       ExpressionFactory elFactory,
                                       ExpressionContext elContext) throws RecognitionException {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visit(parser.readHttpParameterNode());
        }
    };

    public static final ScriptParseStrategy WRITE_HTTP_PARAMETER = new ScriptParseStrategy() {
        @Override
        public AstWriteConfigNode parse(RobotParser parser,
                                               ExpressionFactory elFactory,
                                               ExpressionContext elContext) throws RecognitionException {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visit(parser.writeHttpParameterNode());
        }
    };

    public static final ScriptParseStrategy READ_HTTP_VERSION = new ScriptParseStrategy() {
        @Override
        public AstReadConfigNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visit(parser.readHttpVersionNode());
        }
    };

    public static final ScriptParseStrategy WRITE_HTTP_VERSION = new ScriptParseStrategy() {
        @Override
        public AstWriteConfigNode parse(RobotParser parser,
                                             ExpressionFactory elFactory,
                                             ExpressionContext elContext) throws RecognitionException {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visit(parser.writeHttpVersionNode());
        }
    };

    public static final ScriptParseStrategy READ_HTTP_STATUS = new ScriptParseStrategy() {
        @Override
        public AstReadConfigNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visit(parser.readHttpStatusNode());
        }
    };

    public static final ScriptParseStrategy WRITE_HTTP_STATUS = new ScriptParseStrategy() {
        @Override
        public AstWriteConfigNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visit(parser.writeHttpStatusNode());
        }
    };

    public static final ScriptParseStrategy READ_CLOSED = new ScriptParseStrategy() {
        @Override
        public AstReadClosedNode parse(RobotParser parser,
                                             ExpressionFactory elFactory,
                                             ExpressionContext elContext) throws RecognitionException {
            return new AstReadClosedNodeVisitor(elFactory, elContext).visit(parser.readClosedNode());
        }
    };

    public static final ScriptParseStrategy WRITE_CLOSE = new ScriptParseStrategy() {
        @Override
        public AstWriteCloseNode parse(RobotParser parser,
                                              ExpressionFactory elFactory,
                                              ExpressionContext elContext) throws RecognitionException {
            return new AstWriteCloseNodeVisitor(elFactory, elContext).visit(parser.writeCloseNode());
        }
    };

    public static final ScriptParseStrategy UNBOUND = new ScriptParseStrategy() {
        @Override
        public AstUnboundNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstUnboundNodeVisitor(elFactory, elContext).visit(parser.unboundNode());
        }
    };

    public static final ScriptParseStrategy READ_AWAIT = new ScriptParseStrategy() {
        @Override
        public AstReadAwaitNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstReadAwaitNodeVisitor(elFactory, elContext).visit(parser.readAwaitNode());
        }
    };

    public static final ScriptParseStrategy READ_NOTIFY = new ScriptParseStrategy() {
        @Override
        public AstReadNotifyNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstReadNotifyNodeVisitor(elFactory, elContext).visit(parser.readNotifyNode());
        }
    };

    public static final ScriptParseStrategy WRITE_AWAIT = new ScriptParseStrategy() {
        @Override
        public AstWriteAwaitNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstWriteAwaitNodeVisitor(elFactory, elContext).visit(parser.writeAwaitNode());
        }
    };

    public static final ScriptParseStrategy WRITE_NOTIFY = new ScriptParseStrategy() {
        @Override
        public AstWriteNotifyNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstWriteNotifyNodeVisitor(elFactory, elContext).visit(parser.writeNotifyNode());
        }
    };

    public static final ScriptParseStrategy MATCHER = new ScriptParseStrategy() {
        @Override
        public AstValueMatcher parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstValueMatcherVisitor(elFactory, elContext).visit(parser.matcher());
        }
    };

    public static final ScriptParseStrategy EXACT_TEXT_MATCHER = new ScriptParseStrategy() {
        @Override
        public AstExactTextMatcher parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstExactTextMatcherVisitor(elFactory, elContext).visit(parser.exactTextMatcher());
        }
    };

    public static final ScriptParseStrategy EXACT_BYTES_MATCHER = new ScriptParseStrategy() {
        @Override
        public AstExactBytesMatcher parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstExactBytesMatcherVisitor(elFactory, elContext).visit(parser.exactBytesMatcher());
        }
    };

    public static final ScriptParseStrategy REGEX_MATCHER = new ScriptParseStrategy() {
        @Override
        public AstRegexMatcher parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstRegexMatcherVisitor(elFactory, elContext).visit(parser.regexMatcher());
        }
    };

    public static final ScriptParseStrategy EXPRESSION_MATCHER = new ScriptParseStrategy() {
        @Override
        public AstExpressionMatcher parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstExpressionMatcherVisitor(elFactory, elContext).visit(parser.expressionMatcher());
        }
    };

    public static final ScriptParseStrategy FIXED_LENGTH_BYTES_MATCHER = new ScriptParseStrategy() {
        @Override
        public AstFixedLengthBytesMatcher parse(RobotParser parser,
                                                ExpressionFactory elFactory,
                                                ExpressionContext elContext) throws RecognitionException {
            return new AstFixedLengthBytesMatcherVisitor(elFactory, elContext).visit(parser.fixedLengthBytesMatcher());
        }
    };

    public static final ScriptParseStrategy VARIABLE_LENGTH_BYTES_MATCHER = new ScriptParseStrategy() {
        @Override
        public AstVariableLengthBytesMatcher parse(RobotParser parser,
                                                   ExpressionFactory elFactory,
                                                   ExpressionContext elContext) throws RecognitionException {
            return new AstVariableLengthBytesMatcherVisitor(elFactory, elContext).visit(parser
                    .variableLengthBytesMatcher());
        }
    };

    public static final ScriptParseStrategy VALUE = new ScriptParseStrategy() {
        @Override
        public AstValue parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstValueVisitor(elFactory, elContext).visit(parser.writeValue());
        }
    };

    public static final ScriptParseStrategy LITERAL_TEXT_VALUE = new ScriptParseStrategy() {
        @Override
        public AstLiteralTextValue parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstLiteralTextValueVisitor(elFactory, elContext).visit(parser.literalText());
        }
    };

    public static final ScriptParseStrategy LITERAL_BYTES_VALUE = new ScriptParseStrategy() {
        @Override
        public AstLiteralBytesValue parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstLiteralBytesValueVisitor(elFactory, elContext).visit(parser.literalBytes());
        }
    };

    public static final ScriptParseStrategy EXPRESSION_VALUE = new ScriptParseStrategy() {
        @Override
        public AstExpressionValue parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return new AstExpressionValueVisitor(elFactory, elContext).visit(parser.expressionValue());
        }
    };

    public static final ScriptParseStrategy READ_OPTION = new ScriptParseStrategy() {
        @Override
        public AstReadOptionNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return (AstReadOptionNode) new AstOptionNodeVisitor(elFactory, elContext).visit(parser.readOptionNode());
        }
    };

    public static final ScriptParseStrategy WRITE_OPTION = new ScriptParseStrategy() {
        @Override
        public AstWriteOptionNode parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
                throws RecognitionException {
            return (AstWriteOptionNode) new AstOptionNodeVisitor(elFactory, elContext).visit(parser.writeOptionNode());
        }
    };

    public abstract T parse(RobotParser parser, ExpressionFactory elFactory, ExpressionContext elContext)
            throws RecognitionException;

    private static class AstVisitor extends RobotBaseVisitor {
        protected final ExpressionFactory elFactory;
        protected final ExpressionContext elContext;

        protected AstVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            this.elFactory = elFactory;
            this.elContext = elContext;
        }
    }

    private static class AstNodeVisitor extends AstVisitor {
        protected T node;

        public AstNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        protected T defaultResult() {
            return node;
        }
    }

    private static class AstScriptNodeVisitor extends AstNodeVisitor {

        public AstScriptNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstScriptNode visitScriptNode(ScriptNodeContext ctx) {
            node = new AstScriptNode();
            return super.visitScriptNode(ctx);
        }

        @Override
        public AstScriptNode visitStreamNode(StreamNodeContext ctx) {
            AstStreamNodeVisitor visitor = new AstStreamNodeVisitor(elFactory, elContext);
            AstStreamNode streamNode = visitor.visitStreamNode(ctx);
            node.getStreams().add(streamNode);
            return node;
        }

    }

    private static class AstStreamNodeVisitor extends AstNodeVisitor {

        public AstStreamNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstAcceptNode visitAcceptNode(AcceptNodeContext ctx) {
            return new AstAcceptNodeVisitor(elFactory, elContext).visitAcceptNode(ctx);
        }

        @Override
        public AstAcceptableNode visitAcceptableNode(AcceptableNodeContext ctx) {
            return new AstAcceptedNodeVisitor(elFactory, elContext).visitAcceptableNode(ctx);
        }

        @Override
        public AstConnectNode visitConnectNode(ConnectNodeContext ctx) {
            return new AstConnectNodeVisitor(elFactory, elContext).visitConnectNode(ctx);
        }

    }

    private static class AstAcceptNodeVisitor extends AstNodeVisitor {

        public AstAcceptNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstAcceptNode visitAcceptNode(AcceptNodeContext ctx) {
            node = new AstAcceptNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setLocation(URI.create(ctx.acceptURI.getText()));
            if (ctx.text != null) {
                node.setAcceptName(ctx.text.getText());
            }
            return super.visitAcceptNode(ctx);
        }

        @Override
        public AstAcceptNode visitServerStreamableNode(ServerStreamableNodeContext ctx) {
            AstStreamableNodeVisitor visitor = new AstStreamableNodeVisitor(elFactory, elContext);
            AstStreamableNode streamable = visitor.visitServerStreamableNode(ctx);
            node.getStreamables().add(streamable);
            return node;
        }

    }

    private static class AstAcceptedNodeVisitor extends AstNodeVisitor {

        public AstAcceptedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstAcceptableNode visitAcceptableNode(AcceptableNodeContext ctx) {
            node = new AstAcceptableNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            if (ctx.text != null) {
                node.setAcceptName(ctx.text.getText());
            }
            return super.visitAcceptableNode(ctx);
        }

        @Override
        public AstAcceptableNode visitStreamableNode(StreamableNodeContext ctx) {
            AstStreamableNodeVisitor visitor = new AstStreamableNodeVisitor(elFactory, elContext);
            AstStreamableNode streamable = visitor.visitStreamableNode(ctx);
            node.getStreamables().add(streamable);
            return node;
        }

    }

    private static class AstConnectNodeVisitor extends AstNodeVisitor {

        public AstConnectNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
            // TODO Auto-generated constructor stub
        }

        @Override
        public AstConnectNode visitConnectNode(ConnectNodeContext ctx) {
            node = new AstConnectNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setLocation(URI.create(ctx.connectURI.getText()));
            return super.visitConnectNode(ctx);
        }

        @Override
        public AstConnectNode visitStreamableNode(StreamableNodeContext ctx) {
            AstStreamableNodeVisitor visitor = new AstStreamableNodeVisitor(elFactory, elContext);
            AstStreamableNode streamable = visitor.visitStreamableNode(ctx);
            node.getStreamables().add(streamable);
            return node;
        }

    }

    private static class AstStreamableNodeVisitor extends AstNodeVisitor {

        public AstStreamableNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstBarrierNode visitBarrierNode(BarrierNodeContext ctx) {
            return new AstBarrierNodeVisitor(elFactory, elContext).visitBarrierNode(ctx);
        }

        @Override
        public AstEventNode visitEventNode(EventNodeContext ctx) {
            return new AstEventNodeVisitor(elFactory, elContext).visitEventNode(ctx);
        }

        @Override
        public AstCommandNode visitCommandNode(CommandNodeContext ctx) {
            return new AstCommandNodeVisitor(elFactory, elContext).visitCommandNode(ctx);
        }

        @Override
        public AstOptionNode visitOptionNode(OptionNodeContext ctx) {
            return new AstOptionNodeVisitor(elFactory, elContext).visitOptionNode(ctx);
        }

    }

    // Not needed as of now as very similar to StreamableNodeVisitor except for unsupported features
    // private static class AstServerStreamableNodeVisitor extends AstNodeVisitor {
    //
    // public AstServerStreamableNodeVisitor(ExpressionFactory elFactory,
    // ExpressionContext elContext) {
    // super(elFactory, elContext);
    // }
    //
    // }

    private static class AstOptionNodeVisitor extends AstNodeVisitor {

        public AstOptionNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstOptionNode visitReadOptionNode(ReadOptionNodeContext ctx) {
            node = new AstReadOptionNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setOptionName(ctx.name.getText());
            AstValue value = new AstValueVisitor(elFactory, elContext).visit(ctx);
            node.setOptionValue(value);
            return node;
        }

        @Override
        public AstOptionNode visitWriteOptionNode(WriteOptionNodeContext ctx) {
            node = new AstWriteOptionNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setOptionName(ctx.name.getText());
            AstValue value = new AstValueVisitor(elFactory, elContext).visit(ctx);
            node.setOptionValue(value);
            return node;
        }
    }

    private static class AstBarrierNodeVisitor extends AstNodeVisitor {

        public AstBarrierNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstReadAwaitNode visitReadAwaitNode(ReadAwaitNodeContext ctx) {
            return new AstReadAwaitNodeVisitor(elFactory, elContext).visitReadAwaitNode(ctx);
        }

        @Override
        public AstReadNotifyNode visitReadNotifyNode(ReadNotifyNodeContext ctx) {
            return new AstReadNotifyNodeVisitor(elFactory, elContext).visitReadNotifyNode(ctx);
        }

        @Override
        public AstWriteAwaitNode visitWriteAwaitNode(WriteAwaitNodeContext ctx) {
            return new AstWriteAwaitNodeVisitor(elFactory, elContext).visitWriteAwaitNode(ctx);
        }

        @Override
        public AstWriteNotifyNode visitWriteNotifyNode(WriteNotifyNodeContext ctx) {
            return new AstWriteNotifyNodeVisitor(elFactory, elContext).visitWriteNotifyNode(ctx);
        }

    }

    private static class AstEventNodeVisitor extends AstNodeVisitor {

        public AstEventNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstBoundNode visitBoundNode(BoundNodeContext ctx) {
            return new AstBoundNodeVisitor(elFactory, elContext).visitBoundNode(ctx);
        }

        @Override
        public AstClosedNode visitClosedNode(ClosedNodeContext ctx) {
            return new AstClosedNodeVisitor(elFactory, elContext).visitClosedNode(ctx);
        }

        @Override
        public AstConnectedNode visitConnectedNode(ConnectedNodeContext ctx) {
            return new AstConnectedNodeVisitor(elFactory, elContext).visitConnectedNode(ctx);
        }

        @Override
        public AstDisconnectedNode visitDisconnectedNode(DisconnectedNodeContext ctx) {
            return new AstDisconnectedNodeVisitor(elFactory, elContext).visitDisconnectedNode(ctx);
        }

        @Override
        public AstOpenedNode visitOpenedNode(OpenedNodeContext ctx) {
            return new AstOpenedNodeVisitor(elFactory, elContext).visitOpenedNode(ctx);
        }

        @Override
        public AstReadValueNode visitReadNode(ReadNodeContext ctx) {
            return new AstReadValueNodeVisitor(elFactory, elContext).visitReadNode(ctx);
        }

        @Override
        public AstReadClosedNode visitReadClosedNode(ReadClosedNodeContext ctx) {
            return new AstReadClosedNodeVisitor(elFactory, elContext).visitReadClosedNode(ctx);
        }

        @Override
        public AstUnboundNode visitUnboundNode(UnboundNodeContext ctx) {
            return new AstUnboundNodeVisitor(elFactory, elContext).visitUnboundNode(ctx);
        }

        // HTTP events

        @Override
        public AstReadConfigNode visitReadHttpHeaderNode(ReadHttpHeaderNodeContext ctx) {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visitReadHttpHeaderNode(ctx);
        }

        @Override
        public AstReadConfigNode visitReadHttpMethodNode(ReadHttpMethodNodeContext ctx) {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visitReadHttpMethodNode(ctx);
        }

        @Override
        public AstReadConfigNode visitReadHttpParameterNode(ReadHttpParameterNodeContext ctx) {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visitReadHttpParameterNode(ctx);
        }

        @Override
        public AstReadConfigNode visitReadHttpVersionNode(ReadHttpVersionNodeContext ctx) {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visitReadHttpVersionNode(ctx);
        }

        @Override
        public AstReadConfigNode visitReadHttpStatusNode(ReadHttpStatusNodeContext ctx) {
            return new AstReadHttpConfigNodeVisitor(elFactory, elContext).visitReadHttpStatusNode(ctx);
        }

    }

    private static class AstCommandNodeVisitor extends AstNodeVisitor {

        public AstCommandNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstUnbindNode visitUnbindNode(UnbindNodeContext ctx) {
            return new AstUnbindNodeVisitor(elFactory, elContext).visitUnbindNode(ctx);
        }

        @Override
        public AstWriteValueNode visitWriteNode(WriteNodeContext ctx) {
            return new AstWriteValueNodeVisitor(elFactory, elContext).visitWriteNode(ctx);
        }

        @Override
        public AstWriteCloseNode visitWriteCloseNode(WriteCloseNodeContext ctx) {
            return new AstWriteCloseNodeVisitor(elFactory, elContext).visitWriteCloseNode(ctx);
        }

        @Override
        public AstCloseNode visitCloseNode(CloseNodeContext ctx) {
            return new AstCloseNodeVisitor(elFactory, elContext).visitCloseNode(ctx);
        }

        // HTTP commands

        @Override
        public AstWriteConfigNode visitWriteHttpHeaderNode(WriteHttpHeaderNodeContext ctx) {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visitWriteHttpHeaderNode(ctx);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpContentLengthNode(WriteHttpContentLengthNodeContext ctx) {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visitWriteHttpContentLengthNode(ctx);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpMethodNode(WriteHttpMethodNodeContext ctx) {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visitWriteHttpMethodNode(ctx);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpParameterNode(WriteHttpParameterNodeContext ctx) {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visitWriteHttpParameterNode(ctx);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpVersionNode(WriteHttpVersionNodeContext ctx) {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visitWriteHttpVersionNode(ctx);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpStatusNode(WriteHttpStatusNodeContext ctx) {
            return new AstWriteConfigNodeVisitor(elFactory, elContext).visitWriteHttpStatusNode(ctx);
        }

    }

    private static class AstCloseNodeVisitor extends AstNodeVisitor {

        public AstCloseNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstCloseNode visitCloseNode(CloseNodeContext ctx) {
            node = new AstCloseNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstDisconnectNodeVisitor extends AstNodeVisitor {

        public AstDisconnectNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstDisconnectNode visitDisconnectNode(DisconnectNodeContext ctx) {
            node = new AstDisconnectNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstUnbindNodeVisitor extends AstNodeVisitor {

        public AstUnbindNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstUnbindNode visitUnbindNode(UnbindNodeContext ctx) {
            node = new AstUnbindNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstWriteValueNodeVisitor extends AstNodeVisitor {

        private List values;

        public AstWriteValueNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstWriteValueNode visitWriteNode(WriteNodeContext ctx) {
            node = new AstWriteValueNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            values = new LinkedList<>();
            AstWriteValueNode result = super.visitWriteNode(ctx);
            node.setValues(values);
            return result;
        }

        @Override
        public AstWriteValueNode visitWriteValue(WriteValueContext ctx) {
            AstValue value = new AstValueVisitor(elFactory, elContext).visit(ctx);
            values.add(value);
            return node;
        }
    }

    private static class AstChildOpenedNodeVisitor extends AstNodeVisitor {

        public AstChildOpenedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstChildOpenedNode visitChildOpenedNode(ChildOpenedNodeContext ctx) {
            node = new AstChildOpenedNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstChildClosedNodeVisitor extends AstNodeVisitor {

        public AstChildClosedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstChildClosedNode visitChildClosedNode(ChildClosedNodeContext ctx) {
            node = new AstChildClosedNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstBoundNodeVisitor extends AstNodeVisitor {

        public AstBoundNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstBoundNode visitBoundNode(BoundNodeContext ctx) {
            node = new AstBoundNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstClosedNodeVisitor extends AstNodeVisitor {

        public AstClosedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstClosedNode visitClosedNode(ClosedNodeContext ctx) {
            node = new AstClosedNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstConnectedNodeVisitor extends AstNodeVisitor {

        public AstConnectedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstConnectedNode visitConnectedNode(ConnectedNodeContext ctx) {
            node = new AstConnectedNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstDisconnectedNodeVisitor extends AstNodeVisitor {

        public AstDisconnectedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstDisconnectedNode visitDisconnectedNode(DisconnectedNodeContext ctx) {
            node = new AstDisconnectedNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstOpenedNodeVisitor extends AstNodeVisitor {

        public AstOpenedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstOpenedNode visitOpenedNode(OpenedNodeContext ctx) {
            node = new AstOpenedNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstReadValueNodeVisitor extends AstNodeVisitor {

        private List matchers;

        public AstReadValueNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstReadValueNode visitReadNode(ReadNodeContext ctx) {
            node = new AstReadValueNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            matchers = new LinkedList<>();
            AstReadValueNode result = super.visitReadNode(ctx);
            node.setMatchers(matchers);
            return result;
        }

        @Override
        public AstReadValueNode visitMatcher(MatcherContext ctx) {
            AstValueMatcher matcher = new AstValueMatcherVisitor(elFactory, elContext).visit(ctx);
            matchers.add(matcher);
            return node;
        }

    }

    private static class AstUnboundNodeVisitor extends AstNodeVisitor {

        public AstUnboundNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstUnboundNode visitUnboundNode(UnboundNodeContext ctx) {
            node = new AstUnboundNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstReadAwaitNodeVisitor extends AstNodeVisitor {

        public AstReadAwaitNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstReadAwaitNode visitReadAwaitNode(ReadAwaitNodeContext ctx) {
            node = new AstReadAwaitNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setBarrierName(ctx.barrier.getText());
            return node;
        }

    }

    private static class AstReadNotifyNodeVisitor extends AstNodeVisitor {

        public AstReadNotifyNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstReadNotifyNode visitReadNotifyNode(ReadNotifyNodeContext ctx) {
            node = new AstReadNotifyNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setBarrierName(ctx.barrier.getText());
            return node;
        }

    }

    private static class AstWriteAwaitNodeVisitor extends AstNodeVisitor {

        public AstWriteAwaitNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstWriteAwaitNode visitWriteAwaitNode(WriteAwaitNodeContext ctx) {
            node = new AstWriteAwaitNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setBarrierName(ctx.barrier.getText());
            return node;
        }

    }

    private static class AstWriteNotifyNodeVisitor extends AstNodeVisitor {

        public AstWriteNotifyNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstWriteNotifyNode visitWriteNotifyNode(WriteNotifyNodeContext ctx) {
            node = new AstWriteNotifyNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setBarrierName(ctx.barrier.getText());
            return node;
        }

    }

    private static class AstValueMatcherVisitor extends AstVisitor {

        public AstValueMatcherVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstExactTextMatcher visitExactTextMatcher(ExactTextMatcherContext ctx) {
            return new AstExactTextMatcherVisitor(elFactory, elContext).visit(ctx);
        }

        @Override
        public AstExactBytesMatcher visitExactBytesMatcher(ExactBytesMatcherContext ctx) {
            return new AstExactBytesMatcherVisitor(elFactory, elContext).visit(ctx);
        }

        @Override
        public AstRegexMatcher visitRegexMatcher(RegexMatcherContext ctx) {
            return new AstRegexMatcherVisitor(elFactory, elContext).visit(ctx);
        }

        @Override
        public AstExpressionMatcher visitExpressionMatcher(ExpressionMatcherContext ctx) {
            return new AstExpressionMatcherVisitor(elFactory, elContext).visit(ctx);
        }

        @Override
        public AstFixedLengthBytesMatcher visitFixedLengthBytesMatcher(FixedLengthBytesMatcherContext ctx) {
            return new AstFixedLengthBytesMatcherVisitor(elFactory, elContext).visit(ctx);
        }

        @Override
        public AstVariableLengthBytesMatcher visitVariableLengthBytesMatcher(VariableLengthBytesMatcherContext ctx) {
            return new AstVariableLengthBytesMatcherVisitor(elFactory, elContext).visit(ctx);
        }

    }

    private static class AstExactTextMatcherVisitor extends AstVisitor {

        public AstExactTextMatcherVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstExactTextMatcher visitExactTextMatcher(ExactTextMatcherContext ctx) {
            String text = ctx.text.getText();
            String textWithoutQuote = text.substring(1, text.length() - 1);
            String escapedText = escapeString(textWithoutQuote);
            return new AstExactTextMatcher(escapedText);
        }

    }

    private static class AstExactBytesMatcherVisitor extends AstVisitor {

        public AstExactBytesMatcherVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstExactBytesMatcher visitExactBytesMatcher(ExactBytesMatcherContext ctx) {
            if (ctx.bytes != null) {
                byte[] array = parseHexBytes(ctx.bytes.getText());
                return new AstExactBytesMatcher(array);
            } else if (ctx.byteLiteral != null) {
                byte[] array = parseHexBytes(ctx.byteLiteral.getText());
                return new AstExactBytesMatcher(array);
            } else if (ctx.shortLiteral != null) {
                byte[] array = parseHexBytes(ctx.shortLiteral.getText());
                return new AstExactBytesMatcher(array);
            } else if (ctx.longLiteral != null) {
                ByteBuffer buf = ByteBuffer.allocate(Long.SIZE / 8);
                buf.putLong(Long.parseLong(ctx.longLiteral.getText()));
                byte[] array = buf.array();
                return new AstExactBytesMatcher(array);
            } else if (ctx.intLiteral != null) {
                ByteBuffer buf = ByteBuffer.allocate(Integer.SIZE / 8);
                buf.putInt(Integer.parseInt(ctx.intLiteral.getText()));
                byte[] array = buf.array();
                return new AstExactBytesMatcher(array);
            }

            return null;
        }

    }

    private static class AstRegexMatcherVisitor extends AstVisitor {

        public AstRegexMatcherVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstRegexMatcher visitRegexMatcher(RegexMatcherContext ctx) {
            String regex = ctx.regex.getText();
            return new AstRegexMatcher(NamedGroupPattern.compile(regex));
        }

    }

    private static class AstExpressionMatcherVisitor extends AstVisitor {

        public AstExpressionMatcherVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstExpressionMatcher visitExpressionMatcher(ExpressionMatcherContext ctx) {
            ValueExpression expression = elFactory.createValueExpression(elContext, ctx.expression.getText(),
                    byte[].class);
            return new AstExpressionMatcher(expression);
        }

    }

    private static class AstFixedLengthBytesMatcherVisitor extends AstVisitor {

        public AstFixedLengthBytesMatcherVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstFixedLengthBytesMatcher visitFixedLengthBytesMatcher(FixedLengthBytesMatcherContext ctx) {
            if (ctx.lastIndex != null) {
                String lastIndex = ctx.lastIndex.getText();
                if (ctx.capture != null) {
                    String capture = ctx.capture.getText();
                    return new AstFixedLengthBytesMatcher(parseInt(lastIndex), capture.substring(1, capture.length()));
                } else {
                    return new AstFixedLengthBytesMatcher(parseInt(lastIndex));
                }
            } else if (ctx.byteCapture != null) {
                String byteCapture = ctx.byteCapture.getText();
                return new AstByteLengthBytesMatcher(byteCapture.substring(1));
            } else if (ctx.shortCapture != null) {
                String shortCapture = ctx.shortCapture.getText();
                return new AstShortLengthBytesMatcher(shortCapture.substring(1));
            } else if (ctx.intCapture != null) {
                String intCapture = ctx.intCapture.getText();
                return new AstIntLengthBytesMatcher(intCapture.substring(1));
            } else if (ctx.longCapture != null) {
                String longCapture = ctx.longCapture.getText();
                return new AstLongLengthBytesMatcher(longCapture.substring(1));
            }

            return null;
        }

    }

    private static class AstVariableLengthBytesMatcherVisitor extends AstVisitor {

        public AstVariableLengthBytesMatcherVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstVariableLengthBytesMatcher visitVariableLengthBytesMatcher(VariableLengthBytesMatcherContext ctx) {
            ValueExpression length = elFactory.createValueExpression(elContext, ctx.length.getText(), Integer.class);
            if (ctx.capture != null) {
                String capture = ctx.capture.getText();
                return new AstVariableLengthBytesMatcher(length, capture.substring(1));
            } else {
                return new AstVariableLengthBytesMatcher(length);
            }
        }
    }

    private static class AstValueVisitor extends AstVisitor {

        public AstValueVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstValue visitLiteralBytes(LiteralBytesContext ctx) {
            return new AstLiteralBytesValueVisitor(elFactory, elContext).visit(ctx);
        }

        @Override
        public AstValue visitLiteralText(LiteralTextContext ctx) {
            return new AstLiteralTextValueVisitor(elFactory, elContext).visit(ctx);
        }

        @Override
        public AstValue visitExpressionValue(ExpressionValueContext ctx) {
            return new AstExpressionValueVisitor(elFactory, elContext).visit(ctx);
        }

    }

    private static class AstLiteralTextValueVisitor extends AstVisitor {

        public AstLiteralTextValueVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstLiteralTextValue visitLiteralText(LiteralTextContext ctx) {
            String text = ctx.text.getText();
            String textWithoutQuotes = text.substring(1, text.length() - 1);
            String escapedText = escapeString(textWithoutQuotes);
            return new AstLiteralTextValue(escapedText);
        }

    }

    private static class AstLiteralBytesValueVisitor extends AstVisitor {

        public AstLiteralBytesValueVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstLiteralBytesValue visitLiteralBytes(LiteralBytesContext ctx) {
            String bytes = ctx.bytes.getText();
            return new AstLiteralBytesValue(parseHexBytes(bytes));
        }

    }

    private static class AstExpressionValueVisitor extends AstVisitor {

        public AstExpressionValueVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstExpressionValue visitExpressionValue(ExpressionValueContext ctx) {
            ValueExpression expression = elFactory.createValueExpression(elContext, ctx.expression.getText(),
                    byte[].class);
            return new AstExpressionValue(expression);
        }

    }

    // HTTP visitors

    private static class AstReadHttpConfigNodeVisitor extends AstNodeVisitor {

        public AstReadHttpConfigNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstReadConfigNode visitReadHttpMethodNode(ReadHttpMethodNodeContext ctx) {
            node = new AstReadConfigNode();
            node.setType("method");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setMatcher("name", new AstValueMatcherVisitor(elFactory, elContext).visit(ctx.method));
            return node;
        }

        @Override
        public AstReadConfigNode visitReadHttpHeaderNode(ReadHttpHeaderNodeContext ctx) {
            node = new AstReadConfigNode();
            node.setType("header");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setValue("name", new AstLiteralTextValueVisitor(elFactory, elContext).visit(ctx.name));
            return super.visitReadHttpHeaderNode(ctx);
        }

        @Override
        public AstReadConfigNode visitReadHttpParameterNode(ReadHttpParameterNodeContext ctx) {
            node = new AstReadConfigNode();
            node.setType("parameter");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setValue("name", new AstLiteralTextValueVisitor(elFactory, elContext).visit(ctx.name));
            return super.visitReadHttpParameterNode(ctx);
        }

        @Override
        public AstReadConfigNode visitReadHttpStatusNode(ReadHttpStatusNodeContext ctx) {
            node = new AstReadConfigNode();
            node.setType("status");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setMatcher("code", new AstValueMatcherVisitor(elFactory, elContext).visit(ctx.code));
            node.setMatcher("reason", new AstValueMatcherVisitor(elFactory, elContext).visit(ctx.reason));
            return node;
        }

        @Override
        public AstReadConfigNode visitReadHttpVersionNode(ReadHttpVersionNodeContext ctx) {
            node = new AstReadConfigNode();
            node.setType("version");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setMatcher("version", new AstValueMatcherVisitor(elFactory, elContext).visit(ctx.version));
            return node;
        }

        @Override
        public AstReadConfigNode visitMatcher(MatcherContext ctx) {
            AstValueMatcher matcher = new AstValueMatcherVisitor(elFactory, elContext).visit(ctx);
            node.addMatcher(matcher);
            return node;
        }

    }

    private static class AstWriteConfigNodeVisitor extends AstNodeVisitor {

        public AstWriteConfigNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpHeaderNode(WriteHttpHeaderNodeContext ctx) {
            node = new AstWriteConfigNode();
            node.setType("header");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setName("name", new AstValueVisitor(elFactory, elContext).visit(ctx.name));
            return super.visitWriteHttpHeaderNode(ctx);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpContentLengthNode(WriteHttpContentLengthNodeContext ctx) {
            node = new AstWriteConfigNode();
            node.setType("content-length");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

        @Override
        public AstWriteConfigNode visitWriteHttpMethodNode(WriteHttpMethodNodeContext ctx) {
            node = new AstWriteConfigNode();
            node.setType("method");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.addValue(new AstValueVisitor(elFactory, elContext).visit(ctx.method));
            return node;
        }

        @Override
        public AstWriteConfigNode visitWriteHttpParameterNode(WriteHttpParameterNodeContext ctx) {
            node = new AstWriteConfigNode();
            node.setType("parameter");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setName("name", new AstValueVisitor(elFactory, elContext).visit(ctx.name));
            return super.visitWriteHttpParameterNode(ctx);
        }

        @Override
        public AstWriteConfigNode visitWriteHttpVersionNode(WriteHttpVersionNodeContext ctx) {
            node = new AstWriteConfigNode();
            node.setType("version");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.addValue(new AstValueVisitor(elFactory, elContext).visit(ctx.version));
            return node;
        }

        @Override
        public AstWriteConfigNode visitWriteHttpStatusNode(WriteHttpStatusNodeContext ctx) {
            node = new AstWriteConfigNode();
            node.setType("status");
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            node.setValue("code", new AstValueVisitor(elFactory, elContext).visit(ctx.code));
            node.setValue("reason", new AstValueVisitor(elFactory, elContext).visit(ctx.reason));
            return node;
        }

        @Override
        public AstWriteConfigNode visitWriteValue(WriteValueContext ctx) {
            AstValue value = new AstValueVisitor(elFactory, elContext).visit(ctx);
            node.addValue(value);
            return node;
        }
    }

    private static class AstReadClosedNodeVisitor extends AstNodeVisitor {

        public AstReadClosedNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstReadClosedNode visitReadClosedNode(ReadClosedNodeContext ctx) {
            node = new AstReadClosedNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static class AstWriteCloseNodeVisitor extends AstNodeVisitor {

        public AstWriteCloseNodeVisitor(ExpressionFactory elFactory, ExpressionContext elContext) {
            super(elFactory, elContext);
        }

        @Override
        public AstWriteCloseNode visitWriteCloseNode(WriteCloseNodeContext ctx) {
            node = new AstWriteCloseNode();
            node.setLocationInfo(ctx.k.getLine(), ctx.k.getCharPositionInLine());
            return node;
        }

    }

    private static String escapeString(String toEscape) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < toEscape.length(); i++) {
            char current = toEscape.charAt(i);
            if (current == '\\') {
                char next = toEscape.charAt(i + 1);
                switch (next) {
                case 'b':
                    sb.append('\b');
                    break;
                case 'f':
                    sb.append('\f');
                    break;
                case 'r':
                    sb.append('\r');
                    break;
                case 'n':
                    sb.append('\n');
                    break;
                case 't':
                    sb.append('\t');
                    break;
                case '"':
                    sb.append('"');
                    break;
                case '\'':
                    sb.append('\'');
                    break;
                case '\\':
                    sb.append('\\');
                    break;
                default:
                    // parser will handle out of bounds errors here so we don't need to check
                    // throw new Exception("escaping unescapable character"); will ruin the method signature
                    // of the visitor
                    assert false;
                }
                i++;
            } else {
                sb.append(current);
            }
        }
        return sb.toString();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy