@brief Deserializes the YAML nodes recursively. @param lexer The lexical analyzer to be used. @param first_type The first lexical token. @param last_type Storage for last lexical token type.
| 7451 | /// @param first_type The first lexical token. |
| 7452 | /// @param last_type Storage for last lexical token type. |
| 7453 | void deserialize_node( |
| 7454 | lexer_type& lexer, const lexical_token& first_token, uint32_t first_line, uint32_t first_indent, |
| 7455 | lexical_token_t& last_type) { |
| 7456 | lexical_token token = first_token; |
| 7457 | uint32_t line = first_line; |
| 7458 | uint32_t indent = first_indent; |
| 7459 | |
| 7460 | do { |
| 7461 | switch (token.type) { |
| 7462 | case lexical_token_t::EXPLICIT_KEY_PREFIX: { |
| 7463 | const bool needs_to_move_back = indent == 0 || indent < m_context_stack.back().indent; |
| 7464 | if (needs_to_move_back) { |
| 7465 | pop_to_parent_node(line, indent, [indent](const parse_context& c) { |
| 7466 | return c.state == context_state_t::BLOCK_MAPPING && indent == c.indent; |
| 7467 | }); |
| 7468 | } |
| 7469 | |
| 7470 | switch (m_context_stack.back().state) { |
| 7471 | case context_state_t::MAPPING_VALUE: |
| 7472 | case context_state_t::BLOCK_MAPPING_EXPLICIT_KEY: |
| 7473 | case context_state_t::BLOCK_MAPPING_EXPLICIT_VALUE: |
| 7474 | case context_state_t::BLOCK_SEQUENCE_ENTRY: |
| 7475 | // This path is needed in case the input contains nested explicit keys. |
| 7476 | // ```yaml |
| 7477 | // foo: |
| 7478 | // ? ? foo |
| 7479 | // : bar |
| 7480 | // : ? baz |
| 7481 | // : - ? qux |
| 7482 | // : 123 |
| 7483 | // ``` |
| 7484 | *mp_current_node = basic_node_type::mapping(); |
| 7485 | apply_directive_set(*mp_current_node); |
| 7486 | m_context_stack.emplace_back(line, indent, context_state_t::BLOCK_MAPPING, mp_current_node); |
| 7487 | break; |
| 7488 | default: |
| 7489 | break; |
| 7490 | } |
| 7491 | |
| 7492 | token = lexer.get_next_token(); |
| 7493 | if (token.type == lexical_token_t::SEQUENCE_BLOCK_PREFIX) { |
| 7494 | // heap-allocated node will be freed in handling the corresponding KEY_SEPARATOR event |
| 7495 | auto* p_node = new basic_node_type(node_type::SEQUENCE); |
| 7496 | m_context_stack.emplace_back(line, indent, context_state_t::BLOCK_MAPPING_EXPLICIT_KEY, p_node); |
| 7497 | |
| 7498 | apply_directive_set(*p_node); |
| 7499 | parse_context context( |
| 7500 | lexer.get_lines_processed(), |
| 7501 | lexer.get_last_token_begin_pos(), |
| 7502 | context_state_t::BLOCK_SEQUENCE, |
| 7503 | p_node); |
| 7504 | m_context_stack.emplace_back(context); |
| 7505 | |
| 7506 | p_node->as_seq().emplace_back(basic_node_type()); |
| 7507 | mp_current_node = &(p_node->as_seq().back()); |
| 7508 | apply_directive_set(*mp_current_node); |
| 7509 | context.state = context_state_t::BLOCK_SEQUENCE_ENTRY; |
| 7510 | context.p_node = mp_current_node; |
no test coverage detected