emitterc.go

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