1package yaml
2
3import (
4	"bytes"
5)
6
7// The parser implements the following grammar:
8//
9// stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
10// implicit_document    ::= block_node DOCUMENT-END*
11// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
12// block_node_or_indentless_sequence    ::=
13//                          ALIAS
14//                          | properties (block_content | indentless_block_sequence)?
15//                          | block_content
16//                          | indentless_block_sequence
17// block_node           ::= ALIAS
18//                          | properties block_content?
19//                          | block_content
20// flow_node            ::= ALIAS
21//                          | properties flow_content?
22//                          | flow_content
23// properties           ::= TAG ANCHOR? | ANCHOR TAG?
24// block_content        ::= block_collection | flow_collection | SCALAR
25// flow_content         ::= flow_collection | SCALAR
26// block_collection     ::= block_sequence | block_mapping
27// flow_collection      ::= flow_sequence | flow_mapping
28// block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
29// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
30// block_mapping        ::= BLOCK-MAPPING_START
31//                          ((KEY block_node_or_indentless_sequence?)?
32//                          (VALUE block_node_or_indentless_sequence?)?)*
33//                          BLOCK-END
34// flow_sequence        ::= FLOW-SEQUENCE-START
35//                          (flow_sequence_entry FLOW-ENTRY)*
36//                          flow_sequence_entry?
37//                          FLOW-SEQUENCE-END
38// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
39// flow_mapping         ::= FLOW-MAPPING-START
40//                          (flow_mapping_entry FLOW-ENTRY)*
41//                          flow_mapping_entry?
42//                          FLOW-MAPPING-END
43// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
44
45// Peek the next token in the token queue.
46func peek_token(parser *yaml_parser_t) *yaml_token_t {
47	if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
48		return &parser.tokens[parser.tokens_head]
49	}
50	return nil
51}
52
53// Remove the next token from the queue (must be called after peek_token).
54func skip_token(parser *yaml_parser_t) {
55	parser.token_available = false
56	parser.tokens_parsed++
57	parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
58	parser.tokens_head++
59}
60
61// Get the next event.
62func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
63	// Erase the event object.
64	*event = yaml_event_t{}
65
66	// No events after the end of the stream or error.
67	if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
68		return true
69	}
70
71	// Generate the next event.
72	return yaml_parser_state_machine(parser, event)
73}
74
75// Set parser error.
76func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
77	parser.error = yaml_PARSER_ERROR
78	parser.problem = problem
79	parser.problem_mark = problem_mark
80	return false
81}
82
83func 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 {
84	parser.error = yaml_PARSER_ERROR
85	parser.context = context
86	parser.context_mark = context_mark
87	parser.problem = problem
88	parser.problem_mark = problem_mark
89	return false
90}
91
92// State dispatcher.
93func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
94	//trace("yaml_parser_state_machine", "state:", parser.state.String())
95
96	switch parser.state {
97	case yaml_PARSE_STREAM_START_STATE:
98		return yaml_parser_parse_stream_start(parser, event)
99
100	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
101		return yaml_parser_parse_document_start(parser, event, true)
102
103	case yaml_PARSE_DOCUMENT_START_STATE:
104		return yaml_parser_parse_document_start(parser, event, false)
105
106	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
107		return yaml_parser_parse_document_content(parser, event)
108
109	case yaml_PARSE_DOCUMENT_END_STATE:
110		return yaml_parser_parse_document_end(parser, event)
111
112	case yaml_PARSE_BLOCK_NODE_STATE:
113		return yaml_parser_parse_node(parser, event, true, false)
114
115	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
116		return yaml_parser_parse_node(parser, event, true, true)
117
118	case yaml_PARSE_FLOW_NODE_STATE:
119		return yaml_parser_parse_node(parser, event, false, false)
120
121	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
122		return yaml_parser_parse_block_sequence_entry(parser, event, true)
123
124	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
125		return yaml_parser_parse_block_sequence_entry(parser, event, false)
126
127	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
128		return yaml_parser_parse_indentless_sequence_entry(parser, event)
129
130	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
131		return yaml_parser_parse_block_mapping_key(parser, event, true)
132
133	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
134		return yaml_parser_parse_block_mapping_key(parser, event, false)
135
136	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
137		return yaml_parser_parse_block_mapping_value(parser, event)
138
139	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
140		return yaml_parser_parse_flow_sequence_entry(parser, event, true)
141
142	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
143		return yaml_parser_parse_flow_sequence_entry(parser, event, false)
144
145	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
146		return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
147
148	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
149		return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
150
151	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
152		return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
153
154	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
155		return yaml_parser_parse_flow_mapping_key(parser, event, true)
156
157	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
158		return yaml_parser_parse_flow_mapping_key(parser, event, false)
159
160	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
161		return yaml_parser_parse_flow_mapping_value(parser, event, false)
162
163	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
164		return yaml_parser_parse_flow_mapping_value(parser, event, true)
165
166	default:
167		panic("invalid parser state")
168	}
169}
170
171// Parse the production:
172// stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
173//              ************
174func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
175	token := peek_token(parser)
176	if token == nil {
177		return false
178	}
179	if token.typ != yaml_STREAM_START_TOKEN {
180		return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
181	}
182	parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
183	*event = yaml_event_t{
184		typ:        yaml_STREAM_START_EVENT,
185		start_mark: token.start_mark,
186		end_mark:   token.end_mark,
187		encoding:   token.encoding,
188	}
189	skip_token(parser)
190	return true
191}
192
193// Parse the productions:
194// implicit_document    ::= block_node DOCUMENT-END*
195//                          *
196// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
197//                          *************************
198func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
199
200	token := peek_token(parser)
201	if token == nil {
202		return false
203	}
204
205	// Parse extra document end indicators.
206	if !implicit {
207		for token.typ == yaml_DOCUMENT_END_TOKEN {
208			skip_token(parser)
209			token = peek_token(parser)
210			if token == nil {
211				return false
212			}
213		}
214	}
215
216	if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
217		token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
218		token.typ != yaml_DOCUMENT_START_TOKEN &&
219		token.typ != yaml_STREAM_END_TOKEN {
220		// Parse an implicit document.
221		if !yaml_parser_process_directives(parser, nil, nil) {
222			return false
223		}
224		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
225		parser.state = yaml_PARSE_BLOCK_NODE_STATE
226
227		*event = yaml_event_t{
228			typ:        yaml_DOCUMENT_START_EVENT,
229			start_mark: token.start_mark,
230			end_mark:   token.end_mark,
231		}
232
233	} else if token.typ != yaml_STREAM_END_TOKEN {
234		// Parse an explicit document.
235		var version_directive *yaml_version_directive_t
236		var tag_directives []yaml_tag_directive_t
237		start_mark := token.start_mark
238		if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
239			return false
240		}
241		token = peek_token(parser)
242		if token == nil {
243			return false
244		}
245		if token.typ != yaml_DOCUMENT_START_TOKEN {
246			yaml_parser_set_parser_error(parser,
247				"did not find expected <document start>", token.start_mark)
248			return false
249		}
250		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
251		parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
252		end_mark := token.end_mark
253
254		*event = yaml_event_t{
255			typ:               yaml_DOCUMENT_START_EVENT,
256			start_mark:        start_mark,
257			end_mark:          end_mark,
258			version_directive: version_directive,
259			tag_directives:    tag_directives,
260			implicit:          false,
261		}
262		skip_token(parser)
263
264	} else {
265		// Parse the stream end.
266		parser.state = yaml_PARSE_END_STATE
267		*event = yaml_event_t{
268			typ:        yaml_STREAM_END_EVENT,
269			start_mark: token.start_mark,
270			end_mark:   token.end_mark,
271		}
272		skip_token(parser)
273	}
274
275	return true
276}
277
278// Parse the productions:
279// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
280//                                                    ***********
281//
282func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
283	token := peek_token(parser)
284	if token == nil {
285		return false
286	}
287	if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
288		token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
289		token.typ == yaml_DOCUMENT_START_TOKEN ||
290		token.typ == yaml_DOCUMENT_END_TOKEN ||
291		token.typ == yaml_STREAM_END_TOKEN {
292		parser.state = parser.states[len(parser.states)-1]
293		parser.states = parser.states[:len(parser.states)-1]
294		return yaml_parser_process_empty_scalar(parser, event,
295			token.start_mark)
296	}
297	return yaml_parser_parse_node(parser, event, true, false)
298}
299
300// Parse the productions:
301// implicit_document    ::= block_node DOCUMENT-END*
302//                                     *************
303// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
304//
305func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
306	token := peek_token(parser)
307	if token == nil {
308		return false
309	}
310
311	start_mark := token.start_mark
312	end_mark := token.start_mark
313
314	implicit := true
315	if token.typ == yaml_DOCUMENT_END_TOKEN {
316		end_mark = token.end_mark
317		skip_token(parser)
318		implicit = false
319	}
320
321	parser.tag_directives = parser.tag_directives[:0]
322
323	parser.state = yaml_PARSE_DOCUMENT_START_STATE
324	*event = yaml_event_t{
325		typ:        yaml_DOCUMENT_END_EVENT,
326		start_mark: start_mark,
327		end_mark:   end_mark,
328		implicit:   implicit,
329	}
330	return true
331}
332
333// Parse the productions:
334// block_node_or_indentless_sequence    ::=
335//                          ALIAS
336//                          *****
337//                          | properties (block_content | indentless_block_sequence)?
338//                            **********  *
339//                          | block_content | indentless_block_sequence
340//                            *
341// block_node           ::= ALIAS
342//                          *****
343//                          | properties block_content?
344//                            ********** *
345//                          | block_content
346//                            *
347// flow_node            ::= ALIAS
348//                          *****
349//                          | properties flow_content?
350//                            ********** *
351//                          | flow_content
352//                            *
353// properties           ::= TAG ANCHOR? | ANCHOR TAG?
354//                          *************************
355// block_content        ::= block_collection | flow_collection | SCALAR
356//                                                               ******
357// flow_content         ::= flow_collection | SCALAR
358//                                            ******
359func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
360	//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
361
362	token := peek_token(parser)
363	if token == nil {
364		return false
365	}
366
367	if token.typ == yaml_ALIAS_TOKEN {
368		parser.state = parser.states[len(parser.states)-1]
369		parser.states = parser.states[:len(parser.states)-1]
370		*event = yaml_event_t{
371			typ:        yaml_ALIAS_EVENT,
372			start_mark: token.start_mark,
373			end_mark:   token.end_mark,
374			anchor:     token.value,
375		}
376		skip_token(parser)
377		return true
378	}
379
380	start_mark := token.start_mark
381	end_mark := token.start_mark
382
383	var tag_token bool
384	var tag_handle, tag_suffix, anchor []byte
385	var tag_mark yaml_mark_t
386	if token.typ == yaml_ANCHOR_TOKEN {
387		anchor = token.value
388		start_mark = token.start_mark
389		end_mark = token.end_mark
390		skip_token(parser)
391		token = peek_token(parser)
392		if token == nil {
393			return false
394		}
395		if token.typ == yaml_TAG_TOKEN {
396			tag_token = true
397			tag_handle = token.value
398			tag_suffix = token.suffix
399			tag_mark = token.start_mark
400			end_mark = token.end_mark
401			skip_token(parser)
402			token = peek_token(parser)
403			if token == nil {
404				return false
405			}
406		}
407	} else if token.typ == yaml_TAG_TOKEN {
408		tag_token = true
409		tag_handle = token.value
410		tag_suffix = token.suffix
411		start_mark = token.start_mark
412		tag_mark = token.start_mark
413		end_mark = token.end_mark
414		skip_token(parser)
415		token = peek_token(parser)
416		if token == nil {
417			return false
418		}
419		if token.typ == yaml_ANCHOR_TOKEN {
420			anchor = token.value
421			end_mark = token.end_mark
422			skip_token(parser)
423			token = peek_token(parser)
424			if token == nil {
425				return false
426			}
427		}
428	}
429
430	var tag []byte
431	if tag_token {
432		if len(tag_handle) == 0 {
433			tag = tag_suffix
434			tag_suffix = nil
435		} else {
436			for i := range parser.tag_directives {
437				if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
438					tag = append([]byte(nil), parser.tag_directives[i].prefix...)
439					tag = append(tag, tag_suffix...)
440					break
441				}
442			}
443			if len(tag) == 0 {
444				yaml_parser_set_parser_error_context(parser,
445					"while parsing a node", start_mark,
446					"found undefined tag handle", tag_mark)
447				return false
448			}
449		}
450	}
451
452	implicit := len(tag) == 0
453	if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
454		end_mark = token.end_mark
455		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
456		*event = yaml_event_t{
457			typ:        yaml_SEQUENCE_START_EVENT,
458			start_mark: start_mark,
459			end_mark:   end_mark,
460			anchor:     anchor,
461			tag:        tag,
462			implicit:   implicit,
463			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
464		}
465		return true
466	}
467	if token.typ == yaml_SCALAR_TOKEN {
468		var plain_implicit, quoted_implicit bool
469		end_mark = token.end_mark
470		if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
471			plain_implicit = true
472		} else if len(tag) == 0 {
473			quoted_implicit = true
474		}
475		parser.state = parser.states[len(parser.states)-1]
476		parser.states = parser.states[:len(parser.states)-1]
477
478		*event = yaml_event_t{
479			typ:             yaml_SCALAR_EVENT,
480			start_mark:      start_mark,
481			end_mark:        end_mark,
482			anchor:          anchor,
483			tag:             tag,
484			value:           token.value,
485			implicit:        plain_implicit,
486			quoted_implicit: quoted_implicit,
487			style:           yaml_style_t(token.style),
488		}
489		skip_token(parser)
490		return true
491	}
492	if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
493		// [Go] Some of the events below can be merged as they differ only on style.
494		end_mark = token.end_mark
495		parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
496		*event = yaml_event_t{
497			typ:        yaml_SEQUENCE_START_EVENT,
498			start_mark: start_mark,
499			end_mark:   end_mark,
500			anchor:     anchor,
501			tag:        tag,
502			implicit:   implicit,
503			style:      yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
504		}
505		return true
506	}
507	if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
508		end_mark = token.end_mark
509		parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
510		*event = yaml_event_t{
511			typ:        yaml_MAPPING_START_EVENT,
512			start_mark: start_mark,
513			end_mark:   end_mark,
514			anchor:     anchor,
515			tag:        tag,
516			implicit:   implicit,
517			style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
518		}
519		return true
520	}
521	if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
522		end_mark = token.end_mark
523		parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
524		*event = yaml_event_t{
525			typ:        yaml_SEQUENCE_START_EVENT,
526			start_mark: start_mark,
527			end_mark:   end_mark,
528			anchor:     anchor,
529			tag:        tag,
530			implicit:   implicit,
531			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
532		}
533		return true
534	}
535	if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
536		end_mark = token.end_mark
537		parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
538		*event = yaml_event_t{
539			typ:        yaml_MAPPING_START_EVENT,
540			start_mark: start_mark,
541			end_mark:   end_mark,
542			anchor:     anchor,
543			tag:        tag,
544			implicit:   implicit,
545			style:      yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
546		}
547		return true
548	}
549	if len(anchor) > 0 || len(tag) > 0 {
550		parser.state = parser.states[len(parser.states)-1]
551		parser.states = parser.states[:len(parser.states)-1]
552
553		*event = yaml_event_t{
554			typ:             yaml_SCALAR_EVENT,
555			start_mark:      start_mark,
556			end_mark:        end_mark,
557			anchor:          anchor,
558			tag:             tag,
559			implicit:        implicit,
560			quoted_implicit: false,
561			style:           yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
562		}
563		return true
564	}
565
566	context := "while parsing a flow node"
567	if block {
568		context = "while parsing a block node"
569	}
570	yaml_parser_set_parser_error_context(parser, context, start_mark,
571		"did not find expected node content", token.start_mark)
572	return false
573}
574
575// Parse the productions:
576// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
577//                    ********************  *********** *             *********
578//
579func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
580	if first {
581		token := peek_token(parser)
582		parser.marks = append(parser.marks, token.start_mark)
583		skip_token(parser)
584	}
585
586	token := peek_token(parser)
587	if token == nil {
588		return false
589	}
590
591	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
592		mark := token.end_mark
593		skip_token(parser)
594		token = peek_token(parser)
595		if token == nil {
596			return false
597		}
598		if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
599			parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
600			return yaml_parser_parse_node(parser, event, true, false)
601		} else {
602			parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
603			return yaml_parser_process_empty_scalar(parser, event, mark)
604		}
605	}
606	if token.typ == yaml_BLOCK_END_TOKEN {
607		parser.state = parser.states[len(parser.states)-1]
608		parser.states = parser.states[:len(parser.states)-1]
609		parser.marks = parser.marks[:len(parser.marks)-1]
610
611		*event = yaml_event_t{
612			typ:        yaml_SEQUENCE_END_EVENT,
613			start_mark: token.start_mark,
614			end_mark:   token.end_mark,
615		}
616
617		skip_token(parser)
618		return true
619	}
620
621	context_mark := parser.marks[len(parser.marks)-1]
622	parser.marks = parser.marks[:len(parser.marks)-1]
623	return yaml_parser_set_parser_error_context(parser,
624		"while parsing a block collection", context_mark,
625		"did not find expected '-' indicator", token.start_mark)
626}
627
628// Parse the productions:
629// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
630//                           *********** *
631func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
632	token := peek_token(parser)
633	if token == nil {
634		return false
635	}
636
637	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
638		mark := token.end_mark
639		skip_token(parser)
640		token = peek_token(parser)
641		if token == nil {
642			return false
643		}
644		if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
645			token.typ != yaml_KEY_TOKEN &&
646			token.typ != yaml_VALUE_TOKEN &&
647			token.typ != yaml_BLOCK_END_TOKEN {
648			parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
649			return yaml_parser_parse_node(parser, event, true, false)
650		}
651		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
652		return yaml_parser_process_empty_scalar(parser, event, mark)
653	}
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_SEQUENCE_END_EVENT,
659		start_mark: token.start_mark,
660		end_mark:   token.start_mark, // [Go] Shouldn't this be token.end_mark?
661	}
662	return true
663}
664
665// Parse the productions:
666// block_mapping        ::= BLOCK-MAPPING_START
667//                          *******************
668//                          ((KEY block_node_or_indentless_sequence?)?
669//                            *** *
670//                          (VALUE block_node_or_indentless_sequence?)?)*
671//
672//                          BLOCK-END
673//                          *********
674//
675func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
676	if first {
677		token := peek_token(parser)
678		parser.marks = append(parser.marks, token.start_mark)
679		skip_token(parser)
680	}
681
682	token := peek_token(parser)
683	if token == nil {
684		return false
685	}
686
687	if token.typ == yaml_KEY_TOKEN {
688		mark := token.end_mark
689		skip_token(parser)
690		token = peek_token(parser)
691		if token == nil {
692			return false
693		}
694		if token.typ != yaml_KEY_TOKEN &&
695			token.typ != yaml_VALUE_TOKEN &&
696			token.typ != yaml_BLOCK_END_TOKEN {
697			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
698			return yaml_parser_parse_node(parser, event, true, true)
699		} else {
700			parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
701			return yaml_parser_process_empty_scalar(parser, event, mark)
702		}
703	} else if token.typ == yaml_BLOCK_END_TOKEN {
704		parser.state = parser.states[len(parser.states)-1]
705		parser.states = parser.states[:len(parser.states)-1]
706		parser.marks = parser.marks[:len(parser.marks)-1]
707		*event = yaml_event_t{
708			typ:        yaml_MAPPING_END_EVENT,
709			start_mark: token.start_mark,
710			end_mark:   token.end_mark,
711		}
712		skip_token(parser)
713		return true
714	}
715
716	context_mark := parser.marks[len(parser.marks)-1]
717	parser.marks = parser.marks[:len(parser.marks)-1]
718	return yaml_parser_set_parser_error_context(parser,
719		"while parsing a block mapping", context_mark,
720		"did not find expected key", token.start_mark)
721}
722
723// Parse the productions:
724// block_mapping        ::= BLOCK-MAPPING_START
725//
726//                          ((KEY block_node_or_indentless_sequence?)?
727//
728//                          (VALUE block_node_or_indentless_sequence?)?)*
729//                           ***** *
730//                          BLOCK-END
731//
732//
733func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
734	token := peek_token(parser)
735	if token == nil {
736		return false
737	}
738	if token.typ == yaml_VALUE_TOKEN {
739		mark := token.end_mark
740		skip_token(parser)
741		token = peek_token(parser)
742		if token == nil {
743			return false
744		}
745		if token.typ != yaml_KEY_TOKEN &&
746			token.typ != yaml_VALUE_TOKEN &&
747			token.typ != yaml_BLOCK_END_TOKEN {
748			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
749			return yaml_parser_parse_node(parser, event, true, true)
750		}
751		parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
752		return yaml_parser_process_empty_scalar(parser, event, mark)
753	}
754	parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
755	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
756}
757
758// Parse the productions:
759// flow_sequence        ::= FLOW-SEQUENCE-START
760//                          *******************
761//                          (flow_sequence_entry FLOW-ENTRY)*
762//                           *                   **********
763//                          flow_sequence_entry?
764//                          *
765//                          FLOW-SEQUENCE-END
766//                          *****************
767// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
768//                          *
769//
770func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
771	if first {
772		token := peek_token(parser)
773		parser.marks = append(parser.marks, token.start_mark)
774		skip_token(parser)
775	}
776	token := peek_token(parser)
777	if token == nil {
778		return false
779	}
780	if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
781		if !first {
782			if token.typ == yaml_FLOW_ENTRY_TOKEN {
783				skip_token(parser)
784				token = peek_token(parser)
785				if token == nil {
786					return false
787				}
788			} else {
789				context_mark := parser.marks[len(parser.marks)-1]
790				parser.marks = parser.marks[:len(parser.marks)-1]
791				return yaml_parser_set_parser_error_context(parser,
792					"while parsing a flow sequence", context_mark,
793					"did not find expected ',' or ']'", token.start_mark)
794			}
795		}
796
797		if token.typ == yaml_KEY_TOKEN {
798			parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
799			*event = yaml_event_t{
800				typ:        yaml_MAPPING_START_EVENT,
801				start_mark: token.start_mark,
802				end_mark:   token.end_mark,
803				implicit:   true,
804				style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
805			}
806			skip_token(parser)
807			return true
808		} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
809			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
810			return yaml_parser_parse_node(parser, event, false, false)
811		}
812	}
813
814	parser.state = parser.states[len(parser.states)-1]
815	parser.states = parser.states[:len(parser.states)-1]
816	parser.marks = parser.marks[:len(parser.marks)-1]
817
818	*event = yaml_event_t{
819		typ:        yaml_SEQUENCE_END_EVENT,
820		start_mark: token.start_mark,
821		end_mark:   token.end_mark,
822	}
823
824	skip_token(parser)
825	return true
826}
827
828//
829// Parse the productions:
830// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
831//                                      *** *
832//
833func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
834	token := peek_token(parser)
835	if token == nil {
836		return false
837	}
838	if token.typ != yaml_VALUE_TOKEN &&
839		token.typ != yaml_FLOW_ENTRY_TOKEN &&
840		token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
841		parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
842		return yaml_parser_parse_node(parser, event, false, false)
843	}
844	mark := token.end_mark
845	skip_token(parser)
846	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
847	return yaml_parser_process_empty_scalar(parser, event, mark)
848}
849
850// Parse the productions:
851// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
852//                                                      ***** *
853//
854func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
855	token := peek_token(parser)
856	if token == nil {
857		return false
858	}
859	if token.typ == yaml_VALUE_TOKEN {
860		skip_token(parser)
861		token := peek_token(parser)
862		if token == nil {
863			return false
864		}
865		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
866			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
867			return yaml_parser_parse_node(parser, event, false, false)
868		}
869	}
870	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
871	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
872}
873
874// Parse the productions:
875// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
876//                                                                      *
877//
878func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
879	token := peek_token(parser)
880	if token == nil {
881		return false
882	}
883	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
884	*event = yaml_event_t{
885		typ:        yaml_MAPPING_END_EVENT,
886		start_mark: token.start_mark,
887		end_mark:   token.start_mark, // [Go] Shouldn't this be end_mark?
888	}
889	return true
890}
891
892// Parse the productions:
893// flow_mapping         ::= FLOW-MAPPING-START
894//                          ******************
895//                          (flow_mapping_entry FLOW-ENTRY)*
896//                           *                  **********
897//                          flow_mapping_entry?
898//                          ******************
899//                          FLOW-MAPPING-END
900//                          ****************
901// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
902//                          *           *** *
903//
904func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
905	if first {
906		token := peek_token(parser)
907		parser.marks = append(parser.marks, token.start_mark)
908		skip_token(parser)
909	}
910
911	token := peek_token(parser)
912	if token == nil {
913		return false
914	}
915
916	if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
917		if !first {
918			if token.typ == yaml_FLOW_ENTRY_TOKEN {
919				skip_token(parser)
920				token = peek_token(parser)
921				if token == nil {
922					return false
923				}
924			} else {
925				context_mark := parser.marks[len(parser.marks)-1]
926				parser.marks = parser.marks[:len(parser.marks)-1]
927				return yaml_parser_set_parser_error_context(parser,
928					"while parsing a flow mapping", context_mark,
929					"did not find expected ',' or '}'", token.start_mark)
930			}
931		}
932
933		if token.typ == yaml_KEY_TOKEN {
934			skip_token(parser)
935			token = peek_token(parser)
936			if token == nil {
937				return false
938			}
939			if token.typ != yaml_VALUE_TOKEN &&
940				token.typ != yaml_FLOW_ENTRY_TOKEN &&
941				token.typ != yaml_FLOW_MAPPING_END_TOKEN {
942				parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
943				return yaml_parser_parse_node(parser, event, false, false)
944			} else {
945				parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
946				return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
947			}
948		} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
949			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
950			return yaml_parser_parse_node(parser, event, false, false)
951		}
952	}
953
954	parser.state = parser.states[len(parser.states)-1]
955	parser.states = parser.states[:len(parser.states)-1]
956	parser.marks = parser.marks[:len(parser.marks)-1]
957	*event = yaml_event_t{
958		typ:        yaml_MAPPING_END_EVENT,
959		start_mark: token.start_mark,
960		end_mark:   token.end_mark,
961	}
962	skip_token(parser)
963	return true
964}
965
966// Parse the productions:
967// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
968//                                   *                  ***** *
969//
970func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
971	token := peek_token(parser)
972	if token == nil {
973		return false
974	}
975	if empty {
976		parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
977		return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
978	}
979	if token.typ == yaml_VALUE_TOKEN {
980		skip_token(parser)
981		token = peek_token(parser)
982		if token == nil {
983			return false
984		}
985		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
986			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
987			return yaml_parser_parse_node(parser, event, false, false)
988		}
989	}
990	parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
991	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
992}
993
994// Generate an empty scalar event.
995func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
996	*event = yaml_event_t{
997		typ:        yaml_SCALAR_EVENT,
998		start_mark: mark,
999		end_mark:   mark,
1000		value:      nil, // Empty
1001		implicit:   true,
1002		style:      yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
1003	}
1004	return true
1005}
1006
1007var default_tag_directives = []yaml_tag_directive_t{
1008	{[]byte("!"), []byte("!")},
1009	{[]byte("!!"), []byte("tag:yaml.org,2002:")},
1010}
1011
1012// Parse directives.
1013func yaml_parser_process_directives(parser *yaml_parser_t,
1014	version_directive_ref **yaml_version_directive_t,
1015	tag_directives_ref *[]yaml_tag_directive_t) bool {
1016
1017	var version_directive *yaml_version_directive_t
1018	var tag_directives []yaml_tag_directive_t
1019
1020	token := peek_token(parser)
1021	if token == nil {
1022		return false
1023	}
1024
1025	for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1026		if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
1027			if version_directive != nil {
1028				yaml_parser_set_parser_error(parser,
1029					"found duplicate %YAML directive", token.start_mark)
1030				return false
1031			}
1032			if token.major != 1 || token.minor != 1 {
1033				yaml_parser_set_parser_error(parser,
1034					"found incompatible YAML document", token.start_mark)
1035				return false
1036			}
1037			version_directive = &yaml_version_directive_t{
1038				major: token.major,
1039				minor: token.minor,
1040			}
1041		} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1042			value := yaml_tag_directive_t{
1043				handle: token.value,
1044				prefix: token.prefix,
1045			}
1046			if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
1047				return false
1048			}
1049			tag_directives = append(tag_directives, value)
1050		}
1051
1052		skip_token(parser)
1053		token = peek_token(parser)
1054		if token == nil {
1055			return false
1056		}
1057	}
1058
1059	for i := range default_tag_directives {
1060		if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
1061			return false
1062		}
1063	}
1064
1065	if version_directive_ref != nil {
1066		*version_directive_ref = version_directive
1067	}
1068	if tag_directives_ref != nil {
1069		*tag_directives_ref = tag_directives
1070	}
1071	return true
1072}
1073
1074// Append a tag directive to the directives stack.
1075func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
1076	for i := range parser.tag_directives {
1077		if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
1078			if allow_duplicates {
1079				return true
1080			}
1081			return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
1082		}
1083	}
1084
1085	// [Go] I suspect the copy is unnecessary. This was likely done
1086	// because there was no way to track ownership of the data.
1087	value_copy := yaml_tag_directive_t{
1088		handle: make([]byte, len(value.handle)),
1089		prefix: make([]byte, len(value.prefix)),
1090	}
1091	copy(value_copy.handle, value.handle)
1092	copy(value_copy.prefix, value.prefix)
1093	parser.tag_directives = append(parser.tag_directives, value_copy)
1094	return true
1095}
1096