1// 2// Copyright (c) 2011-2019 Canonical Ltd 3// Copyright (c) 2006-2010 Kirill Simonov 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy of 6// this software and associated documentation files (the "Software"), to deal in 7// the Software without restriction, including without limitation the rights to 8// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9// of the Software, and to permit persons to whom the Software is furnished to do 10// so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in all 13// copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21// SOFTWARE. 22 23package yaml 24 25import ( 26 "bytes" 27) 28 29// The parser implements the following grammar: 30// 31// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END 32// implicit_document ::= block_node DOCUMENT-END* 33// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 34// block_node_or_indentless_sequence ::= 35// ALIAS 36// | properties (block_content | indentless_block_sequence)? 37// | block_content 38// | indentless_block_sequence 39// block_node ::= ALIAS 40// | properties block_content? 41// | block_content 42// flow_node ::= ALIAS 43// | properties flow_content? 44// | flow_content 45// properties ::= TAG ANCHOR? | ANCHOR TAG? 46// block_content ::= block_collection | flow_collection | SCALAR 47// flow_content ::= flow_collection | SCALAR 48// block_collection ::= block_sequence | block_mapping 49// flow_collection ::= flow_sequence | flow_mapping 50// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 51// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 52// block_mapping ::= BLOCK-MAPPING_START 53// ((KEY block_node_or_indentless_sequence?)? 54// (VALUE block_node_or_indentless_sequence?)?)* 55// BLOCK-END 56// flow_sequence ::= FLOW-SEQUENCE-START 57// (flow_sequence_entry FLOW-ENTRY)* 58// flow_sequence_entry? 59// FLOW-SEQUENCE-END 60// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 61// flow_mapping ::= FLOW-MAPPING-START 62// (flow_mapping_entry FLOW-ENTRY)* 63// flow_mapping_entry? 64// FLOW-MAPPING-END 65// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 66 67// Peek the next token in the token queue. 68func peek_token(parser *yaml_parser_t) *yaml_token_t { 69 if parser.token_available || yaml_parser_fetch_more_tokens(parser) { 70 token := &parser.tokens[parser.tokens_head] 71 yaml_parser_unfold_comments(parser, token) 72 return token 73 } 74 return nil 75} 76 77// yaml_parser_unfold_comments walks through the comments queue and joins all 78// comments behind the position of the provided token into the respective 79// top-level comment slices in the parser. 80func yaml_parser_unfold_comments(parser *yaml_parser_t, token *yaml_token_t) { 81 for parser.comments_head < len(parser.comments) && token.start_mark.index >= parser.comments[parser.comments_head].token_mark.index { 82 comment := &parser.comments[parser.comments_head] 83 if len(comment.head) > 0 { 84 if token.typ == yaml_BLOCK_END_TOKEN { 85 // No heads on ends, so keep comment.head for a follow up token. 86 break 87 } 88 if len(parser.head_comment) > 0 { 89 parser.head_comment = append(parser.head_comment, '\n') 90 } 91 parser.head_comment = append(parser.head_comment, comment.head...) 92 } 93 if len(comment.foot) > 0 { 94 if len(parser.foot_comment) > 0 { 95 parser.foot_comment = append(parser.foot_comment, '\n') 96 } 97 parser.foot_comment = append(parser.foot_comment, comment.foot...) 98 } 99 if len(comment.line) > 0 { 100 if len(parser.line_comment) > 0 { 101 parser.line_comment = append(parser.line_comment, '\n') 102 } 103 parser.line_comment = append(parser.line_comment, comment.line...) 104 } 105 *comment = yaml_comment_t{} 106 parser.comments_head++ 107 } 108} 109 110// Remove the next token from the queue (must be called after peek_token). 111func skip_token(parser *yaml_parser_t) { 112 parser.token_available = false 113 parser.tokens_parsed++ 114 parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN 115 parser.tokens_head++ 116} 117 118// Get the next event. 119func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { 120 // Erase the event object. 121 *event = yaml_event_t{} 122 123 // No events after the end of the stream or error. 124 if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { 125 return true 126 } 127 128 // Generate the next event. 129 return yaml_parser_state_machine(parser, event) 130} 131 132// Set parser error. 133func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { 134 parser.error = yaml_PARSER_ERROR 135 parser.problem = problem 136 parser.problem_mark = problem_mark 137 return false 138} 139 140func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { 141 parser.error = yaml_PARSER_ERROR 142 parser.context = context 143 parser.context_mark = context_mark 144 parser.problem = problem 145 parser.problem_mark = problem_mark 146 return false 147} 148 149// State dispatcher. 150func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { 151 //trace("yaml_parser_state_machine", "state:", parser.state.String()) 152 153 switch parser.state { 154 case yaml_PARSE_STREAM_START_STATE: 155 return yaml_parser_parse_stream_start(parser, event) 156 157 case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: 158 return yaml_parser_parse_document_start(parser, event, true) 159 160 case yaml_PARSE_DOCUMENT_START_STATE: 161 return yaml_parser_parse_document_start(parser, event, false) 162 163 case yaml_PARSE_DOCUMENT_CONTENT_STATE: 164 return yaml_parser_parse_document_content(parser, event) 165 166 case yaml_PARSE_DOCUMENT_END_STATE: 167 return yaml_parser_parse_document_end(parser, event) 168 169 case yaml_PARSE_BLOCK_NODE_STATE: 170 return yaml_parser_parse_node(parser, event, true, false) 171 172 case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: 173 return yaml_parser_parse_node(parser, event, true, true) 174 175 case yaml_PARSE_FLOW_NODE_STATE: 176 return yaml_parser_parse_node(parser, event, false, false) 177 178 case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: 179 return yaml_parser_parse_block_sequence_entry(parser, event, true) 180 181 case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: 182 return yaml_parser_parse_block_sequence_entry(parser, event, false) 183 184 case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: 185 return yaml_parser_parse_indentless_sequence_entry(parser, event) 186 187 case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: 188 return yaml_parser_parse_block_mapping_key(parser, event, true) 189 190 case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: 191 return yaml_parser_parse_block_mapping_key(parser, event, false) 192 193 case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: 194 return yaml_parser_parse_block_mapping_value(parser, event) 195 196 case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: 197 return yaml_parser_parse_flow_sequence_entry(parser, event, true) 198 199 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: 200 return yaml_parser_parse_flow_sequence_entry(parser, event, false) 201 202 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: 203 return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) 204 205 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: 206 return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) 207 208 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: 209 return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) 210 211 case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: 212 return yaml_parser_parse_flow_mapping_key(parser, event, true) 213 214 case yaml_PARSE_FLOW_MAPPING_KEY_STATE: 215 return yaml_parser_parse_flow_mapping_key(parser, event, false) 216 217 case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: 218 return yaml_parser_parse_flow_mapping_value(parser, event, false) 219 220 case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: 221 return yaml_parser_parse_flow_mapping_value(parser, event, true) 222 223 default: 224 panic("invalid parser state") 225 } 226} 227 228// Parse the production: 229// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END 230// ************ 231func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { 232 token := peek_token(parser) 233 if token == nil { 234 return false 235 } 236 if token.typ != yaml_STREAM_START_TOKEN { 237 return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark) 238 } 239 parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE 240 *event = yaml_event_t{ 241 typ: yaml_STREAM_START_EVENT, 242 start_mark: token.start_mark, 243 end_mark: token.end_mark, 244 encoding: token.encoding, 245 } 246 skip_token(parser) 247 return true 248} 249 250// Parse the productions: 251// implicit_document ::= block_node DOCUMENT-END* 252// * 253// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 254// ************************* 255func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { 256 257 token := peek_token(parser) 258 if token == nil { 259 return false 260 } 261 262 // Parse extra document end indicators. 263 if !implicit { 264 for token.typ == yaml_DOCUMENT_END_TOKEN { 265 skip_token(parser) 266 token = peek_token(parser) 267 if token == nil { 268 return false 269 } 270 } 271 } 272 273 if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && 274 token.typ != yaml_TAG_DIRECTIVE_TOKEN && 275 token.typ != yaml_DOCUMENT_START_TOKEN && 276 token.typ != yaml_STREAM_END_TOKEN { 277 // Parse an implicit document. 278 if !yaml_parser_process_directives(parser, nil, nil) { 279 return false 280 } 281 parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) 282 parser.state = yaml_PARSE_BLOCK_NODE_STATE 283 284 var head_comment []byte 285 if len(parser.head_comment) > 0 { 286 // [Go] Scan the header comment backwards, and if an empty line is found, break 287 // the header so the part before the last empty line goes into the 288 // document header, while the bottom of it goes into a follow up event. 289 for i := len(parser.head_comment) - 1; i > 0; i-- { 290 if parser.head_comment[i] == '\n' { 291 if i == len(parser.head_comment)-1 { 292 head_comment = parser.head_comment[:i] 293 parser.head_comment = parser.head_comment[i+1:] 294 break 295 } else if parser.head_comment[i-1] == '\n' { 296 head_comment = parser.head_comment[:i-1] 297 parser.head_comment = parser.head_comment[i+1:] 298 break 299 } 300 } 301 } 302 } 303 304 *event = yaml_event_t{ 305 typ: yaml_DOCUMENT_START_EVENT, 306 start_mark: token.start_mark, 307 end_mark: token.end_mark, 308 309 head_comment: head_comment, 310 } 311 312 } else if token.typ != yaml_STREAM_END_TOKEN { 313 // Parse an explicit document. 314 var version_directive *yaml_version_directive_t 315 var tag_directives []yaml_tag_directive_t 316 start_mark := token.start_mark 317 if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { 318 return false 319 } 320 token = peek_token(parser) 321 if token == nil { 322 return false 323 } 324 if token.typ != yaml_DOCUMENT_START_TOKEN { 325 yaml_parser_set_parser_error(parser, 326 "did not find expected <document start>", token.start_mark) 327 return false 328 } 329 parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) 330 parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE 331 end_mark := token.end_mark 332 333 *event = yaml_event_t{ 334 typ: yaml_DOCUMENT_START_EVENT, 335 start_mark: start_mark, 336 end_mark: end_mark, 337 version_directive: version_directive, 338 tag_directives: tag_directives, 339 implicit: false, 340 } 341 skip_token(parser) 342 343 } else { 344 // Parse the stream end. 345 parser.state = yaml_PARSE_END_STATE 346 *event = yaml_event_t{ 347 typ: yaml_STREAM_END_EVENT, 348 start_mark: token.start_mark, 349 end_mark: token.end_mark, 350 } 351 skip_token(parser) 352 } 353 354 return true 355} 356 357// Parse the productions: 358// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 359// *********** 360// 361func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { 362 token := peek_token(parser) 363 if token == nil { 364 return false 365 } 366 367 if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || 368 token.typ == yaml_TAG_DIRECTIVE_TOKEN || 369 token.typ == yaml_DOCUMENT_START_TOKEN || 370 token.typ == yaml_DOCUMENT_END_TOKEN || 371 token.typ == yaml_STREAM_END_TOKEN { 372 parser.state = parser.states[len(parser.states)-1] 373 parser.states = parser.states[:len(parser.states)-1] 374 return yaml_parser_process_empty_scalar(parser, event, 375 token.start_mark) 376 } 377 return yaml_parser_parse_node(parser, event, true, false) 378} 379 380// Parse the productions: 381// implicit_document ::= block_node DOCUMENT-END* 382// ************* 383// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 384// 385func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { 386 token := peek_token(parser) 387 if token == nil { 388 return false 389 } 390 391 start_mark := token.start_mark 392 end_mark := token.start_mark 393 394 implicit := true 395 if token.typ == yaml_DOCUMENT_END_TOKEN { 396 end_mark = token.end_mark 397 skip_token(parser) 398 implicit = false 399 } 400 401 parser.tag_directives = parser.tag_directives[:0] 402 403 parser.state = yaml_PARSE_DOCUMENT_START_STATE 404 *event = yaml_event_t{ 405 typ: yaml_DOCUMENT_END_EVENT, 406 start_mark: start_mark, 407 end_mark: end_mark, 408 implicit: implicit, 409 } 410 yaml_parser_set_event_comments(parser, event) 411 if len(event.head_comment) > 0 && len(event.foot_comment) == 0 { 412 event.foot_comment = event.head_comment 413 event.head_comment = nil 414 } 415 return true 416} 417 418func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) { 419 event.head_comment = parser.head_comment 420 event.line_comment = parser.line_comment 421 event.foot_comment = parser.foot_comment 422 parser.head_comment = nil 423 parser.line_comment = nil 424 parser.foot_comment = nil 425 parser.tail_comment = nil 426 parser.stem_comment = nil 427} 428 429// Parse the productions: 430// block_node_or_indentless_sequence ::= 431// ALIAS 432// ***** 433// | properties (block_content | indentless_block_sequence)? 434// ********** * 435// | block_content | indentless_block_sequence 436// * 437// block_node ::= ALIAS 438// ***** 439// | properties block_content? 440// ********** * 441// | block_content 442// * 443// flow_node ::= ALIAS 444// ***** 445// | properties flow_content? 446// ********** * 447// | flow_content 448// * 449// properties ::= TAG ANCHOR? | ANCHOR TAG? 450// ************************* 451// block_content ::= block_collection | flow_collection | SCALAR 452// ****** 453// flow_content ::= flow_collection | SCALAR 454// ****** 455func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { 456 //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() 457 458 token := peek_token(parser) 459 if token == nil { 460 return false 461 } 462 463 if token.typ == yaml_ALIAS_TOKEN { 464 parser.state = parser.states[len(parser.states)-1] 465 parser.states = parser.states[:len(parser.states)-1] 466 *event = yaml_event_t{ 467 typ: yaml_ALIAS_EVENT, 468 start_mark: token.start_mark, 469 end_mark: token.end_mark, 470 anchor: token.value, 471 } 472 yaml_parser_set_event_comments(parser, event) 473 skip_token(parser) 474 return true 475 } 476 477 start_mark := token.start_mark 478 end_mark := token.start_mark 479 480 var tag_token bool 481 var tag_handle, tag_suffix, anchor []byte 482 var tag_mark yaml_mark_t 483 if token.typ == yaml_ANCHOR_TOKEN { 484 anchor = token.value 485 start_mark = token.start_mark 486 end_mark = token.end_mark 487 skip_token(parser) 488 token = peek_token(parser) 489 if token == nil { 490 return false 491 } 492 if token.typ == yaml_TAG_TOKEN { 493 tag_token = true 494 tag_handle = token.value 495 tag_suffix = token.suffix 496 tag_mark = token.start_mark 497 end_mark = token.end_mark 498 skip_token(parser) 499 token = peek_token(parser) 500 if token == nil { 501 return false 502 } 503 } 504 } else if token.typ == yaml_TAG_TOKEN { 505 tag_token = true 506 tag_handle = token.value 507 tag_suffix = token.suffix 508 start_mark = token.start_mark 509 tag_mark = token.start_mark 510 end_mark = token.end_mark 511 skip_token(parser) 512 token = peek_token(parser) 513 if token == nil { 514 return false 515 } 516 if token.typ == yaml_ANCHOR_TOKEN { 517 anchor = token.value 518 end_mark = token.end_mark 519 skip_token(parser) 520 token = peek_token(parser) 521 if token == nil { 522 return false 523 } 524 } 525 } 526 527 var tag []byte 528 if tag_token { 529 if len(tag_handle) == 0 { 530 tag = tag_suffix 531 tag_suffix = nil 532 } else { 533 for i := range parser.tag_directives { 534 if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { 535 tag = append([]byte(nil), parser.tag_directives[i].prefix...) 536 tag = append(tag, tag_suffix...) 537 break 538 } 539 } 540 if len(tag) == 0 { 541 yaml_parser_set_parser_error_context(parser, 542 "while parsing a node", start_mark, 543 "found undefined tag handle", tag_mark) 544 return false 545 } 546 } 547 } 548 549 implicit := len(tag) == 0 550 if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { 551 end_mark = token.end_mark 552 parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE 553 *event = yaml_event_t{ 554 typ: yaml_SEQUENCE_START_EVENT, 555 start_mark: start_mark, 556 end_mark: end_mark, 557 anchor: anchor, 558 tag: tag, 559 implicit: implicit, 560 style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), 561 } 562 return true 563 } 564 if token.typ == yaml_SCALAR_TOKEN { 565 var plain_implicit, quoted_implicit bool 566 end_mark = token.end_mark 567 if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { 568 plain_implicit = true 569 } else if len(tag) == 0 { 570 quoted_implicit = true 571 } 572 parser.state = parser.states[len(parser.states)-1] 573 parser.states = parser.states[:len(parser.states)-1] 574 575 *event = yaml_event_t{ 576 typ: yaml_SCALAR_EVENT, 577 start_mark: start_mark, 578 end_mark: end_mark, 579 anchor: anchor, 580 tag: tag, 581 value: token.value, 582 implicit: plain_implicit, 583 quoted_implicit: quoted_implicit, 584 style: yaml_style_t(token.style), 585 } 586 yaml_parser_set_event_comments(parser, event) 587 skip_token(parser) 588 return true 589 } 590 if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { 591 // [Go] Some of the events below can be merged as they differ only on style. 592 end_mark = token.end_mark 593 parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE 594 *event = yaml_event_t{ 595 typ: yaml_SEQUENCE_START_EVENT, 596 start_mark: start_mark, 597 end_mark: end_mark, 598 anchor: anchor, 599 tag: tag, 600 implicit: implicit, 601 style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), 602 } 603 yaml_parser_set_event_comments(parser, event) 604 return true 605 } 606 if token.typ == yaml_FLOW_MAPPING_START_TOKEN { 607 end_mark = token.end_mark 608 parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE 609 *event = yaml_event_t{ 610 typ: yaml_MAPPING_START_EVENT, 611 start_mark: start_mark, 612 end_mark: end_mark, 613 anchor: anchor, 614 tag: tag, 615 implicit: implicit, 616 style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), 617 } 618 yaml_parser_set_event_comments(parser, event) 619 return true 620 } 621 if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { 622 end_mark = token.end_mark 623 parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE 624 *event = yaml_event_t{ 625 typ: yaml_SEQUENCE_START_EVENT, 626 start_mark: start_mark, 627 end_mark: end_mark, 628 anchor: anchor, 629 tag: tag, 630 implicit: implicit, 631 style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), 632 } 633 if parser.stem_comment != nil { 634 event.head_comment = parser.stem_comment 635 parser.stem_comment = nil 636 } 637 return true 638 } 639 if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { 640 end_mark = token.end_mark 641 parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE 642 *event = yaml_event_t{ 643 typ: yaml_MAPPING_START_EVENT, 644 start_mark: start_mark, 645 end_mark: end_mark, 646 anchor: anchor, 647 tag: tag, 648 implicit: implicit, 649 style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), 650 } 651 if parser.stem_comment != nil { 652 event.head_comment = parser.stem_comment 653 parser.stem_comment = nil 654 } 655 return true 656 } 657 if len(anchor) > 0 || len(tag) > 0 { 658 parser.state = parser.states[len(parser.states)-1] 659 parser.states = parser.states[:len(parser.states)-1] 660 661 *event = yaml_event_t{ 662 typ: yaml_SCALAR_EVENT, 663 start_mark: start_mark, 664 end_mark: end_mark, 665 anchor: anchor, 666 tag: tag, 667 implicit: implicit, 668 quoted_implicit: false, 669 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 670 } 671 return true 672 } 673 674 context := "while parsing a flow node" 675 if block { 676 context = "while parsing a block node" 677 } 678 yaml_parser_set_parser_error_context(parser, context, start_mark, 679 "did not find expected node content", token.start_mark) 680 return false 681} 682 683// Parse the productions: 684// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 685// ******************** *********** * ********* 686// 687func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 688 if first { 689 token := peek_token(parser) 690 parser.marks = append(parser.marks, token.start_mark) 691 skip_token(parser) 692 } 693 694 token := peek_token(parser) 695 if token == nil { 696 return false 697 } 698 699 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 700 mark := token.end_mark 701 prior_head_len := len(parser.head_comment) 702 skip_token(parser) 703 yaml_parser_split_stem_comment(parser, prior_head_len) 704 token = peek_token(parser) 705 if token == nil { 706 return false 707 } 708 if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { 709 parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) 710 return yaml_parser_parse_node(parser, event, true, false) 711 } else { 712 parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE 713 return yaml_parser_process_empty_scalar(parser, event, mark) 714 } 715 } 716 if token.typ == yaml_BLOCK_END_TOKEN { 717 parser.state = parser.states[len(parser.states)-1] 718 parser.states = parser.states[:len(parser.states)-1] 719 parser.marks = parser.marks[:len(parser.marks)-1] 720 721 *event = yaml_event_t{ 722 typ: yaml_SEQUENCE_END_EVENT, 723 start_mark: token.start_mark, 724 end_mark: token.end_mark, 725 } 726 727 skip_token(parser) 728 return true 729 } 730 731 context_mark := parser.marks[len(parser.marks)-1] 732 parser.marks = parser.marks[:len(parser.marks)-1] 733 return yaml_parser_set_parser_error_context(parser, 734 "while parsing a block collection", context_mark, 735 "did not find expected '-' indicator", token.start_mark) 736} 737 738// Parse the productions: 739// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 740// *********** * 741func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { 742 token := peek_token(parser) 743 if token == nil { 744 return false 745 } 746 747 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 748 mark := token.end_mark 749 prior_head_len := len(parser.head_comment) 750 skip_token(parser) 751 yaml_parser_split_stem_comment(parser, prior_head_len) 752 token = peek_token(parser) 753 if token == nil { 754 return false 755 } 756 if token.typ != yaml_BLOCK_ENTRY_TOKEN && 757 token.typ != yaml_KEY_TOKEN && 758 token.typ != yaml_VALUE_TOKEN && 759 token.typ != yaml_BLOCK_END_TOKEN { 760 parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) 761 return yaml_parser_parse_node(parser, event, true, false) 762 } 763 parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE 764 return yaml_parser_process_empty_scalar(parser, event, mark) 765 } 766 parser.state = parser.states[len(parser.states)-1] 767 parser.states = parser.states[:len(parser.states)-1] 768 769 *event = yaml_event_t{ 770 typ: yaml_SEQUENCE_END_EVENT, 771 start_mark: token.start_mark, 772 end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? 773 } 774 return true 775} 776 777// Split stem comment from head comment. 778// 779// When a sequence or map is found under a sequence entry, the former head comment 780// is assigned to the underlying sequence or map as a whole, not the individual 781// sequence or map entry as would be expected otherwise. To handle this case the 782// previous head comment is moved aside as the stem comment. 783func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) { 784 if stem_len == 0 { 785 return 786 } 787 788 token := peek_token(parser) 789 if token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN { 790 return 791 } 792 793 parser.stem_comment = parser.head_comment[:stem_len] 794 if len(parser.head_comment) == stem_len { 795 parser.head_comment = nil 796 } else { 797 // Copy suffix to prevent very strange bugs if someone ever appends 798 // further bytes to the prefix in the stem_comment slice above. 799 parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...) 800 } 801} 802 803// Parse the productions: 804// block_mapping ::= BLOCK-MAPPING_START 805// ******************* 806// ((KEY block_node_or_indentless_sequence?)? 807// *** * 808// (VALUE block_node_or_indentless_sequence?)?)* 809// 810// BLOCK-END 811// ********* 812// 813func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 814 if first { 815 token := peek_token(parser) 816 parser.marks = append(parser.marks, token.start_mark) 817 skip_token(parser) 818 } 819 820 token := peek_token(parser) 821 if token == nil { 822 return false 823 } 824 825 // [Go] A tail comment was left from the prior mapping value processed. Emit an event 826 // as it needs to be processed with that value and not the following key. 827 if len(parser.tail_comment) > 0 { 828 *event = yaml_event_t{ 829 typ: yaml_TAIL_COMMENT_EVENT, 830 start_mark: token.start_mark, 831 end_mark: token.end_mark, 832 foot_comment: parser.tail_comment, 833 } 834 parser.tail_comment = nil 835 return true 836 } 837 838 if token.typ == yaml_KEY_TOKEN { 839 mark := token.end_mark 840 skip_token(parser) 841 token = peek_token(parser) 842 if token == nil { 843 return false 844 } 845 if token.typ != yaml_KEY_TOKEN && 846 token.typ != yaml_VALUE_TOKEN && 847 token.typ != yaml_BLOCK_END_TOKEN { 848 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) 849 return yaml_parser_parse_node(parser, event, true, true) 850 } else { 851 parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE 852 return yaml_parser_process_empty_scalar(parser, event, mark) 853 } 854 } else if token.typ == yaml_BLOCK_END_TOKEN { 855 parser.state = parser.states[len(parser.states)-1] 856 parser.states = parser.states[:len(parser.states)-1] 857 parser.marks = parser.marks[:len(parser.marks)-1] 858 *event = yaml_event_t{ 859 typ: yaml_MAPPING_END_EVENT, 860 start_mark: token.start_mark, 861 end_mark: token.end_mark, 862 } 863 yaml_parser_set_event_comments(parser, event) 864 skip_token(parser) 865 return true 866 } 867 868 context_mark := parser.marks[len(parser.marks)-1] 869 parser.marks = parser.marks[:len(parser.marks)-1] 870 return yaml_parser_set_parser_error_context(parser, 871 "while parsing a block mapping", context_mark, 872 "did not find expected key", token.start_mark) 873} 874 875// Parse the productions: 876// block_mapping ::= BLOCK-MAPPING_START 877// 878// ((KEY block_node_or_indentless_sequence?)? 879// 880// (VALUE block_node_or_indentless_sequence?)?)* 881// ***** * 882// BLOCK-END 883// 884// 885func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 886 token := peek_token(parser) 887 if token == nil { 888 return false 889 } 890 if token.typ == yaml_VALUE_TOKEN { 891 mark := token.end_mark 892 skip_token(parser) 893 token = peek_token(parser) 894 if token == nil { 895 return false 896 } 897 if token.typ != yaml_KEY_TOKEN && 898 token.typ != yaml_VALUE_TOKEN && 899 token.typ != yaml_BLOCK_END_TOKEN { 900 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) 901 return yaml_parser_parse_node(parser, event, true, true) 902 } 903 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 904 return yaml_parser_process_empty_scalar(parser, event, mark) 905 } 906 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 907 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 908} 909 910// Parse the productions: 911// flow_sequence ::= FLOW-SEQUENCE-START 912// ******************* 913// (flow_sequence_entry FLOW-ENTRY)* 914// * ********** 915// flow_sequence_entry? 916// * 917// FLOW-SEQUENCE-END 918// ***************** 919// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 920// * 921// 922func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 923 if first { 924 token := peek_token(parser) 925 parser.marks = append(parser.marks, token.start_mark) 926 skip_token(parser) 927 } 928 token := peek_token(parser) 929 if token == nil { 930 return false 931 } 932 if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 933 if !first { 934 if token.typ == yaml_FLOW_ENTRY_TOKEN { 935 skip_token(parser) 936 token = peek_token(parser) 937 if token == nil { 938 return false 939 } 940 } else { 941 context_mark := parser.marks[len(parser.marks)-1] 942 parser.marks = parser.marks[:len(parser.marks)-1] 943 return yaml_parser_set_parser_error_context(parser, 944 "while parsing a flow sequence", context_mark, 945 "did not find expected ',' or ']'", token.start_mark) 946 } 947 } 948 949 if token.typ == yaml_KEY_TOKEN { 950 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE 951 *event = yaml_event_t{ 952 typ: yaml_MAPPING_START_EVENT, 953 start_mark: token.start_mark, 954 end_mark: token.end_mark, 955 implicit: true, 956 style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), 957 } 958 skip_token(parser) 959 return true 960 } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 961 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) 962 return yaml_parser_parse_node(parser, event, false, false) 963 } 964 } 965 966 parser.state = parser.states[len(parser.states)-1] 967 parser.states = parser.states[:len(parser.states)-1] 968 parser.marks = parser.marks[:len(parser.marks)-1] 969 970 *event = yaml_event_t{ 971 typ: yaml_SEQUENCE_END_EVENT, 972 start_mark: token.start_mark, 973 end_mark: token.end_mark, 974 } 975 yaml_parser_set_event_comments(parser, event) 976 977 skip_token(parser) 978 return true 979} 980 981// 982// Parse the productions: 983// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 984// *** * 985// 986func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { 987 token := peek_token(parser) 988 if token == nil { 989 return false 990 } 991 if token.typ != yaml_VALUE_TOKEN && 992 token.typ != yaml_FLOW_ENTRY_TOKEN && 993 token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 994 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) 995 return yaml_parser_parse_node(parser, event, false, false) 996 } 997 mark := token.end_mark 998 skip_token(parser) 999 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE 1000 return yaml_parser_process_empty_scalar(parser, event, mark) 1001} 1002 1003// Parse the productions: 1004// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1005// ***** * 1006// 1007func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 1008 token := peek_token(parser) 1009 if token == nil { 1010 return false 1011 } 1012 if token.typ == yaml_VALUE_TOKEN { 1013 skip_token(parser) 1014 token := peek_token(parser) 1015 if token == nil { 1016 return false 1017 } 1018 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 1019 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) 1020 return yaml_parser_parse_node(parser, event, false, false) 1021 } 1022 } 1023 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE 1024 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1025} 1026 1027// Parse the productions: 1028// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1029// * 1030// 1031func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { 1032 token := peek_token(parser) 1033 if token == nil { 1034 return false 1035 } 1036 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE 1037 *event = yaml_event_t{ 1038 typ: yaml_MAPPING_END_EVENT, 1039 start_mark: token.start_mark, 1040 end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? 1041 } 1042 return true 1043} 1044 1045// Parse the productions: 1046// flow_mapping ::= FLOW-MAPPING-START 1047// ****************** 1048// (flow_mapping_entry FLOW-ENTRY)* 1049// * ********** 1050// flow_mapping_entry? 1051// ****************** 1052// FLOW-MAPPING-END 1053// **************** 1054// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1055// * *** * 1056// 1057func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 1058 if first { 1059 token := peek_token(parser) 1060 parser.marks = append(parser.marks, token.start_mark) 1061 skip_token(parser) 1062 } 1063 1064 token := peek_token(parser) 1065 if token == nil { 1066 return false 1067 } 1068 1069 if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1070 if !first { 1071 if token.typ == yaml_FLOW_ENTRY_TOKEN { 1072 skip_token(parser) 1073 token = peek_token(parser) 1074 if token == nil { 1075 return false 1076 } 1077 } else { 1078 context_mark := parser.marks[len(parser.marks)-1] 1079 parser.marks = parser.marks[:len(parser.marks)-1] 1080 return yaml_parser_set_parser_error_context(parser, 1081 "while parsing a flow mapping", context_mark, 1082 "did not find expected ',' or '}'", token.start_mark) 1083 } 1084 } 1085 1086 if token.typ == yaml_KEY_TOKEN { 1087 skip_token(parser) 1088 token = peek_token(parser) 1089 if token == nil { 1090 return false 1091 } 1092 if token.typ != yaml_VALUE_TOKEN && 1093 token.typ != yaml_FLOW_ENTRY_TOKEN && 1094 token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1095 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) 1096 return yaml_parser_parse_node(parser, event, false, false) 1097 } else { 1098 parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE 1099 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1100 } 1101 } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1102 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) 1103 return yaml_parser_parse_node(parser, event, false, false) 1104 } 1105 } 1106 1107 parser.state = parser.states[len(parser.states)-1] 1108 parser.states = parser.states[:len(parser.states)-1] 1109 parser.marks = parser.marks[:len(parser.marks)-1] 1110 *event = yaml_event_t{ 1111 typ: yaml_MAPPING_END_EVENT, 1112 start_mark: token.start_mark, 1113 end_mark: token.end_mark, 1114 } 1115 yaml_parser_set_event_comments(parser, event) 1116 skip_token(parser) 1117 return true 1118} 1119 1120// Parse the productions: 1121// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1122// * ***** * 1123// 1124func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { 1125 token := peek_token(parser) 1126 if token == nil { 1127 return false 1128 } 1129 if empty { 1130 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1131 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1132 } 1133 if token.typ == yaml_VALUE_TOKEN { 1134 skip_token(parser) 1135 token = peek_token(parser) 1136 if token == nil { 1137 return false 1138 } 1139 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1140 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) 1141 return yaml_parser_parse_node(parser, event, false, false) 1142 } 1143 } 1144 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1145 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1146} 1147 1148// Generate an empty scalar event. 1149func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { 1150 *event = yaml_event_t{ 1151 typ: yaml_SCALAR_EVENT, 1152 start_mark: mark, 1153 end_mark: mark, 1154 value: nil, // Empty 1155 implicit: true, 1156 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 1157 } 1158 return true 1159} 1160 1161var default_tag_directives = []yaml_tag_directive_t{ 1162 {[]byte("!"), []byte("!")}, 1163 {[]byte("!!"), []byte("tag:yaml.org,2002:")}, 1164} 1165 1166// Parse directives. 1167func yaml_parser_process_directives(parser *yaml_parser_t, 1168 version_directive_ref **yaml_version_directive_t, 1169 tag_directives_ref *[]yaml_tag_directive_t) bool { 1170 1171 var version_directive *yaml_version_directive_t 1172 var tag_directives []yaml_tag_directive_t 1173 1174 token := peek_token(parser) 1175 if token == nil { 1176 return false 1177 } 1178 1179 for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1180 if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { 1181 if version_directive != nil { 1182 yaml_parser_set_parser_error(parser, 1183 "found duplicate %YAML directive", token.start_mark) 1184 return false 1185 } 1186 if token.major != 1 || token.minor != 1 { 1187 yaml_parser_set_parser_error(parser, 1188 "found incompatible YAML document", token.start_mark) 1189 return false 1190 } 1191 version_directive = &yaml_version_directive_t{ 1192 major: token.major, 1193 minor: token.minor, 1194 } 1195 } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1196 value := yaml_tag_directive_t{ 1197 handle: token.value, 1198 prefix: token.prefix, 1199 } 1200 if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { 1201 return false 1202 } 1203 tag_directives = append(tag_directives, value) 1204 } 1205 1206 skip_token(parser) 1207 token = peek_token(parser) 1208 if token == nil { 1209 return false 1210 } 1211 } 1212 1213 for i := range default_tag_directives { 1214 if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { 1215 return false 1216 } 1217 } 1218 1219 if version_directive_ref != nil { 1220 *version_directive_ref = version_directive 1221 } 1222 if tag_directives_ref != nil { 1223 *tag_directives_ref = tag_directives 1224 } 1225 return true 1226} 1227 1228// Append a tag directive to the directives stack. 1229func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { 1230 for i := range parser.tag_directives { 1231 if bytes.Equal(value.handle, parser.tag_directives[i].handle) { 1232 if allow_duplicates { 1233 return true 1234 } 1235 return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) 1236 } 1237 } 1238 1239 // [Go] I suspect the copy is unnecessary. This was likely done 1240 // because there was no way to track ownership of the data. 1241 value_copy := yaml_tag_directive_t{ 1242 handle: make([]byte, len(value.handle)), 1243 prefix: make([]byte, len(value.prefix)), 1244 } 1245 copy(value_copy.handle, value.handle) 1246 copy(value_copy.prefix, value.prefix) 1247 parser.tag_directives = append(parser.tag_directives, value_copy) 1248 return true 1249} 1250