class_docstr: Combines branches where the leaf node is a ComputeMetricsNode.
  
  This considers two branches, a left branch and a right branch. The left branch is supplied via the argument in the
  initializer while the right branch is supplied via .accept(). This then attempts to create a similar branch that is
  the superposition of the two branches. For this to be possible, the two branches must be of the same structure,
  and the respective nodes in each branch must be the same type and have compatible parameters.
  
  For example, the superposition / combination of
  
  left_branch:
      <ComputeMetricsNode metrics=["bookings"]
          <AggregateMeasuresNode>
              <FilterElementsNode include_specs=["bookings"]>
                  <ReadSqlSourceNode semantic_model="bookings_source"/>
              </>
          </>
      </>
  right_branch:
      <ComputeMetricsNode metrics=["booking_value"]
          <AggregateMeasuresNode>
              <FilterElementsNode include_specs=["booking_value"]>
                  <ReadSqlSourceNode semantic_model="bookings_source"/>
              </>
          </>
      </>
  
  is
  
  <ComputeMetricsNode metrics=["bookings", "booking_value"]
      <AggregateMeasuresNode>
          <FilterElementsNode include_specs=["bookings", "booking_value"]>
              <ReadSqlSourceNode semantic_model="bookings_source"/>
          </>
      </>
  </>
  
  However,
  
  left_branch:
      <ComputeMetricsNode metrics=["bookings"]
          <AggregateMeasuresNode>
              <FilterElementsNode include_specs=["bookings", "is_instant"]>
                  <ReadSqlSourceNode semantic_model="bookings_source"/>
              </>
          </>
      </>
  right_branch:
      <ComputeMetricsNode metrics=["booking_value"]
          <AggregateMeasuresNode>
              <FilterElementsNode include_specs=["booking_value"]>
                  <ReadSqlSourceNode semantic_model="bookings_source"/>
              </>
          </>
      </>
  
  can't be superpositioned / combined because the different set of linkable specs in the FilterElementsNode will cause
  the AggregatedMeasuresNode to produce values for the measure that is different from the original branches. The logic
  to determine whether this is possible for each node type is encapsulated into the handler for each node type.
  
  In general, the questions to consider for combination are:
  
  * For nodes with no parents, can you combine the corresponding left and right nodes to produce an output
  that is has the same linkable specs, but a superset of the measures / metrics?
  * For other nodes, does a set of inputs that have the same linkable specs as the inputs to the left and right nodes
  but a superset of measures / metrics produce an output that superset of measures / metrics (with the same values)
  as the left and right nodes?
  
  The visitor traverses the dataflow plan via DFS, recursively combining the parent nodes first and combining the
  current node. During each step, current_left_node and current_right node always points to nodes that should be
  correlated between the two branches. If the structure is different or if combination can't happen due to node
  differences between the branches, a ComputeMetricsBranchCombinerResult (indicating that combination not possible)
  is propagated up to the result at the root node.
code: def visit_join_to_time_spine_node(
      self, node: JoinToTimeSpineNode
  ) -> ComputeMetricsBranchCombinerResult:  # noqa: D
      self._log_visit_node_type(node)
      return self._default_handler(node)
  
imports: from __future__ import annotations
  import logging
  from dataclasses import dataclass
  from typing import List, Optional, Sequence
  from metricflow.dataflow.dataflow_plan import AddGeneratedUuidColumnNode, AggregateMeasuresNode, BaseOutput, CombineAggregatedOutputsNode, ComputeMetricsNode, ConstrainTimeRangeNode, DataflowPlanNode, DataflowPlanNodeVisitor, FilterElementsNode, JoinConversionEventsNode, JoinOverTimeRangeNode, JoinToBaseOutputNode, JoinToTimeSpineNode, MetricTimeDimensionTransformNode, MinMaxNode, OrderByLimitNode, ReadSqlSourceNode, SemiAdditiveJoinNode, WhereConstraintNode, WriteToResultDataframeNode, WriteToResultTableNode
  from metricflow.dataflow.optimizer.source_scan.matching_linkable_specs import MatchingLinkableSpecsTransform
  from metricflow.specs.specs import MetricSpec
label_desc: Use image node_id 22 for calling the ComputeMetricsBranchCombiner obj's underlying member method code with example usage: obj.visit_join_to_time_spine_node(node) and returns: self