gitee.com/quant1x/pkg@v0.2.8/yaml/parserc.go (about)

     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  
    23  package yaml
    24  
    25  import (
    26  	"bytes"
    27  )
    28  
    29  // The parser implements the following grammar:
    30  //
    31  // stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
    32  // implicit_document    ::= block_node DOCUMENT-END*
    33  // explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
    34  // block_node_or_indentless_sequence    ::=
    35  //                          ALIAS
    36  //                          | properties (block_content | indentless_block_sequence)?
    37  //                          | block_content
    38  //                          | indentless_block_sequence
    39  // block_node           ::= ALIAS
    40  //                          | properties block_content?
    41  //                          | block_content
    42  // flow_node            ::= ALIAS
    43  //                          | properties flow_content?
    44  //                          | flow_content
    45  // properties           ::= TAG ANCHOR? | ANCHOR TAG?
    46  // block_content        ::= block_collection | flow_collection | SCALAR
    47  // flow_content         ::= flow_collection | SCALAR
    48  // block_collection     ::= block_sequence | block_mapping
    49  // flow_collection      ::= flow_sequence | flow_mapping
    50  // block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
    51  // indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
    52  // block_mapping        ::= BLOCK-MAPPING_START
    53  //                          ((KEY block_node_or_indentless_sequence?)?
    54  //                          (VALUE block_node_or_indentless_sequence?)?)*
    55  //                          BLOCK-END
    56  // flow_sequence        ::= FLOW-SEQUENCE-START
    57  //                          (flow_sequence_entry FLOW-ENTRY)*
    58  //                          flow_sequence_entry?
    59  //                          FLOW-SEQUENCE-END
    60  // flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
    61  // flow_mapping         ::= FLOW-MAPPING-START
    62  //                          (flow_mapping_entry FLOW-ENTRY)*
    63  //                          flow_mapping_entry?
    64  //                          FLOW-MAPPING-END
    65  // flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
    66  
    67  // Peek the next token in the token queue.
    68  func peek_token(parser *yaml_parser_t) *yaml_token_t {
    69  	if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
    70  		token := &parser.tokens[parser.tokens_head]
    71  		yaml_parser_unfold_comments(parser, token)
    72  		return token
    73  	}
    74  	return nil
    75  }
    76  
    77  // yaml_parser_unfold_comments walks through the comments queue and joins all
    78  // comments behind the position of the provided token into the respective
    79  // top-level comment slices in the parser.
    80  func yaml_parser_unfold_comments(parser *yaml_parser_t, token *yaml_token_t) {
    81  	for parser.comments_head < len(parser.comments) && token.start_mark.index >= parser.comments[parser.comments_head].token_mark.index {
    82  		comment := &parser.comments[parser.comments_head]
    83  		if len(comment.head) > 0 {
    84  			if token.typ == yaml_BLOCK_END_TOKEN {
    85  				// No heads on ends, so keep comment.head for a follow up token.
    86  				break
    87  			}
    88  			if len(parser.head_comment) > 0 {
    89  				parser.head_comment = append(parser.head_comment, '\n')
    90  			}
    91  			parser.head_comment = append(parser.head_comment, comment.head...)
    92  		}
    93  		if len(comment.foot) > 0 {
    94  			if len(parser.foot_comment) > 0 {
    95  				parser.foot_comment = append(parser.foot_comment, '\n')
    96  			}
    97  			parser.foot_comment = append(parser.foot_comment, comment.foot...)
    98  		}
    99  		if len(comment.line) > 0 {
   100  			if len(parser.line_comment) > 0 {
   101  				parser.line_comment = append(parser.line_comment, '\n')
   102  			}
   103  			parser.line_comment = append(parser.line_comment, comment.line...)
   104  		}
   105  		*comment = yaml_comment_t{}
   106  		parser.comments_head++
   107  	}
   108  }
   109  
   110  // Remove the next token from the queue (must be called after peek_token).
   111  func skip_token(parser *yaml_parser_t) {
   112  	parser.token_available = false
   113  	parser.tokens_parsed++
   114  	parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
   115  	parser.tokens_head++
   116  }
   117  
   118  // Get the next event.
   119  func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
   120  	// Erase the event object.
   121  	*event = yaml_event_t{}
   122  
   123  	// No events after the end of the stream or error.
   124  	if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
   125  		return true
   126  	}
   127  
   128  	// Generate the next event.
   129  	return yaml_parser_state_machine(parser, event)
   130  }
   131  
   132  // Set parser error.
   133  func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
   134  	parser.error = yaml_PARSER_ERROR
   135  	parser.problem = problem
   136  	parser.problem_mark = problem_mark
   137  	return false
   138  }
   139  
   140  func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {
   141  	parser.error = yaml_PARSER_ERROR
   142  	parser.context = context
   143  	parser.context_mark = context_mark
   144  	parser.problem = problem
   145  	parser.problem_mark = problem_mark
   146  	return false
   147  }
   148  
   149  // State dispatcher.
   150  func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
   151  	//trace("yaml_parser_state_machine", "state:", parser.state.String())
   152  
   153  	switch parser.state {
   154  	case yaml_PARSE_STREAM_START_STATE:
   155  		return yaml_parser_parse_stream_start(parser, event)
   156  
   157  	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
   158  		return yaml_parser_parse_document_start(parser, event, true)
   159  
   160  	case yaml_PARSE_DOCUMENT_START_STATE:
   161  		return yaml_parser_parse_document_start(parser, event, false)
   162  
   163  	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
   164  		return yaml_parser_parse_document_content(parser, event)
   165  
   166  	case yaml_PARSE_DOCUMENT_END_STATE:
   167  		return yaml_parser_parse_document_end(parser, event)
   168  
   169  	case yaml_PARSE_BLOCK_NODE_STATE:
   170  		return yaml_parser_parse_node(parser, event, true, false)
   171  
   172  	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
   173  		return yaml_parser_parse_node(parser, event, true, true)
   174  
   175  	case yaml_PARSE_FLOW_NODE_STATE:
   176  		return yaml_parser_parse_node(parser, event, false, false)
   177  
   178  	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
   179  		return yaml_parser_parse_block_sequence_entry(parser, event, true)
   180  
   181  	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
   182  		return yaml_parser_parse_block_sequence_entry(parser, event, false)
   183  
   184  	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
   185  		return yaml_parser_parse_indentless_sequence_entry(parser, event)
   186  
   187  	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
   188  		return yaml_parser_parse_block_mapping_key(parser, event, true)
   189  
   190  	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
   191  		return yaml_parser_parse_block_mapping_key(parser, event, false)
   192  
   193  	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
   194  		return yaml_parser_parse_block_mapping_value(parser, event)
   195  
   196  	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
   197  		return yaml_parser_parse_flow_sequence_entry(parser, event, true)
   198  
   199  	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
   200  		return yaml_parser_parse_flow_sequence_entry(parser, event, false)
   201  
   202  	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
   203  		return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
   204  
   205  	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
   206  		return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
   207  
   208  	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
   209  		return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
   210  
   211  	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
   212  		return yaml_parser_parse_flow_mapping_key(parser, event, true)
   213  
   214  	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
   215  		return yaml_parser_parse_flow_mapping_key(parser, event, false)
   216  
   217  	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
   218  		return yaml_parser_parse_flow_mapping_value(parser, event, false)
   219  
   220  	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
   221  		return yaml_parser_parse_flow_mapping_value(parser, event, true)
   222  
   223  	default:
   224  		panic("invalid parser state")
   225  	}
   226  }
   227  
   228  // Parse the production:
   229  // stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
   230  //
   231  //	************
   232  func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
   233  	token := peek_token(parser)
   234  	if token == nil {
   235  		return false
   236  	}
   237  	if token.typ != yaml_STREAM_START_TOKEN {
   238  		return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
   239  	}
   240  	parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
   241  	*event = yaml_event_t{
   242  		typ:        yaml_STREAM_START_EVENT,
   243  		start_mark: token.start_mark,
   244  		end_mark:   token.end_mark,
   245  		encoding:   token.encoding,
   246  	}
   247  	skip_token(parser)
   248  	return true
   249  }
   250  
   251  // Parse the productions:
   252  // implicit_document    ::= block_node DOCUMENT-END*
   253  //
   254  //	*
   255  //
   256  // explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
   257  //
   258  //	*************************
   259  func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
   260  
   261  	token := peek_token(parser)
   262  	if token == nil {
   263  		return false
   264  	}
   265  
   266  	// Parse extra document end indicators.
   267  	if !implicit {
   268  		for token.typ == yaml_DOCUMENT_END_TOKEN {
   269  			skip_token(parser)
   270  			token = peek_token(parser)
   271  			if token == nil {
   272  				return false
   273  			}
   274  		}
   275  	}
   276  
   277  	if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
   278  		token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
   279  		token.typ != yaml_DOCUMENT_START_TOKEN &&
   280  		token.typ != yaml_STREAM_END_TOKEN {
   281  		// Parse an implicit document.
   282  		if !yaml_parser_process_directives(parser, nil, nil) {
   283  			return false
   284  		}
   285  		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
   286  		parser.state = yaml_PARSE_BLOCK_NODE_STATE
   287  
   288  		var head_comment []byte
   289  		if len(parser.head_comment) > 0 {
   290  			// [Go] Scan the header comment backwards, and if an empty line is found, break
   291  			//      the header so the part before the last empty line goes into the
   292  			//      document header, while the bottom of it goes into a follow up event.
   293  			for i := len(parser.head_comment) - 1; i > 0; i-- {
   294  				if parser.head_comment[i] == '\n' {
   295  					if i == len(parser.head_comment)-1 {
   296  						head_comment = parser.head_comment[:i]
   297  						parser.head_comment = parser.head_comment[i+1:]
   298  						break
   299  					} else if parser.head_comment[i-1] == '\n' {
   300  						head_comment = parser.head_comment[:i-1]
   301  						parser.head_comment = parser.head_comment[i+1:]
   302  						break
   303  					}
   304  				}
   305  			}
   306  		}
   307  
   308  		*event = yaml_event_t{
   309  			typ:        yaml_DOCUMENT_START_EVENT,
   310  			start_mark: token.start_mark,
   311  			end_mark:   token.end_mark,
   312  
   313  			head_comment: head_comment,
   314  		}
   315  
   316  	} else if token.typ != yaml_STREAM_END_TOKEN {
   317  		// Parse an explicit document.
   318  		var version_directive *yaml_version_directive_t
   319  		var tag_directives []yaml_tag_directive_t
   320  		start_mark := token.start_mark
   321  		if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
   322  			return false
   323  		}
   324  		token = peek_token(parser)
   325  		if token == nil {
   326  			return false
   327  		}
   328  		if token.typ != yaml_DOCUMENT_START_TOKEN {
   329  			yaml_parser_set_parser_error(parser,
   330  				"did not find expected <document start>", token.start_mark)
   331  			return false
   332  		}
   333  		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
   334  		parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
   335  		end_mark := token.end_mark
   336  
   337  		*event = yaml_event_t{
   338  			typ:               yaml_DOCUMENT_START_EVENT,
   339  			start_mark:        start_mark,
   340  			end_mark:          end_mark,
   341  			version_directive: version_directive,
   342  			tag_directives:    tag_directives,
   343  			implicit:          false,
   344  		}
   345  		skip_token(parser)
   346  
   347  	} else {
   348  		// Parse the stream end.
   349  		parser.state = yaml_PARSE_END_STATE
   350  		*event = yaml_event_t{
   351  			typ:        yaml_STREAM_END_EVENT,
   352  			start_mark: token.start_mark,
   353  			end_mark:   token.end_mark,
   354  		}
   355  		skip_token(parser)
   356  	}
   357  
   358  	return true
   359  }
   360  
   361  // Parse the productions:
   362  // explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
   363  //
   364  //	***********
   365  func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
   366  	token := peek_token(parser)
   367  	if token == nil {
   368  		return false
   369  	}
   370  
   371  	if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
   372  		token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
   373  		token.typ == yaml_DOCUMENT_START_TOKEN ||
   374  		token.typ == yaml_DOCUMENT_END_TOKEN ||
   375  		token.typ == yaml_STREAM_END_TOKEN {
   376  		parser.state = parser.states[len(parser.states)-1]
   377  		parser.states = parser.states[:len(parser.states)-1]
   378  		return yaml_parser_process_empty_scalar(parser, event,
   379  			token.start_mark)
   380  	}
   381  	return yaml_parser_parse_node(parser, event, true, false)
   382  }
   383  
   384  // Parse the productions:
   385  // implicit_document    ::= block_node DOCUMENT-END*
   386  //
   387  //	*************
   388  //
   389  // explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
   390  func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
   391  	token := peek_token(parser)
   392  	if token == nil {
   393  		return false
   394  	}
   395  
   396  	start_mark := token.start_mark
   397  	end_mark := token.start_mark
   398  
   399  	implicit := true
   400  	if token.typ == yaml_DOCUMENT_END_TOKEN {
   401  		end_mark = token.end_mark
   402  		skip_token(parser)
   403  		implicit = false
   404  	}
   405  
   406  	parser.tag_directives = parser.tag_directives[:0]
   407  
   408  	parser.state = yaml_PARSE_DOCUMENT_START_STATE
   409  	*event = yaml_event_t{
   410  		typ:        yaml_DOCUMENT_END_EVENT,
   411  		start_mark: start_mark,
   412  		end_mark:   end_mark,
   413  		implicit:   implicit,
   414  	}
   415  	yaml_parser_set_event_comments(parser, event)
   416  	if len(event.head_comment) > 0 && len(event.foot_comment) == 0 {
   417  		event.foot_comment = event.head_comment
   418  		event.head_comment = nil
   419  	}
   420  	return true
   421  }
   422  
   423  func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) {
   424  	event.head_comment = parser.head_comment
   425  	event.line_comment = parser.line_comment
   426  	event.foot_comment = parser.foot_comment
   427  	parser.head_comment = nil
   428  	parser.line_comment = nil
   429  	parser.foot_comment = nil
   430  	parser.tail_comment = nil
   431  	parser.stem_comment = nil
   432  }
   433  
   434  // Parse the productions:
   435  // block_node_or_indentless_sequence    ::=
   436  //
   437  //	ALIAS
   438  //	*****
   439  //	| properties (block_content | indentless_block_sequence)?
   440  //	  **********  *
   441  //	| block_content | indentless_block_sequence
   442  //	  *
   443  //
   444  // block_node           ::= ALIAS
   445  //
   446  //	*****
   447  //	| properties block_content?
   448  //	  ********** *
   449  //	| block_content
   450  //	  *
   451  //
   452  // flow_node            ::= ALIAS
   453  //
   454  //	*****
   455  //	| properties flow_content?
   456  //	  ********** *
   457  //	| flow_content
   458  //	  *
   459  //
   460  // properties           ::= TAG ANCHOR? | ANCHOR TAG?
   461  //
   462  //	*************************
   463  //
   464  // block_content        ::= block_collection | flow_collection | SCALAR
   465  //
   466  //	******
   467  //
   468  // flow_content         ::= flow_collection | SCALAR
   469  //
   470  //	******
   471  func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
   472  	//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
   473  
   474  	token := peek_token(parser)
   475  	if token == nil {
   476  		return false
   477  	}
   478  
   479  	if token.typ == yaml_ALIAS_TOKEN {
   480  		parser.state = parser.states[len(parser.states)-1]
   481  		parser.states = parser.states[:len(parser.states)-1]
   482  		*event = yaml_event_t{
   483  			typ:        yaml_ALIAS_EVENT,
   484  			start_mark: token.start_mark,
   485  			end_mark:   token.end_mark,
   486  			anchor:     token.value,
   487  		}
   488  		yaml_parser_set_event_comments(parser, event)
   489  		skip_token(parser)
   490  		return true
   491  	}
   492  
   493  	start_mark := token.start_mark
   494  	end_mark := token.start_mark
   495  
   496  	var tag_token bool
   497  	var tag_handle, tag_suffix, anchor []byte
   498  	var tag_mark yaml_mark_t
   499  	if token.typ == yaml_ANCHOR_TOKEN {
   500  		anchor = token.value
   501  		start_mark = token.start_mark
   502  		end_mark = token.end_mark
   503  		skip_token(parser)
   504  		token = peek_token(parser)
   505  		if token == nil {
   506  			return false
   507  		}
   508  		if token.typ == yaml_TAG_TOKEN {
   509  			tag_token = true
   510  			tag_handle = token.value
   511  			tag_suffix = token.suffix
   512  			tag_mark = token.start_mark
   513  			end_mark = token.end_mark
   514  			skip_token(parser)
   515  			token = peek_token(parser)
   516  			if token == nil {
   517  				return false
   518  			}
   519  		}
   520  	} else if token.typ == yaml_TAG_TOKEN {
   521  		tag_token = true
   522  		tag_handle = token.value
   523  		tag_suffix = token.suffix
   524  		start_mark = token.start_mark
   525  		tag_mark = token.start_mark
   526  		end_mark = token.end_mark
   527  		skip_token(parser)
   528  		token = peek_token(parser)
   529  		if token == nil {
   530  			return false
   531  		}
   532  		if token.typ == yaml_ANCHOR_TOKEN {
   533  			anchor = token.value
   534  			end_mark = token.end_mark
   535  			skip_token(parser)
   536  			token = peek_token(parser)
   537  			if token == nil {
   538  				return false
   539  			}
   540  		}
   541  	}
   542  
   543  	var tag []byte
   544  	if tag_token {
   545  		if len(tag_handle) == 0 {
   546  			tag = tag_suffix
   547  			tag_suffix = nil
   548  		} else {
   549  			for i := range parser.tag_directives {
   550  				if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
   551  					tag = append([]byte(nil), parser.tag_directives[i].prefix...)
   552  					tag = append(tag, tag_suffix...)
   553  					break
   554  				}
   555  			}
   556  			if len(tag) == 0 {
   557  				yaml_parser_set_parser_error_context(parser,
   558  					"while parsing a node", start_mark,
   559  					"found undefined tag handle", tag_mark)
   560  				return false
   561  			}
   562  		}
   563  	}
   564  
   565  	implicit := len(tag) == 0
   566  	if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
   567  		end_mark = token.end_mark
   568  		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
   569  		*event = yaml_event_t{
   570  			typ:        yaml_SEQUENCE_START_EVENT,
   571  			start_mark: start_mark,
   572  			end_mark:   end_mark,
   573  			anchor:     anchor,
   574  			tag:        tag,
   575  			implicit:   implicit,
   576  			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
   577  		}
   578  		return true
   579  	}
   580  	if token.typ == yaml_SCALAR_TOKEN {
   581  		var plain_implicit, quoted_implicit bool
   582  		end_mark = token.end_mark
   583  		if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
   584  			plain_implicit = true
   585  		} else if len(tag) == 0 {
   586  			quoted_implicit = true
   587  		}
   588  		parser.state = parser.states[len(parser.states)-1]
   589  		parser.states = parser.states[:len(parser.states)-1]
   590  
   591  		*event = yaml_event_t{
   592  			typ:             yaml_SCALAR_EVENT,
   593  			start_mark:      start_mark,
   594  			end_mark:        end_mark,
   595  			anchor:          anchor,
   596  			tag:             tag,
   597  			value:           token.value,
   598  			implicit:        plain_implicit,
   599  			quoted_implicit: quoted_implicit,
   600  			style:           yaml_style_t(token.style),
   601  		}
   602  		yaml_parser_set_event_comments(parser, event)
   603  		skip_token(parser)
   604  		return true
   605  	}
   606  	if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
   607  		// [Go] Some of the events below can be merged as they differ only on style.
   608  		end_mark = token.end_mark
   609  		parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
   610  		*event = yaml_event_t{
   611  			typ:        yaml_SEQUENCE_START_EVENT,
   612  			start_mark: start_mark,
   613  			end_mark:   end_mark,
   614  			anchor:     anchor,
   615  			tag:        tag,
   616  			implicit:   implicit,
   617  			style:      yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
   618  		}
   619  		yaml_parser_set_event_comments(parser, event)
   620  		return true
   621  	}
   622  	if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
   623  		end_mark = token.end_mark
   624  		parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
   625  		*event = yaml_event_t{
   626  			typ:        yaml_MAPPING_START_EVENT,
   627  			start_mark: start_mark,
   628  			end_mark:   end_mark,
   629  			anchor:     anchor,
   630  			tag:        tag,
   631  			implicit:   implicit,
   632  			style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
   633  		}
   634  		yaml_parser_set_event_comments(parser, event)
   635  		return true
   636  	}
   637  	if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
   638  		end_mark = token.end_mark
   639  		parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
   640  		*event = yaml_event_t{
   641  			typ:        yaml_SEQUENCE_START_EVENT,
   642  			start_mark: start_mark,
   643  			end_mark:   end_mark,
   644  			anchor:     anchor,
   645  			tag:        tag,
   646  			implicit:   implicit,
   647  			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
   648  		}
   649  		if parser.stem_comment != nil {
   650  			event.head_comment = parser.stem_comment
   651  			parser.stem_comment = nil
   652  		}
   653  		return true
   654  	}
   655  	if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
   656  		end_mark = token.end_mark
   657  		parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
   658  		*event = yaml_event_t{
   659  			typ:        yaml_MAPPING_START_EVENT,
   660  			start_mark: start_mark,
   661  			end_mark:   end_mark,
   662  			anchor:     anchor,
   663  			tag:        tag,
   664  			implicit:   implicit,
   665  			style:      yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
   666  		}
   667  		if parser.stem_comment != nil {
   668  			event.head_comment = parser.stem_comment
   669  			parser.stem_comment = nil
   670  		}
   671  		return true
   672  	}
   673  	if len(anchor) > 0 || len(tag) > 0 {
   674  		parser.state = parser.states[len(parser.states)-1]
   675  		parser.states = parser.states[:len(parser.states)-1]
   676  
   677  		*event = yaml_event_t{
   678  			typ:             yaml_SCALAR_EVENT,
   679  			start_mark:      start_mark,
   680  			end_mark:        end_mark,
   681  			anchor:          anchor,
   682  			tag:             tag,
   683  			implicit:        implicit,
   684  			quoted_implicit: false,
   685  			style:           yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
   686  		}
   687  		return true
   688  	}
   689  
   690  	context := "while parsing a flow node"
   691  	if block {
   692  		context = "while parsing a block node"
   693  	}
   694  	yaml_parser_set_parser_error_context(parser, context, start_mark,
   695  		"did not find expected node content", token.start_mark)
   696  	return false
   697  }
   698  
   699  // Parse the productions:
   700  // block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
   701  //
   702  //	********************  *********** *             *********
   703  func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
   704  	if first {
   705  		token := peek_token(parser)
   706  		if token == nil {
   707  			return false
   708  		}
   709  		parser.marks = append(parser.marks, token.start_mark)
   710  		skip_token(parser)
   711  	}
   712  
   713  	token := peek_token(parser)
   714  	if token == nil {
   715  		return false
   716  	}
   717  
   718  	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
   719  		mark := token.end_mark
   720  		prior_head_len := len(parser.head_comment)
   721  		skip_token(parser)
   722  		yaml_parser_split_stem_comment(parser, prior_head_len)
   723  		token = peek_token(parser)
   724  		if token == nil {
   725  			return false
   726  		}
   727  		if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
   728  			parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
   729  			return yaml_parser_parse_node(parser, event, true, false)
   730  		} else {
   731  			parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
   732  			return yaml_parser_process_empty_scalar(parser, event, mark)
   733  		}
   734  	}
   735  	if token.typ == yaml_BLOCK_END_TOKEN {
   736  		parser.state = parser.states[len(parser.states)-1]
   737  		parser.states = parser.states[:len(parser.states)-1]
   738  		parser.marks = parser.marks[:len(parser.marks)-1]
   739  
   740  		*event = yaml_event_t{
   741  			typ:        yaml_SEQUENCE_END_EVENT,
   742  			start_mark: token.start_mark,
   743  			end_mark:   token.end_mark,
   744  		}
   745  
   746  		skip_token(parser)
   747  		return true
   748  	}
   749  
   750  	context_mark := parser.marks[len(parser.marks)-1]
   751  	parser.marks = parser.marks[:len(parser.marks)-1]
   752  	return yaml_parser_set_parser_error_context(parser,
   753  		"while parsing a block collection", context_mark,
   754  		"did not find expected '-' indicator", token.start_mark)
   755  }
   756  
   757  // Parse the productions:
   758  // indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
   759  //
   760  //	*********** *
   761  func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
   762  	token := peek_token(parser)
   763  	if token == nil {
   764  		return false
   765  	}
   766  
   767  	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
   768  		mark := token.end_mark
   769  		prior_head_len := len(parser.head_comment)
   770  		skip_token(parser)
   771  		yaml_parser_split_stem_comment(parser, prior_head_len)
   772  		token = peek_token(parser)
   773  		if token == nil {
   774  			return false
   775  		}
   776  		if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
   777  			token.typ != yaml_KEY_TOKEN &&
   778  			token.typ != yaml_VALUE_TOKEN &&
   779  			token.typ != yaml_BLOCK_END_TOKEN {
   780  			parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
   781  			return yaml_parser_parse_node(parser, event, true, false)
   782  		}
   783  		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
   784  		return yaml_parser_process_empty_scalar(parser, event, mark)
   785  	}
   786  	parser.state = parser.states[len(parser.states)-1]
   787  	parser.states = parser.states[:len(parser.states)-1]
   788  
   789  	*event = yaml_event_t{
   790  		typ:        yaml_SEQUENCE_END_EVENT,
   791  		start_mark: token.start_mark,
   792  		end_mark:   token.start_mark, // [Go] Shouldn't this be token.end_mark?
   793  	}
   794  	return true
   795  }
   796  
   797  // Split stem comment from head comment.
   798  //
   799  // When a sequence or map is found under a sequence entry, the former head comment
   800  // is assigned to the underlying sequence or map as a whole, not the individual
   801  // sequence or map entry as would be expected otherwise. To handle this case the
   802  // previous head comment is moved aside as the stem comment.
   803  func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
   804  	if stem_len == 0 {
   805  		return
   806  	}
   807  
   808  	token := peek_token(parser)
   809  	if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
   810  		return
   811  	}
   812  
   813  	parser.stem_comment = parser.head_comment[:stem_len]
   814  	if len(parser.head_comment) == stem_len {
   815  		parser.head_comment = nil
   816  	} else {
   817  		// Copy suffix to prevent very strange bugs if someone ever appends
   818  		// further bytes to the prefix in the stem_comment slice above.
   819  		parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...)
   820  	}
   821  }
   822  
   823  // Parse the productions:
   824  // block_mapping        ::= BLOCK-MAPPING_START
   825  //
   826  //	*******************
   827  //	((KEY block_node_or_indentless_sequence?)?
   828  //	  *** *
   829  //	(VALUE block_node_or_indentless_sequence?)?)*
   830  //
   831  //	BLOCK-END
   832  //	*********
   833  func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
   834  	if first {
   835  		token := peek_token(parser)
   836  		if token == nil {
   837  			return false
   838  		}
   839  		parser.marks = append(parser.marks, token.start_mark)
   840  		skip_token(parser)
   841  	}
   842  
   843  	token := peek_token(parser)
   844  	if token == nil {
   845  		return false
   846  	}
   847  
   848  	// [Go] A tail comment was left from the prior mapping value processed. Emit an event
   849  	//      as it needs to be processed with that value and not the following key.
   850  	if len(parser.tail_comment) > 0 {
   851  		*event = yaml_event_t{
   852  			typ:          yaml_TAIL_COMMENT_EVENT,
   853  			start_mark:   token.start_mark,
   854  			end_mark:     token.end_mark,
   855  			foot_comment: parser.tail_comment,
   856  		}
   857  		parser.tail_comment = nil
   858  		return true
   859  	}
   860  
   861  	if token.typ == yaml_KEY_TOKEN {
   862  		mark := token.end_mark
   863  		skip_token(parser)
   864  		token = peek_token(parser)
   865  		if token == nil {
   866  			return false
   867  		}
   868  		if token.typ != yaml_KEY_TOKEN &&
   869  			token.typ != yaml_VALUE_TOKEN &&
   870  			token.typ != yaml_BLOCK_END_TOKEN {
   871  			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
   872  			return yaml_parser_parse_node(parser, event, true, true)
   873  		} else {
   874  			parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
   875  			return yaml_parser_process_empty_scalar(parser, event, mark)
   876  		}
   877  	} else if token.typ == yaml_BLOCK_END_TOKEN {
   878  		parser.state = parser.states[len(parser.states)-1]
   879  		parser.states = parser.states[:len(parser.states)-1]
   880  		parser.marks = parser.marks[:len(parser.marks)-1]
   881  		*event = yaml_event_t{
   882  			typ:        yaml_MAPPING_END_EVENT,
   883  			start_mark: token.start_mark,
   884  			end_mark:   token.end_mark,
   885  		}
   886  		yaml_parser_set_event_comments(parser, event)
   887  		skip_token(parser)
   888  		return true
   889  	}
   890  
   891  	context_mark := parser.marks[len(parser.marks)-1]
   892  	parser.marks = parser.marks[:len(parser.marks)-1]
   893  	return yaml_parser_set_parser_error_context(parser,
   894  		"while parsing a block mapping", context_mark,
   895  		"did not find expected key", token.start_mark)
   896  }
   897  
   898  // Parse the productions:
   899  // block_mapping        ::= BLOCK-MAPPING_START
   900  //
   901  //	((KEY block_node_or_indentless_sequence?)?
   902  //
   903  //	(VALUE block_node_or_indentless_sequence?)?)*
   904  //	 ***** *
   905  //	BLOCK-END
   906  func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
   907  	token := peek_token(parser)
   908  	if token == nil {
   909  		return false
   910  	}
   911  	if token.typ == yaml_VALUE_TOKEN {
   912  		mark := token.end_mark
   913  		skip_token(parser)
   914  		token = peek_token(parser)
   915  		if token == nil {
   916  			return false
   917  		}
   918  		if token.typ != yaml_KEY_TOKEN &&
   919  			token.typ != yaml_VALUE_TOKEN &&
   920  			token.typ != yaml_BLOCK_END_TOKEN {
   921  			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
   922  			return yaml_parser_parse_node(parser, event, true, true)
   923  		}
   924  		parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
   925  		return yaml_parser_process_empty_scalar(parser, event, mark)
   926  	}
   927  	parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
   928  	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
   929  }
   930  
   931  // Parse the productions:
   932  // flow_sequence        ::= FLOW-SEQUENCE-START
   933  //
   934  //	*******************
   935  //	(flow_sequence_entry FLOW-ENTRY)*
   936  //	 *                   **********
   937  //	flow_sequence_entry?
   938  //	*
   939  //	FLOW-SEQUENCE-END
   940  //	*****************
   941  //
   942  // flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
   943  //
   944  //	*
   945  func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
   946  	if first {
   947  		token := peek_token(parser)
   948  		if token == nil {
   949  			return false
   950  		}
   951  		parser.marks = append(parser.marks, token.start_mark)
   952  		skip_token(parser)
   953  	}
   954  	token := peek_token(parser)
   955  	if token == nil {
   956  		return false
   957  	}
   958  	if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
   959  		if !first {
   960  			if token.typ == yaml_FLOW_ENTRY_TOKEN {
   961  				skip_token(parser)
   962  				token = peek_token(parser)
   963  				if token == nil {
   964  					return false
   965  				}
   966  			} else {
   967  				context_mark := parser.marks[len(parser.marks)-1]
   968  				parser.marks = parser.marks[:len(parser.marks)-1]
   969  				return yaml_parser_set_parser_error_context(parser,
   970  					"while parsing a flow sequence", context_mark,
   971  					"did not find expected ',' or ']'", token.start_mark)
   972  			}
   973  		}
   974  
   975  		if token.typ == yaml_KEY_TOKEN {
   976  			parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
   977  			*event = yaml_event_t{
   978  				typ:        yaml_MAPPING_START_EVENT,
   979  				start_mark: token.start_mark,
   980  				end_mark:   token.end_mark,
   981  				implicit:   true,
   982  				style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
   983  			}
   984  			skip_token(parser)
   985  			return true
   986  		} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
   987  			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
   988  			return yaml_parser_parse_node(parser, event, false, false)
   989  		}
   990  	}
   991  
   992  	parser.state = parser.states[len(parser.states)-1]
   993  	parser.states = parser.states[:len(parser.states)-1]
   994  	parser.marks = parser.marks[:len(parser.marks)-1]
   995  
   996  	*event = yaml_event_t{
   997  		typ:        yaml_SEQUENCE_END_EVENT,
   998  		start_mark: token.start_mark,
   999  		end_mark:   token.end_mark,
  1000  	}
  1001  	yaml_parser_set_event_comments(parser, event)
  1002  
  1003  	skip_token(parser)
  1004  	return true
  1005  }
  1006  
  1007  // Parse the productions:
  1008  // flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
  1009  //
  1010  //	*** *
  1011  func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
  1012  	token := peek_token(parser)
  1013  	if token == nil {
  1014  		return false
  1015  	}
  1016  	if token.typ != yaml_VALUE_TOKEN &&
  1017  		token.typ != yaml_FLOW_ENTRY_TOKEN &&
  1018  		token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
  1019  		parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
  1020  		return yaml_parser_parse_node(parser, event, false, false)
  1021  	}
  1022  	mark := token.end_mark
  1023  	skip_token(parser)
  1024  	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
  1025  	return yaml_parser_process_empty_scalar(parser, event, mark)
  1026  }
  1027  
  1028  // Parse the productions:
  1029  // flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
  1030  //
  1031  //	***** *
  1032  func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
  1033  	token := peek_token(parser)
  1034  	if token == nil {
  1035  		return false
  1036  	}
  1037  	if token.typ == yaml_VALUE_TOKEN {
  1038  		skip_token(parser)
  1039  		token := peek_token(parser)
  1040  		if token == nil {
  1041  			return false
  1042  		}
  1043  		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
  1044  			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
  1045  			return yaml_parser_parse_node(parser, event, false, false)
  1046  		}
  1047  	}
  1048  	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
  1049  	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
  1050  }
  1051  
  1052  // Parse the productions:
  1053  // flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
  1054  //
  1055  //	*
  1056  func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
  1057  	token := peek_token(parser)
  1058  	if token == nil {
  1059  		return false
  1060  	}
  1061  	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
  1062  	*event = yaml_event_t{
  1063  		typ:        yaml_MAPPING_END_EVENT,
  1064  		start_mark: token.start_mark,
  1065  		end_mark:   token.start_mark, // [Go] Shouldn't this be end_mark?
  1066  	}
  1067  	return true
  1068  }
  1069  
  1070  // Parse the productions:
  1071  // flow_mapping         ::= FLOW-MAPPING-START
  1072  //
  1073  //	******************
  1074  //	(flow_mapping_entry FLOW-ENTRY)*
  1075  //	 *                  **********
  1076  //	flow_mapping_entry?
  1077  //	******************
  1078  //	FLOW-MAPPING-END
  1079  //	****************
  1080  //
  1081  // flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
  1082  //   - *** *
  1083  func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
  1084  	if first {
  1085  		token := peek_token(parser)
  1086  		parser.marks = append(parser.marks, token.start_mark)
  1087  		skip_token(parser)
  1088  	}
  1089  
  1090  	token := peek_token(parser)
  1091  	if token == nil {
  1092  		return false
  1093  	}
  1094  
  1095  	if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
  1096  		if !first {
  1097  			if token.typ == yaml_FLOW_ENTRY_TOKEN {
  1098  				skip_token(parser)
  1099  				token = peek_token(parser)
  1100  				if token == nil {
  1101  					return false
  1102  				}
  1103  			} else {
  1104  				context_mark := parser.marks[len(parser.marks)-1]
  1105  				parser.marks = parser.marks[:len(parser.marks)-1]
  1106  				return yaml_parser_set_parser_error_context(parser,
  1107  					"while parsing a flow mapping", context_mark,
  1108  					"did not find expected ',' or '}'", token.start_mark)
  1109  			}
  1110  		}
  1111  
  1112  		if token.typ == yaml_KEY_TOKEN {
  1113  			skip_token(parser)
  1114  			token = peek_token(parser)
  1115  			if token == nil {
  1116  				return false
  1117  			}
  1118  			if token.typ != yaml_VALUE_TOKEN &&
  1119  				token.typ != yaml_FLOW_ENTRY_TOKEN &&
  1120  				token.typ != yaml_FLOW_MAPPING_END_TOKEN {
  1121  				parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
  1122  				return yaml_parser_parse_node(parser, event, false, false)
  1123  			} else {
  1124  				parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
  1125  				return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
  1126  			}
  1127  		} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
  1128  			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
  1129  			return yaml_parser_parse_node(parser, event, false, false)
  1130  		}
  1131  	}
  1132  
  1133  	parser.state = parser.states[len(parser.states)-1]
  1134  	parser.states = parser.states[:len(parser.states)-1]
  1135  	parser.marks = parser.marks[:len(parser.marks)-1]
  1136  	*event = yaml_event_t{
  1137  		typ:        yaml_MAPPING_END_EVENT,
  1138  		start_mark: token.start_mark,
  1139  		end_mark:   token.end_mark,
  1140  	}
  1141  	yaml_parser_set_event_comments(parser, event)
  1142  	skip_token(parser)
  1143  	return true
  1144  }
  1145  
  1146  // Parse the productions:
  1147  // flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
  1148  //   - ***** *
  1149  func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
  1150  	token := peek_token(parser)
  1151  	if token == nil {
  1152  		return false
  1153  	}
  1154  	if empty {
  1155  		parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
  1156  		return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
  1157  	}
  1158  	if token.typ == yaml_VALUE_TOKEN {
  1159  		skip_token(parser)
  1160  		token = peek_token(parser)
  1161  		if token == nil {
  1162  			return false
  1163  		}
  1164  		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
  1165  			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
  1166  			return yaml_parser_parse_node(parser, event, false, false)
  1167  		}
  1168  	}
  1169  	parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
  1170  	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
  1171  }
  1172  
  1173  // Generate an empty scalar event.
  1174  func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
  1175  	*event = yaml_event_t{
  1176  		typ:        yaml_SCALAR_EVENT,
  1177  		start_mark: mark,
  1178  		end_mark:   mark,
  1179  		value:      nil, // Empty
  1180  		implicit:   true,
  1181  		style:      yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
  1182  	}
  1183  	return true
  1184  }
  1185  
  1186  var default_tag_directives = []yaml_tag_directive_t{
  1187  	{[]byte("!"), []byte("!")},
  1188  	{[]byte("!!"), []byte("tag:yaml.org,2002:")},
  1189  }
  1190  
  1191  // Parse directives.
  1192  func yaml_parser_process_directives(parser *yaml_parser_t,
  1193  	version_directive_ref **yaml_version_directive_t,
  1194  	tag_directives_ref *[]yaml_tag_directive_t) bool {
  1195  
  1196  	var version_directive *yaml_version_directive_t
  1197  	var tag_directives []yaml_tag_directive_t
  1198  
  1199  	token := peek_token(parser)
  1200  	if token == nil {
  1201  		return false
  1202  	}
  1203  
  1204  	for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
  1205  		if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
  1206  			if version_directive != nil {
  1207  				yaml_parser_set_parser_error(parser,
  1208  					"found duplicate %YAML directive", token.start_mark)
  1209  				return false
  1210  			}
  1211  			if token.major != 1 || token.minor != 1 {
  1212  				yaml_parser_set_parser_error(parser,
  1213  					"found incompatible YAML document", token.start_mark)
  1214  				return false
  1215  			}
  1216  			version_directive = &yaml_version_directive_t{
  1217  				major: token.major,
  1218  				minor: token.minor,
  1219  			}
  1220  		} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
  1221  			value := yaml_tag_directive_t{
  1222  				handle: token.value,
  1223  				prefix: token.prefix,
  1224  			}
  1225  			if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
  1226  				return false
  1227  			}
  1228  			tag_directives = append(tag_directives, value)
  1229  		}
  1230  
  1231  		skip_token(parser)
  1232  		token = peek_token(parser)
  1233  		if token == nil {
  1234  			return false
  1235  		}
  1236  	}
  1237  
  1238  	for i := range default_tag_directives {
  1239  		if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
  1240  			return false
  1241  		}
  1242  	}
  1243  
  1244  	if version_directive_ref != nil {
  1245  		*version_directive_ref = version_directive
  1246  	}
  1247  	if tag_directives_ref != nil {
  1248  		*tag_directives_ref = tag_directives
  1249  	}
  1250  	return true
  1251  }
  1252  
  1253  // Append a tag directive to the directives stack.
  1254  func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
  1255  	for i := range parser.tag_directives {
  1256  		if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
  1257  			if allow_duplicates {
  1258  				return true
  1259  			}
  1260  			return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
  1261  		}
  1262  	}
  1263  
  1264  	// [Go] I suspect the copy is unnecessary. This was likely done
  1265  	// because there was no way to track ownership of the data.
  1266  	value_copy := yaml_tag_directive_t{
  1267  		handle: make([]byte, len(value.handle)),
  1268  		prefix: make([]byte, len(value.prefix)),
  1269  	}
  1270  	copy(value_copy.handle, value.handle)
  1271  	copy(value_copy.prefix, value.prefix)
  1272  	parser.tag_directives = append(parser.tag_directives, value_copy)
  1273  	return true
  1274  }