use super::*;
fn parse_metadata_annotation<P: KerMLParser>(p: &mut P) {
bump_and_skip(p);
if p.at_name_token()
&& p.peek_kind(1) != SyntaxKind::SEMICOLON
&& p.peek_kind(1) != SyntaxKind::L_BRACE
&& matches!(p.peek_kind(1), SyntaxKind::COLON | SyntaxKind::TYPED_KW)
{
parse_identification_and_skip(p);
bump_and_skip(p); consume_if(p, SyntaxKind::BY_KW);
}
parse_optional_qualified_name(p);
if p.at(SyntaxKind::ABOUT_KW) {
bump_and_skip(p);
p.parse_qualified_name_list();
p.skip_trivia();
}
if p.at(SyntaxKind::L_BRACE) {
parse_annotation_body(p);
} else if p.at(SyntaxKind::SEMICOLON) {
p.bump();
}
}
fn parse_locale_annotation<P: KerMLParser>(p: &mut P) {
p.bump(); p.skip_trivia_except_block_comments();
if p.at(SyntaxKind::STRING) {
p.bump();
p.skip_trivia_except_block_comments();
}
if p.at(SyntaxKind::BLOCK_COMMENT) {
p.bump();
}
}
fn check_block_comment<P: KerMLParser>(p: &mut P) -> bool {
if p.at(SyntaxKind::BLOCK_COMMENT) {
p.bump();
true
} else {
false
}
}
fn parse_locale_clause<P: KerMLParser>(p: &mut P) {
if p.at(SyntaxKind::LOCALE_KW) {
p.bump();
p.skip_trivia_except_block_comments();
if p.at(SyntaxKind::STRING) {
p.bump();
p.skip_trivia_except_block_comments();
}
}
}
fn parse_about_clause<P: KerMLParser>(p: &mut P) {
if p.at(SyntaxKind::ABOUT_KW) {
p.bump();
p.skip_trivia();
p.parse_qualified_name_list();
p.skip_trivia_except_block_comments();
parse_locale_clause(p);
}
}
fn parse_comment_doc_annotation<P: KerMLParser>(p: &mut P) {
p.skip_trivia_except_block_comments();
if check_block_comment(p) {
return;
}
if (p.at_name_token() || p.at(SyntaxKind::LT))
&& !p.at(SyntaxKind::ABOUT_KW)
&& !p.at(SyntaxKind::LOCALE_KW)
{
p.parse_identification();
p.skip_trivia_except_block_comments();
if check_block_comment(p) {
return;
}
}
parse_locale_clause(p);
if check_block_comment(p) {
return;
}
parse_about_clause(p);
if check_block_comment(p) {
return;
}
if p.at(SyntaxKind::L_BRACE) {
parse_annotation_body(p);
} else if p.at(SyntaxKind::SEMICOLON) {
p.bump();
}
}
pub fn parse_annotation<P: KerMLParser>(p: &mut P) {
p.start_node(SyntaxKind::COMMENT_ELEMENT);
if p.at(SyntaxKind::AT) || p.at(SyntaxKind::AT_AT) || p.at(SyntaxKind::METADATA_KW) {
parse_metadata_annotation(p);
} else if p.at(SyntaxKind::LOCALE_KW) {
parse_locale_annotation(p);
} else {
if p.at(SyntaxKind::COMMENT_KW) || p.at(SyntaxKind::DOC_KW) {
p.bump();
}
parse_comment_doc_annotation(p);
}
p.finish_node();
}
fn parse_annotation_body<P: KerMLParser>(p: &mut P) {
p.expect(SyntaxKind::L_BRACE);
p.skip_trivia();
let mut depth = 1;
while depth > 0 {
if p.at(SyntaxKind::L_BRACE) {
depth += 1;
p.bump();
} else if p.at(SyntaxKind::R_BRACE) {
depth -= 1;
if depth > 0 {
p.bump();
}
} else if p.current_kind() == SyntaxKind::ERROR {
break; } else {
p.bump();
}
}
p.expect(SyntaxKind::R_BRACE);
}