-
Notifications
You must be signed in to change notification settings - Fork 2.2k
chore(remap): re-implement VRL parser/compiler #6353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
111 commits
Select commit
Hold shift + click to select a range
f0b44ab
chore(remap): improve test harness set-up
JeanMertz 1ec92e1
chore(remap): expand UI test cases
JeanMertz 4240bba
chore(remap): add new remap-parser crate
JeanMertz 9bb1509
chore(remap): add new remap-compiler crate
JeanMertz 86daabf
chore(remap): add new remap-diagnostic crate
JeanMertz 11e86dc
chore(remap): update remap-lang crate to use remap-compiler
JeanMertz 277c412
chore(remap): update remap-cli crate to use remap-compiler
JeanMertz 6fca455
chore(remap): update first batch of function for remap-compiler
JeanMertz 65a03c3
chore(remap): move vrl crates to lib/vrl
JeanMertz 58a6c67
chore(remap): add missing unary-not support
JeanMertz abdf9c0
chore(remap): remove unused files
JeanMertz 70bc26c
chore(remap): resolve failing equality operations
JeanMertz 3fb39db
fixup! chore(remap): add missing unary-not support
JeanMertz 2a02381
chore(remap): add missing comparison tests
JeanMertz 119f90a
chore(remap): add missing logical operation tests
JeanMertz 6fb2661
chore(remap): add more diagnostic tests
JeanMertz 4691b3c
chore(remap): resolve review feedback
JeanMertz 53c07ef
chore(remap): more bug fixes and function updates
JeanMertz 39785d0
Temporarily break stdlib features into multiple lines to avoid merge …
pablosichert 698e9af
Sort feature list
pablosichert 7d4e6be
chore(remap): fix lexer bug with query detection
JeanMertz ab124b2
chore(remap): re-enable VRL inside Vector
JeanMertz 04c0c85
Migrate parse_aws_alb_log VRL function
pablosichert 221dd87
Derive `Clone` for structs implementing `Expression`
pablosichert b47f7ab
Added property tests
StephenWakely aa7594d
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely 2c1d734
chore(remap): upgrade more functions
JeanMertz ceb5f5d
chore(remap): resolve non-boolean conditions to false
JeanMertz 5e0c9de
chore(remap): allow multi-line logical operations
JeanMertz 1ca8153
chore(remap): add multi-line expressions test
JeanMertz 499fab5
chore(remap): more function updates
JeanMertz bbe26d5
chore(remap): more function updates
JeanMertz d4d1a9f
Migrate parse_aws_cloudwatch_log_subscription_message VRL function
pablosichert fb652f1
chore(remap): more function updates
JeanMertz cffb4c5
Updated Remap functions a-f
StephenWakely e602709
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely 4e8de7a
Fixed encode_json example
StephenWakely 1fd2909
chore(remap): more function updates
JeanMertz 2710c72
Formatting
StephenWakely c0117e0
chore(remap): add functions to tests/cli
JeanMertz efec15c
Accept bytes only in parse_aws_alb_log/parse_aws_cloudwatch_log_subsc…
pablosichert 6739f7e
Update nullable inner types in parse_aws_alb_log
pablosichert 7d9b821
Replace no-op test with actual assertion (fails, needs fix!)
pablosichert 63be13d
Fix parse_aws_cloudwatch_log_subscription_message with encode_json hack
pablosichert be33293
Migrate parse_aws_vpc_flow_log VRL function
pablosichert 6c70752
Migrate parse_duration VRL function
pablosichert 8378567
Hotfix `unknown_function` test because with function suggestion
pablosichert e43598c
chore(remap): update "push" function
JeanMertz 9c37cec
chore(remap): more function updates
JeanMertz 614f0e6
chore(remap): more function updates
JeanMertz bafe045
Updated parse_grok and parse_key_value
StephenWakely ef7cf56
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely fe6d8bb
Remove merge conflict
pablosichert 387a78d
chore(remap): partially fix nested type def query
JeanMertz 9ee9cc3
chore(remap): partially fix nested type def query
JeanMertz 08810ba
chore(remap): add failing nested query type
JeanMertz 7e570d2
Migrate parse_timestamp VRL function
pablosichert 3db2292
Migrate parse_tokens VRL function
pablosichert 679f585
Apply array type definition to every index
pablosichert 2513b61
Added parse_regex and parse_regex_all
StephenWakely 341a942
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely 9139fc5
Merge remote-tracking branch 'origin/master' into jean/vrl-refactor
pablosichert 580a950
chore(remap): fix failing nested query type
JeanMertz 6b0bc17
Updated parse_common_log, join and redact
StephenWakely f0194c1
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely d88e4c9
Migrate parse_glog VRL function
pablosichert 3dee7b3
formatting
StephenWakely 488316b
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely 094a7da
join is fallible
StephenWakely 4018b20
Migrate get_hostname VRL function
pablosichert c84124a
Sort features list
pablosichert d487668
Fix parse_key_value type definitions
pablosichert fc3cd0e
Fix unused variables / mutability
pablosichert 60fd560
chore(remap): fix failing type check tests
JeanMertz 674cefb
Make VRL unit tests compile
pablosichert 535b8a2
chore(remap): clippy fixe
JeanMertz c6285f7
chore(remap): fix linting issues
JeanMertz da77186
chore(remap): first update to remap.toml tests
JeanMertz cfe735d
chore(remap): fix linting issues
JeanMertz a7b88a1
chore(remap): fix linting issues
JeanMertz 828d4ac
chore(remap): fix linting issues
JeanMertz 83315e6
chore(remap): add error codes
JeanMertz ae702fa
chore(remap): don't show links for non-existant error pages
JeanMertz 40549ad
chore(remap): fixes
JeanMertz e21fab6
chore(remap): clippy fixes
JeanMertz e6cfad9
Added type ensuring functions
StephenWakely 27f3768
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely c888f97
chore(remap): fix issues
JeanMertz ea227aa
chore(remap): fix issues
JeanMertz 97534fb
chore(remap): fix issues
JeanMertz d000618
chore(remap): more fixes
JeanMertz 8a13fe6
chore(remap): rename function names
JeanMertz 30e5ddd
chore(remap): clippy fixes
JeanMertz 6d88367
chore(remap): support shallow type def merging
JeanMertz c343bdb
chore(remap): temporary disable old parser tests
JeanMertz 2911b44
Add vrl to the logging levels
StephenWakely 7b0aa5d
Remove timestamp literal from property tests
StephenWakely fe4ce8b
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely 47f198d
formatting
StephenWakely fe7d73b
log should take any parameter
StephenWakely 0dd9ada
array and object functions restrict type_def to arrays and objects
StephenWakely 9c70c5f
chore(remap): fix benchmarks
JeanMertz 7fb719d
chore(remap): add type def test
JeanMertz f80c154
chore(remap): fix benchmarks
JeanMertz 87ea092
chore(remap): fix benchmarks
JeanMertz 3b528e9
chore(remap): fix benchmarks
JeanMertz 76e5c69
array and object functions should set an array type if unknown before.
StephenWakely 93ad40a
Allow tags to be set on metrics
StephenWakely 9ca636b
Merge branch 'jean/vrl-refactor' of github.com:timberio/vector into j…
StephenWakely 9c12840
Updated behavior tests
StephenWakely b7fd57f
Merge branch 'master' into jean/vrl-refactor
JeanMertz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| [package] | ||
| name = "remap-compiler" | ||
| version = "0.1.0" | ||
| authors = ["Vector Contributors <vector@timber.io>"] | ||
| edition = "2018" | ||
| publish = false | ||
|
|
||
| [dependencies] | ||
| bitflags = "1" | ||
| bytes = "0.5.6" | ||
| chrono = "0.4" | ||
| diagnostic = { package = "remap-diagnostic", path = "../remap-diagnostic" } | ||
| lalrpop-util = "0.19" | ||
| ngrammatic = "0.3" | ||
| ordered-float = "2" | ||
| parser = { package = "remap-parser", path = "../remap-parser" } | ||
| paste = "1" | ||
| regex = "1" | ||
| serde = "1" | ||
| thiserror = "1" |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,302 @@ | ||
| use crate::expression::*; | ||
| use crate::{Function, Program, State}; | ||
| use chrono::{TimeZone, Utc}; | ||
| use diagnostic::DiagnosticError; | ||
| use ordered_float::NotNan; | ||
| use parser::ast::{self, Node}; | ||
| use std::convert::TryFrom; | ||
|
|
||
| pub type Errors = Vec<Box<dyn DiagnosticError>>; | ||
|
|
||
| pub struct Compiler<'a> { | ||
| fns: &'a [Box<dyn Function>], | ||
| state: &'a mut State, | ||
| errors: Errors, | ||
| } | ||
|
|
||
| impl<'a> Compiler<'a> { | ||
| pub(super) fn new(fns: &'a [Box<dyn Function>], state: &'a mut State) -> Self { | ||
| Self { | ||
| fns, | ||
| state, | ||
| errors: vec![], | ||
| } | ||
| } | ||
|
|
||
| pub(super) fn compile(mut self, ast: parser::Program) -> Result<Program, Errors> { | ||
| let expressions = self | ||
| .compile_root_exprs(ast) | ||
| .into_iter() | ||
| .map(|expr| Box::new(expr) as _) | ||
| .collect(); | ||
|
|
||
| if !self.errors.is_empty() { | ||
| return Err(self.errors); | ||
| } | ||
|
|
||
| Ok(Program(expressions)) | ||
| } | ||
|
|
||
| fn compile_root_exprs( | ||
| &mut self, | ||
| nodes: impl IntoIterator<Item = Node<ast::RootExpr>>, | ||
| ) -> Vec<Expr> { | ||
| use ast::RootExpr::*; | ||
|
|
||
| nodes | ||
| .into_iter() | ||
| .filter_map(|node| { | ||
| let span = node.span(); | ||
|
|
||
| match node.into_inner() { | ||
| Expr(expr) => { | ||
| let expr = self.compile_expr(expr); | ||
| if expr.type_def(self.state).is_fallible() { | ||
| use crate::expression::Error; | ||
| let err = Error::Fallible { span }; | ||
| self.errors.push(Box::new(err)); | ||
| } | ||
|
|
||
| Some(expr) | ||
| } | ||
| InvalidTokens(_) => None, | ||
| Error(err) => { | ||
| self.handle_parser_error(err); | ||
| None | ||
| } | ||
| } | ||
| }) | ||
| .collect() | ||
| } | ||
|
|
||
| fn compile_exprs(&mut self, nodes: impl IntoIterator<Item = Node<ast::Expr>>) -> Vec<Expr> { | ||
| nodes | ||
| .into_iter() | ||
| .map(|node| self.compile_expr(node)) | ||
| .collect() | ||
| } | ||
|
|
||
| fn compile_expr(&mut self, node: Node<ast::Expr>) -> Expr { | ||
| use ast::Expr::*; | ||
|
|
||
| match node.into_inner() { | ||
| Literal(node) => self.compile_literal(node).into(), | ||
| Container(node) => self.compile_container(node).into(), | ||
| IfStatement(node) => self.compile_if_statement(node).into(), | ||
| Op(node) => self.compile_op(node).into(), | ||
| Assignment(node) => self.compile_assignment(node).into(), | ||
| Query(node) => self.compile_query(node).into(), | ||
| FunctionCall(node) => self.compile_function_call(node).into(), | ||
| Variable(node) => self.compile_variable(node).into(), | ||
| } | ||
| } | ||
|
|
||
| fn compile_literal(&mut self, node: Node<ast::Literal>) -> Literal { | ||
| use literal::ErrorVariant::*; | ||
|
|
||
| Literal::try_from(node).unwrap_or_else(|err| match &err.variant { | ||
| InvalidRegex(_) => { | ||
| self.errors.push(Box::new(err)); | ||
| regex::Regex::new("").unwrap().into() | ||
| } | ||
| InvalidTimestamp(..) => { | ||
| self.errors.push(Box::new(err)); | ||
| Utc.timestamp(0, 0).into() | ||
| } | ||
| NanFloat => { | ||
| self.errors.push(Box::new(err)); | ||
| NotNan::new(0.0).unwrap().into() | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| fn compile_container(&mut self, node: Node<ast::Container>) -> Container { | ||
| use ast::Container::*; | ||
|
|
||
| let variant = match node.into_inner() { | ||
| Group(node) => self.compile_group(*node).into(), | ||
| Block(node) => self.compile_block(node).into(), | ||
| Array(node) => self.compile_array(node).into(), | ||
| Object(node) => self.compile_object(node).into(), | ||
| }; | ||
|
|
||
| Container::new(variant) | ||
| } | ||
|
|
||
| fn compile_group(&mut self, node: Node<ast::Group>) -> Group { | ||
| let expr = self.compile_expr(node.into_inner().into_inner()); | ||
|
|
||
| Group::new(expr) | ||
| } | ||
|
|
||
| fn compile_block(&mut self, node: Node<ast::Block>) -> Block { | ||
| let exprs = self.compile_exprs(node.into_inner().into_iter()); | ||
|
|
||
| Block::new(exprs) | ||
| } | ||
|
|
||
| fn compile_array(&mut self, node: Node<ast::Array>) -> Array { | ||
| let exprs = self.compile_exprs(node.into_inner().into_iter()); | ||
|
|
||
| Array::new(exprs) | ||
| } | ||
|
|
||
| fn compile_object(&mut self, node: Node<ast::Object>) -> Object { | ||
| use std::collections::BTreeMap; | ||
|
|
||
| let exprs = node | ||
| .into_inner() | ||
| .into_iter() | ||
| .map(|(k, expr)| (k.into_inner(), self.compile_expr(expr))) | ||
| .collect::<BTreeMap<_, _>>(); | ||
|
|
||
| Object::new(exprs) | ||
| } | ||
|
|
||
| fn compile_if_statement(&mut self, node: Node<ast::IfStatement>) -> IfStatement { | ||
| let ast::IfStatement { | ||
| predicate, | ||
| consequent, | ||
| alternative, | ||
| } = node.into_inner(); | ||
|
|
||
| let predicate = match self.compile_predicate(predicate) { | ||
| Ok(v) => v, | ||
| Err(err) => { | ||
| self.errors.push(Box::new(err)); | ||
| return IfStatement::noop(); | ||
| } | ||
| }; | ||
|
|
||
| let consequent = self.compile_block(consequent); | ||
| let alternative = alternative.map(|block| self.compile_block(block)); | ||
|
|
||
| IfStatement { | ||
| predicate, | ||
| consequent, | ||
| alternative, | ||
| } | ||
| } | ||
|
|
||
| fn compile_predicate(&mut self, node: Node<ast::Predicate>) -> predicate::Result { | ||
| use ast::Predicate::*; | ||
|
|
||
| let (span, predicate) = node.take(); | ||
|
|
||
| let exprs = match predicate { | ||
| One(node) => vec![self.compile_expr(*node)], | ||
| Many(nodes) => self.compile_exprs(nodes), | ||
| }; | ||
|
|
||
| Predicate::new(Node::new(span, Block::new(exprs)), &mut self.state) | ||
| } | ||
|
|
||
| fn compile_op(&mut self, node: Node<ast::Op>) -> Op { | ||
| let op = node.into_inner(); | ||
| let ast::Op(lhs, opcode, rhs) = op; | ||
|
|
||
| let lhs = Box::new(self.compile_expr(*lhs)); | ||
| let rhs = Box::new(self.compile_expr(*rhs)); | ||
|
|
||
| Op { lhs, rhs, opcode } | ||
| } | ||
|
|
||
| fn compile_assignment(&mut self, node: Node<ast::Assignment>) -> Assignment { | ||
| use assignment::Variant; | ||
| use ast::Assignment::*; | ||
|
|
||
| self.state.snapshot(); | ||
|
|
||
| let node = node.map(|assignment| match assignment { | ||
| Single { target, expr } => { | ||
| let span = expr.span(); | ||
| let expr = Box::new(expr.map(|node| self.compile_expr(Node::new(span, node)))); | ||
|
|
||
| Variant::Single { target, expr } | ||
| } | ||
| Infallible { ok, err, expr } => { | ||
| let span = expr.span(); | ||
| let expr = Box::new(expr.map(|node| self.compile_expr(Node::new(span, node)))); | ||
|
|
||
| Variant::Infallible { ok, err, expr } | ||
| } | ||
| }); | ||
|
|
||
| Assignment::new(node, &mut self.state).unwrap_or_else(|err| { | ||
| self.state.rollback(); | ||
| self.errors.push(Box::new(err)); | ||
| Assignment::noop() | ||
| }) | ||
| } | ||
|
|
||
| fn compile_query(&mut self, node: Node<ast::Query>) -> Query { | ||
| let ast::Query { target, path } = node.into_inner(); | ||
| let target = self.compile_query_target(target); | ||
|
|
||
| Query::new(target, path.into_inner().into()) | ||
| } | ||
|
|
||
| fn compile_query_target(&mut self, node: Node<ast::QueryTarget>) -> query::Target { | ||
| use ast::QueryTarget::*; | ||
| use query::Target; | ||
|
|
||
| let span = node.span(); | ||
|
|
||
| match node.into_inner() { | ||
| External => Target::External, | ||
| Internal(ident) => { | ||
| let variable = self.compile_variable(Node::new(span, ident)); | ||
| Target::Internal(variable) | ||
| } | ||
| Container(container) => { | ||
| let container = self.compile_container(Node::new(span, container)); | ||
| Target::Container(container) | ||
| } | ||
| FunctionCall(call) => { | ||
| let call = self.compile_function_call(Node::new(span, call)); | ||
| Target::FunctionCall(call) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| fn compile_function_call(&mut self, node: Node<ast::FunctionCall>) -> FunctionCall { | ||
| let call_span = node.span(); | ||
| let ast::FunctionCall { | ||
| ident, | ||
| abort_on_error, | ||
| arguments, | ||
| } = node.into_inner(); | ||
|
|
||
| let arguments = arguments | ||
| .into_iter() | ||
| .map(|node| Node::new(node.span(), self.compile_function_argument(node))) | ||
| .collect(); | ||
|
|
||
| FunctionCall::new( | ||
| call_span, | ||
| ident, | ||
| abort_on_error, | ||
| arguments, | ||
| self.fns, | ||
| self.state, | ||
| ) | ||
| .unwrap_or_else(|err| { | ||
| self.errors.push(Box::new(err)); | ||
| FunctionCall::noop() | ||
| }) | ||
| } | ||
|
|
||
| fn compile_function_argument(&mut self, node: Node<ast::FunctionArgument>) -> FunctionArgument { | ||
| let ast::FunctionArgument { ident, expr } = node.into_inner(); | ||
| let expr = Node::new(expr.span(), self.compile_expr(expr)); | ||
| FunctionArgument::new(ident, expr) | ||
| } | ||
|
|
||
| fn compile_variable(&mut self, node: Node<ast::Ident>) -> Variable { | ||
| Variable::new(node.into_inner()) | ||
| } | ||
|
|
||
| fn handle_parser_error(&mut self, error: parser::Error) { | ||
| self.errors.push(Box::new(error)) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| use crate::{state::Runtime, Target}; | ||
|
|
||
| pub struct Context<'a> { | ||
| target: &'a mut dyn Target, | ||
| state: &'a mut Runtime, | ||
| } | ||
|
|
||
| impl<'a> Context<'a> { | ||
| /// Create a new [`Context`]. | ||
| pub fn new(target: &'a mut dyn Target, state: &'a mut Runtime) -> Self { | ||
| Self { target, state } | ||
| } | ||
|
|
||
| /// Get a reference to the [`Target`]. | ||
| pub(crate) fn target(&self) -> &dyn Target { | ||
| self.target | ||
| } | ||
|
|
||
| /// Get a mutable reference to the [`Target`]. | ||
| pub(crate) fn target_mut(&mut self) -> &mut dyn Target { | ||
| self.target | ||
| } | ||
|
|
||
| /// Get a reference to the [`runtime state`](Runtime). | ||
| pub(crate) fn state(&self) -> &Runtime { | ||
| &self.state | ||
| } | ||
|
|
||
| /// Get a mutable reference to the [`runtime state`](Runtime). | ||
| pub(crate) fn state_mut(&mut self) -> &mut Runtime { | ||
| &mut self.state | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.