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