gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

parserc.go (40822B)


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