Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* 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
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* .
*/
package org.graylog.plugins.pipelineprocessor.parser;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.swrve.ratelimitedlogger.RateLimitedLog;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.DefaultErrorStrategy;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTreeProperty;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.mina.util.IdentityHashSet;
import org.graylog.plugins.pipelineprocessor.ast.Pipeline;
import org.graylog.plugins.pipelineprocessor.ast.Rule;
import org.graylog.plugins.pipelineprocessor.ast.Stage;
import org.graylog.plugins.pipelineprocessor.ast.exceptions.PrecomputeFailure;
import org.graylog.plugins.pipelineprocessor.ast.expressions.AdditionExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.AndExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.ArrayLiteralExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.BinaryExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.BooleanExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.BooleanValuedFunctionWrapper;
import org.graylog.plugins.pipelineprocessor.ast.expressions.ComparisonExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.DoubleExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.EqualityExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.Expression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.FieldAccessExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.FieldRefExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.FunctionExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.IndexedAccessExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.LogicalExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.LongExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.MapLiteralExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.MessageRefExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.MultiplicationExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.NotExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.OrExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.SignedExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.StringExpression;
import org.graylog.plugins.pipelineprocessor.ast.expressions.VarRefExpression;
import org.graylog.plugins.pipelineprocessor.ast.functions.Function;
import org.graylog.plugins.pipelineprocessor.ast.functions.FunctionArgs;
import org.graylog.plugins.pipelineprocessor.ast.functions.FunctionDescriptor;
import org.graylog.plugins.pipelineprocessor.ast.functions.ParameterDescriptor;
import org.graylog.plugins.pipelineprocessor.ast.statements.FunctionStatement;
import org.graylog.plugins.pipelineprocessor.ast.statements.Statement;
import org.graylog.plugins.pipelineprocessor.ast.statements.VarAssignStatement;
import org.graylog.plugins.pipelineprocessor.parser.errors.IncompatibleArgumentType;
import org.graylog.plugins.pipelineprocessor.parser.errors.IncompatibleIndexType;
import org.graylog.plugins.pipelineprocessor.parser.errors.IncompatibleType;
import org.graylog.plugins.pipelineprocessor.parser.errors.IncompatibleTypes;
import org.graylog.plugins.pipelineprocessor.parser.errors.InvalidFunctionArgument;
import org.graylog.plugins.pipelineprocessor.parser.errors.InvalidOperation;
import org.graylog.plugins.pipelineprocessor.parser.errors.MissingRequiredParam;
import org.graylog.plugins.pipelineprocessor.parser.errors.NonIndexableType;
import org.graylog.plugins.pipelineprocessor.parser.errors.OptionalParametersMustBeNamed;
import org.graylog.plugins.pipelineprocessor.parser.errors.ParseError;
import org.graylog.plugins.pipelineprocessor.parser.errors.SyntaxError;
import org.graylog.plugins.pipelineprocessor.parser.errors.UndeclaredFunction;
import org.graylog.plugins.pipelineprocessor.parser.errors.UndeclaredVariable;
import org.graylog.plugins.pipelineprocessor.parser.errors.WrongNumberOfArgs;
import org.graylog2.plugin.Message;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Period;
import javax.inject.Inject;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import static com.google.common.collect.ImmutableSortedSet.orderedBy;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.toList;
import static org.graylog.plugins.pipelineprocessor.processors.PipelineInterpreter.getRateLimitedLog;
public class PipelineRuleParser {
private final FunctionRegistry functionRegistry;
private static AtomicLong uniqueId = new AtomicLong(0);
@Inject
public PipelineRuleParser(FunctionRegistry functionRegistry) {
this.functionRegistry = functionRegistry;
}
private static final RateLimitedLog log = getRateLimitedLog(PipelineRuleParser.class);
public static final ParseTreeWalker WALKER = ParseTreeWalker.DEFAULT;
public Rule parseRule(String rule, boolean silent) throws ParseException {
return parseRule("dummy" + uniqueId.getAndIncrement(), rule, silent);
}
/**
* Parses the given rule source and optionally generates a Java class for it if the classloader is not null.
*
* @param id the id of the rule, necessary to generate code
* @param rule rule source code
* @param silent don't emit status messages during parsing
* @return the parse rule
* @throws ParseException if a one or more parse errors occur
*/
public Rule parseRule(String id, String rule, boolean silent) throws ParseException {
final ParseContext parseContext = new ParseContext(silent);
final SyntaxErrorListener errorListener = new SyntaxErrorListener(parseContext);
final RuleLangLexer lexer = new RuleLangLexer(new ANTLRInputStream(rule));
lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);
final RuleLangParser parser = new RuleLangParser(new CommonTokenStream(lexer));
parser.setErrorHandler(new DefaultErrorStrategy());
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
final RuleLangParser.RuleDeclarationContext ruleDeclaration = parser.ruleDeclaration();
// parsing stages:
// 1. build AST nodes, checks for invalid var, function refs
// 2. type annotator: infer type information from var refs, func refs
// 3. checker: static type check w/ coercion nodes
// 4. optimizer: TODO
WALKER.walk(new RuleAstBuilder(parseContext), ruleDeclaration);
WALKER.walk(new RuleTypeAnnotator(parseContext), ruleDeclaration);
WALKER.walk(new RuleTypeChecker(parseContext), ruleDeclaration);
if (parseContext.getErrors().isEmpty()) {
return parseContext.getRules().get(0).withId(id);
}
throw new ParseException(parseContext.getErrors());
}
public List 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());
}
public Pipeline parsePipeline(String id, String source) {
final ParseContext parseContext = new ParseContext(false);
final SyntaxErrorListener errorListener = new SyntaxErrorListener(parseContext);
final RuleLangLexer lexer = new RuleLangLexer(new ANTLRInputStream(source));
lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);
final RuleLangParser parser = new RuleLangParser(new CommonTokenStream(lexer));
parser.setErrorHandler(new DefaultErrorStrategy());
parser.removeErrorListeners();
parser.addErrorListener(errorListener);
final RuleLangParser.PipelineContext pipelineContext = parser.pipeline();
WALKER.walk(new PipelineAstBuilder(parseContext), pipelineContext);
if (parseContext.getErrors().isEmpty()) {
final Pipeline pipeline = parseContext.pipelines.get(0);
return pipeline.withId(id);
}
throw new ParseException(parseContext.getErrors());
}
public static String unquote(String string, char quoteChar) {
if (string.length() >= 2 &&
string.charAt(0) == quoteChar && string.charAt(string.length() - 1) == quoteChar) {
return string.substring(1, string.length() - 1);
}
return string;
}
public static String unescape(String string) {
return StringEscapeUtils.unescapeJava(string);
}
private static class SyntaxErrorListener extends BaseErrorListener {
private final ParseContext parseContext;
public SyntaxErrorListener(ParseContext parseContext) {
this.parseContext = parseContext;
}
@Override
public void syntaxError(Recognizer, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
parseContext.addError(new SyntaxError(offendingSymbol, line, charPositionInLine, msg, e));
}
}
private class RuleAstBuilder extends RuleLangBaseListener {
private final ParseContext parseContext;
private final ParseTreeProperty