Path: blob/main/vendor/go.yaml.in/yaml/v3/emitterc.go
2872 views
//1// Copyright (c) 2011-2019 Canonical Ltd2// Copyright (c) 2006-2010 Kirill Simonov3//4// Permission is hereby granted, free of charge, to any person obtaining a copy of5// this software and associated documentation files (the "Software"), to deal in6// the Software without restriction, including without limitation the rights to7// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies8// of the Software, and to permit persons to whom the Software is furnished to do9// so, subject to the following conditions:10//11// The above copyright notice and this permission notice shall be included in all12// copies or substantial portions of the Software.13//14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20// SOFTWARE.2122package yaml2324import (25"bytes"26"fmt"27)2829// Flush the buffer if needed.30func flush(emitter *yaml_emitter_t) bool {31if emitter.buffer_pos+5 >= len(emitter.buffer) {32return yaml_emitter_flush(emitter)33}34return true35}3637// Put a character to the output buffer.38func put(emitter *yaml_emitter_t, value byte) bool {39if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {40return false41}42emitter.buffer[emitter.buffer_pos] = value43emitter.buffer_pos++44emitter.column++45return true46}4748// Put a line break to the output buffer.49func put_break(emitter *yaml_emitter_t) bool {50if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {51return false52}53switch emitter.line_break {54case yaml_CR_BREAK:55emitter.buffer[emitter.buffer_pos] = '\r'56emitter.buffer_pos += 157case yaml_LN_BREAK:58emitter.buffer[emitter.buffer_pos] = '\n'59emitter.buffer_pos += 160case yaml_CRLN_BREAK:61emitter.buffer[emitter.buffer_pos+0] = '\r'62emitter.buffer[emitter.buffer_pos+1] = '\n'63emitter.buffer_pos += 264default:65panic("unknown line break setting")66}67if emitter.column == 0 {68emitter.space_above = true69}70emitter.column = 071emitter.line++72// [Go] Do this here and below and drop from everywhere else (see commented lines).73emitter.indention = true74return true75}7677// Copy a character from a string into buffer.78func write(emitter *yaml_emitter_t, s []byte, i *int) bool {79if emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {80return false81}82p := emitter.buffer_pos83w := width(s[*i])84switch w {85case 4:86emitter.buffer[p+3] = s[*i+3]87fallthrough88case 3:89emitter.buffer[p+2] = s[*i+2]90fallthrough91case 2:92emitter.buffer[p+1] = s[*i+1]93fallthrough94case 1:95emitter.buffer[p+0] = s[*i+0]96default:97panic("unknown character width")98}99emitter.column++100emitter.buffer_pos += w101*i += w102return true103}104105// Write a whole string into buffer.106func write_all(emitter *yaml_emitter_t, s []byte) bool {107for i := 0; i < len(s); {108if !write(emitter, s, &i) {109return false110}111}112return true113}114115// Copy a line break character from a string into buffer.116func write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {117if s[*i] == '\n' {118if !put_break(emitter) {119return false120}121*i++122} else {123if !write(emitter, s, i) {124return false125}126if emitter.column == 0 {127emitter.space_above = true128}129emitter.column = 0130emitter.line++131// [Go] Do this here and above and drop from everywhere else (see commented lines).132emitter.indention = true133}134return true135}136137// Set an emitter error and return false.138func yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {139emitter.error = yaml_EMITTER_ERROR140emitter.problem = problem141return false142}143144// Emit an event.145func yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {146emitter.events = append(emitter.events, *event)147for !yaml_emitter_need_more_events(emitter) {148event := &emitter.events[emitter.events_head]149if !yaml_emitter_analyze_event(emitter, event) {150return false151}152if !yaml_emitter_state_machine(emitter, event) {153return false154}155yaml_event_delete(event)156emitter.events_head++157}158return true159}160161// Check if we need to accumulate more events before emitting.162//163// We accumulate extra164// - 1 event for DOCUMENT-START165// - 2 events for SEQUENCE-START166// - 3 events for MAPPING-START167func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {168if emitter.events_head == len(emitter.events) {169return true170}171var accumulate int172switch emitter.events[emitter.events_head].typ {173case yaml_DOCUMENT_START_EVENT:174accumulate = 1175break176case yaml_SEQUENCE_START_EVENT:177accumulate = 2178break179case yaml_MAPPING_START_EVENT:180accumulate = 3181break182default:183return false184}185if len(emitter.events)-emitter.events_head > accumulate {186return false187}188var level int189for i := emitter.events_head; i < len(emitter.events); i++ {190switch emitter.events[i].typ {191case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:192level++193case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:194level--195}196if level == 0 {197return false198}199}200return true201}202203// Append a directive to the directives stack.204func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {205for i := 0; i < len(emitter.tag_directives); i++ {206if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {207if allow_duplicates {208return true209}210return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")211}212}213214// [Go] Do we actually need to copy this given garbage collection215// and the lack of deallocating destructors?216tag_copy := yaml_tag_directive_t{217handle: make([]byte, len(value.handle)),218prefix: make([]byte, len(value.prefix)),219}220copy(tag_copy.handle, value.handle)221copy(tag_copy.prefix, value.prefix)222emitter.tag_directives = append(emitter.tag_directives, tag_copy)223return true224}225226// Increase the indentation level.227func yaml_emitter_increase_indent_compact(emitter *yaml_emitter_t, flow, indentless bool, compact_seq bool) bool {228emitter.indents = append(emitter.indents, emitter.indent)229if emitter.indent < 0 {230if flow {231emitter.indent = emitter.best_indent232} else {233emitter.indent = 0234}235} else if !indentless {236// [Go] This was changed so that indentations are more regular.237if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {238// The first indent inside a sequence will just skip the "- " indicator.239emitter.indent += 2240} else {241// Everything else aligns to the chosen indentation.242emitter.indent = emitter.best_indent * ((emitter.indent + emitter.best_indent) / emitter.best_indent)243if compact_seq {244// The value compact_seq passed in is almost always set to `false` when this function is called,245// except when we are dealing with sequence nodes. So this gets triggered to subtract 2 only when we246// are increasing the indent to account for sequence nodes, which will be correct because we need to247// subtract 2 to account for the - at the beginning of the sequence node.248emitter.indent = emitter.indent - 2249}250}251}252return true253}254255// State dispatcher.256func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {257switch emitter.state {258default:259case yaml_EMIT_STREAM_START_STATE:260return yaml_emitter_emit_stream_start(emitter, event)261262case yaml_EMIT_FIRST_DOCUMENT_START_STATE:263return yaml_emitter_emit_document_start(emitter, event, true)264265case yaml_EMIT_DOCUMENT_START_STATE:266return yaml_emitter_emit_document_start(emitter, event, false)267268case yaml_EMIT_DOCUMENT_CONTENT_STATE:269return yaml_emitter_emit_document_content(emitter, event)270271case yaml_EMIT_DOCUMENT_END_STATE:272return yaml_emitter_emit_document_end(emitter, event)273274case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:275return yaml_emitter_emit_flow_sequence_item(emitter, event, true, false)276277case yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE:278return yaml_emitter_emit_flow_sequence_item(emitter, event, false, true)279280case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:281return yaml_emitter_emit_flow_sequence_item(emitter, event, false, false)282283case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:284return yaml_emitter_emit_flow_mapping_key(emitter, event, true, false)285286case yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE:287return yaml_emitter_emit_flow_mapping_key(emitter, event, false, true)288289case yaml_EMIT_FLOW_MAPPING_KEY_STATE:290return yaml_emitter_emit_flow_mapping_key(emitter, event, false, false)291292case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:293return yaml_emitter_emit_flow_mapping_value(emitter, event, true)294295case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:296return yaml_emitter_emit_flow_mapping_value(emitter, event, false)297298case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:299return yaml_emitter_emit_block_sequence_item(emitter, event, true)300301case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:302return yaml_emitter_emit_block_sequence_item(emitter, event, false)303304case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:305return yaml_emitter_emit_block_mapping_key(emitter, event, true)306307case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:308return yaml_emitter_emit_block_mapping_key(emitter, event, false)309310case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:311return yaml_emitter_emit_block_mapping_value(emitter, event, true)312313case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:314return yaml_emitter_emit_block_mapping_value(emitter, event, false)315316case yaml_EMIT_END_STATE:317return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")318}319panic("invalid emitter state")320}321322// Expect STREAM-START.323func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {324if event.typ != yaml_STREAM_START_EVENT {325return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")326}327if emitter.encoding == yaml_ANY_ENCODING {328emitter.encoding = event.encoding329if emitter.encoding == yaml_ANY_ENCODING {330emitter.encoding = yaml_UTF8_ENCODING331}332}333if emitter.best_indent < 2 || emitter.best_indent > 9 {334emitter.best_indent = 2335}336if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {337emitter.best_width = 80338}339if emitter.best_width < 0 {340emitter.best_width = 1<<31 - 1341}342if emitter.line_break == yaml_ANY_BREAK {343emitter.line_break = yaml_LN_BREAK344}345346emitter.indent = -1347emitter.line = 0348emitter.column = 0349emitter.whitespace = true350emitter.indention = true351emitter.space_above = true352emitter.foot_indent = -1353354if emitter.encoding != yaml_UTF8_ENCODING {355if !yaml_emitter_write_bom(emitter) {356return false357}358}359emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE360return true361}362363// Expect DOCUMENT-START or STREAM-END.364func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {365366if event.typ == yaml_DOCUMENT_START_EVENT {367368if event.version_directive != nil {369if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {370return false371}372}373374for i := 0; i < len(event.tag_directives); i++ {375tag_directive := &event.tag_directives[i]376if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {377return false378}379if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {380return false381}382}383384for i := 0; i < len(default_tag_directives); i++ {385tag_directive := &default_tag_directives[i]386if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {387return false388}389}390391implicit := event.implicit392if !first || emitter.canonical {393implicit = false394}395396if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {397if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {398return false399}400if !yaml_emitter_write_indent(emitter) {401return false402}403}404405if event.version_directive != nil {406implicit = false407if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {408return false409}410if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {411return false412}413if !yaml_emitter_write_indent(emitter) {414return false415}416}417418if len(event.tag_directives) > 0 {419implicit = false420for i := 0; i < len(event.tag_directives); i++ {421tag_directive := &event.tag_directives[i]422if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {423return false424}425if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {426return false427}428if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {429return false430}431if !yaml_emitter_write_indent(emitter) {432return false433}434}435}436437if yaml_emitter_check_empty_document(emitter) {438implicit = false439}440if !implicit {441if !yaml_emitter_write_indent(emitter) {442return false443}444if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {445return false446}447if emitter.canonical || true {448if !yaml_emitter_write_indent(emitter) {449return false450}451}452}453454if len(emitter.head_comment) > 0 {455if !yaml_emitter_process_head_comment(emitter) {456return false457}458if !put_break(emitter) {459return false460}461}462463emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE464return true465}466467if event.typ == yaml_STREAM_END_EVENT {468if emitter.open_ended {469if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {470return false471}472if !yaml_emitter_write_indent(emitter) {473return false474}475}476if !yaml_emitter_flush(emitter) {477return false478}479emitter.state = yaml_EMIT_END_STATE480return true481}482483return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")484}485486// yaml_emitter_increase_indent preserves the original signature and delegates to487// yaml_emitter_increase_indent_compact without compact-sequence indentation488func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {489return yaml_emitter_increase_indent_compact(emitter, flow, indentless, false)490}491492// yaml_emitter_process_line_comment preserves the original signature and delegates to493// yaml_emitter_process_line_comment_linebreak passing false for linebreak494func yaml_emitter_process_line_comment(emitter *yaml_emitter_t) bool {495return yaml_emitter_process_line_comment_linebreak(emitter, false)496}497498// Expect the root node.499func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {500emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)501502if !yaml_emitter_process_head_comment(emitter) {503return false504}505if !yaml_emitter_emit_node(emitter, event, true, false, false, false) {506return false507}508if !yaml_emitter_process_line_comment(emitter) {509return false510}511if !yaml_emitter_process_foot_comment(emitter) {512return false513}514return true515}516517// Expect DOCUMENT-END.518func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {519if event.typ != yaml_DOCUMENT_END_EVENT {520return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")521}522// [Go] Force document foot separation.523emitter.foot_indent = 0524if !yaml_emitter_process_foot_comment(emitter) {525return false526}527emitter.foot_indent = -1528if !yaml_emitter_write_indent(emitter) {529return false530}531if !event.implicit {532// [Go] Allocate the slice elsewhere.533if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {534return false535}536if !yaml_emitter_write_indent(emitter) {537return false538}539}540if !yaml_emitter_flush(emitter) {541return false542}543emitter.state = yaml_EMIT_DOCUMENT_START_STATE544emitter.tag_directives = emitter.tag_directives[:0]545return true546}547548// Expect a flow item node.549func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {550if first {551if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {552return false553}554if !yaml_emitter_increase_indent(emitter, true, false) {555return false556}557emitter.flow_level++558}559560if event.typ == yaml_SEQUENCE_END_EVENT {561if emitter.canonical && !first && !trail {562if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {563return false564}565}566emitter.flow_level--567emitter.indent = emitter.indents[len(emitter.indents)-1]568emitter.indents = emitter.indents[:len(emitter.indents)-1]569if emitter.column == 0 || emitter.canonical && !first {570if !yaml_emitter_write_indent(emitter) {571return false572}573}574if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {575return false576}577if !yaml_emitter_process_line_comment(emitter) {578return false579}580if !yaml_emitter_process_foot_comment(emitter) {581return false582}583emitter.state = emitter.states[len(emitter.states)-1]584emitter.states = emitter.states[:len(emitter.states)-1]585586return true587}588589if !first && !trail {590if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {591return false592}593}594595if !yaml_emitter_process_head_comment(emitter) {596return false597}598if emitter.column == 0 {599if !yaml_emitter_write_indent(emitter) {600return false601}602}603604if emitter.canonical || emitter.column > emitter.best_width {605if !yaml_emitter_write_indent(emitter) {606return false607}608}609if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {610emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE)611} else {612emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)613}614if !yaml_emitter_emit_node(emitter, event, false, true, false, false) {615return false616}617if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {618if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {619return false620}621}622if !yaml_emitter_process_line_comment(emitter) {623return false624}625if !yaml_emitter_process_foot_comment(emitter) {626return false627}628return true629}630631// Expect a flow key node.632func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {633if first {634if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {635return false636}637if !yaml_emitter_increase_indent(emitter, true, false) {638return false639}640emitter.flow_level++641}642643if event.typ == yaml_MAPPING_END_EVENT {644if (emitter.canonical || len(emitter.head_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0) && !first && !trail {645if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {646return false647}648}649if !yaml_emitter_process_head_comment(emitter) {650return false651}652emitter.flow_level--653emitter.indent = emitter.indents[len(emitter.indents)-1]654emitter.indents = emitter.indents[:len(emitter.indents)-1]655if emitter.canonical && !first {656if !yaml_emitter_write_indent(emitter) {657return false658}659}660if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {661return false662}663if !yaml_emitter_process_line_comment(emitter) {664return false665}666if !yaml_emitter_process_foot_comment(emitter) {667return false668}669emitter.state = emitter.states[len(emitter.states)-1]670emitter.states = emitter.states[:len(emitter.states)-1]671return true672}673674if !first && !trail {675if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {676return false677}678}679680if !yaml_emitter_process_head_comment(emitter) {681return false682}683684if emitter.column == 0 {685if !yaml_emitter_write_indent(emitter) {686return false687}688}689690if emitter.canonical || emitter.column > emitter.best_width {691if !yaml_emitter_write_indent(emitter) {692return false693}694}695696if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {697emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)698return yaml_emitter_emit_node(emitter, event, false, false, true, true)699}700if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {701return false702}703emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)704return yaml_emitter_emit_node(emitter, event, false, false, true, false)705}706707// Expect a flow value node.708func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {709if simple {710if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {711return false712}713} else {714if emitter.canonical || emitter.column > emitter.best_width {715if !yaml_emitter_write_indent(emitter) {716return false717}718}719if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {720return false721}722}723if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {724emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE)725} else {726emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)727}728if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {729return false730}731if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {732if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {733return false734}735}736if !yaml_emitter_process_line_comment(emitter) {737return false738}739if !yaml_emitter_process_foot_comment(emitter) {740return false741}742return true743}744745// Expect a block item node.746func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {747if first {748// emitter.mapping context tells us if we are currently in a mapping context.749// emiiter.column tells us which column we are in in the yaml output. 0 is the first char of the column.750// emitter.indentation tells us if the last character was an indentation character.751// emitter.compact_sequence_indent tells us if '- ' is considered part of the indentation for sequence elements.752// So, `seq` means that we are in a mapping context, and we are either at the first char of the column or753// the last character was not an indentation character, and we consider '- ' part of the indentation754// for sequence elements.755seq := emitter.mapping_context && (emitter.column == 0 || !emitter.indention) &&756emitter.compact_sequence_indent757if !yaml_emitter_increase_indent_compact(emitter, false, false, seq) {758return false759}760}761if event.typ == yaml_SEQUENCE_END_EVENT {762emitter.indent = emitter.indents[len(emitter.indents)-1]763emitter.indents = emitter.indents[:len(emitter.indents)-1]764emitter.state = emitter.states[len(emitter.states)-1]765emitter.states = emitter.states[:len(emitter.states)-1]766return true767}768if !yaml_emitter_process_head_comment(emitter) {769return false770}771if !yaml_emitter_write_indent(emitter) {772return false773}774if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {775return false776}777emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)778if !yaml_emitter_emit_node(emitter, event, false, true, false, false) {779return false780}781if !yaml_emitter_process_line_comment(emitter) {782return false783}784if !yaml_emitter_process_foot_comment(emitter) {785return false786}787return true788}789790// Expect a block key node.791func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {792if first {793if !yaml_emitter_increase_indent(emitter, false, false) {794return false795}796}797if !yaml_emitter_process_head_comment(emitter) {798return false799}800if event.typ == yaml_MAPPING_END_EVENT {801emitter.indent = emitter.indents[len(emitter.indents)-1]802emitter.indents = emitter.indents[:len(emitter.indents)-1]803emitter.state = emitter.states[len(emitter.states)-1]804emitter.states = emitter.states[:len(emitter.states)-1]805return true806}807if !yaml_emitter_write_indent(emitter) {808return false809}810if len(emitter.line_comment) > 0 {811// [Go] A line comment was provided for the key. That's unusual as the812// scanner associates line comments with the value. Either way,813// save the line comment and render it appropriately later.814emitter.key_line_comment = emitter.line_comment815emitter.line_comment = nil816}817if yaml_emitter_check_simple_key(emitter) {818emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)819return yaml_emitter_emit_node(emitter, event, false, false, true, true)820}821if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {822return false823}824emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)825return yaml_emitter_emit_node(emitter, event, false, false, true, false)826}827828// Expect a block value node.829func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {830if simple {831if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {832return false833}834} else {835if !yaml_emitter_write_indent(emitter) {836return false837}838if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {839return false840}841}842if len(emitter.key_line_comment) > 0 {843// [Go] Line comments are generally associated with the value, but when there's844// no value on the same line as a mapping key they end up attached to the845// key itself.846if event.typ == yaml_SCALAR_EVENT {847if len(emitter.line_comment) == 0 {848// A scalar is coming and it has no line comments by itself yet,849// so just let it handle the line comment as usual. If it has a850// line comment, we can't have both so the one from the key is lost.851emitter.line_comment = emitter.key_line_comment852emitter.key_line_comment = nil853}854} else if event.sequence_style() != yaml_FLOW_SEQUENCE_STYLE && (event.typ == yaml_MAPPING_START_EVENT || event.typ == yaml_SEQUENCE_START_EVENT) {855// An indented block follows, so write the comment right now.856emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment857if !yaml_emitter_process_line_comment(emitter) {858return false859}860emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment861}862}863emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)864if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {865return false866}867if !yaml_emitter_process_line_comment(emitter) {868return false869}870if !yaml_emitter_process_foot_comment(emitter) {871return false872}873return true874}875876func yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {877return event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0878}879880// Expect a node.881func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,882root bool, sequence bool, mapping bool, simple_key bool) bool {883884emitter.root_context = root885emitter.sequence_context = sequence886emitter.mapping_context = mapping887emitter.simple_key_context = simple_key888889switch event.typ {890case yaml_ALIAS_EVENT:891return yaml_emitter_emit_alias(emitter, event)892case yaml_SCALAR_EVENT:893return yaml_emitter_emit_scalar(emitter, event)894case yaml_SEQUENCE_START_EVENT:895return yaml_emitter_emit_sequence_start(emitter, event)896case yaml_MAPPING_START_EVENT:897return yaml_emitter_emit_mapping_start(emitter, event)898default:899return yaml_emitter_set_emitter_error(emitter,900fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))901}902}903904// Expect ALIAS.905func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {906if !yaml_emitter_process_anchor(emitter) {907return false908}909emitter.state = emitter.states[len(emitter.states)-1]910emitter.states = emitter.states[:len(emitter.states)-1]911return true912}913914// Expect SCALAR.915func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {916if !yaml_emitter_select_scalar_style(emitter, event) {917return false918}919if !yaml_emitter_process_anchor(emitter) {920return false921}922if !yaml_emitter_process_tag(emitter) {923return false924}925if !yaml_emitter_increase_indent(emitter, true, false) {926return false927}928if !yaml_emitter_process_scalar(emitter) {929return false930}931emitter.indent = emitter.indents[len(emitter.indents)-1]932emitter.indents = emitter.indents[:len(emitter.indents)-1]933emitter.state = emitter.states[len(emitter.states)-1]934emitter.states = emitter.states[:len(emitter.states)-1]935return true936}937938// Expect SEQUENCE-START.939func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {940if !yaml_emitter_process_anchor(emitter) {941return false942}943if !yaml_emitter_process_tag(emitter) {944return false945}946if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||947yaml_emitter_check_empty_sequence(emitter) {948emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE949} else {950emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE951}952return true953}954955// Expect MAPPING-START.956func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {957if !yaml_emitter_process_anchor(emitter) {958return false959}960if !yaml_emitter_process_tag(emitter) {961return false962}963if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||964yaml_emitter_check_empty_mapping(emitter) {965emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE966} else {967emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE968}969return true970}971972// Check if the document content is an empty scalar.973func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {974return false // [Go] Huh?975}976977// Check if the next events represent an empty sequence.978func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {979if len(emitter.events)-emitter.events_head < 2 {980return false981}982return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&983emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT984}985986// Check if the next events represent an empty mapping.987func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {988if len(emitter.events)-emitter.events_head < 2 {989return false990}991return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&992emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT993}994995// Check if the next node can be expressed as a simple key.996func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {997length := 0998switch emitter.events[emitter.events_head].typ {999case yaml_ALIAS_EVENT:1000length += len(emitter.anchor_data.anchor)1001case yaml_SCALAR_EVENT:1002if emitter.scalar_data.multiline {1003return false1004}1005length += len(emitter.anchor_data.anchor) +1006len(emitter.tag_data.handle) +1007len(emitter.tag_data.suffix) +1008len(emitter.scalar_data.value)1009case yaml_SEQUENCE_START_EVENT:1010if !yaml_emitter_check_empty_sequence(emitter) {1011return false1012}1013length += len(emitter.anchor_data.anchor) +1014len(emitter.tag_data.handle) +1015len(emitter.tag_data.suffix)1016case yaml_MAPPING_START_EVENT:1017if !yaml_emitter_check_empty_mapping(emitter) {1018return false1019}1020length += len(emitter.anchor_data.anchor) +1021len(emitter.tag_data.handle) +1022len(emitter.tag_data.suffix)1023default:1024return false1025}1026return length <= 1281027}10281029// Determine an acceptable scalar style.1030func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {10311032no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 01033if no_tag && !event.implicit && !event.quoted_implicit {1034return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")1035}10361037style := event.scalar_style()1038if style == yaml_ANY_SCALAR_STYLE {1039style = yaml_PLAIN_SCALAR_STYLE1040}1041if emitter.canonical {1042style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1043}1044if emitter.simple_key_context && emitter.scalar_data.multiline {1045style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1046}10471048if style == yaml_PLAIN_SCALAR_STYLE {1049if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||1050emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {1051style = yaml_SINGLE_QUOTED_SCALAR_STYLE1052}1053if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {1054style = yaml_SINGLE_QUOTED_SCALAR_STYLE1055}1056if no_tag && !event.implicit {1057style = yaml_SINGLE_QUOTED_SCALAR_STYLE1058}1059}1060if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {1061if !emitter.scalar_data.single_quoted_allowed {1062style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1063}1064}1065if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {1066if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {1067style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1068}1069}10701071if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {1072emitter.tag_data.handle = []byte{'!'}1073}1074emitter.scalar_data.style = style1075return true1076}10771078// Write an anchor.1079func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {1080if emitter.anchor_data.anchor == nil {1081return true1082}1083c := []byte{'&'}1084if emitter.anchor_data.alias {1085c[0] = '*'1086}1087if !yaml_emitter_write_indicator(emitter, c, true, false, false) {1088return false1089}1090return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)1091}10921093// Write a tag.1094func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {1095if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {1096return true1097}1098if len(emitter.tag_data.handle) > 0 {1099if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {1100return false1101}1102if len(emitter.tag_data.suffix) > 0 {1103if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {1104return false1105}1106}1107} else {1108// [Go] Allocate these slices elsewhere.1109if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {1110return false1111}1112if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {1113return false1114}1115if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {1116return false1117}1118}1119return true1120}11211122// Write a scalar.1123func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {1124switch emitter.scalar_data.style {1125case yaml_PLAIN_SCALAR_STYLE:1126return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)11271128case yaml_SINGLE_QUOTED_SCALAR_STYLE:1129return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)11301131case yaml_DOUBLE_QUOTED_SCALAR_STYLE:1132return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)11331134case yaml_LITERAL_SCALAR_STYLE:1135return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)11361137case yaml_FOLDED_SCALAR_STYLE:1138return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)1139}1140panic("unknown scalar style")1141}11421143// Write a head comment.1144func yaml_emitter_process_head_comment(emitter *yaml_emitter_t) bool {1145if len(emitter.tail_comment) > 0 {1146if !yaml_emitter_write_indent(emitter) {1147return false1148}1149if !yaml_emitter_write_comment(emitter, emitter.tail_comment) {1150return false1151}1152emitter.tail_comment = emitter.tail_comment[:0]1153emitter.foot_indent = emitter.indent1154if emitter.foot_indent < 0 {1155emitter.foot_indent = 01156}1157}11581159if len(emitter.head_comment) == 0 {1160return true1161}1162if !yaml_emitter_write_indent(emitter) {1163return false1164}1165if !yaml_emitter_write_comment(emitter, emitter.head_comment) {1166return false1167}1168emitter.head_comment = emitter.head_comment[:0]1169return true1170}11711172// Write an line comment.1173func yaml_emitter_process_line_comment_linebreak(emitter *yaml_emitter_t, linebreak bool) bool {1174if len(emitter.line_comment) == 0 {1175// The next 3 lines are needed to resolve an issue with leading newlines1176// See https://github.com/go-yaml/yaml/issues/7551177// When linebreak is set to true, put_break will be called and will add1178// the needed newline.1179if linebreak && !put_break(emitter) {1180return false1181}1182return true1183}1184if !emitter.whitespace {1185if !put(emitter, ' ') {1186return false1187}1188}1189if !yaml_emitter_write_comment(emitter, emitter.line_comment) {1190return false1191}1192emitter.line_comment = emitter.line_comment[:0]1193return true1194}11951196// Write a foot comment.1197func yaml_emitter_process_foot_comment(emitter *yaml_emitter_t) bool {1198if len(emitter.foot_comment) == 0 {1199return true1200}1201if !yaml_emitter_write_indent(emitter) {1202return false1203}1204if !yaml_emitter_write_comment(emitter, emitter.foot_comment) {1205return false1206}1207emitter.foot_comment = emitter.foot_comment[:0]1208emitter.foot_indent = emitter.indent1209if emitter.foot_indent < 0 {1210emitter.foot_indent = 01211}1212return true1213}12141215// Check if a %YAML directive is valid.1216func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {1217if version_directive.major != 1 || version_directive.minor != 1 {1218return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")1219}1220return true1221}12221223// Check if a %TAG directive is valid.1224func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {1225handle := tag_directive.handle1226prefix := tag_directive.prefix1227if len(handle) == 0 {1228return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")1229}1230if handle[0] != '!' {1231return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")1232}1233if handle[len(handle)-1] != '!' {1234return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")1235}1236for i := 1; i < len(handle)-1; i += width(handle[i]) {1237if !is_alpha(handle, i) {1238return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")1239}1240}1241if len(prefix) == 0 {1242return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")1243}1244return true1245}12461247// Check if an anchor is valid.1248func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {1249if len(anchor) == 0 {1250problem := "anchor value must not be empty"1251if alias {1252problem = "alias value must not be empty"1253}1254return yaml_emitter_set_emitter_error(emitter, problem)1255}1256for i := 0; i < len(anchor); i += width(anchor[i]) {1257if !is_alpha(anchor, i) {1258problem := "anchor value must contain alphanumerical characters only"1259if alias {1260problem = "alias value must contain alphanumerical characters only"1261}1262return yaml_emitter_set_emitter_error(emitter, problem)1263}1264}1265emitter.anchor_data.anchor = anchor1266emitter.anchor_data.alias = alias1267return true1268}12691270// Check if a tag is valid.1271func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {1272if len(tag) == 0 {1273return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")1274}1275for i := 0; i < len(emitter.tag_directives); i++ {1276tag_directive := &emitter.tag_directives[i]1277if bytes.HasPrefix(tag, tag_directive.prefix) {1278emitter.tag_data.handle = tag_directive.handle1279emitter.tag_data.suffix = tag[len(tag_directive.prefix):]1280return true1281}1282}1283emitter.tag_data.suffix = tag1284return true1285}12861287// Check if a scalar is valid.1288func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {1289var (1290block_indicators = false1291flow_indicators = false1292line_breaks = false1293special_characters = false1294tab_characters = false12951296leading_space = false1297leading_break = false1298trailing_space = false1299trailing_break = false1300break_space = false1301space_break = false13021303preceded_by_whitespace = false1304followed_by_whitespace = false1305previous_space = false1306previous_break = false1307)13081309emitter.scalar_data.value = value13101311if len(value) == 0 {1312emitter.scalar_data.multiline = false1313emitter.scalar_data.flow_plain_allowed = false1314emitter.scalar_data.block_plain_allowed = true1315emitter.scalar_data.single_quoted_allowed = true1316emitter.scalar_data.block_allowed = false1317return true1318}13191320if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {1321block_indicators = true1322flow_indicators = true1323}13241325preceded_by_whitespace = true1326for i, w := 0, 0; i < len(value); i += w {1327w = width(value[i])1328followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)13291330if i == 0 {1331switch value[i] {1332case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':1333flow_indicators = true1334block_indicators = true1335case '?', ':':1336flow_indicators = true1337if followed_by_whitespace {1338block_indicators = true1339}1340case '-':1341if followed_by_whitespace {1342flow_indicators = true1343block_indicators = true1344}1345}1346} else {1347switch value[i] {1348case ',', '?', '[', ']', '{', '}':1349flow_indicators = true1350case ':':1351flow_indicators = true1352if followed_by_whitespace {1353block_indicators = true1354}1355case '#':1356if preceded_by_whitespace {1357flow_indicators = true1358block_indicators = true1359}1360}1361}13621363if value[i] == '\t' {1364tab_characters = true1365} else if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {1366special_characters = true1367}1368if is_space(value, i) {1369if i == 0 {1370leading_space = true1371}1372if i+width(value[i]) == len(value) {1373trailing_space = true1374}1375if previous_break {1376break_space = true1377}1378previous_space = true1379previous_break = false1380} else if is_break(value, i) {1381line_breaks = true1382if i == 0 {1383leading_break = true1384}1385if i+width(value[i]) == len(value) {1386trailing_break = true1387}1388if previous_space {1389space_break = true1390}1391previous_space = false1392previous_break = true1393} else {1394previous_space = false1395previous_break = false1396}13971398// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.1399preceded_by_whitespace = is_blankz(value, i)1400}14011402emitter.scalar_data.multiline = line_breaks1403emitter.scalar_data.flow_plain_allowed = true1404emitter.scalar_data.block_plain_allowed = true1405emitter.scalar_data.single_quoted_allowed = true1406emitter.scalar_data.block_allowed = true14071408if leading_space || leading_break || trailing_space || trailing_break {1409emitter.scalar_data.flow_plain_allowed = false1410emitter.scalar_data.block_plain_allowed = false1411}1412if trailing_space {1413emitter.scalar_data.block_allowed = false1414}1415if break_space {1416emitter.scalar_data.flow_plain_allowed = false1417emitter.scalar_data.block_plain_allowed = false1418emitter.scalar_data.single_quoted_allowed = false1419}1420if space_break || tab_characters || special_characters {1421emitter.scalar_data.flow_plain_allowed = false1422emitter.scalar_data.block_plain_allowed = false1423emitter.scalar_data.single_quoted_allowed = false1424}1425if space_break || special_characters {1426emitter.scalar_data.block_allowed = false1427}1428if line_breaks {1429emitter.scalar_data.flow_plain_allowed = false1430emitter.scalar_data.block_plain_allowed = false1431}1432if flow_indicators {1433emitter.scalar_data.flow_plain_allowed = false1434}1435if block_indicators {1436emitter.scalar_data.block_plain_allowed = false1437}1438return true1439}14401441// Check if the event data is valid.1442func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {14431444emitter.anchor_data.anchor = nil1445emitter.tag_data.handle = nil1446emitter.tag_data.suffix = nil1447emitter.scalar_data.value = nil14481449if len(event.head_comment) > 0 {1450emitter.head_comment = event.head_comment1451}1452if len(event.line_comment) > 0 {1453emitter.line_comment = event.line_comment1454}1455if len(event.foot_comment) > 0 {1456emitter.foot_comment = event.foot_comment1457}1458if len(event.tail_comment) > 0 {1459emitter.tail_comment = event.tail_comment1460}14611462switch event.typ {1463case yaml_ALIAS_EVENT:1464if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {1465return false1466}14671468case yaml_SCALAR_EVENT:1469if len(event.anchor) > 0 {1470if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {1471return false1472}1473}1474if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {1475if !yaml_emitter_analyze_tag(emitter, event.tag) {1476return false1477}1478}1479if !yaml_emitter_analyze_scalar(emitter, event.value) {1480return false1481}14821483case yaml_SEQUENCE_START_EVENT:1484if len(event.anchor) > 0 {1485if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {1486return false1487}1488}1489if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {1490if !yaml_emitter_analyze_tag(emitter, event.tag) {1491return false1492}1493}14941495case yaml_MAPPING_START_EVENT:1496if len(event.anchor) > 0 {1497if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {1498return false1499}1500}1501if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {1502if !yaml_emitter_analyze_tag(emitter, event.tag) {1503return false1504}1505}1506}1507return true1508}15091510// Write the BOM character.1511func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {1512if !flush(emitter) {1513return false1514}1515pos := emitter.buffer_pos1516emitter.buffer[pos+0] = '\xEF'1517emitter.buffer[pos+1] = '\xBB'1518emitter.buffer[pos+2] = '\xBF'1519emitter.buffer_pos += 31520return true1521}15221523func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {1524indent := emitter.indent1525if indent < 0 {1526indent = 01527}1528if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {1529if !put_break(emitter) {1530return false1531}1532}1533if emitter.foot_indent == indent {1534if !put_break(emitter) {1535return false1536}1537}1538for emitter.column < indent {1539if !put(emitter, ' ') {1540return false1541}1542}1543emitter.whitespace = true1544//emitter.indention = true1545emitter.space_above = false1546emitter.foot_indent = -11547return true1548}15491550func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {1551if need_whitespace && !emitter.whitespace {1552if !put(emitter, ' ') {1553return false1554}1555}1556if !write_all(emitter, indicator) {1557return false1558}1559emitter.whitespace = is_whitespace1560emitter.indention = (emitter.indention && is_indention)1561emitter.open_ended = false1562return true1563}15641565func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {1566if !write_all(emitter, value) {1567return false1568}1569emitter.whitespace = false1570emitter.indention = false1571return true1572}15731574func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {1575if !emitter.whitespace {1576if !put(emitter, ' ') {1577return false1578}1579}1580if !write_all(emitter, value) {1581return false1582}1583emitter.whitespace = false1584emitter.indention = false1585return true1586}15871588func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {1589if need_whitespace && !emitter.whitespace {1590if !put(emitter, ' ') {1591return false1592}1593}1594for i := 0; i < len(value); {1595var must_write bool1596switch value[i] {1597case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':1598must_write = true1599default:1600must_write = is_alpha(value, i)1601}1602if must_write {1603if !write(emitter, value, &i) {1604return false1605}1606} else {1607w := width(value[i])1608for k := 0; k < w; k++ {1609octet := value[i]1610i++1611if !put(emitter, '%') {1612return false1613}16141615c := octet >> 41616if c < 10 {1617c += '0'1618} else {1619c += 'A' - 101620}1621if !put(emitter, c) {1622return false1623}16241625c = octet & 0x0f1626if c < 10 {1627c += '0'1628} else {1629c += 'A' - 101630}1631if !put(emitter, c) {1632return false1633}1634}1635}1636}1637emitter.whitespace = false1638emitter.indention = false1639return true1640}16411642func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {1643if len(value) > 0 && !emitter.whitespace {1644if !put(emitter, ' ') {1645return false1646}1647}16481649spaces := false1650breaks := false1651for i := 0; i < len(value); {1652if is_space(value, i) {1653if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {1654if !yaml_emitter_write_indent(emitter) {1655return false1656}1657i += width(value[i])1658} else {1659if !write(emitter, value, &i) {1660return false1661}1662}1663spaces = true1664} else if is_break(value, i) {1665if !breaks && value[i] == '\n' {1666if !put_break(emitter) {1667return false1668}1669}1670if !write_break(emitter, value, &i) {1671return false1672}1673//emitter.indention = true1674breaks = true1675} else {1676if breaks {1677if !yaml_emitter_write_indent(emitter) {1678return false1679}1680}1681if !write(emitter, value, &i) {1682return false1683}1684emitter.indention = false1685spaces = false1686breaks = false1687}1688}16891690if len(value) > 0 {1691emitter.whitespace = false1692}1693emitter.indention = false1694if emitter.root_context {1695emitter.open_ended = true1696}16971698return true1699}17001701func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {17021703if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {1704return false1705}17061707spaces := false1708breaks := false1709for i := 0; i < len(value); {1710if is_space(value, i) {1711if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {1712if !yaml_emitter_write_indent(emitter) {1713return false1714}1715i += width(value[i])1716} else {1717if !write(emitter, value, &i) {1718return false1719}1720}1721spaces = true1722} else if is_break(value, i) {1723if !breaks && value[i] == '\n' {1724if !put_break(emitter) {1725return false1726}1727}1728if !write_break(emitter, value, &i) {1729return false1730}1731//emitter.indention = true1732breaks = true1733} else {1734if breaks {1735if !yaml_emitter_write_indent(emitter) {1736return false1737}1738}1739if value[i] == '\'' {1740if !put(emitter, '\'') {1741return false1742}1743}1744if !write(emitter, value, &i) {1745return false1746}1747emitter.indention = false1748spaces = false1749breaks = false1750}1751}1752if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {1753return false1754}1755emitter.whitespace = false1756emitter.indention = false1757return true1758}17591760func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {1761spaces := false1762if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {1763return false1764}17651766for i := 0; i < len(value); {1767if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||1768is_bom(value, i) || is_break(value, i) ||1769value[i] == '"' || value[i] == '\\' {17701771octet := value[i]17721773var w int1774var v rune1775switch {1776case octet&0x80 == 0x00:1777w, v = 1, rune(octet&0x7F)1778case octet&0xE0 == 0xC0:1779w, v = 2, rune(octet&0x1F)1780case octet&0xF0 == 0xE0:1781w, v = 3, rune(octet&0x0F)1782case octet&0xF8 == 0xF0:1783w, v = 4, rune(octet&0x07)1784}1785for k := 1; k < w; k++ {1786octet = value[i+k]1787v = (v << 6) + (rune(octet) & 0x3F)1788}1789i += w17901791if !put(emitter, '\\') {1792return false1793}17941795var ok bool1796switch v {1797case 0x00:1798ok = put(emitter, '0')1799case 0x07:1800ok = put(emitter, 'a')1801case 0x08:1802ok = put(emitter, 'b')1803case 0x09:1804ok = put(emitter, 't')1805case 0x0A:1806ok = put(emitter, 'n')1807case 0x0b:1808ok = put(emitter, 'v')1809case 0x0c:1810ok = put(emitter, 'f')1811case 0x0d:1812ok = put(emitter, 'r')1813case 0x1b:1814ok = put(emitter, 'e')1815case 0x22:1816ok = put(emitter, '"')1817case 0x5c:1818ok = put(emitter, '\\')1819case 0x85:1820ok = put(emitter, 'N')1821case 0xA0:1822ok = put(emitter, '_')1823case 0x2028:1824ok = put(emitter, 'L')1825case 0x2029:1826ok = put(emitter, 'P')1827default:1828if v <= 0xFF {1829ok = put(emitter, 'x')1830w = 21831} else if v <= 0xFFFF {1832ok = put(emitter, 'u')1833w = 41834} else {1835ok = put(emitter, 'U')1836w = 81837}1838for k := (w - 1) * 4; ok && k >= 0; k -= 4 {1839digit := byte((v >> uint(k)) & 0x0F)1840if digit < 10 {1841ok = put(emitter, digit+'0')1842} else {1843ok = put(emitter, digit+'A'-10)1844}1845}1846}1847if !ok {1848return false1849}1850spaces = false1851} else if is_space(value, i) {1852if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {1853if !yaml_emitter_write_indent(emitter) {1854return false1855}1856if is_space(value, i+1) {1857if !put(emitter, '\\') {1858return false1859}1860}1861i += width(value[i])1862} else if !write(emitter, value, &i) {1863return false1864}1865spaces = true1866} else {1867if !write(emitter, value, &i) {1868return false1869}1870spaces = false1871}1872}1873if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {1874return false1875}1876emitter.whitespace = false1877emitter.indention = false1878return true1879}18801881func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {1882if is_space(value, 0) || is_break(value, 0) {1883indent_hint := []byte{'0' + byte(emitter.best_indent)}1884if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {1885return false1886}1887}18881889emitter.open_ended = false18901891var chomp_hint [1]byte1892if len(value) == 0 {1893chomp_hint[0] = '-'1894} else {1895i := len(value) - 11896for value[i]&0xC0 == 0x80 {1897i--1898}1899if !is_break(value, i) {1900chomp_hint[0] = '-'1901} else if i == 0 {1902chomp_hint[0] = '+'1903emitter.open_ended = true1904} else {1905i--1906for value[i]&0xC0 == 0x80 {1907i--1908}1909if is_break(value, i) {1910chomp_hint[0] = '+'1911emitter.open_ended = true1912}1913}1914}1915if chomp_hint[0] != 0 {1916if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {1917return false1918}1919}1920return true1921}19221923func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {1924if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {1925return false1926}1927if !yaml_emitter_write_block_scalar_hints(emitter, value) {1928return false1929}1930if !yaml_emitter_process_line_comment_linebreak(emitter, true) {1931return false1932}1933//emitter.indention = true1934emitter.whitespace = true1935breaks := true1936for i := 0; i < len(value); {1937if is_break(value, i) {1938if !write_break(emitter, value, &i) {1939return false1940}1941//emitter.indention = true1942breaks = true1943} else {1944if breaks {1945if !yaml_emitter_write_indent(emitter) {1946return false1947}1948}1949if !write(emitter, value, &i) {1950return false1951}1952emitter.indention = false1953breaks = false1954}1955}19561957return true1958}19591960func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {1961if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {1962return false1963}1964if !yaml_emitter_write_block_scalar_hints(emitter, value) {1965return false1966}1967if !yaml_emitter_process_line_comment_linebreak(emitter, true) {1968return false1969}19701971//emitter.indention = true1972emitter.whitespace = true19731974breaks := true1975leading_spaces := true1976for i := 0; i < len(value); {1977if is_break(value, i) {1978if !breaks && !leading_spaces && value[i] == '\n' {1979k := 01980for is_break(value, k) {1981k += width(value[k])1982}1983if !is_blankz(value, k) {1984if !put_break(emitter) {1985return false1986}1987}1988}1989if !write_break(emitter, value, &i) {1990return false1991}1992//emitter.indention = true1993breaks = true1994} else {1995if breaks {1996if !yaml_emitter_write_indent(emitter) {1997return false1998}1999leading_spaces = is_blank(value, i)2000}2001if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {2002if !yaml_emitter_write_indent(emitter) {2003return false2004}2005i += width(value[i])2006} else {2007if !write(emitter, value, &i) {2008return false2009}2010}2011emitter.indention = false2012breaks = false2013}2014}2015return true2016}20172018func yaml_emitter_write_comment(emitter *yaml_emitter_t, comment []byte) bool {2019breaks := false2020pound := false2021for i := 0; i < len(comment); {2022if is_break(comment, i) {2023if !write_break(emitter, comment, &i) {2024return false2025}2026//emitter.indention = true2027breaks = true2028pound = false2029} else {2030if breaks && !yaml_emitter_write_indent(emitter) {2031return false2032}2033if !pound {2034if comment[i] != '#' && (!put(emitter, '#') || !put(emitter, ' ')) {2035return false2036}2037pound = true2038}2039if !write(emitter, comment, &i) {2040return false2041}2042emitter.indention = false2043breaks = false2044}2045}2046if !breaks && !put_break(emitter) {2047return false2048}20492050emitter.whitespace = true2051//emitter.indention = true2052return true2053}205420552056