def get_forest_lists(root_node,
                     rhs_emb_idx_map,
                     lhs_emb_idx_map,
                     max_num_nts=2):
  """Get integer lists for serialized forest.

  Args:
    root_node: Root parsing_utils.ForestNode for parse forest.
    rhs_emb_idx_map: Map from (rule, nt_idx) to rhs_emb_idx.
    lhs_emb_idx_map: Map from rule to lhs_emb_idx.
    max_num_nts: The maximum number of nonterminals.

  Returns:
    A tuple (node_type_list, node_idx_list,
             rhs_emb_idx_list, lhs_emb_idx_list, num_nodes).
  """
  sorted_nodes = _get_sorted_nodes(root_node)

  # Setup empty lists.
  node_type_list = []
  node_idx_list = []
  rhs_emb_idx_list = []
  lhs_emb_idx_list = []

  # Map of fingerprints to index.
  fingerprint_to_idx = {}
  current_index = 0

  # Iterate through chart.
  for node in sorted_nodes:
    if isinstance(node, parsing_utils.RuleApplicationNode):
      fingerprint = _get_node_fingerprint(node)
      fingerprint_to_idx[fingerprint] = current_index
      current_index += 1

      node_type_list.append(data_constants.RULE_APPLICATION)

      num_children = len(node.children) if node.children else 0
      node_idx = [-1] * max_num_nts
      lhs_emb_idx = [-1] * max_num_nts
      rhs_emb_idx = [-1] * max_num_nts
      for nt_idx in range(num_children):
        child_fingerprint = _get_node_fingerprint(node.children[nt_idx])
        if child_fingerprint not in fingerprint_to_idx:
          raise ValueError("Child of %s not in `fingerprint_to_idx`: %s" %
                           (node, node.children[nt_idx]))
        node_idx[nt_idx] = fingerprint_to_idx[child_fingerprint]
        rhs_emb_idx[nt_idx] = rhs_emb_idx_map[(node.rule, nt_idx)]
        lhs_emb_idx[nt_idx] = lhs_emb_idx_map[node.children[nt_idx].rule]
      node_idx_list.append(node_idx)
      rhs_emb_idx_list.append(rhs_emb_idx)
      lhs_emb_idx_list.append(lhs_emb_idx)
    elif isinstance(node, parsing_utils.AggregationNode):
      node_1_fingerprint = _get_node_fingerprint(node.children[0])
      node_1_idx = fingerprint_to_idx[node_1_fingerprint]

      for idx in range(1, len(node.children)):
        node_type_list.append(data_constants.AGGREGATION)
        node_2_idx = fingerprint_to_idx[_get_node_fingerprint(
            node.children[idx])]

        node_idx = [-1] * max_num_nts
        node_idx[0] = node_1_idx
        node_idx[1] = node_2_idx
        node_idx_list.append(node_idx)

        lhs_emb_idx = [-1] * max_num_nts
        lhs_emb_idx_list.append(lhs_emb_idx)
        rhs_emb_idx = [-1] * max_num_nts
        rhs_emb_idx_list.append(rhs_emb_idx)

        node_1_idx = current_index
        current_index += 1

      # Point to last node for index.
      fingerprint = _get_node_fingerprint(node)
      fingerprint_to_idx[fingerprint] = current_index - 1
    else:
      raise ValueError

  num_nodes = current_index
  return (node_type_list, node_idx_list, rhs_emb_idx_list, lhs_emb_idx_list,
          num_nodes)
Get integer lists for serialized forest.

  Args:
    root_node: Root parsing_utils.ForestNode for parse forest.
    rhs_emb_idx_map: Map from (rule, nt_idx) to rhs_emb_idx.
    lhs_emb_idx_map: Map from rule to lhs_emb_idx.
    max_num_nts: The maximum number of nonterminals.

  Returns:
    A tuple (node_type_list, node_idx_list,
             rhs_emb_idx_list, lhs_emb_idx_list, num_nodes).
  
language/compgen/csl/model/data/forest_serialization.py