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 return true 652 } 653 if len(anchor) > 0 || len(tag) > 0 { 654 parser.state = parser.states[len(parser.states)-1] 655 parser.states = parser.states[:len(parser.states)-1] 656 657 *event = yaml_event_t{ 658 typ: yaml_SCALAR_EVENT, 659 start_mark: start_mark, 660 end_mark: end_mark, 661 anchor: anchor, 662 tag: tag, 663 implicit: implicit, 664 quoted_implicit: false, 665 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 666 } 667 return true 668 } 669 670 context := "while parsing a flow node" 671 if block { 672 context = "while parsing a block node" 673 } 674 yaml_parser_set_parser_error_context(parser, context, start_mark, 675 "did not find expected node content", token.start_mark) 676 return false 677} 678 679// Parse the productions: 680// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 681// ******************** *********** * ********* 682// 683func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 684 if first { 685 token := peek_token(parser) 686 parser.marks = append(parser.marks, token.start_mark) 687 skip_token(parser) 688 } 689 690 token := peek_token(parser) 691 if token == nil { 692 return false 693 } 694 695 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 696 mark := token.end_mark 697 prior_head := len(parser.head_comment) 698 skip_token(parser) 699 token = peek_token(parser) 700 if token == nil { 701 return false 702 } 703 if prior_head > 0 && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { 704 // [Go] It's a sequence under a sequence entry, so the former head comment 705 // is for the list itself, not the first list item under it. 706 parser.stem_comment = parser.head_comment[:prior_head] 707 if len(parser.head_comment) == prior_head { 708 parser.head_comment = nil 709 } else { 710 // Copy suffix to prevent very strange bugs if someone ever appends 711 // further bytes to the prefix in the stem_comment slice above. 712 parser.head_comment = append([]byte(nil), parser.head_comment[prior_head+1:]...) 713 } 714 715 } 716 if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { 717 parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) 718 return yaml_parser_parse_node(parser, event, true, false) 719 } else { 720 parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE 721 return yaml_parser_process_empty_scalar(parser, event, mark) 722 } 723 } 724 if token.typ == yaml_BLOCK_END_TOKEN { 725 parser.state = parser.states[len(parser.states)-1] 726 parser.states = parser.states[:len(parser.states)-1] 727 parser.marks = parser.marks[:len(parser.marks)-1] 728 729 *event = yaml_event_t{ 730 typ: yaml_SEQUENCE_END_EVENT, 731 start_mark: token.start_mark, 732 end_mark: token.end_mark, 733 } 734 735 skip_token(parser) 736 return true 737 } 738 739 context_mark := parser.marks[len(parser.marks)-1] 740 parser.marks = parser.marks[:len(parser.marks)-1] 741 return yaml_parser_set_parser_error_context(parser, 742 "while parsing a block collection", context_mark, 743 "did not find expected '-' indicator", token.start_mark) 744} 745 746// Parse the productions: 747// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 748// *********** * 749func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { 750 token := peek_token(parser) 751 if token == nil { 752 return false 753 } 754 755 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 756 mark := token.end_mark 757 skip_token(parser) 758 token = peek_token(parser) 759 if token == nil { 760 return false 761 } 762 if token.typ != yaml_BLOCK_ENTRY_TOKEN && 763 token.typ != yaml_KEY_TOKEN && 764 token.typ != yaml_VALUE_TOKEN && 765 token.typ != yaml_BLOCK_END_TOKEN { 766 parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) 767 return yaml_parser_parse_node(parser, event, true, false) 768 } 769 parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE 770 return yaml_parser_process_empty_scalar(parser, event, mark) 771 } 772 parser.state = parser.states[len(parser.states)-1] 773 parser.states = parser.states[:len(parser.states)-1] 774 775 *event = yaml_event_t{ 776 typ: yaml_SEQUENCE_END_EVENT, 777 start_mark: token.start_mark, 778 end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? 779 } 780 return true 781} 782 783// Parse the productions: 784// block_mapping ::= BLOCK-MAPPING_START 785// ******************* 786// ((KEY block_node_or_indentless_sequence?)? 787// *** * 788// (VALUE block_node_or_indentless_sequence?)?)* 789// 790// BLOCK-END 791// ********* 792// 793func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 794 if first { 795 token := peek_token(parser) 796 parser.marks = append(parser.marks, token.start_mark) 797 skip_token(parser) 798 } 799 800 token := peek_token(parser) 801 if token == nil { 802 return false 803 } 804 805 // [Go] A tail comment was left from the prior mapping value processed. Emit an event 806 // as it needs to be processed with that value and not the following key. 807 if len(parser.tail_comment) > 0 { 808 *event = yaml_event_t{ 809 typ: yaml_TAIL_COMMENT_EVENT, 810 start_mark: token.start_mark, 811 end_mark: token.end_mark, 812 foot_comment: parser.tail_comment, 813 } 814 parser.tail_comment = nil 815 return true 816 } 817 818 if token.typ == yaml_KEY_TOKEN { 819 mark := token.end_mark 820 skip_token(parser) 821 token = peek_token(parser) 822 if token == nil { 823 return false 824 } 825 if token.typ != yaml_KEY_TOKEN && 826 token.typ != yaml_VALUE_TOKEN && 827 token.typ != yaml_BLOCK_END_TOKEN { 828 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) 829 return yaml_parser_parse_node(parser, event, true, true) 830 } else { 831 parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE 832 return yaml_parser_process_empty_scalar(parser, event, mark) 833 } 834 } else if token.typ == yaml_BLOCK_END_TOKEN { 835 parser.state = parser.states[len(parser.states)-1] 836 parser.states = parser.states[:len(parser.states)-1] 837 parser.marks = parser.marks[:len(parser.marks)-1] 838 *event = yaml_event_t{ 839 typ: yaml_MAPPING_END_EVENT, 840 start_mark: token.start_mark, 841 end_mark: token.end_mark, 842 } 843 yaml_parser_set_event_comments(parser, event) 844 skip_token(parser) 845 return true 846 } 847 848 context_mark := parser.marks[len(parser.marks)-1] 849 parser.marks = parser.marks[:len(parser.marks)-1] 850 return yaml_parser_set_parser_error_context(parser, 851 "while parsing a block mapping", context_mark, 852 "did not find expected key", token.start_mark) 853} 854 855// Parse the productions: 856// block_mapping ::= BLOCK-MAPPING_START 857// 858// ((KEY block_node_or_indentless_sequence?)? 859// 860// (VALUE block_node_or_indentless_sequence?)?)* 861// ***** * 862// BLOCK-END 863// 864// 865func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 866 token := peek_token(parser) 867 if token == nil { 868 return false 869 } 870 if token.typ == yaml_VALUE_TOKEN { 871 mark := token.end_mark 872 skip_token(parser) 873 token = peek_token(parser) 874 if token == nil { 875 return false 876 } 877 if token.typ != yaml_KEY_TOKEN && 878 token.typ != yaml_VALUE_TOKEN && 879 token.typ != yaml_BLOCK_END_TOKEN { 880 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) 881 return yaml_parser_parse_node(parser, event, true, true) 882 } 883 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 884 return yaml_parser_process_empty_scalar(parser, event, mark) 885 } 886 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 887 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 888} 889 890// Parse the productions: 891// flow_sequence ::= FLOW-SEQUENCE-START 892// ******************* 893// (flow_sequence_entry FLOW-ENTRY)* 894// * ********** 895// flow_sequence_entry? 896// * 897// FLOW-SEQUENCE-END 898// ***************** 899// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 900// * 901// 902func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 903 if first { 904 token := peek_token(parser) 905 parser.marks = append(parser.marks, token.start_mark) 906 skip_token(parser) 907 } 908 token := peek_token(parser) 909 if token == nil { 910 return false 911 } 912 if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 913 if !first { 914 if token.typ == yaml_FLOW_ENTRY_TOKEN { 915 skip_token(parser) 916 token = peek_token(parser) 917 if token == nil { 918 return false 919 } 920 } else { 921 context_mark := parser.marks[len(parser.marks)-1] 922 parser.marks = parser.marks[:len(parser.marks)-1] 923 return yaml_parser_set_parser_error_context(parser, 924 "while parsing a flow sequence", context_mark, 925 "did not find expected ',' or ']'", token.start_mark) 926 } 927 } 928 929 if token.typ == yaml_KEY_TOKEN { 930 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE 931 *event = yaml_event_t{ 932 typ: yaml_MAPPING_START_EVENT, 933 start_mark: token.start_mark, 934 end_mark: token.end_mark, 935 implicit: true, 936 style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), 937 } 938 skip_token(parser) 939 return true 940 } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 941 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) 942 return yaml_parser_parse_node(parser, event, false, false) 943 } 944 } 945 946 parser.state = parser.states[len(parser.states)-1] 947 parser.states = parser.states[:len(parser.states)-1] 948 parser.marks = parser.marks[:len(parser.marks)-1] 949 950 *event = yaml_event_t{ 951 typ: yaml_SEQUENCE_END_EVENT, 952 start_mark: token.start_mark, 953 end_mark: token.end_mark, 954 } 955 yaml_parser_set_event_comments(parser, event) 956 957 skip_token(parser) 958 return true 959} 960 961// 962// Parse the productions: 963// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 964// *** * 965// 966func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { 967 token := peek_token(parser) 968 if token == nil { 969 return false 970 } 971 if token.typ != yaml_VALUE_TOKEN && 972 token.typ != yaml_FLOW_ENTRY_TOKEN && 973 token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 974 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) 975 return yaml_parser_parse_node(parser, event, false, false) 976 } 977 mark := token.end_mark 978 skip_token(parser) 979 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE 980 return yaml_parser_process_empty_scalar(parser, event, mark) 981} 982 983// Parse the productions: 984// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 985// ***** * 986// 987func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 988 token := peek_token(parser) 989 if token == nil { 990 return false 991 } 992 if token.typ == yaml_VALUE_TOKEN { 993 skip_token(parser) 994 token := peek_token(parser) 995 if token == nil { 996 return false 997 } 998 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 999 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) 1000 return yaml_parser_parse_node(parser, event, false, false) 1001 } 1002 } 1003 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE 1004 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1005} 1006 1007// Parse the productions: 1008// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1009// * 1010// 1011func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { 1012 token := peek_token(parser) 1013 if token == nil { 1014 return false 1015 } 1016 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE 1017 *event = yaml_event_t{ 1018 typ: yaml_MAPPING_END_EVENT, 1019 start_mark: token.start_mark, 1020 end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? 1021 } 1022 return true 1023} 1024 1025// Parse the productions: 1026// flow_mapping ::= FLOW-MAPPING-START 1027// ****************** 1028// (flow_mapping_entry FLOW-ENTRY)* 1029// * ********** 1030// flow_mapping_entry? 1031// ****************** 1032// FLOW-MAPPING-END 1033// **************** 1034// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1035// * *** * 1036// 1037func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 1038 if first { 1039 token := peek_token(parser) 1040 parser.marks = append(parser.marks, token.start_mark) 1041 skip_token(parser) 1042 } 1043 1044 token := peek_token(parser) 1045 if token == nil { 1046 return false 1047 } 1048 1049 if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1050 if !first { 1051 if token.typ == yaml_FLOW_ENTRY_TOKEN { 1052 skip_token(parser) 1053 token = peek_token(parser) 1054 if token == nil { 1055 return false 1056 } 1057 } else { 1058 context_mark := parser.marks[len(parser.marks)-1] 1059 parser.marks = parser.marks[:len(parser.marks)-1] 1060 return yaml_parser_set_parser_error_context(parser, 1061 "while parsing a flow mapping", context_mark, 1062 "did not find expected ',' or '}'", token.start_mark) 1063 } 1064 } 1065 1066 if token.typ == yaml_KEY_TOKEN { 1067 skip_token(parser) 1068 token = peek_token(parser) 1069 if token == nil { 1070 return false 1071 } 1072 if token.typ != yaml_VALUE_TOKEN && 1073 token.typ != yaml_FLOW_ENTRY_TOKEN && 1074 token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1075 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) 1076 return yaml_parser_parse_node(parser, event, false, false) 1077 } else { 1078 parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE 1079 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1080 } 1081 } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1082 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) 1083 return yaml_parser_parse_node(parser, event, false, false) 1084 } 1085 } 1086 1087 parser.state = parser.states[len(parser.states)-1] 1088 parser.states = parser.states[:len(parser.states)-1] 1089 parser.marks = parser.marks[:len(parser.marks)-1] 1090 *event = yaml_event_t{ 1091 typ: yaml_MAPPING_END_EVENT, 1092 start_mark: token.start_mark, 1093 end_mark: token.end_mark, 1094 } 1095 yaml_parser_set_event_comments(parser, event) 1096 skip_token(parser) 1097 return true 1098} 1099 1100// Parse the productions: 1101// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1102// * ***** * 1103// 1104func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { 1105 token := peek_token(parser) 1106 if token == nil { 1107 return false 1108 } 1109 if empty { 1110 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1111 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1112 } 1113 if token.typ == yaml_VALUE_TOKEN { 1114 skip_token(parser) 1115 token = peek_token(parser) 1116 if token == nil { 1117 return false 1118 } 1119 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1120 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) 1121 return yaml_parser_parse_node(parser, event, false, false) 1122 } 1123 } 1124 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1125 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1126} 1127 1128// Generate an empty scalar event. 1129func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { 1130 *event = yaml_event_t{ 1131 typ: yaml_SCALAR_EVENT, 1132 start_mark: mark, 1133 end_mark: mark, 1134 value: nil, // Empty 1135 implicit: true, 1136 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 1137 } 1138 return true 1139} 1140 1141var default_tag_directives = []yaml_tag_directive_t{ 1142 {[]byte("!"), []byte("!")}, 1143 {[]byte("!!"), []byte("tag:yaml.org,2002:")}, 1144} 1145 1146// Parse directives. 1147func yaml_parser_process_directives(parser *yaml_parser_t, 1148 version_directive_ref **yaml_version_directive_t, 1149 tag_directives_ref *[]yaml_tag_directive_t) bool { 1150 1151 var version_directive *yaml_version_directive_t 1152 var tag_directives []yaml_tag_directive_t 1153 1154 token := peek_token(parser) 1155 if token == nil { 1156 return false 1157 } 1158 1159 for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1160 if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { 1161 if version_directive != nil { 1162 yaml_parser_set_parser_error(parser, 1163 "found duplicate %YAML directive", token.start_mark) 1164 return false 1165 } 1166 if token.major != 1 || token.minor != 1 { 1167 yaml_parser_set_parser_error(parser, 1168 "found incompatible YAML document", token.start_mark) 1169 return false 1170 } 1171 version_directive = &yaml_version_directive_t{ 1172 major: token.major, 1173 minor: token.minor, 1174 } 1175 } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1176 value := yaml_tag_directive_t{ 1177 handle: token.value, 1178 prefix: token.prefix, 1179 } 1180 if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { 1181 return false 1182 } 1183 tag_directives = append(tag_directives, value) 1184 } 1185 1186 skip_token(parser) 1187 token = peek_token(parser) 1188 if token == nil { 1189 return false 1190 } 1191 } 1192 1193 for i := range default_tag_directives { 1194 if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { 1195 return false 1196 } 1197 } 1198 1199 if version_directive_ref != nil { 1200 *version_directive_ref = version_directive 1201 } 1202 if tag_directives_ref != nil { 1203 *tag_directives_ref = tag_directives 1204 } 1205 return true 1206} 1207 1208// Append a tag directive to the directives stack. 1209func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { 1210 for i := range parser.tag_directives { 1211 if bytes.Equal(value.handle, parser.tag_directives[i].handle) { 1212 if allow_duplicates { 1213 return true 1214 } 1215 return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) 1216 } 1217 } 1218 1219 // [Go] I suspect the copy is unnecessary. This was likely done 1220 // because there was no way to track ownership of the data. 1221 value_copy := yaml_tag_directive_t{ 1222 handle: make([]byte, len(value.handle)), 1223 prefix: make([]byte, len(value.prefix)), 1224 } 1225 copy(value_copy.handle, value.handle) 1226 copy(value_copy.prefix, value.prefix) 1227 parser.tag_directives = append(parser.tag_directives, value_copy) 1228 return true 1229} 1230