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