7 // Flush the buffer if needed.
8 func flush(emitter *yaml_emitter_t) bool {
9 if emitter.buffer_pos+5 >= len(emitter.buffer) {
10 return yaml_emitter_flush(emitter)
15 // Put a character to the output buffer.
16 func put(emitter *yaml_emitter_t, value byte) bool {
17 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
20 emitter.buffer[emitter.buffer_pos] = value
26 // Put a line break to the output buffer.
27 func put_break(emitter *yaml_emitter_t) bool {
28 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
31 switch emitter.line_break {
33 emitter.buffer[emitter.buffer_pos] = '\r'
34 emitter.buffer_pos += 1
36 emitter.buffer[emitter.buffer_pos] = '\n'
37 emitter.buffer_pos += 1
39 emitter.buffer[emitter.buffer_pos+0] = '\r'
40 emitter.buffer[emitter.buffer_pos+1] = '\n'
41 emitter.buffer_pos += 2
43 panic("unknown line break setting")
50 // Copy a character from a string into buffer.
51 func write(emitter *yaml_emitter_t, s []byte, i *int) bool {
52 if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {
55 p := emitter.buffer_pos
59 emitter.buffer[p+3] = s[*i+3]
62 emitter.buffer[p+2] = s[*i+2]
65 emitter.buffer[p+1] = s[*i+1]
68 emitter.buffer[p+0] = s[*i+0]
70 panic("unknown character width")
73 emitter.buffer_pos += w
78 // Write a whole string into buffer.
79 func write_all(emitter *yaml_emitter_t, s []byte) bool {
80 for i := 0; i < len(s); {
81 if !write(emitter, s, &i) {
88 // Copy a line break character from a string into buffer.
89 func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {
91 if !put_break(emitter) {
96 if !write(emitter, s, i) {
105 // Set an emitter error and return false.
106 func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {
107 emitter.error = yaml_EMITTER_ERROR
108 emitter.problem = problem
113 func 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) {
120 if !yaml_emitter_state_machine(emitter, event) {
123 yaml_event_delete(event)
124 emitter.events_head++
129 // Check if we need to accumulate more events before emitting.
131 // We accumulate extra
132 // - 1 event for DOCUMENT-START
133 // - 2 events for SEQUENCE-START
134 // - 3 events for MAPPING-START
136 func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {
137 if emitter.events_head == len(emitter.events) {
141 switch emitter.events[emitter.events_head].typ {
142 case yaml_DOCUMENT_START_EVENT:
145 case yaml_SEQUENCE_START_EVENT:
148 case yaml_MAPPING_START_EVENT:
154 if len(emitter.events)-emitter.events_head > accumulate {
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:
162 case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:
172 // Append a directive to the directives stack.
173 func 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 {
179 return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")
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)),
189 copy(tag_copy.handle, value.handle)
190 copy(tag_copy.prefix, value.prefix)
191 emitter.tag_directives = append(emitter.tag_directives, tag_copy)
195 // Increase the indentation level.
196 func 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 {
200 emitter.indent = emitter.best_indent
204 } else if !indentless {
205 emitter.indent += emitter.best_indent
211 func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {
212 switch emitter.state {
214 case yaml_EMIT_STREAM_START_STATE:
215 return yaml_emitter_emit_stream_start(emitter, event)
217 case yaml_EMIT_FIRST_DOCUMENT_START_STATE:
218 return yaml_emitter_emit_document_start(emitter, event, true)
220 case yaml_EMIT_DOCUMENT_START_STATE:
221 return yaml_emitter_emit_document_start(emitter, event, false)
223 case yaml_EMIT_DOCUMENT_CONTENT_STATE:
224 return yaml_emitter_emit_document_content(emitter, event)
226 case yaml_EMIT_DOCUMENT_END_STATE:
227 return yaml_emitter_emit_document_end(emitter, event)
229 case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
230 return yaml_emitter_emit_flow_sequence_item(emitter, event, true)
232 case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:
233 return yaml_emitter_emit_flow_sequence_item(emitter, event, false)
235 case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
236 return yaml_emitter_emit_flow_mapping_key(emitter, event, true)
238 case yaml_EMIT_FLOW_MAPPING_KEY_STATE:
239 return yaml_emitter_emit_flow_mapping_key(emitter, event, false)
241 case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
242 return yaml_emitter_emit_flow_mapping_value(emitter, event, true)
244 case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:
245 return yaml_emitter_emit_flow_mapping_value(emitter, event, false)
247 case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
248 return yaml_emitter_emit_block_sequence_item(emitter, event, true)
250 case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
251 return yaml_emitter_emit_block_sequence_item(emitter, event, false)
253 case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
254 return yaml_emitter_emit_block_mapping_key(emitter, event, true)
256 case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:
257 return yaml_emitter_emit_block_mapping_key(emitter, event, false)
259 case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
260 return yaml_emitter_emit_block_mapping_value(emitter, event, true)
262 case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:
263 return yaml_emitter_emit_block_mapping_value(emitter, event, false)
265 case yaml_EMIT_END_STATE:
266 return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
268 panic("invalid emitter state")
271 // Expect STREAM-START.
272 func 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")
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
282 if emitter.best_indent < 2 || emitter.best_indent > 9 {
283 emitter.best_indent = 2
285 if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {
286 emitter.best_width = 80
288 if emitter.best_width < 0 {
289 emitter.best_width = 1<<31 - 1
291 if emitter.line_break == yaml_ANY_BREAK {
292 emitter.line_break = yaml_LN_BREAK
298 emitter.whitespace = true
299 emitter.indention = true
301 if emitter.encoding != yaml_UTF8_ENCODING {
302 if !yaml_emitter_write_bom(emitter) {
306 emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE
310 // Expect DOCUMENT-START or STREAM-END.
311 func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
313 if event.typ == yaml_DOCUMENT_START_EVENT {
315 if event.version_directive != nil {
316 if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {
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) {
326 if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {
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) {
338 implicit := event.implicit
339 if !first || emitter.canonical {
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) {
347 if !yaml_emitter_write_indent(emitter) {
352 if event.version_directive != nil {
354 if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {
357 if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {
360 if !yaml_emitter_write_indent(emitter) {
365 if len(event.tag_directives) > 0 {
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) {
372 if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {
375 if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {
378 if !yaml_emitter_write_indent(emitter) {
384 if yaml_emitter_check_empty_document(emitter) {
388 if !yaml_emitter_write_indent(emitter) {
391 if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {
394 if emitter.canonical {
395 if !yaml_emitter_write_indent(emitter) {
401 emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE
405 if event.typ == yaml_STREAM_END_EVENT {
406 if emitter.open_ended {
407 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
410 if !yaml_emitter_write_indent(emitter) {
414 if !yaml_emitter_flush(emitter) {
417 emitter.state = yaml_EMIT_END_STATE
421 return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")
424 // Expect the root node.
425 func 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)
430 // Expect DOCUMENT-END.
431 func 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")
435 if !yaml_emitter_write_indent(emitter) {
439 // [Go] Allocate the slice elsewhere.
440 if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {
443 if !yaml_emitter_write_indent(emitter) {
447 if !yaml_emitter_flush(emitter) {
450 emitter.state = yaml_EMIT_DOCUMENT_START_STATE
451 emitter.tag_directives = emitter.tag_directives[:0]
455 // Expect a flow item node.
456 func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
458 if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {
461 if !yaml_emitter_increase_indent(emitter, true, false) {
467 if event.typ == yaml_SEQUENCE_END_EVENT {
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) {
475 if !yaml_emitter_write_indent(emitter) {
479 if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {
482 emitter.state = emitter.states[len(emitter.states)-1]
483 emitter.states = emitter.states[:len(emitter.states)-1]
489 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
494 if emitter.canonical || emitter.column > emitter.best_width {
495 if !yaml_emitter_write_indent(emitter) {
499 emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)
500 return yaml_emitter_emit_node(emitter, event, false, true, false, false)
503 // Expect a flow key node.
504 func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
506 if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {
509 if !yaml_emitter_increase_indent(emitter, true, false) {
515 if event.typ == yaml_MAPPING_END_EVENT {
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) {
523 if !yaml_emitter_write_indent(emitter) {
527 if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {
530 emitter.state = emitter.states[len(emitter.states)-1]
531 emitter.states = emitter.states[:len(emitter.states)-1]
536 if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {
540 if emitter.canonical || emitter.column > emitter.best_width {
541 if !yaml_emitter_write_indent(emitter) {
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)
550 if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {
553 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)
554 return yaml_emitter_emit_node(emitter, event, false, false, true, false)
557 // Expect a flow value node.
558 func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
560 if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
564 if emitter.canonical || emitter.column > emitter.best_width {
565 if !yaml_emitter_write_indent(emitter) {
569 if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {
573 emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)
574 return yaml_emitter_emit_node(emitter, event, false, false, true, false)
577 // Expect a block item node.
578 func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
580 if !yaml_emitter_increase_indent(emitter, false, emitter.mapping_context && !emitter.indention) {
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]
591 if !yaml_emitter_write_indent(emitter) {
594 if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {
597 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)
598 return yaml_emitter_emit_node(emitter, event, false, true, false, false)
601 // Expect a block key node.
602 func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {
604 if !yaml_emitter_increase_indent(emitter, false, false) {
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]
615 if !yaml_emitter_write_indent(emitter) {
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)
622 if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {
625 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)
626 return yaml_emitter_emit_node(emitter, event, false, false, true, false)
629 // Expect a block value node.
630 func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {
632 if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {
636 if !yaml_emitter_write_indent(emitter) {
639 if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {
643 emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)
644 return yaml_emitter_emit_node(emitter, event, false, false, true, false)
648 func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,
649 root bool, sequence bool, mapping bool, simple_key bool) bool {
651 emitter.root_context = root
652 emitter.sequence_context = sequence
653 emitter.mapping_context = mapping
654 emitter.simple_key_context = simple_key
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)
666 return yaml_emitter_set_emitter_error(emitter,
667 "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
672 func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {
673 if !yaml_emitter_process_anchor(emitter) {
676 emitter.state = emitter.states[len(emitter.states)-1]
677 emitter.states = emitter.states[:len(emitter.states)-1]
682 func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {
683 if !yaml_emitter_select_scalar_style(emitter, event) {
686 if !yaml_emitter_process_anchor(emitter) {
689 if !yaml_emitter_process_tag(emitter) {
692 if !yaml_emitter_increase_indent(emitter, true, false) {
695 if !yaml_emitter_process_scalar(emitter) {
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]
705 // Expect SEQUENCE-START.
706 func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
707 if !yaml_emitter_process_anchor(emitter) {
710 if !yaml_emitter_process_tag(emitter) {
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
717 emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE
722 // Expect MAPPING-START.
723 func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {
724 if !yaml_emitter_process_anchor(emitter) {
727 if !yaml_emitter_process_tag(emitter) {
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
734 emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE
739 // Check if the document content is an empty scalar.
740 func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {
741 return false // [Go] Huh?
744 // Check if the next events represent an empty sequence.
745 func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {
746 if len(emitter.events)-emitter.events_head < 2 {
749 return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&
750 emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT
753 // Check if the next events represent an empty mapping.
754 func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {
755 if len(emitter.events)-emitter.events_head < 2 {
758 return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&
759 emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT
762 // Check if the next node can be expressed as a simple key.
763 func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {
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 {
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) {
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) {
787 length += len(emitter.anchor_data.anchor) +
788 len(emitter.tag_data.handle) +
789 len(emitter.tag_data.suffix)
796 // Determine an acceptable scalar style.
797 func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {
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")
804 style := event.scalar_style()
805 if style == yaml_ANY_SCALAR_STYLE {
806 style = yaml_PLAIN_SCALAR_STYLE
808 if emitter.canonical {
809 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
811 if emitter.simple_key_context && emitter.scalar_data.multiline {
812 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
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
820 if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {
821 style = yaml_SINGLE_QUOTED_SCALAR_STYLE
823 if no_tag && !event.implicit {
824 style = yaml_SINGLE_QUOTED_SCALAR_STYLE
827 if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {
828 if !emitter.scalar_data.single_quoted_allowed {
829 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
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
838 if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {
839 emitter.tag_data.handle = []byte{'!'}
841 emitter.scalar_data.style = style
846 func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
847 if emitter.anchor_data.anchor == nil {
851 if emitter.anchor_data.alias {
854 if !yaml_emitter_write_indicator(emitter, c, true, false, false) {
857 return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)
861 func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {
862 if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {
865 if len(emitter.tag_data.handle) > 0 {
866 if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {
869 if len(emitter.tag_data.suffix) > 0 {
870 if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
875 // [Go] Allocate these slices elsewhere.
876 if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {
879 if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {
882 if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {
890 func 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)
895 case yaml_SINGLE_QUOTED_SCALAR_STYLE:
896 return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
898 case yaml_DOUBLE_QUOTED_SCALAR_STYLE:
899 return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)
901 case yaml_LITERAL_SCALAR_STYLE:
902 return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)
904 case yaml_FOLDED_SCALAR_STYLE:
905 return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)
907 panic("unknown scalar style")
910 // Check if a %YAML directive is valid.
911 func 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")
918 // Check if a %TAG directive is valid.
919 func 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")
925 if handle[0] != '!' {
926 return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")
928 if handle[len(handle)-1] != '!' {
929 return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")
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")
936 if len(prefix) == 0 {
937 return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")
942 // Check if an anchor is valid.
943 func 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"
947 problem = "alias value must not be empty"
949 return yaml_emitter_set_emitter_error(emitter, problem)
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"
955 problem = "alias value must contain alphanumerical characters only"
957 return yaml_emitter_set_emitter_error(emitter, problem)
960 emitter.anchor_data.anchor = anchor
961 emitter.anchor_data.alias = alias
965 // Check if a tag is valid.
966 func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {
968 return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")
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):]
978 emitter.tag_data.suffix = tag
982 // Check if a scalar is valid.
983 func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {
985 block_indicators = false
986 flow_indicators = false
988 special_characters = false
990 leading_space = false
991 leading_break = false
992 trailing_space = false
993 trailing_break = false
997 preceded_by_whitespace = false
998 followed_by_whitespace = false
999 previous_space = false
1000 previous_break = false
1003 emitter.scalar_data.value = value
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
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
1019 preceded_by_whitespace = true
1020 for i, w := 0, 0; i < len(value); i += w {
1022 followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
1026 case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':
1027 flow_indicators = true
1028 block_indicators = true
1030 flow_indicators = true
1031 if followed_by_whitespace {
1032 block_indicators = true
1035 if followed_by_whitespace {
1036 flow_indicators = true
1037 block_indicators = true
1042 case ',', '?', '[', ']', '{', '}':
1043 flow_indicators = true
1045 flow_indicators = true
1046 if followed_by_whitespace {
1047 block_indicators = true
1050 if preceded_by_whitespace {
1051 flow_indicators = true
1052 block_indicators = true
1057 if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {
1058 special_characters = true
1060 if is_space(value, i) {
1062 leading_space = true
1064 if i+width(value[i]) == len(value) {
1065 trailing_space = true
1070 previous_space = true
1071 previous_break = false
1072 } else if is_break(value, i) {
1075 leading_break = true
1077 if i+width(value[i]) == len(value) {
1078 trailing_break = true
1083 previous_space = false
1084 previous_break = true
1086 previous_space = false
1087 previous_break = false
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)
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
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
1105 emitter.scalar_data.block_allowed = false
1108 emitter.scalar_data.flow_plain_allowed = false
1109 emitter.scalar_data.block_plain_allowed = false
1110 emitter.scalar_data.single_quoted_allowed = false
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
1119 emitter.scalar_data.flow_plain_allowed = false
1120 emitter.scalar_data.block_plain_allowed = false
1122 if flow_indicators {
1123 emitter.scalar_data.flow_plain_allowed = false
1125 if block_indicators {
1126 emitter.scalar_data.block_plain_allowed = false
1131 // Check if the event data is valid.
1132 func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {
1134 emitter.anchor_data.anchor = nil
1135 emitter.tag_data.handle = nil
1136 emitter.tag_data.suffix = nil
1137 emitter.scalar_data.value = nil
1140 case yaml_ALIAS_EVENT:
1141 if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {
1145 case yaml_SCALAR_EVENT:
1146 if len(event.anchor) > 0 {
1147 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1151 if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {
1152 if !yaml_emitter_analyze_tag(emitter, event.tag) {
1156 if !yaml_emitter_analyze_scalar(emitter, event.value) {
1160 case yaml_SEQUENCE_START_EVENT:
1161 if len(event.anchor) > 0 {
1162 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1166 if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1167 if !yaml_emitter_analyze_tag(emitter, event.tag) {
1172 case yaml_MAPPING_START_EVENT:
1173 if len(event.anchor) > 0 {
1174 if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {
1178 if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {
1179 if !yaml_emitter_analyze_tag(emitter, event.tag) {
1187 // Write the BOM character.
1188 func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {
1189 if !flush(emitter) {
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
1200 func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {
1201 indent := emitter.indent
1205 if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {
1206 if !put_break(emitter) {
1210 for emitter.column < indent {
1211 if !put(emitter, ' ') {
1215 emitter.whitespace = true
1216 emitter.indention = true
1220 func 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, ' ') {
1226 if !write_all(emitter, indicator) {
1229 emitter.whitespace = is_whitespace
1230 emitter.indention = (emitter.indention && is_indention)
1231 emitter.open_ended = false
1235 func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {
1236 if !write_all(emitter, value) {
1239 emitter.whitespace = false
1240 emitter.indention = false
1244 func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {
1245 if !emitter.whitespace {
1246 if !put(emitter, ' ') {
1250 if !write_all(emitter, value) {
1253 emitter.whitespace = false
1254 emitter.indention = false
1258 func 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, ' ') {
1264 for i := 0; i < len(value); {
1267 case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':
1270 must_write = is_alpha(value, i)
1273 if !write(emitter, value, &i) {
1277 w := width(value[i])
1278 for k := 0; k < w; k++ {
1281 if !put(emitter, '%') {
1291 if !put(emitter, c) {
1301 if !put(emitter, c) {
1307 emitter.whitespace = false
1308 emitter.indention = false
1312 func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1313 if !emitter.whitespace {
1314 if !put(emitter, ' ') {
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) {
1327 i += width(value[i])
1329 if !write(emitter, value, &i) {
1334 } else if is_break(value, i) {
1335 if !breaks && value[i] == '\n' {
1336 if !put_break(emitter) {
1340 if !write_break(emitter, value, &i) {
1343 emitter.indention = true
1347 if !yaml_emitter_write_indent(emitter) {
1351 if !write(emitter, value, &i) {
1354 emitter.indention = false
1360 emitter.whitespace = false
1361 emitter.indention = false
1362 if emitter.root_context {
1363 emitter.open_ended = true
1369 func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1371 if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, 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) {
1383 i += width(value[i])
1385 if !write(emitter, value, &i) {
1390 } else if is_break(value, i) {
1391 if !breaks && value[i] == '\n' {
1392 if !put_break(emitter) {
1396 if !write_break(emitter, value, &i) {
1399 emitter.indention = true
1403 if !yaml_emitter_write_indent(emitter) {
1407 if value[i] == '\'' {
1408 if !put(emitter, '\'') {
1412 if !write(emitter, value, &i) {
1415 emitter.indention = false
1420 if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {
1423 emitter.whitespace = false
1424 emitter.indention = false
1428 func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {
1430 if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {
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] == '\\' {
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)
1453 for k := 1; k < w; k++ {
1455 v = (v << 6) + (rune(octet) & 0x3F)
1459 if !put(emitter, '\\') {
1466 ok = put(emitter, '0')
1468 ok = put(emitter, 'a')
1470 ok = put(emitter, 'b')
1472 ok = put(emitter, 't')
1474 ok = put(emitter, 'n')
1476 ok = put(emitter, 'v')
1478 ok = put(emitter, 'f')
1480 ok = put(emitter, 'r')
1482 ok = put(emitter, 'e')
1484 ok = put(emitter, '"')
1486 ok = put(emitter, '\\')
1488 ok = put(emitter, 'N')
1490 ok = put(emitter, '_')
1492 ok = put(emitter, 'L')
1494 ok = put(emitter, 'P')
1497 ok = put(emitter, 'x')
1499 } else if v <= 0xFFFF {
1500 ok = put(emitter, 'u')
1503 ok = put(emitter, 'U')
1506 for k := (w - 1) * 4; ok && k >= 0; k -= 4 {
1507 digit := byte((v >> uint(k)) & 0x0F)
1509 ok = put(emitter, digit+'0')
1511 ok = put(emitter, digit+'A'-10)
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) {
1524 if is_space(value, i+1) {
1525 if !put(emitter, '\\') {
1529 i += width(value[i])
1530 } else if !write(emitter, value, &i) {
1535 if !write(emitter, value, &i) {
1541 if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {
1544 emitter.whitespace = false
1545 emitter.indention = false
1549 func 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) {
1557 emitter.open_ended = false
1559 var chomp_hint [1]byte
1560 if len(value) == 0 {
1564 for value[i]&0xC0 == 0x80 {
1567 if !is_break(value, i) {
1571 emitter.open_ended = true
1574 for value[i]&0xC0 == 0x80 {
1577 if is_break(value, i) {
1579 emitter.open_ended = true
1583 if chomp_hint[0] != 0 {
1584 if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {
1591 func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {
1592 if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {
1595 if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1598 if !put_break(emitter) {
1601 emitter.indention = true
1602 emitter.whitespace = true
1604 for i := 0; i < len(value); {
1605 if is_break(value, i) {
1606 if !write_break(emitter, value, &i) {
1609 emitter.indention = true
1613 if !yaml_emitter_write_indent(emitter) {
1617 if !write(emitter, value, &i) {
1620 emitter.indention = false
1628 func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {
1629 if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {
1632 if !yaml_emitter_write_block_scalar_hints(emitter, value) {
1636 if !put_break(emitter) {
1639 emitter.indention = true
1640 emitter.whitespace = 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' {
1648 for is_break(value, k) {
1649 k += width(value[k])
1651 if !is_blankz(value, k) {
1652 if !put_break(emitter) {
1657 if !write_break(emitter, value, &i) {
1660 emitter.indention = true
1664 if !yaml_emitter_write_indent(emitter) {
1667 leading_spaces = is_blank(value, i)
1669 if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {
1670 if !yaml_emitter_write_indent(emitter) {
1673 i += width(value[i])
1675 if !write(emitter, value, &i) {
1679 emitter.indention = false