Path: blob/main/vendor/gopkg.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-START167//168func yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {169if emitter.events_head == len(emitter.events) {170return true171}172var accumulate int173switch emitter.events[emitter.events_head].typ {174case yaml_DOCUMENT_START_EVENT:175accumulate = 1176break177case yaml_SEQUENCE_START_EVENT:178accumulate = 2179break180case yaml_MAPPING_START_EVENT:181accumulate = 3182break183default:184return false185}186if len(emitter.events)-emitter.events_head > accumulate {187return false188}189var level int190for i := emitter.events_head; i < len(emitter.events); i++ {191switch emitter.events[i].typ {192case yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:193level++194case yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:195level--196}197if level == 0 {198return false199}200}201return true202}203204// Append a directive to the directives stack.205func yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {206for i := 0; i < len(emitter.tag_directives); i++ {207if bytes.Equal(value.handle, emitter.tag_directives[i].handle) {208if allow_duplicates {209return true210}211return yaml_emitter_set_emitter_error(emitter, "duplicate %TAG directive")212}213}214215// [Go] Do we actually need to copy this given garbage collection216// and the lack of deallocating destructors?217tag_copy := yaml_tag_directive_t{218handle: make([]byte, len(value.handle)),219prefix: make([]byte, len(value.prefix)),220}221copy(tag_copy.handle, value.handle)222copy(tag_copy.prefix, value.prefix)223emitter.tag_directives = append(emitter.tag_directives, tag_copy)224return true225}226227// Increase the indentation level.228func yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {229emitter.indents = append(emitter.indents, emitter.indent)230if emitter.indent < 0 {231if flow {232emitter.indent = emitter.best_indent233} else {234emitter.indent = 0235}236} else if !indentless {237// [Go] This was changed so that indentations are more regular.238if emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {239// The first indent inside a sequence will just skip the "- " indicator.240emitter.indent += 2241} else {242// Everything else aligns to the chosen indentation.243emitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent)244}245}246return true247}248249// State dispatcher.250func yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {251switch emitter.state {252default:253case yaml_EMIT_STREAM_START_STATE:254return yaml_emitter_emit_stream_start(emitter, event)255256case yaml_EMIT_FIRST_DOCUMENT_START_STATE:257return yaml_emitter_emit_document_start(emitter, event, true)258259case yaml_EMIT_DOCUMENT_START_STATE:260return yaml_emitter_emit_document_start(emitter, event, false)261262case yaml_EMIT_DOCUMENT_CONTENT_STATE:263return yaml_emitter_emit_document_content(emitter, event)264265case yaml_EMIT_DOCUMENT_END_STATE:266return yaml_emitter_emit_document_end(emitter, event)267268case yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:269return yaml_emitter_emit_flow_sequence_item(emitter, event, true, false)270271case yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE:272return yaml_emitter_emit_flow_sequence_item(emitter, event, false, true)273274case yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:275return yaml_emitter_emit_flow_sequence_item(emitter, event, false, false)276277case yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:278return yaml_emitter_emit_flow_mapping_key(emitter, event, true, false)279280case yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE:281return yaml_emitter_emit_flow_mapping_key(emitter, event, false, true)282283case yaml_EMIT_FLOW_MAPPING_KEY_STATE:284return yaml_emitter_emit_flow_mapping_key(emitter, event, false, false)285286case yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:287return yaml_emitter_emit_flow_mapping_value(emitter, event, true)288289case yaml_EMIT_FLOW_MAPPING_VALUE_STATE:290return yaml_emitter_emit_flow_mapping_value(emitter, event, false)291292case yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:293return yaml_emitter_emit_block_sequence_item(emitter, event, true)294295case yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:296return yaml_emitter_emit_block_sequence_item(emitter, event, false)297298case yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:299return yaml_emitter_emit_block_mapping_key(emitter, event, true)300301case yaml_EMIT_BLOCK_MAPPING_KEY_STATE:302return yaml_emitter_emit_block_mapping_key(emitter, event, false)303304case yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:305return yaml_emitter_emit_block_mapping_value(emitter, event, true)306307case yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:308return yaml_emitter_emit_block_mapping_value(emitter, event, false)309310case yaml_EMIT_END_STATE:311return yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")312}313panic("invalid emitter state")314}315316// Expect STREAM-START.317func yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {318if event.typ != yaml_STREAM_START_EVENT {319return yaml_emitter_set_emitter_error(emitter, "expected STREAM-START")320}321if emitter.encoding == yaml_ANY_ENCODING {322emitter.encoding = event.encoding323if emitter.encoding == yaml_ANY_ENCODING {324emitter.encoding = yaml_UTF8_ENCODING325}326}327if emitter.best_indent < 2 || emitter.best_indent > 9 {328emitter.best_indent = 2329}330if emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {331emitter.best_width = 80332}333if emitter.best_width < 0 {334emitter.best_width = 1<<31 - 1335}336if emitter.line_break == yaml_ANY_BREAK {337emitter.line_break = yaml_LN_BREAK338}339340emitter.indent = -1341emitter.line = 0342emitter.column = 0343emitter.whitespace = true344emitter.indention = true345emitter.space_above = true346emitter.foot_indent = -1347348if emitter.encoding != yaml_UTF8_ENCODING {349if !yaml_emitter_write_bom(emitter) {350return false351}352}353emitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE354return true355}356357// Expect DOCUMENT-START or STREAM-END.358func yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {359360if event.typ == yaml_DOCUMENT_START_EVENT {361362if event.version_directive != nil {363if !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {364return false365}366}367368for i := 0; i < len(event.tag_directives); i++ {369tag_directive := &event.tag_directives[i]370if !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {371return false372}373if !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {374return false375}376}377378for i := 0; i < len(default_tag_directives); i++ {379tag_directive := &default_tag_directives[i]380if !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {381return false382}383}384385implicit := event.implicit386if !first || emitter.canonical {387implicit = false388}389390if emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {391if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {392return false393}394if !yaml_emitter_write_indent(emitter) {395return false396}397}398399if event.version_directive != nil {400implicit = false401if !yaml_emitter_write_indicator(emitter, []byte("%YAML"), true, false, false) {402return false403}404if !yaml_emitter_write_indicator(emitter, []byte("1.1"), true, false, false) {405return false406}407if !yaml_emitter_write_indent(emitter) {408return false409}410}411412if len(event.tag_directives) > 0 {413implicit = false414for i := 0; i < len(event.tag_directives); i++ {415tag_directive := &event.tag_directives[i]416if !yaml_emitter_write_indicator(emitter, []byte("%TAG"), true, false, false) {417return false418}419if !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {420return false421}422if !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {423return false424}425if !yaml_emitter_write_indent(emitter) {426return false427}428}429}430431if yaml_emitter_check_empty_document(emitter) {432implicit = false433}434if !implicit {435if !yaml_emitter_write_indent(emitter) {436return false437}438if !yaml_emitter_write_indicator(emitter, []byte("---"), true, false, false) {439return false440}441if emitter.canonical || true {442if !yaml_emitter_write_indent(emitter) {443return false444}445}446}447448if len(emitter.head_comment) > 0 {449if !yaml_emitter_process_head_comment(emitter) {450return false451}452if !put_break(emitter) {453return false454}455}456457emitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE458return true459}460461if event.typ == yaml_STREAM_END_EVENT {462if emitter.open_ended {463if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {464return false465}466if !yaml_emitter_write_indent(emitter) {467return false468}469}470if !yaml_emitter_flush(emitter) {471return false472}473emitter.state = yaml_EMIT_END_STATE474return true475}476477return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-START or STREAM-END")478}479480// Expect the root node.481func yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {482emitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)483484if !yaml_emitter_process_head_comment(emitter) {485return false486}487if !yaml_emitter_emit_node(emitter, event, true, false, false, false) {488return false489}490if !yaml_emitter_process_line_comment(emitter) {491return false492}493if !yaml_emitter_process_foot_comment(emitter) {494return false495}496return true497}498499// Expect DOCUMENT-END.500func yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {501if event.typ != yaml_DOCUMENT_END_EVENT {502return yaml_emitter_set_emitter_error(emitter, "expected DOCUMENT-END")503}504// [Go] Force document foot separation.505emitter.foot_indent = 0506if !yaml_emitter_process_foot_comment(emitter) {507return false508}509emitter.foot_indent = -1510if !yaml_emitter_write_indent(emitter) {511return false512}513if !event.implicit {514// [Go] Allocate the slice elsewhere.515if !yaml_emitter_write_indicator(emitter, []byte("..."), true, false, false) {516return false517}518if !yaml_emitter_write_indent(emitter) {519return false520}521}522if !yaml_emitter_flush(emitter) {523return false524}525emitter.state = yaml_EMIT_DOCUMENT_START_STATE526emitter.tag_directives = emitter.tag_directives[:0]527return true528}529530// Expect a flow item node.531func yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {532if first {533if !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {534return false535}536if !yaml_emitter_increase_indent(emitter, true, false) {537return false538}539emitter.flow_level++540}541542if event.typ == yaml_SEQUENCE_END_EVENT {543if emitter.canonical && !first && !trail {544if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {545return false546}547}548emitter.flow_level--549emitter.indent = emitter.indents[len(emitter.indents)-1]550emitter.indents = emitter.indents[:len(emitter.indents)-1]551if emitter.column == 0 || emitter.canonical && !first {552if !yaml_emitter_write_indent(emitter) {553return false554}555}556if !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {557return false558}559if !yaml_emitter_process_line_comment(emitter) {560return false561}562if !yaml_emitter_process_foot_comment(emitter) {563return false564}565emitter.state = emitter.states[len(emitter.states)-1]566emitter.states = emitter.states[:len(emitter.states)-1]567568return true569}570571if !first && !trail {572if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {573return false574}575}576577if !yaml_emitter_process_head_comment(emitter) {578return false579}580if emitter.column == 0 {581if !yaml_emitter_write_indent(emitter) {582return false583}584}585586if emitter.canonical || emitter.column > emitter.best_width {587if !yaml_emitter_write_indent(emitter) {588return false589}590}591if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {592emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE)593} else {594emitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)595}596if !yaml_emitter_emit_node(emitter, event, false, true, false, false) {597return false598}599if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {600if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {601return false602}603}604if !yaml_emitter_process_line_comment(emitter) {605return false606}607if !yaml_emitter_process_foot_comment(emitter) {608return false609}610return true611}612613// Expect a flow key node.614func yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {615if first {616if !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {617return false618}619if !yaml_emitter_increase_indent(emitter, true, false) {620return false621}622emitter.flow_level++623}624625if event.typ == yaml_MAPPING_END_EVENT {626if (emitter.canonical || len(emitter.head_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0) && !first && !trail {627if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {628return false629}630}631if !yaml_emitter_process_head_comment(emitter) {632return false633}634emitter.flow_level--635emitter.indent = emitter.indents[len(emitter.indents)-1]636emitter.indents = emitter.indents[:len(emitter.indents)-1]637if emitter.canonical && !first {638if !yaml_emitter_write_indent(emitter) {639return false640}641}642if !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {643return false644}645if !yaml_emitter_process_line_comment(emitter) {646return false647}648if !yaml_emitter_process_foot_comment(emitter) {649return false650}651emitter.state = emitter.states[len(emitter.states)-1]652emitter.states = emitter.states[:len(emitter.states)-1]653return true654}655656if !first && !trail {657if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {658return false659}660}661662if !yaml_emitter_process_head_comment(emitter) {663return false664}665666if emitter.column == 0 {667if !yaml_emitter_write_indent(emitter) {668return false669}670}671672if emitter.canonical || emitter.column > emitter.best_width {673if !yaml_emitter_write_indent(emitter) {674return false675}676}677678if !emitter.canonical && yaml_emitter_check_simple_key(emitter) {679emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)680return yaml_emitter_emit_node(emitter, event, false, false, true, true)681}682if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {683return false684}685emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)686return yaml_emitter_emit_node(emitter, event, false, false, true, false)687}688689// Expect a flow value node.690func yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {691if simple {692if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {693return false694}695} else {696if emitter.canonical || emitter.column > emitter.best_width {697if !yaml_emitter_write_indent(emitter) {698return false699}700}701if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {702return false703}704}705if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {706emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE)707} else {708emitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)709}710if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {711return false712}713if len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {714if !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {715return false716}717}718if !yaml_emitter_process_line_comment(emitter) {719return false720}721if !yaml_emitter_process_foot_comment(emitter) {722return false723}724return true725}726727// Expect a block item node.728func yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {729if first {730if !yaml_emitter_increase_indent(emitter, false, false) {731return false732}733}734if event.typ == yaml_SEQUENCE_END_EVENT {735emitter.indent = emitter.indents[len(emitter.indents)-1]736emitter.indents = emitter.indents[:len(emitter.indents)-1]737emitter.state = emitter.states[len(emitter.states)-1]738emitter.states = emitter.states[:len(emitter.states)-1]739return true740}741if !yaml_emitter_process_head_comment(emitter) {742return false743}744if !yaml_emitter_write_indent(emitter) {745return false746}747if !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {748return false749}750emitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)751if !yaml_emitter_emit_node(emitter, event, false, true, false, false) {752return false753}754if !yaml_emitter_process_line_comment(emitter) {755return false756}757if !yaml_emitter_process_foot_comment(emitter) {758return false759}760return true761}762763// Expect a block key node.764func yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {765if first {766if !yaml_emitter_increase_indent(emitter, false, false) {767return false768}769}770if !yaml_emitter_process_head_comment(emitter) {771return false772}773if event.typ == yaml_MAPPING_END_EVENT {774emitter.indent = emitter.indents[len(emitter.indents)-1]775emitter.indents = emitter.indents[:len(emitter.indents)-1]776emitter.state = emitter.states[len(emitter.states)-1]777emitter.states = emitter.states[:len(emitter.states)-1]778return true779}780if !yaml_emitter_write_indent(emitter) {781return false782}783if len(emitter.line_comment) > 0 {784// [Go] A line comment was provided for the key. That's unusual as the785// scanner associates line comments with the value. Either way,786// save the line comment and render it appropriately later.787emitter.key_line_comment = emitter.line_comment788emitter.line_comment = nil789}790if yaml_emitter_check_simple_key(emitter) {791emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)792return yaml_emitter_emit_node(emitter, event, false, false, true, true)793}794if !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {795return false796}797emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)798return yaml_emitter_emit_node(emitter, event, false, false, true, false)799}800801// Expect a block value node.802func yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {803if simple {804if !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {805return false806}807} else {808if !yaml_emitter_write_indent(emitter) {809return false810}811if !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {812return false813}814}815if len(emitter.key_line_comment) > 0 {816// [Go] Line comments are generally associated with the value, but when there's817// no value on the same line as a mapping key they end up attached to the818// key itself.819if event.typ == yaml_SCALAR_EVENT {820if len(emitter.line_comment) == 0 {821// A scalar is coming and it has no line comments by itself yet,822// so just let it handle the line comment as usual. If it has a823// line comment, we can't have both so the one from the key is lost.824emitter.line_comment = emitter.key_line_comment825emitter.key_line_comment = nil826}827} else if event.sequence_style() != yaml_FLOW_SEQUENCE_STYLE && (event.typ == yaml_MAPPING_START_EVENT || event.typ == yaml_SEQUENCE_START_EVENT) {828// An indented block follows, so write the comment right now.829emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment830if !yaml_emitter_process_line_comment(emitter) {831return false832}833emitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment834}835}836emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)837if !yaml_emitter_emit_node(emitter, event, false, false, true, false) {838return false839}840if !yaml_emitter_process_line_comment(emitter) {841return false842}843if !yaml_emitter_process_foot_comment(emitter) {844return false845}846return true847}848849func yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {850return event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0851}852853// Expect a node.854func yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,855root bool, sequence bool, mapping bool, simple_key bool) bool {856857emitter.root_context = root858emitter.sequence_context = sequence859emitter.mapping_context = mapping860emitter.simple_key_context = simple_key861862switch event.typ {863case yaml_ALIAS_EVENT:864return yaml_emitter_emit_alias(emitter, event)865case yaml_SCALAR_EVENT:866return yaml_emitter_emit_scalar(emitter, event)867case yaml_SEQUENCE_START_EVENT:868return yaml_emitter_emit_sequence_start(emitter, event)869case yaml_MAPPING_START_EVENT:870return yaml_emitter_emit_mapping_start(emitter, event)871default:872return yaml_emitter_set_emitter_error(emitter,873fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))874}875}876877// Expect ALIAS.878func yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {879if !yaml_emitter_process_anchor(emitter) {880return false881}882emitter.state = emitter.states[len(emitter.states)-1]883emitter.states = emitter.states[:len(emitter.states)-1]884return true885}886887// Expect SCALAR.888func yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {889if !yaml_emitter_select_scalar_style(emitter, event) {890return false891}892if !yaml_emitter_process_anchor(emitter) {893return false894}895if !yaml_emitter_process_tag(emitter) {896return false897}898if !yaml_emitter_increase_indent(emitter, true, false) {899return false900}901if !yaml_emitter_process_scalar(emitter) {902return false903}904emitter.indent = emitter.indents[len(emitter.indents)-1]905emitter.indents = emitter.indents[:len(emitter.indents)-1]906emitter.state = emitter.states[len(emitter.states)-1]907emitter.states = emitter.states[:len(emitter.states)-1]908return true909}910911// Expect SEQUENCE-START.912func yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {913if !yaml_emitter_process_anchor(emitter) {914return false915}916if !yaml_emitter_process_tag(emitter) {917return false918}919if emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||920yaml_emitter_check_empty_sequence(emitter) {921emitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE922} else {923emitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE924}925return true926}927928// Expect MAPPING-START.929func yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {930if !yaml_emitter_process_anchor(emitter) {931return false932}933if !yaml_emitter_process_tag(emitter) {934return false935}936if emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||937yaml_emitter_check_empty_mapping(emitter) {938emitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE939} else {940emitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE941}942return true943}944945// Check if the document content is an empty scalar.946func yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {947return false // [Go] Huh?948}949950// Check if the next events represent an empty sequence.951func yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {952if len(emitter.events)-emitter.events_head < 2 {953return false954}955return emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&956emitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT957}958959// Check if the next events represent an empty mapping.960func yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {961if len(emitter.events)-emitter.events_head < 2 {962return false963}964return emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&965emitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT966}967968// Check if the next node can be expressed as a simple key.969func yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {970length := 0971switch emitter.events[emitter.events_head].typ {972case yaml_ALIAS_EVENT:973length += len(emitter.anchor_data.anchor)974case yaml_SCALAR_EVENT:975if emitter.scalar_data.multiline {976return false977}978length += len(emitter.anchor_data.anchor) +979len(emitter.tag_data.handle) +980len(emitter.tag_data.suffix) +981len(emitter.scalar_data.value)982case yaml_SEQUENCE_START_EVENT:983if !yaml_emitter_check_empty_sequence(emitter) {984return false985}986length += len(emitter.anchor_data.anchor) +987len(emitter.tag_data.handle) +988len(emitter.tag_data.suffix)989case yaml_MAPPING_START_EVENT:990if !yaml_emitter_check_empty_mapping(emitter) {991return false992}993length += len(emitter.anchor_data.anchor) +994len(emitter.tag_data.handle) +995len(emitter.tag_data.suffix)996default:997return false998}999return length <= 1281000}10011002// Determine an acceptable scalar style.1003func yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {10041005no_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 01006if no_tag && !event.implicit && !event.quoted_implicit {1007return yaml_emitter_set_emitter_error(emitter, "neither tag nor implicit flags are specified")1008}10091010style := event.scalar_style()1011if style == yaml_ANY_SCALAR_STYLE {1012style = yaml_PLAIN_SCALAR_STYLE1013}1014if emitter.canonical {1015style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1016}1017if emitter.simple_key_context && emitter.scalar_data.multiline {1018style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1019}10201021if style == yaml_PLAIN_SCALAR_STYLE {1022if emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||1023emitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {1024style = yaml_SINGLE_QUOTED_SCALAR_STYLE1025}1026if len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {1027style = yaml_SINGLE_QUOTED_SCALAR_STYLE1028}1029if no_tag && !event.implicit {1030style = yaml_SINGLE_QUOTED_SCALAR_STYLE1031}1032}1033if style == yaml_SINGLE_QUOTED_SCALAR_STYLE {1034if !emitter.scalar_data.single_quoted_allowed {1035style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1036}1037}1038if style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {1039if !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {1040style = yaml_DOUBLE_QUOTED_SCALAR_STYLE1041}1042}10431044if no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {1045emitter.tag_data.handle = []byte{'!'}1046}1047emitter.scalar_data.style = style1048return true1049}10501051// Write an anchor.1052func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {1053if emitter.anchor_data.anchor == nil {1054return true1055}1056c := []byte{'&'}1057if emitter.anchor_data.alias {1058c[0] = '*'1059}1060if !yaml_emitter_write_indicator(emitter, c, true, false, false) {1061return false1062}1063return yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)1064}10651066// Write a tag.1067func yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {1068if len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {1069return true1070}1071if len(emitter.tag_data.handle) > 0 {1072if !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {1073return false1074}1075if len(emitter.tag_data.suffix) > 0 {1076if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {1077return false1078}1079}1080} else {1081// [Go] Allocate these slices elsewhere.1082if !yaml_emitter_write_indicator(emitter, []byte("!<"), true, false, false) {1083return false1084}1085if !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {1086return false1087}1088if !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {1089return false1090}1091}1092return true1093}10941095// Write a scalar.1096func yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {1097switch emitter.scalar_data.style {1098case yaml_PLAIN_SCALAR_STYLE:1099return yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)11001101case yaml_SINGLE_QUOTED_SCALAR_STYLE:1102return yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)11031104case yaml_DOUBLE_QUOTED_SCALAR_STYLE:1105return yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)11061107case yaml_LITERAL_SCALAR_STYLE:1108return yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)11091110case yaml_FOLDED_SCALAR_STYLE:1111return yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)1112}1113panic("unknown scalar style")1114}11151116// Write a head comment.1117func yaml_emitter_process_head_comment(emitter *yaml_emitter_t) bool {1118if len(emitter.tail_comment) > 0 {1119if !yaml_emitter_write_indent(emitter) {1120return false1121}1122if !yaml_emitter_write_comment(emitter, emitter.tail_comment) {1123return false1124}1125emitter.tail_comment = emitter.tail_comment[:0]1126emitter.foot_indent = emitter.indent1127if emitter.foot_indent < 0 {1128emitter.foot_indent = 01129}1130}11311132if len(emitter.head_comment) == 0 {1133return true1134}1135if !yaml_emitter_write_indent(emitter) {1136return false1137}1138if !yaml_emitter_write_comment(emitter, emitter.head_comment) {1139return false1140}1141emitter.head_comment = emitter.head_comment[:0]1142return true1143}11441145// Write an line comment.1146func yaml_emitter_process_line_comment(emitter *yaml_emitter_t) bool {1147if len(emitter.line_comment) == 0 {1148return true1149}1150if !emitter.whitespace {1151if !put(emitter, ' ') {1152return false1153}1154}1155if !yaml_emitter_write_comment(emitter, emitter.line_comment) {1156return false1157}1158emitter.line_comment = emitter.line_comment[:0]1159return true1160}11611162// Write a foot comment.1163func yaml_emitter_process_foot_comment(emitter *yaml_emitter_t) bool {1164if len(emitter.foot_comment) == 0 {1165return true1166}1167if !yaml_emitter_write_indent(emitter) {1168return false1169}1170if !yaml_emitter_write_comment(emitter, emitter.foot_comment) {1171return false1172}1173emitter.foot_comment = emitter.foot_comment[:0]1174emitter.foot_indent = emitter.indent1175if emitter.foot_indent < 0 {1176emitter.foot_indent = 01177}1178return true1179}11801181// Check if a %YAML directive is valid.1182func yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {1183if version_directive.major != 1 || version_directive.minor != 1 {1184return yaml_emitter_set_emitter_error(emitter, "incompatible %YAML directive")1185}1186return true1187}11881189// Check if a %TAG directive is valid.1190func yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {1191handle := tag_directive.handle1192prefix := tag_directive.prefix1193if len(handle) == 0 {1194return yaml_emitter_set_emitter_error(emitter, "tag handle must not be empty")1195}1196if handle[0] != '!' {1197return yaml_emitter_set_emitter_error(emitter, "tag handle must start with '!'")1198}1199if handle[len(handle)-1] != '!' {1200return yaml_emitter_set_emitter_error(emitter, "tag handle must end with '!'")1201}1202for i := 1; i < len(handle)-1; i += width(handle[i]) {1203if !is_alpha(handle, i) {1204return yaml_emitter_set_emitter_error(emitter, "tag handle must contain alphanumerical characters only")1205}1206}1207if len(prefix) == 0 {1208return yaml_emitter_set_emitter_error(emitter, "tag prefix must not be empty")1209}1210return true1211}12121213// Check if an anchor is valid.1214func yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {1215if len(anchor) == 0 {1216problem := "anchor value must not be empty"1217if alias {1218problem = "alias value must not be empty"1219}1220return yaml_emitter_set_emitter_error(emitter, problem)1221}1222for i := 0; i < len(anchor); i += width(anchor[i]) {1223if !is_alpha(anchor, i) {1224problem := "anchor value must contain alphanumerical characters only"1225if alias {1226problem = "alias value must contain alphanumerical characters only"1227}1228return yaml_emitter_set_emitter_error(emitter, problem)1229}1230}1231emitter.anchor_data.anchor = anchor1232emitter.anchor_data.alias = alias1233return true1234}12351236// Check if a tag is valid.1237func yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {1238if len(tag) == 0 {1239return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")1240}1241for i := 0; i < len(emitter.tag_directives); i++ {1242tag_directive := &emitter.tag_directives[i]1243if bytes.HasPrefix(tag, tag_directive.prefix) {1244emitter.tag_data.handle = tag_directive.handle1245emitter.tag_data.suffix = tag[len(tag_directive.prefix):]1246return true1247}1248}1249emitter.tag_data.suffix = tag1250return true1251}12521253// Check if a scalar is valid.1254func yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {1255var (1256block_indicators = false1257flow_indicators = false1258line_breaks = false1259special_characters = false1260tab_characters = false12611262leading_space = false1263leading_break = false1264trailing_space = false1265trailing_break = false1266break_space = false1267space_break = false12681269preceded_by_whitespace = false1270followed_by_whitespace = false1271previous_space = false1272previous_break = false1273)12741275emitter.scalar_data.value = value12761277if len(value) == 0 {1278emitter.scalar_data.multiline = false1279emitter.scalar_data.flow_plain_allowed = false1280emitter.scalar_data.block_plain_allowed = true1281emitter.scalar_data.single_quoted_allowed = true1282emitter.scalar_data.block_allowed = false1283return true1284}12851286if len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {1287block_indicators = true1288flow_indicators = true1289}12901291preceded_by_whitespace = true1292for i, w := 0, 0; i < len(value); i += w {1293w = width(value[i])1294followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)12951296if i == 0 {1297switch value[i] {1298case '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\'', '"', '%', '@', '`':1299flow_indicators = true1300block_indicators = true1301case '?', ':':1302flow_indicators = true1303if followed_by_whitespace {1304block_indicators = true1305}1306case '-':1307if followed_by_whitespace {1308flow_indicators = true1309block_indicators = true1310}1311}1312} else {1313switch value[i] {1314case ',', '?', '[', ']', '{', '}':1315flow_indicators = true1316case ':':1317flow_indicators = true1318if followed_by_whitespace {1319block_indicators = true1320}1321case '#':1322if preceded_by_whitespace {1323flow_indicators = true1324block_indicators = true1325}1326}1327}13281329if value[i] == '\t' {1330tab_characters = true1331} else if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {1332special_characters = true1333}1334if is_space(value, i) {1335if i == 0 {1336leading_space = true1337}1338if i+width(value[i]) == len(value) {1339trailing_space = true1340}1341if previous_break {1342break_space = true1343}1344previous_space = true1345previous_break = false1346} else if is_break(value, i) {1347line_breaks = true1348if i == 0 {1349leading_break = true1350}1351if i+width(value[i]) == len(value) {1352trailing_break = true1353}1354if previous_space {1355space_break = true1356}1357previous_space = false1358previous_break = true1359} else {1360previous_space = false1361previous_break = false1362}13631364// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.1365preceded_by_whitespace = is_blankz(value, i)1366}13671368emitter.scalar_data.multiline = line_breaks1369emitter.scalar_data.flow_plain_allowed = true1370emitter.scalar_data.block_plain_allowed = true1371emitter.scalar_data.single_quoted_allowed = true1372emitter.scalar_data.block_allowed = true13731374if leading_space || leading_break || trailing_space || trailing_break {1375emitter.scalar_data.flow_plain_allowed = false1376emitter.scalar_data.block_plain_allowed = false1377}1378if trailing_space {1379emitter.scalar_data.block_allowed = false1380}1381if break_space {1382emitter.scalar_data.flow_plain_allowed = false1383emitter.scalar_data.block_plain_allowed = false1384emitter.scalar_data.single_quoted_allowed = false1385}1386if space_break || tab_characters || special_characters {1387emitter.scalar_data.flow_plain_allowed = false1388emitter.scalar_data.block_plain_allowed = false1389emitter.scalar_data.single_quoted_allowed = false1390}1391if space_break || special_characters {1392emitter.scalar_data.block_allowed = false1393}1394if line_breaks {1395emitter.scalar_data.flow_plain_allowed = false1396emitter.scalar_data.block_plain_allowed = false1397}1398if flow_indicators {1399emitter.scalar_data.flow_plain_allowed = false1400}1401if block_indicators {1402emitter.scalar_data.block_plain_allowed = false1403}1404return true1405}14061407// Check if the event data is valid.1408func yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {14091410emitter.anchor_data.anchor = nil1411emitter.tag_data.handle = nil1412emitter.tag_data.suffix = nil1413emitter.scalar_data.value = nil14141415if len(event.head_comment) > 0 {1416emitter.head_comment = event.head_comment1417}1418if len(event.line_comment) > 0 {1419emitter.line_comment = event.line_comment1420}1421if len(event.foot_comment) > 0 {1422emitter.foot_comment = event.foot_comment1423}1424if len(event.tail_comment) > 0 {1425emitter.tail_comment = event.tail_comment1426}14271428switch event.typ {1429case yaml_ALIAS_EVENT:1430if !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {1431return false1432}14331434case yaml_SCALAR_EVENT:1435if len(event.anchor) > 0 {1436if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {1437return false1438}1439}1440if len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {1441if !yaml_emitter_analyze_tag(emitter, event.tag) {1442return false1443}1444}1445if !yaml_emitter_analyze_scalar(emitter, event.value) {1446return false1447}14481449case yaml_SEQUENCE_START_EVENT:1450if len(event.anchor) > 0 {1451if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {1452return false1453}1454}1455if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {1456if !yaml_emitter_analyze_tag(emitter, event.tag) {1457return false1458}1459}14601461case yaml_MAPPING_START_EVENT:1462if len(event.anchor) > 0 {1463if !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {1464return false1465}1466}1467if len(event.tag) > 0 && (emitter.canonical || !event.implicit) {1468if !yaml_emitter_analyze_tag(emitter, event.tag) {1469return false1470}1471}1472}1473return true1474}14751476// Write the BOM character.1477func yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {1478if !flush(emitter) {1479return false1480}1481pos := emitter.buffer_pos1482emitter.buffer[pos+0] = '\xEF'1483emitter.buffer[pos+1] = '\xBB'1484emitter.buffer[pos+2] = '\xBF'1485emitter.buffer_pos += 31486return true1487}14881489func yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {1490indent := emitter.indent1491if indent < 0 {1492indent = 01493}1494if !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {1495if !put_break(emitter) {1496return false1497}1498}1499if emitter.foot_indent == indent {1500if !put_break(emitter) {1501return false1502}1503}1504for emitter.column < indent {1505if !put(emitter, ' ') {1506return false1507}1508}1509emitter.whitespace = true1510//emitter.indention = true1511emitter.space_above = false1512emitter.foot_indent = -11513return true1514}15151516func yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {1517if need_whitespace && !emitter.whitespace {1518if !put(emitter, ' ') {1519return false1520}1521}1522if !write_all(emitter, indicator) {1523return false1524}1525emitter.whitespace = is_whitespace1526emitter.indention = (emitter.indention && is_indention)1527emitter.open_ended = false1528return true1529}15301531func yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {1532if !write_all(emitter, value) {1533return false1534}1535emitter.whitespace = false1536emitter.indention = false1537return true1538}15391540func yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {1541if !emitter.whitespace {1542if !put(emitter, ' ') {1543return false1544}1545}1546if !write_all(emitter, value) {1547return false1548}1549emitter.whitespace = false1550emitter.indention = false1551return true1552}15531554func yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {1555if need_whitespace && !emitter.whitespace {1556if !put(emitter, ' ') {1557return false1558}1559}1560for i := 0; i < len(value); {1561var must_write bool1562switch value[i] {1563case ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\'', '(', ')', '[', ']':1564must_write = true1565default:1566must_write = is_alpha(value, i)1567}1568if must_write {1569if !write(emitter, value, &i) {1570return false1571}1572} else {1573w := width(value[i])1574for k := 0; k < w; k++ {1575octet := value[i]1576i++1577if !put(emitter, '%') {1578return false1579}15801581c := octet >> 41582if c < 10 {1583c += '0'1584} else {1585c += 'A' - 101586}1587if !put(emitter, c) {1588return false1589}15901591c = octet & 0x0f1592if c < 10 {1593c += '0'1594} else {1595c += 'A' - 101596}1597if !put(emitter, c) {1598return false1599}1600}1601}1602}1603emitter.whitespace = false1604emitter.indention = false1605return true1606}16071608func yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {1609if len(value) > 0 && !emitter.whitespace {1610if !put(emitter, ' ') {1611return false1612}1613}16141615spaces := false1616breaks := false1617for i := 0; i < len(value); {1618if is_space(value, i) {1619if allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {1620if !yaml_emitter_write_indent(emitter) {1621return false1622}1623i += width(value[i])1624} else {1625if !write(emitter, value, &i) {1626return false1627}1628}1629spaces = true1630} else if is_break(value, i) {1631if !breaks && value[i] == '\n' {1632if !put_break(emitter) {1633return false1634}1635}1636if !write_break(emitter, value, &i) {1637return false1638}1639//emitter.indention = true1640breaks = true1641} else {1642if breaks {1643if !yaml_emitter_write_indent(emitter) {1644return false1645}1646}1647if !write(emitter, value, &i) {1648return false1649}1650emitter.indention = false1651spaces = false1652breaks = false1653}1654}16551656if len(value) > 0 {1657emitter.whitespace = false1658}1659emitter.indention = false1660if emitter.root_context {1661emitter.open_ended = true1662}16631664return true1665}16661667func yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {16681669if !yaml_emitter_write_indicator(emitter, []byte{'\''}, true, false, false) {1670return false1671}16721673spaces := false1674breaks := false1675for i := 0; i < len(value); {1676if is_space(value, i) {1677if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {1678if !yaml_emitter_write_indent(emitter) {1679return false1680}1681i += width(value[i])1682} else {1683if !write(emitter, value, &i) {1684return false1685}1686}1687spaces = true1688} else if is_break(value, i) {1689if !breaks && value[i] == '\n' {1690if !put_break(emitter) {1691return false1692}1693}1694if !write_break(emitter, value, &i) {1695return false1696}1697//emitter.indention = true1698breaks = true1699} else {1700if breaks {1701if !yaml_emitter_write_indent(emitter) {1702return false1703}1704}1705if value[i] == '\'' {1706if !put(emitter, '\'') {1707return false1708}1709}1710if !write(emitter, value, &i) {1711return false1712}1713emitter.indention = false1714spaces = false1715breaks = false1716}1717}1718if !yaml_emitter_write_indicator(emitter, []byte{'\''}, false, false, false) {1719return false1720}1721emitter.whitespace = false1722emitter.indention = false1723return true1724}17251726func yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {1727spaces := false1728if !yaml_emitter_write_indicator(emitter, []byte{'"'}, true, false, false) {1729return false1730}17311732for i := 0; i < len(value); {1733if !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||1734is_bom(value, i) || is_break(value, i) ||1735value[i] == '"' || value[i] == '\\' {17361737octet := value[i]17381739var w int1740var v rune1741switch {1742case octet&0x80 == 0x00:1743w, v = 1, rune(octet&0x7F)1744case octet&0xE0 == 0xC0:1745w, v = 2, rune(octet&0x1F)1746case octet&0xF0 == 0xE0:1747w, v = 3, rune(octet&0x0F)1748case octet&0xF8 == 0xF0:1749w, v = 4, rune(octet&0x07)1750}1751for k := 1; k < w; k++ {1752octet = value[i+k]1753v = (v << 6) + (rune(octet) & 0x3F)1754}1755i += w17561757if !put(emitter, '\\') {1758return false1759}17601761var ok bool1762switch v {1763case 0x00:1764ok = put(emitter, '0')1765case 0x07:1766ok = put(emitter, 'a')1767case 0x08:1768ok = put(emitter, 'b')1769case 0x09:1770ok = put(emitter, 't')1771case 0x0A:1772ok = put(emitter, 'n')1773case 0x0b:1774ok = put(emitter, 'v')1775case 0x0c:1776ok = put(emitter, 'f')1777case 0x0d:1778ok = put(emitter, 'r')1779case 0x1b:1780ok = put(emitter, 'e')1781case 0x22:1782ok = put(emitter, '"')1783case 0x5c:1784ok = put(emitter, '\\')1785case 0x85:1786ok = put(emitter, 'N')1787case 0xA0:1788ok = put(emitter, '_')1789case 0x2028:1790ok = put(emitter, 'L')1791case 0x2029:1792ok = put(emitter, 'P')1793default:1794if v <= 0xFF {1795ok = put(emitter, 'x')1796w = 21797} else if v <= 0xFFFF {1798ok = put(emitter, 'u')1799w = 41800} else {1801ok = put(emitter, 'U')1802w = 81803}1804for k := (w - 1) * 4; ok && k >= 0; k -= 4 {1805digit := byte((v >> uint(k)) & 0x0F)1806if digit < 10 {1807ok = put(emitter, digit+'0')1808} else {1809ok = put(emitter, digit+'A'-10)1810}1811}1812}1813if !ok {1814return false1815}1816spaces = false1817} else if is_space(value, i) {1818if allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {1819if !yaml_emitter_write_indent(emitter) {1820return false1821}1822if is_space(value, i+1) {1823if !put(emitter, '\\') {1824return false1825}1826}1827i += width(value[i])1828} else if !write(emitter, value, &i) {1829return false1830}1831spaces = true1832} else {1833if !write(emitter, value, &i) {1834return false1835}1836spaces = false1837}1838}1839if !yaml_emitter_write_indicator(emitter, []byte{'"'}, false, false, false) {1840return false1841}1842emitter.whitespace = false1843emitter.indention = false1844return true1845}18461847func yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {1848if is_space(value, 0) || is_break(value, 0) {1849indent_hint := []byte{'0' + byte(emitter.best_indent)}1850if !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {1851return false1852}1853}18541855emitter.open_ended = false18561857var chomp_hint [1]byte1858if len(value) == 0 {1859chomp_hint[0] = '-'1860} else {1861i := len(value) - 11862for value[i]&0xC0 == 0x80 {1863i--1864}1865if !is_break(value, i) {1866chomp_hint[0] = '-'1867} else if i == 0 {1868chomp_hint[0] = '+'1869emitter.open_ended = true1870} else {1871i--1872for value[i]&0xC0 == 0x80 {1873i--1874}1875if is_break(value, i) {1876chomp_hint[0] = '+'1877emitter.open_ended = true1878}1879}1880}1881if chomp_hint[0] != 0 {1882if !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {1883return false1884}1885}1886return true1887}18881889func yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {1890if !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {1891return false1892}1893if !yaml_emitter_write_block_scalar_hints(emitter, value) {1894return false1895}1896if !yaml_emitter_process_line_comment(emitter) {1897return false1898}1899//emitter.indention = true1900emitter.whitespace = true1901breaks := true1902for i := 0; i < len(value); {1903if is_break(value, i) {1904if !write_break(emitter, value, &i) {1905return false1906}1907//emitter.indention = true1908breaks = true1909} else {1910if breaks {1911if !yaml_emitter_write_indent(emitter) {1912return false1913}1914}1915if !write(emitter, value, &i) {1916return false1917}1918emitter.indention = false1919breaks = false1920}1921}19221923return true1924}19251926func yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {1927if !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {1928return false1929}1930if !yaml_emitter_write_block_scalar_hints(emitter, value) {1931return false1932}1933if !yaml_emitter_process_line_comment(emitter) {1934return false1935}19361937//emitter.indention = true1938emitter.whitespace = true19391940breaks := true1941leading_spaces := true1942for i := 0; i < len(value); {1943if is_break(value, i) {1944if !breaks && !leading_spaces && value[i] == '\n' {1945k := 01946for is_break(value, k) {1947k += width(value[k])1948}1949if !is_blankz(value, k) {1950if !put_break(emitter) {1951return false1952}1953}1954}1955if !write_break(emitter, value, &i) {1956return false1957}1958//emitter.indention = true1959breaks = true1960} else {1961if breaks {1962if !yaml_emitter_write_indent(emitter) {1963return false1964}1965leading_spaces = is_blank(value, i)1966}1967if !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {1968if !yaml_emitter_write_indent(emitter) {1969return false1970}1971i += width(value[i])1972} else {1973if !write(emitter, value, &i) {1974return false1975}1976}1977emitter.indention = false1978breaks = false1979}1980}1981return true1982}19831984func yaml_emitter_write_comment(emitter *yaml_emitter_t, comment []byte) bool {1985breaks := false1986pound := false1987for i := 0; i < len(comment); {1988if is_break(comment, i) {1989if !write_break(emitter, comment, &i) {1990return false1991}1992//emitter.indention = true1993breaks = true1994pound = false1995} else {1996if breaks && !yaml_emitter_write_indent(emitter) {1997return false1998}1999if !pound {2000if comment[i] != '#' && (!put(emitter, '#') || !put(emitter, ' ')) {2001return false2002}2003pound = true2004}2005if !write(emitter, comment, &i) {2006return false2007}2008emitter.indention = false2009breaks = false2010}2011}2012if !breaks && !put_break(emitter) {2013return false2014}20152016emitter.whitespace = true2017//emitter.indention = true2018return true2019}202020212022