1use std::{mem, num::NonZeroUsize};23use rowan::{GreenNodeBuilder, Language, TextRange, TextSize};45use crate::{6 AstToken, JsonnetLanguage, SyntaxKind,7 lex::Lexeme,8 nodes::Trivia,9 parser::{LocatedSyntaxError, Parse, SyntaxError},10};1112#[derive(Clone, Debug)]13pub enum Event {14 15 Pending,16 17 Start {18 kind: SyntaxKind,19 20 21 forward_parent: Option<NonZeroUsize>,22 },23 24 Token { kind: SyntaxKind },25 26 27 28 Finish {29 30 wrapper: Option<NonZeroUsize>,31 error: Option<Box<SyntaxError>>,32 },33 34 Noop,35}3637pub(super) struct Sink<'i> {38 pub builder: GreenNodeBuilder<'static>,39 lexemes: &'i [Lexeme<'i>],40 offset: usize,41 events: Vec<Event>,42 pub errors: Vec<LocatedSyntaxError>,43}4445impl<'i> Sink<'i> {46 pub(super) fn new(events: Vec<Event>, lexemes: &'i [Lexeme<'i>]) -> Self {47 Self {48 builder: GreenNodeBuilder::new(),49 lexemes,50 offset: 0,51 events,52 errors: vec![],53 }54 }5556 fn text_offset(&self) -> TextSize {57 if self.offset == 0 {58 return 0.into();59 }60 self.lexemes.get(self.offset).map_or_else(61 || {62 self.lexemes63 .get(self.offset - 1)64 .map_or_else(|| panic!("hard oob"), |lex| lex.range.end())65 },66 |lex| lex.range.start(),67 )68 }6970 pub(super) fn finish(mut self) -> Parse {71 let mut eat_start_whitespace = false;72 let mut depth = 0;73 let mut error_starts_at = Vec::new();74 for idx in 0..self.events.len() {75 match mem::replace(&mut self.events[idx], Event::Noop) {76 Event::Start {77 kind,78 forward_parent,79 } => {80 if depth != 0 {81 self.skip_whitespace();82 }83 let mut kinds = vec![kind];8485 let mut idx = idx;86 let mut forward_parent = forward_parent;8788 89 90 91 while let Some(fp) = forward_parent {92 idx += fp.get();9394 forward_parent = if let Event::Start {95 kind,96 forward_parent,97 } = mem::replace(&mut self.events[idx], Event::Noop)98 {99 kinds.push(kind);100 forward_parent101 } else {102 unreachable!()103 };104 }105106 for kind in kinds.into_iter().rev() {107 self.builder.start_node(JsonnetLanguage::kind_to_raw(kind));108 depth += 1;109 if depth == 1 {110 self.skip_whitespace();111 }112 error_starts_at.push(self.text_offset());113 }114115 eat_start_whitespace = false;116 }117 Event::Token { kind } => {118 if eat_start_whitespace {119 self.skip_whitespace();120 }121 self.token(kind);122 eat_start_whitespace = true;123 }124 125 126 127 128 129 130 131 Event::Finish { wrapper, error } => {132 if depth == 1 {133 self.skip_whitespace();134 }135 let range = (136 error_starts_at.pop().expect("starts == finishes"),137 self.text_offset(),138 );139 if let Some(error) = error {140 self.errors.push(LocatedSyntaxError {141 error: *error,142 range: TextRange::new(range.0, range.1),143 });144 }145 self.builder.finish_node();146 depth -= 1;147 let mut idx = idx;148 let mut wrapper = wrapper;149 while let Some(w) = wrapper {150 idx += w.get();151 wrapper = if let Event::Finish { wrapper, error } =152 mem::replace(&mut self.events[idx], Event::Noop)153 {154 let range = (155 error_starts_at.pop().expect("starts == finishes"),156 self.text_offset(),157 );158 if let Some(error) = error {159 self.errors.push(LocatedSyntaxError {160 error: *error,161 range: TextRange::new(range.0, range.1),162 });163 }164165 if depth == 1 {166 self.skip_whitespace();167 }168 self.builder.finish_node();169 depth -= 1;170 wrapper171 } else {172 unreachable!()173 }174 }175 eat_start_whitespace = true;176 }177 Event::Pending => panic!("pending event should not appear in finished events"),178 Event::Noop => {}179 }180 }181182 Parse {183 green_node: self.builder.finish(),184 errors: self.errors,185 }186 }187 188 189 190 fn token(&mut self, kind: SyntaxKind) {191 let lexeme = self.lexemes[self.offset];192 self.builder193 .token(JsonnetLanguage::kind_to_raw(kind), lexeme.text);194 self.offset += 1;195 }196 fn skip_whitespace(&mut self) {197 while let Some(lexeme) = self.lexemes.get(self.offset) {198 if !Trivia::can_cast(lexeme.kind) {199 break;200 }201202 self.token(lexeme.kind);203 }204 }205}