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	"fmt"
28)
29
30// Flush the buffer if needed.
31func flush(emitter *yaml_emitter_t) bool {
32	if emitter.buffer_pos+5 >= len(emitter.buffer) {
33		return yaml_emitter_flush(emitter)
34	}
35	return true
36}
37
38// Put a character to the output buffer.
39func put(emitter *yaml_emitter_t, value byte) bool {
40	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
41		return false
42	}
43	emitter.buffer[emitter.buffer_pos] = value
44	emitter.buffer_pos++
45	emitter.column++
46	return true
47}
48
49// Put a line break to the output buffer.
50func put_break(emitter *yaml_emitter_t) bool {
51	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
52		return false
53	}
54	switch emitter.line_break {
55	case yaml_CR_BREAK:
56		emitter.buffer[emitter.buffer_pos] = '\r'
57		emitter.buffer_pos += 1
58	case yaml_LN_BREAK:
59		emitter.buffer[emitter.buffer_pos] = '\n'
60		emitter.buffer_pos += 1
61	case yaml_CRLN_BREAK:
62		emitter.buffer[emitter.buffer_pos+0] = '\r'
63		emitter.buffer[emitter.buffer_pos+1] = '\n'
64		emitter.buffer_pos += 2
65	default:
66		panic("unknown line break setting")
67	}
68	if emitter.column == 0 {
69		emitter.space_above = true
70	}
71	emitter.column = 0
72	emitter.line++
73	// [Go] Do this here and below and drop from everywhere else (see commented lines).
74	emitter.indention = true
75	return true
76}
77
78// Copy a character from a string into buffer.
79func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
80	if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
81		return false
82	}
83	p := emitter.buffer_pos
84	w := width(s[*i])
85	switch w {
86	case 4:
87		emitter.buffer[p+3] = s[*i+3]
88		fallthrough
89	case 3:
90		emitter.buffer[p+2] = s[*i+2]
91		fallthrough
92	case 2:
93		emitter.buffer[p+1] = s[*i+1]
94		fallthrough
95	case 1:
96		emitter.buffer[p+0] = s[*i+0]
97	default:
98		panic("unknown character width")
99	}
100	emitter.column++
101	emitter.buffer_pos += w
102	*i += w
103	return true
104}
105
106// Write a whole string into buffer.
107func write_all(emitter *yaml_emitter_t, s []byte) bool {
108	for i := 0; i < len(s); {
109		if !write(emitter, s, &i) {
110			return false
111		}
112	}
113	return true
114}
115
116// Copy a line break character from a string into buffer.
117func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
118	if s[*i] == '\n' {
119		if !put_break(emitter) {
120			return false
121		}
122		*i++
123	} else {
124		if !write(emitter, s, i) {
125			return false
126		}
127		if emitter.column == 0 {
128			emitter.space_above = true
129		}
130		emitter.column = 0
131		emitter.line++
132		// [Go] Do this here and above and drop from everywhere else (see commented lines).
133		emitter.indention = true
134	}
135	return true
136}
137
138// Set an emitter error and return false.
139func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
140	emitter.error = yaml_EMITTER_ERROR
141	emitter.problem = problem
142	return false
143}
144
145// Emit an event.
146func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {
147	emitter.events = append(emitter.events, *event)
148	for !yaml_emitter_need_more_events(emitter) {
149		event := &emitter.events[emitter.events_head]
150		if !yaml_emitter_analyze_event(emitter, event) {
151			return false
152		}
153		if !yaml_emitter_state_machine(emitter, event) {
154			return false
155		}
156		yaml_event_delete(event)
157		emitter.events_head++
158	}
159	return true
160}
161
162// Check if we need to accumulate more events before emitting.
163//
164// We accumulate extra
165//  - 1 event for DOCUMENT-START
166//  - 2 events for SEQUENCE-START
167//  - 3 events for MAPPING-START
168//
169func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
170	if emitter.events_head == len(emitter.events) {
171		return true
172	}
173	var accumulate int
174	switch emitter.events[emitter.events_head].typ {
175	case yaml_DOCUMENT_START_EVENT:
176		accumulate = 1
177		break
178	case yaml_SEQUENCE_START_EVENT:
179		accumulate = 2
180		break
181	case yaml_MAPPING_START_EVENT:
182		accumulate = 3
183		break
184	default:
185		return false
186	}
187	if len(emitter.events)-emitter.events_head > accumulate {
188		return false
189	}
190	var level int
191	for i := emitter.events_head; i < len(emitter.events); i++ {
192		switch emitter.events[i].typ {
193		case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:
194			level++
195		case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
196			level--
197		}
198		if level == 0 {
199			return false
200		}
201	}
202	return true
203}
204
205// Append a directive to the directives stack.
206func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {
207	for i := 0; i < len(emitter.tag_directives); i++ {
208		if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {
209			if allow_duplicates {
210				return true
211			}
212			return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
213		}
214	}
215
216	// [Go] Do we actually need to copy this given garbage collection
217	// and the lack of deallocating destructors?
218	tag_copy := yaml_tag_directive_t{
219		handle: make([]byte, len(value.handle)),
220		prefix: make([]byte, len(value.prefix)),
221	}
222	copy(tag_copy.handle, value.handle)
223	copy(tag_copy.prefix, value.prefix)
224	emitter.tag_directives = append(emitter.tag_directives, tag_copy)
225	return true
226}
227
228// Increase the indentation level.
229func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {
230	emitter.indents = append(emitter.indents, emitter.indent)
231	if emitter.indent < 0 {
232		if flow {
233			emitter.indent = emitter.best_indent
234		} else {
235			emitter.indent = 0
236		}
237	} else if !indentless {
238		// [Go] This was changed so that indentations are more regular.
239		if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {
240			// The first indent inside a sequence will just skip the "- " indicator.
241			emitter.indent += 2
242		} else {
243			// Everything else aligns to the chosen indentation.
244			emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent)
245		}
246	}
247	return true
248}
249
250// State dispatcher.
251func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
252	switch emitter.state {
253	default:
254	case yaml_EMIT_STREAM_START_STATE:
255		return yaml_emitter_emit_stream_start(emitter, event)
256
257	case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
258		return yaml_emitter_emit_document_start(emitter, event, true)
259
260	case yaml_EMIT_DOCUMENT_START_STATE:
261		return yaml_emitter_emit_document_start(emitter, event, false)
262
263	case yaml_EMIT_DOCUMENT_CONTENT_STATE:
264		return yaml_emitter_emit_document_content(emitter, event)
265
266	case yaml_EMIT_DOCUMENT_END_STATE:
267		return yaml_emitter_emit_document_end(emitter, event)
268
269	case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
270		return yaml_emitter_emit_flow_sequence_item(emitter, event, true, false)
271
272	case yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE:
273		return yaml_emitter_emit_flow_sequence_item(emitter, event, false, true)
274
275	case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
276		return yaml_emitter_emit_flow_sequence_item(emitter, event, false, false)
277
278	case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
279		return yaml_emitter_emit_flow_mapping_key(emitter, event, true, false)
280
281	case yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE:
282		return yaml_emitter_emit_flow_mapping_key(emitter, event, false, true)
283
284	case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
285		return yaml_emitter_emit_flow_mapping_key(emitter, event, false, false)
286
287	case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
288		return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
289
290	case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
291		return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
292
293	case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
294		return yaml_emitter_emit_block_sequence_item(emitter, event, true)
295
296	case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
297		return yaml_emitter_emit_block_sequence_item(emitter, event, false)
298
299	case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
300		return yaml_emitter_emit_block_mapping_key(emitter, event, true)
301
302	case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
303		return yaml_emitter_emit_block_mapping_key(emitter, event, false)
304
305	case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
306		return yaml_emitter_emit_block_mapping_value(emitter, event, true)
307
308	case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
309		return yaml_emitter_emit_block_mapping_value(emitter, event, false)
310
311	case yaml_EMIT_END_STATE:
312		return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
313	}
314	panic("invalid emitter state")
315}
316
317// Expect STREAM-START.
318func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
319	if event.typ != yaml_STREAM_START_EVENT {
320		return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")
321	}
322	if emitter.encoding == yaml_ANY_ENCODING {
323		emitter.encoding = event.encoding
324		if emitter.encoding == yaml_ANY_ENCODING {
325			emitter.encoding = yaml_UTF8_ENCODING
326		}
327	}
328	if emitter.best_indent < 2 || emitter.best_indent > 9 {
329		emitter.best_indent = 2
330	}
331	if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
332		emitter.best_width = 80
333	}
334	if emitter.best_width < 0 {
335		emitter.best_width = 1<<31 - 1
336	}
337	if emitter.line_break == yaml_ANY_BREAK {
338		emitter.line_break = yaml_LN_BREAK
339	}
340
341	emitter.indent = -1
342	emitter.line = 0
343	emitter.column = 0
344	emitter.whitespace = true
345	emitter.indention = true
346	emitter.space_above = true
347	emitter.foot_indent = -1
348
349	if emitter.encoding != yaml_UTF8_ENCODING {
350		if !yaml_emitter_write_bom(emitter) {
351			return false
352		}
353	}
354	emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
355	return true
356}
357
358// Expect DOCUMENT-START or STREAM-END.
359func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
360
361	if event.typ == yaml_DOCUMENT_START_EVENT {
362
363		if event.version_directive != nil {
364			if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
365				return false
366			}
367		}
368
369		for i := 0; i < len(event.tag_directives); i++ {
370			tag_directive := &event.tag_directives[i]
371			if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {
372				return false
373			}
374			if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
375				return false
376			}
377		}
378
379		for i := 0; i < len(default_tag_directives); i++ {
380			tag_directive := &default_tag_directives[i]
381			if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {
382				return false
383			}
384		}
385
386		implicit := event.implicit
387		if !first || emitter.canonical {
388			implicit = false
389		}
390
391		if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {
392			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
393				return false
394			}
395			if !yaml_emitter_write_indent(emitter) {
396				return false
397			}
398		}
399
400		if event.version_directive != nil {
401			implicit = false
402			if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
403				return false
404			}
405			if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
406				return false
407			}
408			if !yaml_emitter_write_indent(emitter) {
409				return false
410			}
411		}
412
413		if len(event.tag_directives) > 0 {
414			implicit = false
415			for i := 0; i < len(event.tag_directives); i++ {
416				tag_directive := &event.tag_directives[i]
417				if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {
418					return false
419				}
420				if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
421					return false
422				}
423				if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
424					return false
425				}
426				if !yaml_emitter_write_indent(emitter) {
427					return false
428				}
429			}
430		}
431
432		if yaml_emitter_check_empty_document(emitter) {
433			implicit = false
434		}
435		if !implicit {
436			if !yaml_emitter_write_indent(emitter) {
437				return false
438			}
439			if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
440				return false
441			}
442			if emitter.canonical || true {
443				if !yaml_emitter_write_indent(emitter) {
444					return false
445				}
446			}
447		}
448
449		if len(emitter.head_comment) > 0 {
450			if !yaml_emitter_process_head_comment(emitter) {
451				return false
452			}
453			if !put_break(emitter) {
454				return false
455			}
456		}
457
458		emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
459		return true
460	}
461
462	if event.typ == yaml_STREAM_END_EVENT {
463		if emitter.open_ended {
464			if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
465				return false
466			}
467			if !yaml_emitter_write_indent(emitter) {
468				return false
469			}
470		}
471		if !yaml_emitter_flush(emitter) {
472			return false
473		}
474		emitter.state = yaml_EMIT_END_STATE
475		return true
476	}
477
478	return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
479}
480
481// Expect the root node.
482func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {
483	emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)
484
485	if !yaml_emitter_process_head_comment(emitter) {
486		return false
487	}
488	if !yaml_emitter_emit_node(emitter, event, true, false, false, false) {
489		return false
490	}
491	if !yaml_emitter_process_line_comment(emitter) {
492		return false
493	}
494	if !yaml_emitter_process_foot_comment(emitter) {
495		return false
496	}
497	return true
498}
499
500// Expect DOCUMENT-END.
501func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {
502	if event.typ != yaml_DOCUMENT_END_EVENT {
503		return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")
504	}
505	// [Go] Force document foot separation.
506	emitter.foot_indent = 0
507	if !yaml_emitter_process_foot_comment(emitter) {
508		return false
509	}
510	emitter.foot_indent = -1
511	if !yaml_emitter_write_indent(emitter) {
512		return false
513	}
514	if !event.implicit {
515		// [Go] Allocate the slice elsewhere.
516		if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
517			return false
518		}
519		if !yaml_emitter_write_indent(emitter) {
520			return false
521		}
522	}
523	if !yaml_emitter_flush(emitter) {
524		return false
525	}
526	emitter.state = yaml_EMIT_DOCUMENT_START_STATE
527	emitter.tag_directives = emitter.tag_directives[:0]
528	return true
529}
530
531// Expect a flow item node.
532func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {
533	if first {
534		if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
535			return false
536		}
537		if !yaml_emitter_increase_indent(emitter, true, false) {
538			return false
539		}
540		emitter.flow_level++
541	}
542
543	if event.typ == yaml_SEQUENCE_END_EVENT {
544		if emitter.canonical && !first && !trail {
545			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
546				return false
547			}
548		}
549		emitter.flow_level--
550		emitter.indent = emitter.indents[len(emitter.indents)-1]
551		emitter.indents = emitter.indents[:len(emitter.indents)-1]
552		if emitter.column == 0 || emitter.canonical && !first {
553			if !yaml_emitter_write_indent(emitter) {
554				return false
555			}
556		}
557		if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
558			return false
559		}
560		if !yaml_emitter_process_line_comment(emitter) {
561			return false
562		}
563		if !yaml_emitter_process_foot_comment(emitter) {
564			return false
565		}
566		emitter.state = emitter.states[len(emitter.states)-1]
567		emitter.states = emitter.states[:len(emitter.states)-1]
568
569		return true
570	}
571
572	if !first && !trail {
573		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
574			return false
575		}
576	}
577
578	if !yaml_emitter_process_head_comment(emitter) {
579		return false
580	}
581	if emitter.column == 0 {
582		if !yaml_emitter_write_indent(emitter) {
583			return false
584		}
585	}
586
587	if emitter.canonical || emitter.column > emitter.best_width {
588		if !yaml_emitter_write_indent(emitter) {
589			return false
590		}
591	}
592	if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {
593		emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE)
594	} else {
595		emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
596	}
597	if !yaml_emitter_emit_node(emitter, event, false, true, false, false) {
598		return false
599	}
600	if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {
601		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
602			return false
603		}
604	}
605	if !yaml_emitter_process_line_comment(emitter) {
606		return false
607	}
608	if !yaml_emitter_process_foot_comment(emitter) {
609		return false
610	}
611	return true
612}
613
614// Expect a flow key node.
615func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {
616	if first {
617		if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
618			return false
619		}
620		if !yaml_emitter_increase_indent(emitter, true, false) {
621			return false
622		}
623		emitter.flow_level++
624	}
625
626	if event.typ == yaml_MAPPING_END_EVENT {
627		if (emitter.canonical || len(emitter.head_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0) && !first && !trail {
628			if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
629				return false
630			}
631		}
632		if !yaml_emitter_process_head_comment(emitter) {
633			return false
634		}
635		emitter.flow_level--
636		emitter.indent = emitter.indents[len(emitter.indents)-1]
637		emitter.indents = emitter.indents[:len(emitter.indents)-1]
638		if emitter.canonical && !first {
639			if !yaml_emitter_write_indent(emitter) {
640				return false
641			}
642		}
643		if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
644			return false
645		}
646		if !yaml_emitter_process_line_comment(emitter) {
647			return false
648		}
649		if !yaml_emitter_process_foot_comment(emitter) {
650			return false
651		}
652		emitter.state = emitter.states[len(emitter.states)-1]
653		emitter.states = emitter.states[:len(emitter.states)-1]
654		return true
655	}
656
657	if !first && !trail {
658		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
659			return false
660		}
661	}
662
663	if !yaml_emitter_process_head_comment(emitter) {
664		return false
665	}
666
667	if emitter.column == 0 {
668		if !yaml_emitter_write_indent(emitter) {
669			return false
670		}
671	}
672
673	if emitter.canonical || emitter.column > emitter.best_width {
674		if !yaml_emitter_write_indent(emitter) {
675			return false
676		}
677	}
678
679	if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {
680		emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)
681		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
682	}
683	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
684		return false
685	}
686	emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
687	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
688}
689
690// Expect a flow value node.
691func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
692	if simple {
693		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
694			return false
695		}
696	} else {
697		if emitter.canonical || emitter.column > emitter.best_width {
698			if !yaml_emitter_write_indent(emitter) {
699				return false
700			}
701		}
702		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
703			return false
704		}
705	}
706	if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {
707		emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE)
708	} else {
709		emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
710	}
711	if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {
712		return false
713	}
714	if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {
715		if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
716			return false
717		}
718	}
719	if !yaml_emitter_process_line_comment(emitter) {
720		return false
721	}
722	if !yaml_emitter_process_foot_comment(emitter) {
723		return false
724	}
725	return true
726}
727
728// Expect a block item node.
729func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
730	if first {
731		if !yaml_emitter_increase_indent(emitter, false, false) {
732			return false
733		}
734	}
735	if event.typ == yaml_SEQUENCE_END_EVENT {
736		emitter.indent = emitter.indents[len(emitter.indents)-1]
737		emitter.indents = emitter.indents[:len(emitter.indents)-1]
738		emitter.state = emitter.states[len(emitter.states)-1]
739		emitter.states = emitter.states[:len(emitter.states)-1]
740		return true
741	}
742	if !yaml_emitter_process_head_comment(emitter) {
743		return false
744	}
745	if !yaml_emitter_write_indent(emitter) {
746		return false
747	}
748	if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
749		return false
750	}
751	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
752	if !yaml_emitter_emit_node(emitter, event, false, true, false, false) {
753		return false
754	}
755	if !yaml_emitter_process_line_comment(emitter) {
756		return false
757	}
758	if !yaml_emitter_process_foot_comment(emitter) {
759		return false
760	}
761	return true
762}
763
764// Expect a block key node.
765func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
766	if first {
767		if !yaml_emitter_increase_indent(emitter, false, false) {
768			return false
769		}
770	}
771	if !yaml_emitter_process_head_comment(emitter) {
772		return false
773	}
774	if event.typ == yaml_MAPPING_END_EVENT {
775		emitter.indent = emitter.indents[len(emitter.indents)-1]
776		emitter.indents = emitter.indents[:len(emitter.indents)-1]
777		emitter.state = emitter.states[len(emitter.states)-1]
778		emitter.states = emitter.states[:len(emitter.states)-1]
779		return true
780	}
781	if !yaml_emitter_write_indent(emitter) {
782		return false
783	}
784	if len(emitter.line_comment) > 0 {
785		// [Go] A line comment was provided for the key. That's unusual as the
786		//      scanner associates line comments with the value. Either way,
787		//      save the line comment and render it appropriately later.
788		emitter.key_line_comment = emitter.line_comment
789		emitter.line_comment = nil
790	}
791	if yaml_emitter_check_simple_key(emitter) {
792		emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
793		return yaml_emitter_emit_node(emitter, event, false, false, true, true)
794	}
795	if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
796		return false
797	}
798	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
799	return yaml_emitter_emit_node(emitter, event, false, false, true, false)
800}
801
802// Expect a block value node.
803func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
804	if simple {
805		if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
806			return false
807		}
808	} else {
809		if !yaml_emitter_write_indent(emitter) {
810			return false
811		}
812		if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
813			return false
814		}
815	}
816	if len(emitter.key_line_comment) > 0 {
817		// [Go] A line comment was previously provided for the key. Handle it before
818		//      the value so the inline comments are placed correctly.
819		if yaml_emitter_silent_nil_event(emitter, event) && len(emitter.line_comment) == 0 {
820			// Nothing other than the line comment will be written on the line.
821			emitter.line_comment = emitter.key_line_comment
822			emitter.key_line_comment = nil
823		} else {
824			// An actual value is coming, so emit the comment line.
825			emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment
826			if !yaml_emitter_process_line_comment(emitter) {
827				return false
828			}
829			emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment
830			// Indent in unless it's a block that will reindent anyway.
831			if event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE || (event.typ != yaml_MAPPING_START_EVENT && event.typ != yaml_SEQUENCE_START_EVENT) {
832				emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent)
833				if !yaml_emitter_write_indent(emitter) {
834					return false
835				}
836			}
837		}
838	}
839	emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
840	if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {
841		return false
842	}
843	if !yaml_emitter_process_line_comment(emitter) {
844		return false
845	}
846	if !yaml_emitter_process_foot_comment(emitter) {
847		return false
848	}
849	return true
850}
851
852func yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
853	return event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0
854}
855
856// Expect a node.
857func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
858	root bool, sequence bool, mapping bool, simple_key bool) bool {
859
860	emitter.root_context = root
861	emitter.sequence_context = sequence
862	emitter.mapping_context = mapping
863	emitter.simple_key_context = simple_key
864
865	switch event.typ {
866	case yaml_ALIAS_EVENT:
867		return yaml_emitter_emit_alias(emitter, event)
868	case yaml_SCALAR_EVENT:
869		return yaml_emitter_emit_scalar(emitter, event)
870	case yaml_SEQUENCE_START_EVENT:
871		return yaml_emitter_emit_sequence_start(emitter, event)
872	case yaml_MAPPING_START_EVENT:
873		return yaml_emitter_emit_mapping_start(emitter, event)
874	default:
875		return yaml_emitter_set_emitter_error(emitter,
876			fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
877	}
878}
879
880// Expect ALIAS.
881func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
882	if !yaml_emitter_process_anchor(emitter) {
883		return false
884	}
885	emitter.state = emitter.states[len(emitter.states)-1]
886	emitter.states = emitter.states[:len(emitter.states)-1]
887	return true
888}
889
890// Expect SCALAR.
891func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
892	if !yaml_emitter_select_scalar_style(emitter, event) {
893		return false
894	}
895	if !yaml_emitter_process_anchor(emitter) {
896		return false
897	}
898	if !yaml_emitter_process_tag(emitter) {
899		return false
900	}
901	if !yaml_emitter_increase_indent(emitter, true, false) {
902		return false
903	}
904	if !yaml_emitter_process_scalar(emitter) {
905		return false
906	}
907	emitter.indent = emitter.indents[len(emitter.indents)-1]
908	emitter.indents = emitter.indents[:len(emitter.indents)-1]
909	emitter.state = emitter.states[len(emitter.states)-1]
910	emitter.states = emitter.states[:len(emitter.states)-1]
911	return true
912}
913
914// Expect SEQUENCE-START.
915func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
916	if !yaml_emitter_process_anchor(emitter) {
917		return false
918	}
919	if !yaml_emitter_process_tag(emitter) {
920		return false
921	}
922	if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||
923		yaml_emitter_check_empty_sequence(emitter) {
924		emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE
925	} else {
926		emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
927	}
928	return true
929}
930
931// Expect MAPPING-START.
932func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
933	if !yaml_emitter_process_anchor(emitter) {
934		return false
935	}
936	if !yaml_emitter_process_tag(emitter) {
937		return false
938	}
939	if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||
940		yaml_emitter_check_empty_mapping(emitter) {
941		emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE
942	} else {
943		emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
944	}
945	return true
946}
947
948// Check if the document content is an empty scalar.
949func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
950	return false // [Go] Huh?
951}
952
953// Check if the next events represent an empty sequence.
954func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
955	if len(emitter.events)-emitter.events_head < 2 {
956		return false
957	}
958	return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
959		emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
960}
961
962// Check if the next events represent an empty mapping.
963func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
964	if len(emitter.events)-emitter.events_head < 2 {
965		return false
966	}
967	return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
968		emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
969}
970
971// Check if the next node can be expressed as a simple key.
972func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
973	length := 0
974	switch emitter.events[emitter.events_head].typ {
975	case yaml_ALIAS_EVENT:
976		length += len(emitter.anchor_data.anchor)
977	case yaml_SCALAR_EVENT:
978		if emitter.scalar_data.multiline {
979			return false
980		}
981		length += len(emitter.anchor_data.anchor) +
982			len(emitter.tag_data.handle) +
983			len(emitter.tag_data.suffix) +
984			len(emitter.scalar_data.value)
985	case yaml_SEQUENCE_START_EVENT:
986		if !yaml_emitter_check_empty_sequence(emitter) {
987			return false
988		}
989		length += len(emitter.anchor_data.anchor) +
990			len(emitter.tag_data.handle) +
991			len(emitter.tag_data.suffix)
992	case yaml_MAPPING_START_EVENT:
993		if !yaml_emitter_check_empty_mapping(emitter) {
994			return false
995		}
996		length += len(emitter.anchor_data.anchor) +
997			len(emitter.tag_data.handle) +
998			len(emitter.tag_data.suffix)
999	default:
1000		return false
1001	}
1002	return length <= 128
1003}
1004
1005// Determine an acceptable scalar style.
1006func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
1007
1008	no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0
1009	if no_tag && !event.implicit && !event.quoted_implicit {
1010		return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")
1011	}
1012
1013	style := event.scalar_style()
1014	if style == yaml_ANY_SCALAR_STYLE {
1015		style = yaml_PLAIN_SCALAR_STYLE
1016	}
1017	if emitter.canonical {
1018		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
1019	}
1020	if emitter.simple_key_context && emitter.scalar_data.multiline {
1021		style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
1022	}
1023
1024	if style == yaml_PLAIN_SCALAR_STYLE {
1025		if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||
1026			emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {
1027			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
1028		}
1029		if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
1030			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
1031		}
1032		if no_tag && !event.implicit {
1033			style = yaml_SINGLE_QUOTED_SCALAR_STYLE
1034		}
1035	}
1036	if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
1037		if !emitter.scalar_data.single_quoted_allowed {
1038			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
1039		}
1040	}
1041	if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {
1042		if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {
1043			style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
1044		}
1045	}
1046
1047	if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
1048		emitter.tag_data.handle = []byte{'!'}
1049	}
1050	emitter.scalar_data.style = style
1051	return true
1052}
1053
1054// Write an anchor.
1055func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
1056	if emitter.anchor_data.anchor == nil {
1057		return true
1058	}
1059	c := []byte{'&'}
1060	if emitter.anchor_data.alias {
1061		c[0] = '*'
1062	}
1063	if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
1064		return false
1065	}
1066	return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
1067}
1068
1069// Write a tag.
1070func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
1071	if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
1072		return true
1073	}
1074	if len(emitter.tag_data.handle) > 0 {
1075		if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
1076			return false
1077		}
1078		if len(emitter.tag_data.suffix) > 0 {
1079			if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
1080				return false
1081			}
1082		}
1083	} else {
1084		// [Go] Allocate these slices elsewhere.
1085		if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
1086			return false
1087		}
1088		if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
1089			return false
1090		}
1091		if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
1092			return false
1093		}
1094	}
1095	return true
1096}
1097
1098// Write a scalar.
1099func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {
1100	switch emitter.scalar_data.style {
1101	case yaml_PLAIN_SCALAR_STYLE:
1102		return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
1103
1104	case yaml_SINGLE_QUOTED_SCALAR_STYLE:
1105		return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
1106
1107	case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
1108		return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
1109
1110	case yaml_LITERAL_SCALAR_STYLE:
1111		return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
1112
1113	case yaml_FOLDED_SCALAR_STYLE:
1114		return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
1115	}
1116	panic("unknown scalar style")
1117}
1118
1119// Write a head comment.
1120func yaml_emitter_process_head_comment(emitter *yaml_emitter_t) bool {
1121	if len(emitter.tail_comment) > 0 {
1122		if !yaml_emitter_write_indent(emitter) {
1123			return false
1124		}
1125		if !yaml_emitter_write_comment(emitter, emitter.tail_comment) {
1126			return false
1127		}
1128		emitter.tail_comment = emitter.tail_comment[:0]
1129		emitter.foot_indent = emitter.indent
1130		if emitter.foot_indent < 0 {
1131			emitter.foot_indent = 0
1132		}
1133	}
1134
1135	if len(emitter.head_comment) == 0 {
1136		return true
1137	}
1138	if !yaml_emitter_write_indent(emitter) {
1139		return false
1140	}
1141	if !yaml_emitter_write_comment(emitter, emitter.head_comment) {
1142		return false
1143	}
1144	emitter.head_comment = emitter.head_comment[:0]
1145	return true
1146}
1147
1148// Write an line comment.
1149func yaml_emitter_process_line_comment(emitter *yaml_emitter_t) bool {
1150	if len(emitter.line_comment) == 0 {
1151		return true
1152	}
1153	if !emitter.whitespace {
1154		if !put(emitter, ' ') {
1155			return false
1156		}
1157	}
1158	if !yaml_emitter_write_comment(emitter, emitter.line_comment) {
1159		return false
1160	}
1161	emitter.line_comment = emitter.line_comment[:0]
1162	return true
1163}
1164
1165// Write a foot comment.
1166func yaml_emitter_process_foot_comment(emitter *yaml_emitter_t) bool {
1167	if len(emitter.foot_comment) == 0 {
1168		return true
1169	}
1170	if !yaml_emitter_write_indent(emitter) {
1171		return false
1172	}
1173	if !yaml_emitter_write_comment(emitter, emitter.foot_comment) {
1174		return false
1175	}
1176	emitter.foot_comment = emitter.foot_comment[:0]
1177	emitter.foot_indent = emitter.indent
1178	if emitter.foot_indent < 0 {
1179		emitter.foot_indent = 0
1180	}
1181	return true
1182}
1183
1184// Check if a %YAML directive is valid.
1185func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {
1186	if version_directive.major != 1 || version_directive.minor != 1 {
1187		return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")
1188	}
1189	return true
1190}
1191
1192// Check if a %TAG directive is valid.
1193func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {
1194	handle := tag_directive.handle
1195	prefix := tag_directive.prefix
1196	if len(handle) == 0 {
1197		return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")
1198	}
1199	if handle[0] != '!' {
1200		return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
1201	}
1202	if handle[len(handle)-1] != '!' {
1203		return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
1204	}
1205	for i := 1; i < len(handle)-1; i += width(handle[i]) {
1206		if !is_alpha(handle, i) {
1207			return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")
1208		}
1209	}
1210	if len(prefix) == 0 {
1211		return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
1212	}
1213	return true
1214}
1215
1216// Check if an anchor is valid.
1217func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {
1218	if len(anchor) == 0 {
1219		problem := "anchor value must not be empty"
1220		if alias {
1221			problem = "alias value must not be empty"
1222		}
1223		return yaml_emitter_set_emitter_error(emitter, problem)
1224	}
1225	for i := 0; i < len(anchor); i += width(anchor[i]) {
1226		if !is_alpha(anchor, i) {
1227			problem := "anchor value must contain alphanumerical characters only"
1228			if alias {
1229				problem = "alias value must contain alphanumerical characters only"
1230			}
1231			return yaml_emitter_set_emitter_error(emitter, problem)
1232		}
1233	}
1234	emitter.anchor_data.anchor = anchor
1235	emitter.anchor_data.alias = alias
1236	return true
1237}
1238
1239// Check if a tag is valid.
1240func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
1241	if len(tag) == 0 {
1242		return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
1243	}
1244	for i := 0; i < len(emitter.tag_directives); i++ {
1245		tag_directive := &emitter.tag_directives[i]
1246		if bytes.HasPrefix(tag, tag_directive.prefix) {
1247			emitter.tag_data.handle = tag_directive.handle
1248			emitter.tag_data.suffix = tag[len(tag_directive.prefix):]
1249			return true
1250		}
1251	}
1252	emitter.tag_data.suffix = tag
1253	return true
1254}
1255
1256// Check if a scalar is valid.
1257func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
1258	var (
1259		block_indicators   = false
1260		flow_indicators    = false
1261		line_breaks        = false
1262		special_characters = false
1263		tab_characters     = false
1264
1265		leading_space  = false
1266		leading_break  = false
1267		trailing_space = false
1268		trailing_break = false
1269		break_space    = false
1270		space_break    = false
1271
1272		preceded_by_whitespace = false
1273		followed_by_whitespace = false
1274		previous_space         = false
1275		previous_break         = false
1276	)
1277
1278	emitter.scalar_data.value = value
1279
1280	if len(value) == 0 {
1281		emitter.scalar_data.multiline = false
1282		emitter.scalar_data.flow_plain_allowed = false
1283		emitter.scalar_data.block_plain_allowed = true
1284		emitter.scalar_data.single_quoted_allowed = true
1285		emitter.scalar_data.block_allowed = false
1286		return true
1287	}
1288
1289	if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {
1290		block_indicators = true
1291		flow_indicators = true
1292	}
1293
1294	preceded_by_whitespace = true
1295	for i, w := 0, 0; i < len(value); i += w {
1296		w = width(value[i])
1297		followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
1298
1299		if i == 0 {
1300			switch value[i] {
1301			case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
1302				flow_indicators = true
1303				block_indicators = true
1304			case '?', ':':
1305				flow_indicators = true
1306				if followed_by_whitespace {
1307					block_indicators = true
1308				}
1309			case '-':
1310				if followed_by_whitespace {
1311					flow_indicators = true
1312					block_indicators = true
1313				}
1314			}
1315		} else {
1316			switch value[i] {
1317			case ',', '?', '[', ']', '{', '}':
1318				flow_indicators = true
1319			case ':':
1320				flow_indicators = true
1321				if followed_by_whitespace {
1322					block_indicators = true
1323				}
1324			case '#':
1325				if preceded_by_whitespace {
1326					flow_indicators = true
1327					block_indicators = true
1328				}
1329			}
1330		}
1331
1332		if value[i] == '\t' {
1333			tab_characters = true
1334		} else if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
1335			special_characters = true
1336		}
1337		if is_space(value, i) {
1338			if i == 0 {
1339				leading_space = true
1340			}
1341			if i+width(value[i]) == len(value) {
1342				trailing_space = true
1343			}
1344			if previous_break {
1345				break_space = true
1346			}
1347			previous_space = true
1348			previous_break = false
1349		} else if is_break(value, i) {
1350			line_breaks = true
1351			if i == 0 {
1352				leading_break = true
1353			}
1354			if i+width(value[i]) == len(value) {
1355				trailing_break = true
1356			}
1357			if previous_space {
1358				space_break = true
1359			}
1360			previous_space = false
1361			previous_break = true
1362		} else {
1363			previous_space = false
1364			previous_break = false
1365		}
1366
1367		// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
1368		preceded_by_whitespace = is_blankz(value, i)
1369	}
1370
1371	emitter.scalar_data.multiline = line_breaks
1372	emitter.scalar_data.flow_plain_allowed = true
1373	emitter.scalar_data.block_plain_allowed = true
1374	emitter.scalar_data.single_quoted_allowed = true
1375	emitter.scalar_data.block_allowed = true
1376
1377	if leading_space || leading_break || trailing_space || trailing_break {
1378		emitter.scalar_data.flow_plain_allowed = false
1379		emitter.scalar_data.block_plain_allowed = false
1380	}
1381	if trailing_space {
1382		emitter.scalar_data.block_allowed = false
1383	}
1384	if break_space {
1385		emitter.scalar_data.flow_plain_allowed = false
1386		emitter.scalar_data.block_plain_allowed = false
1387		emitter.scalar_data.single_quoted_allowed = false
1388	}
1389	if space_break || tab_characters || special_characters {
1390		emitter.scalar_data.flow_plain_allowed = false
1391		emitter.scalar_data.block_plain_allowed = false
1392		emitter.scalar_data.single_quoted_allowed = false
1393	}
1394	if space_break || special_characters {
1395		emitter.scalar_data.block_allowed = false
1396	}
1397	if line_breaks {
1398		emitter.scalar_data.flow_plain_allowed = false
1399		emitter.scalar_data.block_plain_allowed = false
1400	}
1401	if flow_indicators {
1402		emitter.scalar_data.flow_plain_allowed = false
1403	}
1404	if block_indicators {
1405		emitter.scalar_data.block_plain_allowed = false
1406	}
1407	return true
1408}
1409
1410// Check if the event data is valid.
1411func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
1412
1413	emitter.anchor_data.anchor = nil
1414	emitter.tag_data.handle = nil
1415	emitter.tag_data.suffix = nil
1416	emitter.scalar_data.value = nil
1417
1418	if len(event.head_comment) > 0 {
1419		emitter.head_comment = event.head_comment
1420	}
1421	if len(event.line_comment) > 0 {
1422		emitter.line_comment = event.line_comment
1423	}
1424	if len(event.foot_comment) > 0 {
1425		emitter.foot_comment = event.foot_comment
1426	}
1427	if len(event.tail_comment) > 0 {
1428		emitter.tail_comment = event.tail_comment
1429	}
1430
1431	switch event.typ {
1432	case yaml_ALIAS_EVENT:
1433		if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
1434			return false
1435		}
1436
1437	case yaml_SCALAR_EVENT:
1438		if len(event.anchor) > 0 {
1439			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1440				return false
1441			}
1442		}
1443		if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
1444			if !yaml_emitter_analyze_tag(emitter, event.tag) {
1445				return false
1446			}
1447		}
1448		if !yaml_emitter_analyze_scalar(emitter, event.value) {
1449			return false
1450		}
1451
1452	case yaml_SEQUENCE_START_EVENT:
1453		if len(event.anchor) > 0 {
1454			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1455				return false
1456			}
1457		}
1458		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1459			if !yaml_emitter_analyze_tag(emitter, event.tag) {
1460				return false
1461			}
1462		}
1463
1464	case yaml_MAPPING_START_EVENT:
1465		if len(event.anchor) > 0 {
1466			if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1467				return false
1468			}
1469		}
1470		if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1471			if !yaml_emitter_analyze_tag(emitter, event.tag) {
1472				return false
1473			}
1474		}
1475	}
1476	return true
1477}
1478
1479// Write the BOM character.
1480func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
1481	if !flush(emitter) {
1482		return false
1483	}
1484	pos := emitter.buffer_pos
1485	emitter.buffer[pos+0] = '\xEF'
1486	emitter.buffer[pos+1] = '\xBB'
1487	emitter.buffer[pos+2] = '\xBF'
1488	emitter.buffer_pos += 3
1489	return true
1490}
1491
1492func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
1493	indent := emitter.indent
1494	if indent < 0 {
1495		indent = 0
1496	}
1497	if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
1498		if !put_break(emitter) {
1499			return false
1500		}
1501	}
1502	if emitter.foot_indent == indent {
1503		if !put_break(emitter) {
1504			return false
1505		}
1506	}
1507	for emitter.column < indent {
1508		if !put(emitter, ' ') {
1509			return false
1510		}
1511	}
1512	emitter.whitespace = true
1513	//emitter.indention = true
1514	emitter.space_above = false
1515	emitter.foot_indent = -1
1516	return true
1517}
1518
1519func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {
1520	if need_whitespace && !emitter.whitespace {
1521		if !put(emitter, ' ') {
1522			return false
1523		}
1524	}
1525	if !write_all(emitter, indicator) {
1526		return false
1527	}
1528	emitter.whitespace = is_whitespace
1529	emitter.indention = (emitter.indention && is_indention)
1530	emitter.open_ended = false
1531	return true
1532}
1533
1534func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
1535	if !write_all(emitter, value) {
1536		return false
1537	}
1538	emitter.whitespace = false
1539	emitter.indention = false
1540	return true
1541}
1542
1543func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
1544	if !emitter.whitespace {
1545		if !put(emitter, ' ') {
1546			return false
1547		}
1548	}
1549	if !write_all(emitter, value) {
1550		return false
1551	}
1552	emitter.whitespace = false
1553	emitter.indention = false
1554	return true
1555}
1556
1557func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {
1558	if need_whitespace && !emitter.whitespace {
1559		if !put(emitter, ' ') {
1560			return false
1561		}
1562	}
1563	for i := 0; i < len(value); {
1564		var must_write bool
1565		switch value[i] {
1566		case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
1567			must_write = true
1568		default:
1569			must_write = is_alpha(value, i)
1570		}
1571		if must_write {
1572			if !write(emitter, value, &i) {
1573				return false
1574			}
1575		} else {
1576			w := width(value[i])
1577			for k := 0; k < w; k++ {
1578				octet := value[i]
1579				i++
1580				if !put(emitter, '%') {
1581					return false
1582				}
1583
1584				c := octet >> 4
1585				if c < 10 {
1586					c += '0'
1587				} else {
1588					c += 'A' - 10
1589				}
1590				if !put(emitter, c) {
1591					return false
1592				}
1593
1594				c = octet & 0x0f
1595				if c < 10 {
1596					c += '0'
1597				} else {
1598					c += 'A' - 10
1599				}
1600				if !put(emitter, c) {
1601					return false
1602				}
1603			}
1604		}
1605	}
1606	emitter.whitespace = false
1607	emitter.indention = false
1608	return true
1609}
1610
1611func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1612	if len(value) > 0 && !emitter.whitespace {
1613		if !put(emitter, ' ') {
1614			return false
1615		}
1616	}
1617
1618	spaces := false
1619	breaks := false
1620	for i := 0; i < len(value); {
1621		if is_space(value, i) {
1622			if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {
1623				if !yaml_emitter_write_indent(emitter) {
1624					return false
1625				}
1626				i += width(value[i])
1627			} else {
1628				if !write(emitter, value, &i) {
1629					return false
1630				}
1631			}
1632			spaces = true
1633		} else if is_break(value, i) {
1634			if !breaks && value[i] == '\n' {
1635				if !put_break(emitter) {
1636					return false
1637				}
1638			}
1639			if !write_break(emitter, value, &i) {
1640				return false
1641			}
1642			//emitter.indention = true
1643			breaks = true
1644		} else {
1645			if breaks {
1646				if !yaml_emitter_write_indent(emitter) {
1647					return false
1648				}
1649			}
1650			if !write(emitter, value, &i) {
1651				return false
1652			}
1653			emitter.indention = false
1654			spaces = false
1655			breaks = false
1656		}
1657	}
1658
1659	if len(value) > 0 {
1660		emitter.whitespace = false
1661	}
1662	emitter.indention = false
1663	if emitter.root_context {
1664		emitter.open_ended = true
1665	}
1666
1667	return true
1668}
1669
1670func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1671
1672	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {
1673		return false
1674	}
1675
1676	spaces := false
1677	breaks := false
1678	for i := 0; i < len(value); {
1679		if is_space(value, i) {
1680			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {
1681				if !yaml_emitter_write_indent(emitter) {
1682					return false
1683				}
1684				i += width(value[i])
1685			} else {
1686				if !write(emitter, value, &i) {
1687					return false
1688				}
1689			}
1690			spaces = true
1691		} else if is_break(value, i) {
1692			if !breaks && value[i] == '\n' {
1693				if !put_break(emitter) {
1694					return false
1695				}
1696			}
1697			if !write_break(emitter, value, &i) {
1698				return false
1699			}
1700			//emitter.indention = true
1701			breaks = true
1702		} else {
1703			if breaks {
1704				if !yaml_emitter_write_indent(emitter) {
1705					return false
1706				}
1707			}
1708			if value[i] == '\'' {
1709				if !put(emitter, '\'') {
1710					return false
1711				}
1712			}
1713			if !write(emitter, value, &i) {
1714				return false
1715			}
1716			emitter.indention = false
1717			spaces = false
1718			breaks = false
1719		}
1720	}
1721	if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
1722		return false
1723	}
1724	emitter.whitespace = false
1725	emitter.indention = false
1726	return true
1727}
1728
1729func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1730	spaces := false
1731	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
1732		return false
1733	}
1734
1735	for i := 0; i < len(value); {
1736		if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||
1737			is_bom(value, i) || is_break(value, i) ||
1738			value[i] == '"' || value[i] == '\\' {
1739
1740			octet := value[i]
1741
1742			var w int
1743			var v rune
1744			switch {
1745			case octet&0x80 == 0x00:
1746				w, v = 1, rune(octet&0x7F)
1747			case octet&0xE0 == 0xC0:
1748				w, v = 2, rune(octet&0x1F)
1749			case octet&0xF0 == 0xE0:
1750				w, v = 3, rune(octet&0x0F)
1751			case octet&0xF8 == 0xF0:
1752				w, v = 4, rune(octet&0x07)
1753			}
1754			for k := 1; k < w; k++ {
1755				octet = value[i+k]
1756				v = (v << 6) + (rune(octet) & 0x3F)
1757			}
1758			i += w
1759
1760			if !put(emitter, '\\') {
1761				return false
1762			}
1763
1764			var ok bool
1765			switch v {
1766			case 0x00:
1767				ok = put(emitter, '0')
1768			case 0x07:
1769				ok = put(emitter, 'a')
1770			case 0x08:
1771				ok = put(emitter, 'b')
1772			case 0x09:
1773				ok = put(emitter, 't')
1774			case 0x0A:
1775				ok = put(emitter, 'n')
1776			case 0x0b:
1777				ok = put(emitter, 'v')
1778			case 0x0c:
1779				ok = put(emitter, 'f')
1780			case 0x0d:
1781				ok = put(emitter, 'r')
1782			case 0x1b:
1783				ok = put(emitter, 'e')
1784			case 0x22:
1785				ok = put(emitter, '"')
1786			case 0x5c:
1787				ok = put(emitter, '\\')
1788			case 0x85:
1789				ok = put(emitter, 'N')
1790			case 0xA0:
1791				ok = put(emitter, '_')
1792			case 0x2028:
1793				ok = put(emitter, 'L')
1794			case 0x2029:
1795				ok = put(emitter, 'P')
1796			default:
1797				if v <= 0xFF {
1798					ok = put(emitter, 'x')
1799					w = 2
1800				} else if v <= 0xFFFF {
1801					ok = put(emitter, 'u')
1802					w = 4
1803				} else {
1804					ok = put(emitter, 'U')
1805					w = 8
1806				}
1807				for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
1808					digit := byte((v >> uint(k)) & 0x0F)
1809					if digit < 10 {
1810						ok = put(emitter, digit+'0')
1811					} else {
1812						ok = put(emitter, digit+'A'-10)
1813					}
1814				}
1815			}
1816			if !ok {
1817				return false
1818			}
1819			spaces = false
1820		} else if is_space(value, i) {
1821			if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {
1822				if !yaml_emitter_write_indent(emitter) {
1823					return false
1824				}
1825				if is_space(value, i+1) {
1826					if !put(emitter, '\\') {
1827						return false
1828					}
1829				}
1830				i += width(value[i])
1831			} else if !write(emitter, value, &i) {
1832				return false
1833			}
1834			spaces = true
1835		} else {
1836			if !write(emitter, value, &i) {
1837				return false
1838			}
1839			spaces = false
1840		}
1841	}
1842	if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
1843		return false
1844	}
1845	emitter.whitespace = false
1846	emitter.indention = false
1847	return true
1848}
1849
1850func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {
1851	if is_space(value, 0) || is_break(value, 0) {
1852		indent_hint := []byte{'0' + byte(emitter.best_indent)}
1853		if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {
1854			return false
1855		}
1856	}
1857
1858	emitter.open_ended = false
1859
1860	var chomp_hint [1]byte
1861	if len(value) == 0 {
1862		chomp_hint[0] = '-'
1863	} else {
1864		i := len(value) - 1
1865		for value[i]&0xC0 == 0x80 {
1866			i--
1867		}
1868		if !is_break(value, i) {
1869			chomp_hint[0] = '-'
1870		} else if i == 0 {
1871			chomp_hint[0] = '+'
1872			emitter.open_ended = true
1873		} else {
1874			i--
1875			for value[i]&0xC0 == 0x80 {
1876				i--
1877			}
1878			if is_break(value, i) {
1879				chomp_hint[0] = '+'
1880				emitter.open_ended = true
1881			}
1882		}
1883	}
1884	if chomp_hint[0] != 0 {
1885		if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
1886			return false
1887		}
1888	}
1889	return true
1890}
1891
1892func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
1893	if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
1894		return false
1895	}
1896	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1897		return false
1898	}
1899	if !put_break(emitter) {
1900		return false
1901	}
1902	//emitter.indention = true
1903	emitter.whitespace = true
1904	breaks := true
1905	for i := 0; i < len(value); {
1906		if is_break(value, i) {
1907			if !write_break(emitter, value, &i) {
1908				return false
1909			}
1910			//emitter.indention = true
1911			breaks = true
1912		} else {
1913			if breaks {
1914				if !yaml_emitter_write_indent(emitter) {
1915					return false
1916				}
1917			}
1918			if !write(emitter, value, &i) {
1919				return false
1920			}
1921			emitter.indention = false
1922			breaks = false
1923		}
1924	}
1925
1926	return true
1927}
1928
1929func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
1930	if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
1931		return false
1932	}
1933	if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1934		return false
1935	}
1936
1937	if !put_break(emitter) {
1938		return false
1939	}
1940	//emitter.indention = true
1941	emitter.whitespace = true
1942
1943	breaks := true
1944	leading_spaces := true
1945	for i := 0; i < len(value); {
1946		if is_break(value, i) {
1947			if !breaks && !leading_spaces && value[i] == '\n' {
1948				k := 0
1949				for is_break(value, k) {
1950					k += width(value[k])
1951				}
1952				if !is_blankz(value, k) {
1953					if !put_break(emitter) {
1954						return false
1955					}
1956				}
1957			}
1958			if !write_break(emitter, value, &i) {
1959				return false
1960			}
1961			//emitter.indention = true
1962			breaks = true
1963		} else {
1964			if breaks {
1965				if !yaml_emitter_write_indent(emitter) {
1966					return false
1967				}
1968				leading_spaces = is_blank(value, i)
1969			}
1970			if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
1971				if !yaml_emitter_write_indent(emitter) {
1972					return false
1973				}
1974				i += width(value[i])
1975			} else {
1976				if !write(emitter, value, &i) {
1977					return false
1978				}
1979			}
1980			emitter.indention = false
1981			breaks = false
1982		}
1983	}
1984	return true
1985}
1986
1987func yaml_emitter_write_comment(emitter *yaml_emitter_t, comment []byte) bool {
1988	breaks := false
1989	pound := false
1990	for i := 0; i < len(comment); {
1991		if is_break(comment, i) {
1992			if !write_break(emitter, comment, &i) {
1993				return false
1994			}
1995			//emitter.indention = true
1996			breaks = true
1997			pound = false
1998		} else {
1999			if breaks && !yaml_emitter_write_indent(emitter) {
2000				return false
2001			}
2002			if !pound {
2003				if comment[i] != '#' && (!put(emitter, '#') || !put(emitter, ' ')) {
2004					return false
2005				}
2006				pound = true
2007			}
2008			if !write(emitter, comment, &i) {
2009				return false
2010			}
2011			emitter.indention = false
2012			breaks = false
2013		}
2014	}
2015	if !breaks && !put_break(emitter) {
2016		return false
2017	}
2018
2019	emitter.whitespace = true
2020	//emitter.indention = true
2021	return true
2022}
2023