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