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