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