public List<Pipeline> parsePipelines(String pipelines) throws ParseException {
        final ParseContext parseContext = new ParseContext(false);
        final SyntaxErrorListener errorListener = new SyntaxErrorListener(parseContext);

        final RuleLangLexer lexer = new RuleLangLexer(new ANTLRInputStream(pipelines));
        lexer.removeErrorListeners();
        lexer.addErrorListener(errorListener);

        final RuleLangParser parser = new RuleLangParser(new CommonTokenStream(lexer));
        parser.setErrorHandler(new DefaultErrorStrategy());
        parser.removeErrorListeners();
        parser.addErrorListener(errorListener);

        final RuleLangParser.PipelineDeclsContext pipelineDeclsContext = parser.pipelineDecls();

        WALKER.walk(new PipelineAstBuilder(parseContext), pipelineDeclsContext);

        if (parseContext.getErrors().isEmpty()) {
            return parseContext.pipelines;
        }
        throw new ParseException(parseContext.getErrors());
    }
@Test
    void pipelineDeclaration() throws Exception {
        final List<Pipeline> pipelines = parser.parsePipelines(ruleForTest());
        assertEquals(1, pipelines.size());
        final Pipeline pipeline = Iterables.getOnlyElement(pipelines);
        assertEquals("cisco", pipeline.name());
        assertEquals(2, pipeline.stages().size());
        final Stage stage1 = pipeline.stages().first();
        final Stage stage2 = pipeline.stages().last();

        assertEquals(Stage.Match.ALL, stage1.match());
        assertEquals(1, stage1.stage());
        assertArrayEquals(new Object[]{"check_ip_whitelist", "cisco_device"}, stage1.ruleReferences().toArray());

        assertEquals(Stage.Match.EITHER, stage2.match());
        assertEquals(2, stage2.stage());
        assertArrayEquals(new Object[]{"parse_cisco_time", "extract_src_dest", "normalize_src_dest", "lookup_ips", "resolve_ips"}, stage2.ruleReferences().toArray());
    }