1#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
9#[repr(u16)]
10pub enum SyntaxKind {
11 WHITESPACE = 0,
13 NEWLINE,
14 COMMENT, BLOCK_COMMENT, IDENT, QUOTED_IDENT, STRING, DOLLAR_STRING, INT_NUMBER,
23 FLOAT_NUMBER,
24 VARIABLE, L_PAREN, R_PAREN, L_BRACKET, R_BRACKET, L_BRACE, R_BRACE, COMMA, DOT, SEMICOLON, COLON, COLON2, ASSIGN, EQ, NEQ, LT, LTE, GT, GTE, PLUS, MINUS, STAR, SLASH, PERCENT, CONCAT, PIPE, PIPE_GT, FLOW_PIPE, ARROW, FAT_ARROW, AMP, CARET, TILDE, AT, DOLLAR, QUESTION, BANG, #[doc(hidden)]
69 __KW_START,
70 SELECT_KW,
71 FROM_KW,
72 WHERE_KW,
73 GROUP_KW,
74 BY_KW,
75 HAVING_KW,
76 ORDER_KW,
77 LIMIT_KW,
78 OFFSET_KW,
79 FETCH_KW,
80 TOP_KW,
81 AS_KW,
82 AND_KW,
83 OR_KW,
84 NOT_KW,
85 NULL_KW,
86 IS_KW,
87 IN_KW,
88 LIKE_KW,
89 ILIKE_KW,
90 RLIKE_KW,
91 REGEXP_KW,
92 BETWEEN_KW,
93 CASE_KW,
94 WHEN_KW,
95 THEN_KW,
96 ELSE_KW,
97 END_KW,
98 JOIN_KW,
99 INNER_KW,
100 LEFT_KW,
101 RIGHT_KW,
102 FULL_KW,
103 OUTER_KW,
104 CROSS_KW,
105 LATERAL_KW,
106 NATURAL_KW,
107 ON_KW,
108 USING_KW,
109 WITH_KW,
110 RECURSIVE_KW,
111 UNION_KW,
112 ALL_KW,
113 ANY_KW,
114 EXCEPT_KW,
115 INTERSECT_KW,
116 MINUS_KW,
117 DISTINCT_KW,
118 QUALIFY_KW,
119 OVER_KW,
120 PARTITION_KW,
121 WINDOW_KW,
122 ROWS_KW,
123 RANGE_KW,
124 UNBOUNDED_KW,
125 PRECEDING_KW,
126 FOLLOWING_KW,
127 CURRENT_KW,
128 ROW_KW,
129 ASC_KW,
130 DESC_KW,
131 NULLS_KW,
132 FIRST_KW,
133 LAST_KW,
134 TRUE_KW,
135 FALSE_KW,
136 CAST_KW,
137 TRY_CAST_KW,
138 EXISTS_KW,
139 VALUES_KW,
140 PIVOT_KW,
141 UNPIVOT_KW,
142 SAMPLE_KW,
143 TABLESAMPLE_KW,
144 CREATE_KW,
145 REPLACE_KW,
146 IF_KW,
147 TABLE_KW,
148 VIEW_KW,
149 TEMPORARY_KW,
150 TEMP_KW,
151 TRANSIENT_KW,
152 VOLATILE_KW,
153 SECURE_KW,
154 INSERT_KW,
155 INTO_KW,
156 UPDATE_KW,
157 DELETE_KW,
158 MERGE_KW,
159 SET_KW,
160 FLATTEN_KW,
161 CONNECT_KW,
162 START_KW,
163 PRIOR_KW,
164 LANGUAGE_KW,
165 JAVASCRIPT_KW,
166 PYTHON_KW,
167 JAVA_KW,
168 SCALA_KW,
169 SQL_KW,
170 BEGIN_KW,
171 DECLARE_KW,
172 LET_KW,
173 RETURN_KW,
174 CALL_KW,
175 PROCEDURE_KW,
176 FUNCTION_KW,
177 RETURNS_KW,
178 TASK_KW,
179 WAREHOUSE_KW,
180 SCHEDULE_KW,
181 AFTER_KW,
182 COPY_KW,
183 GRANTS_KW,
184 HANDLER_KW,
185 PACKAGES_KW,
186 IMPORTS_KW,
187 RUNTIME_VERSION_KW,
188 EXECUTE_KW,
189 OWNER_KW,
190 CALLER_KW,
191 STRICT_KW,
192 CALLED_KW,
193 INPUT_KW,
194 OUTPUT_KW,
195 OUT_KW,
196 MATCHED_KW,
197 DROP_KW,
198 ALTER_KW,
199 WITHIN_KW,
200 FOR_KW,
201 IMMEDIATE_KW,
202 OVERWRITE_KW,
203 GRANT_KW,
204 REVOKE_KW,
205 USE_KW,
206 SHOW_KW,
207 DESCRIBE_KW,
208 TRUNCATE_KW,
209 COMMIT_KW,
210 ROLLBACK_KW,
211 UNDROP_KW,
212 ELSEIF_KW,
213 WHILE_KW,
214 LOOP_KW,
215 REPEAT_KW,
216 UNTIL_KW,
217 DO_KW,
218 EXCEPTION_KW,
219 CURSOR_KW,
220 RESULTSET_KW,
221 #[doc(hidden)]
222 __KW_END,
223
224 SOURCE_FILE,
226 ERROR,
227 EOF,
228 CONTEXTUAL_KEYWORD,
234 SELECT_STMT,
236 EXPR_STMT,
237 SELECT_LIST,
239 SELECT_ITEM,
240 FROM_CLAUSE,
241 WHERE_CLAUSE,
242 TABLE_REF,
243 LATERAL_VIEW,
244 AS_OF_TRAVEL,
245 ARG_LIST,
246 TYPE_NAME,
247 NAME,
248 NAME_REF,
249 LITERAL,
251 STAR_EXPR,
252 PAREN_EXPR,
253 PREFIX_EXPR,
254 BIN_EXPR,
255 CALL_EXPR,
256 INDEX_EXPR,
257 CAST_EXPR,
258 WITH_QUERY,
260 WITH_CLAUSE,
261 CTE,
262 COLUMN_LIST,
263 SET_OP,
264 SUBQUERY,
265 GROUP_BY_CLAUSE,
267 HAVING_CLAUSE,
268 QUALIFY_CLAUSE,
269 ORDER_BY_CLAUSE,
270 ORDER_BY_ITEM,
271 LIMIT_CLAUSE,
272 OFFSET_CLAUSE,
273 JOIN,
274 IS_EXPR,
276 IN_EXPR,
277 BETWEEN_EXPR,
278 EXISTS_EXPR,
279 EXPR_LIST,
280 WINDOW_EXPR,
282 WINDOW_SPEC,
283 PARTITION_BY_CLAUSE,
284 WINDOW_FRAME,
285 CASE_EXPR,
287 CASE_WHEN,
288 JSON_ACCESS,
289 LAMBDA_EXPR,
290 LAMBDA_PARAMS,
291 VALUES_CLAUSE,
292 VALUES_ROW,
293 INSERT_STMT,
295 UPDATE_STMT,
296 DELETE_STMT,
297 MERGE_STMT,
298 SET_CLAUSE,
299 ASSIGNMENT,
300 MERGE_WHEN,
301 CREATE_STMT,
303 DROP_STMT,
304 ALTER_STMT,
305 GRANT_STMT,
306 REVOKE_STMT,
307 CALL_STMT,
308 USE_STMT,
309 SHOW_STMT,
310 DESCRIBE_STMT,
311 TRUNCATE_STMT,
312 COMMENT_STMT,
313 TRANSACTION_STMT,
314 UNDROP_STMT,
315 BLOCK_STMT,
317 DECLARE_SECTION,
318 DECLARE_ITEM,
319 STMT_LIST,
320 EXCEPTION_SECTION,
321 EXCEPTION_WHEN,
322 LET_STMT,
323 ASSIGN_STMT,
324 RETURN_STMT,
325 IF_STMT,
326 LOOP_STMT,
327 CASE_STMT,
329 CASE_STMT_WHEN,
331 SCRIPT_STMT,
332 COLUMN_DEF_LIST,
333 COLUMN_DEF,
334 WITHIN_GROUP,
336 PIVOT_CLAUSE,
337 NAMED_ARG,
338 MATCH_RECOGNIZE,
339 MEASURES_CLAUSE,
341 ROW_MATCH_CLAUSE,
342 AFTER_MATCH_CLAUSE,
343 PATTERN_CLAUSE,
344 PATTERN_BODY,
345 SUBSET_CLAUSE,
346 DEFINE_CLAUSE,
347 DEFINE_ITEM,
348 START_WITH_CLAUSE,
350 CONNECT_BY_CLAUSE,
351 FLOW_STMT,
353 SET_STMT,
355 EXECUTE_STMT,
356 GROUPING_SETS,
357 COPY_STMT,
359 COPY_LOCATION,
360 COPY_OPTION,
361 STAGE_REF,
363 INTO_CLAUSE,
365 INSERT_WHEN,
366 OBJECT_PROPERTY, STREAM_SOURCE, TASK_AFTER, SEMANTIC_VIEW_CLAUSE, SEMANTIC_VIEW_ITEM, PRIV_LIST, GRANT_TARGET, GRANTEE, VACUUM_STMT, OPTIMIZE_STMT, ZORDER_CLAUSE, CACHE_STMT, UNCACHE_STMT, REFRESH_STMT, DESCRIBE_HISTORY_STMT, #[doc(hidden)]
388 __LAST,
389}
390
391impl SyntaxKind {
392 #[inline]
394 pub const fn to_u16(self) -> u16 {
395 self as u16
396 }
397
398 #[inline]
404 pub fn from_u16(raw: u16) -> SyntaxKind {
405 assert!(
406 raw <= SyntaxKind::__LAST as u16,
407 "SyntaxKind out of range: {raw}"
408 );
409 unsafe { std::mem::transmute::<u16, SyntaxKind>(raw) }
412 }
413
414 #[inline]
416 pub const fn is_trivia(self) -> bool {
417 matches!(
418 self,
419 SyntaxKind::WHITESPACE
420 | SyntaxKind::NEWLINE
421 | SyntaxKind::COMMENT
422 | SyntaxKind::BLOCK_COMMENT
423 )
424 }
425
426 #[inline]
428 pub const fn is_comment(self) -> bool {
429 matches!(self, SyntaxKind::COMMENT | SyntaxKind::BLOCK_COMMENT)
430 }
431
432 #[inline]
434 pub fn is_keyword(self) -> bool {
435 let v = self as u16;
436 v > SyntaxKind::__KW_START as u16 && v < SyntaxKind::__KW_END as u16
437 }
438
439 pub fn describe(self) -> &'static str {
446 use SyntaxKind::*;
447 match self {
448 IDENT => "an identifier",
450 QUOTED_IDENT => "a quoted identifier",
451 STRING => "a string literal",
452 DOLLAR_STRING => "a dollar-quoted string",
453 INT_NUMBER => "an integer literal",
454 FLOAT_NUMBER => "a number literal",
455 VARIABLE => "a variable",
456 L_PAREN => "'('",
458 R_PAREN => "')'",
459 L_BRACKET => "'['",
460 R_BRACKET => "']'",
461 L_BRACE => "'{'",
462 R_BRACE => "'}'",
463 COMMA => "','",
464 DOT => "'.'",
465 SEMICOLON => "';'",
466 COLON => "':'",
467 COLON2 => "'::'",
468 ASSIGN => "':='",
469 EQ => "'='",
470 NEQ => "'<>'",
471 LT => "'<'",
472 LTE => "'<='",
473 GT => "'>'",
474 GTE => "'>='",
475 PLUS => "'+'",
476 MINUS => "'-'",
477 STAR => "'*'",
478 SLASH => "'/'",
479 PERCENT => "'%'",
480 CONCAT => "'||'",
481 PIPE => "'|'",
482 PIPE_GT => "'|>'",
483 FLOW_PIPE => "'->>'",
484 ARROW => "'->'",
485 FAT_ARROW => "'=>'",
486 AMP => "'&'",
487 CARET => "'^'",
488 TILDE => "'~'",
489 AT => "'@'",
490 DOLLAR => "'$'",
491 QUESTION => "'?'",
492 BANG => "'!'",
493 WHITESPACE => "whitespace",
495 NEWLINE => "a newline",
496 COMMENT => "a comment",
497 BLOCK_COMMENT => "a block comment",
498 EOF => "end of input",
499 CONTEXTUAL_KEYWORD => "a keyword",
500 kind if kind.is_keyword() => kind.keyword_word(),
502 _ => "input",
504 }
505 }
506
507 fn keyword_word(self) -> &'static str {
510 macro_rules! kw {
511 ($($variant:ident => $word:literal,)*) => {
512 match self {
513 $(SyntaxKind::$variant => $word,)*
514 _ => "",
515 }
516 };
517 }
518 kw! {
519 SELECT_KW => "SELECT", FROM_KW => "FROM", WHERE_KW => "WHERE", GROUP_KW => "GROUP",
520 BY_KW => "BY", HAVING_KW => "HAVING", ORDER_KW => "ORDER", LIMIT_KW => "LIMIT",
521 OFFSET_KW => "OFFSET", FETCH_KW => "FETCH", TOP_KW => "TOP", AS_KW => "AS",
522 AND_KW => "AND", OR_KW => "OR", NOT_KW => "NOT", NULL_KW => "NULL", IS_KW => "IS",
523 IN_KW => "IN", LIKE_KW => "LIKE", ILIKE_KW => "ILIKE", RLIKE_KW => "RLIKE",
524 REGEXP_KW => "REGEXP", BETWEEN_KW => "BETWEEN", CASE_KW => "CASE", WHEN_KW => "WHEN",
525 THEN_KW => "THEN", ELSE_KW => "ELSE", END_KW => "END", JOIN_KW => "JOIN",
526 INNER_KW => "INNER", LEFT_KW => "LEFT", RIGHT_KW => "RIGHT", FULL_KW => "FULL",
527 OUTER_KW => "OUTER", CROSS_KW => "CROSS", LATERAL_KW => "LATERAL",
528 NATURAL_KW => "NATURAL", ON_KW => "ON", USING_KW => "USING", WITH_KW => "WITH",
529 RECURSIVE_KW => "RECURSIVE", UNION_KW => "UNION", ALL_KW => "ALL", ANY_KW => "ANY",
530 EXCEPT_KW => "EXCEPT", INTERSECT_KW => "INTERSECT", MINUS_KW => "MINUS",
531 DISTINCT_KW => "DISTINCT", QUALIFY_KW => "QUALIFY", OVER_KW => "OVER",
532 PARTITION_KW => "PARTITION", WINDOW_KW => "WINDOW", ROWS_KW => "ROWS",
533 RANGE_KW => "RANGE", UNBOUNDED_KW => "UNBOUNDED", PRECEDING_KW => "PRECEDING",
534 FOLLOWING_KW => "FOLLOWING", CURRENT_KW => "CURRENT", ROW_KW => "ROW", ASC_KW => "ASC",
535 DESC_KW => "DESC", NULLS_KW => "NULLS", FIRST_KW => "FIRST", LAST_KW => "LAST",
536 TRUE_KW => "TRUE", FALSE_KW => "FALSE", CAST_KW => "CAST", TRY_CAST_KW => "TRY_CAST",
537 EXISTS_KW => "EXISTS", VALUES_KW => "VALUES", PIVOT_KW => "PIVOT",
538 UNPIVOT_KW => "UNPIVOT", SAMPLE_KW => "SAMPLE", TABLESAMPLE_KW => "TABLESAMPLE",
539 CREATE_KW => "CREATE", REPLACE_KW => "REPLACE", IF_KW => "IF", TABLE_KW => "TABLE",
540 VIEW_KW => "VIEW", TEMPORARY_KW => "TEMPORARY", TEMP_KW => "TEMP",
541 TRANSIENT_KW => "TRANSIENT", VOLATILE_KW => "VOLATILE", SECURE_KW => "SECURE",
542 INSERT_KW => "INSERT", INTO_KW => "INTO", UPDATE_KW => "UPDATE", DELETE_KW => "DELETE",
543 MERGE_KW => "MERGE", SET_KW => "SET", FLATTEN_KW => "FLATTEN", CONNECT_KW => "CONNECT",
544 START_KW => "START", PRIOR_KW => "PRIOR", LANGUAGE_KW => "LANGUAGE",
545 JAVASCRIPT_KW => "JAVASCRIPT", PYTHON_KW => "PYTHON", JAVA_KW => "JAVA",
546 SCALA_KW => "SCALA", SQL_KW => "SQL", BEGIN_KW => "BEGIN", DECLARE_KW => "DECLARE",
547 LET_KW => "LET", RETURN_KW => "RETURN", CALL_KW => "CALL", PROCEDURE_KW => "PROCEDURE",
548 FUNCTION_KW => "FUNCTION", RETURNS_KW => "RETURNS", TASK_KW => "TASK",
549 WAREHOUSE_KW => "WAREHOUSE", SCHEDULE_KW => "SCHEDULE", AFTER_KW => "AFTER",
550 COPY_KW => "COPY", GRANTS_KW => "GRANTS", HANDLER_KW => "HANDLER",
551 PACKAGES_KW => "PACKAGES", IMPORTS_KW => "IMPORTS",
552 RUNTIME_VERSION_KW => "RUNTIME_VERSION", EXECUTE_KW => "EXECUTE", OWNER_KW => "OWNER",
553 CALLER_KW => "CALLER", STRICT_KW => "STRICT", CALLED_KW => "CALLED",
554 INPUT_KW => "INPUT", OUTPUT_KW => "OUTPUT", OUT_KW => "OUT", MATCHED_KW => "MATCHED",
555 DROP_KW => "DROP", ALTER_KW => "ALTER", WITHIN_KW => "WITHIN", FOR_KW => "FOR",
556 IMMEDIATE_KW => "IMMEDIATE", OVERWRITE_KW => "OVERWRITE", GRANT_KW => "GRANT",
557 REVOKE_KW => "REVOKE", USE_KW => "USE", SHOW_KW => "SHOW", DESCRIBE_KW => "DESCRIBE",
558 TRUNCATE_KW => "TRUNCATE", COMMIT_KW => "COMMIT", ROLLBACK_KW => "ROLLBACK",
559 UNDROP_KW => "UNDROP", ELSEIF_KW => "ELSEIF", WHILE_KW => "WHILE", LOOP_KW => "LOOP",
560 REPEAT_KW => "REPEAT", UNTIL_KW => "UNTIL", DO_KW => "DO", EXCEPTION_KW => "EXCEPTION",
561 CURSOR_KW => "CURSOR", RESULTSET_KW => "RESULTSET",
562 }
563 }
564}
565
566#[cfg(test)]
567mod tests {
568 use super::SyntaxKind;
569
570 #[test]
571 fn keyword_and_trivia_predicates() {
572 assert!(SyntaxKind::SELECT_KW.is_keyword());
573 assert!(SyntaxKind::QUALIFY_KW.is_keyword());
574 assert!(!SyntaxKind::IDENT.is_keyword());
575 assert!(!SyntaxKind::PIPE_GT.is_keyword());
576 assert!(SyntaxKind::WHITESPACE.is_trivia());
577 assert!(SyntaxKind::BLOCK_COMMENT.is_trivia());
578 assert!(SyntaxKind::COMMENT.is_comment());
579 assert!(!SyntaxKind::IDENT.is_trivia());
580 }
581
582 #[test]
583 fn u16_roundtrip_is_total() {
584 for raw in 0..=SyntaxKind::__LAST.to_u16() {
586 let kind = SyntaxKind::from_u16(raw);
587 assert_eq!(kind.to_u16(), raw);
588 }
589 }
590
591 #[test]
592 #[should_panic]
593 fn from_u16_out_of_range_panics() {
594 let _ = SyntaxKind::from_u16(u16::MAX);
595 }
596
597 #[test]
598 fn describe_is_human_readable() {
599 assert_eq!(SyntaxKind::INTO_KW.describe(), "INTO");
600 assert_eq!(SyntaxKind::SELECT_KW.describe(), "SELECT");
601 assert_eq!(SyntaxKind::L_PAREN.describe(), "'('");
602 assert_eq!(SyntaxKind::FAT_ARROW.describe(), "'=>'");
603 assert_eq!(SyntaxKind::IDENT.describe(), "an identifier");
604 assert_eq!(SyntaxKind::STRING.describe(), "a string literal");
605 assert_eq!(SyntaxKind::EOF.describe(), "end of input");
606 }
607
608 #[test]
609 fn describe_covers_every_keyword() {
610 for raw in (SyntaxKind::__KW_START as u16 + 1)..(SyntaxKind::__KW_END as u16) {
613 let kind = SyntaxKind::from_u16(raw);
614 assert!(kind.is_keyword());
615 assert!(
616 !kind.describe().is_empty(),
617 "{kind:?} has no describe() text"
618 );
619 }
620 }
621}