class_docstr: Visitor that resolves specs for all filters in a resolution DAG and builds a lookup.
  
  This visitor traverses the group-by-item resolution DAG and if there is a where filter associated with the node,
  this resolves (ambiguous) group-by-items that are specified in the filter. All resolutions are
  collected and returned in a lookup object.
class_docstr_tok: ["Visitor","that","resolves","specs","for","all","filters","in","a","resolution","DAG","and","builds","a","lookup",".","This","visitor","traverses","the","group-by-item","resolution","DAG","and","if","there","is","a","where","filter","associated","with","the","node",",","this","resolves","(","ambiguous",")","group-by-items","that","are","specified","in","the","filter",".","All","resolutions","are","collected","and","returned","in","a","lookup","object","."]
docstr: Given the filters at a particular node, build the spec lookup for those filters.
  
  The start node should be the query node.
docstr_tok: ["Given","the","filters","at","a","particular","node",",","build","the","spec","lookup","for","those","filters",".","The","start","node","should","be","the","query","node","."]
code: def _resolve_specs_for_where_filters(
      self,
      current_node: ResolutionDagSinkNode,
      resolution_path: MetricFlowQueryResolutionPath,
      filter_location: WhereFilterLocation,
      where_filter_intersection: WhereFilterIntersection,
  ) -> FilterSpecResolutionLookUp:
      """Given the filters at a particular node, build the spec lookup for those filters.
  
      The start node should be the query node.
      """
      resolution_dag = GroupByItemResolutionDag(
          sink_node=current_node,
      )
      group_by_item_resolver = GroupByItemResolver(
          manifest_lookup=self._manifest_lookup,
          resolution_dag=resolution_dag,
      )
      non_parsable_resolutions: List[NonParsableFilterResolution] = []
      filter_call_parameter_sets_to_merge: List[
          FilterCallParameterSets
      ] = []
  
      for where_filter in where_filter_intersection.where_filters:
          try:
              filter_call_parameter_sets = (
                  where_filter.call_parameter_sets
              )
          except Exception as e:
              non_parsable_resolutions.append(
                  NonParsableFilterResolution(
                      filter_location_path=resolution_path,
                      where_filter_intersection=where_filter_intersection,
                      issue_set=MetricFlowQueryResolutionIssueSet.from_issue(
                          WhereFilterParsingIssue.from_parameters(
                              where_filter=where_filter,
                              parse_exception=e,
                              query_resolution_path=resolution_path,
                          )
                      ),
                  )
              )
              continue
          filter_call_parameter_sets_to_merge.append(
              filter_call_parameter_sets
          )
  
      deduped_filter_call_parameter_sets = _ResolveWhereFilterSpecVisitor._dedupe_filter_call_parameter_sets(
          filter_call_parameter_sets_to_merge
      )
  
      resolutions: List[FilterSpecResolution] = []
      for (
          group_by_item_in_where_filter
      ) in self._map_filter_parameter_sets_to_pattern(
          filter_call_parameter_sets=deduped_filter_call_parameter_sets,
      ):
          group_by_item_resolution = group_by_item_resolver.resolve_matching_item_for_filters(
              input_str=group_by_item_in_where_filter.object_builder_str,
              spec_pattern=group_by_item_in_where_filter.spec_pattern,
              resolution_node=current_node,
          )
          # The paths in the issue set are generated relative to the current node. For error messaging, it seems more
          # helpful for those paths to be relative to the query. To do, we have to add nodes from the resolution path.
          # e.g. if the current node is B, and the resolution path is [A, B], an issue might have the relative path
          # [B, C]. To join those paths to produce [A, B, C], the path prefix should be [A].
          path_prefix = MetricFlowQueryResolutionPath(
              resolution_path_nodes=resolution_path.resolution_path_nodes[
                  :-1
              ]
          )
          resolutions.append(
              FilterSpecResolution(
                  lookup_key=ResolvedSpecLookUpKey(
                      filter_location=filter_location,
                      call_parameter_set=group_by_item_in_where_filter.call_parameter_set,
                  ),
                  filter_location_path=resolution_path,
                  resolved_spec=group_by_item_resolution.spec,
                  where_filter_intersection=where_filter_intersection,
                  spec_pattern=group_by_item_in_where_filter.spec_pattern,
                  issue_set=group_by_item_resolution.issue_set.with_path_prefix(
                      path_prefix
                  ),
                  object_builder_str=group_by_item_in_where_filter.object_builder_str,
              )
          )
  
      if (
          any(
              resolution.issue_set.has_errors
              for resolution in resolutions
          )
          or len(non_parsable_resolutions) > 0
      ):
          return FilterSpecResolutionLookUp(
              spec_resolutions=tuple(
                  resolution
                  for resolution in resolutions
                  if resolution.issue_set.has_errors
              ),
              non_parsable_resolutions=tuple(non_parsable_resolutions),
          )
  
      return FilterSpecResolutionLookUp(
          spec_resolutions=tuple(resolutions),
          non_parsable_resolutions=tuple(non_parsable_resolutions),
      )
  
imports: from __future__ import annotations
  import itertools
  import logging
  from typing import List, Sequence
  from dbt_semantic_interfaces.call_parameter_sets import FilterCallParameterSets
  from dbt_semantic_interfaces.implementations.filters.where_filter import PydanticWhereFilterIntersection
  from dbt_semantic_interfaces.protocols import WhereFilter, WhereFilterIntersection
  from typing_extensions import override
  from metricflow.mf_logging.runtime import log_runtime
  from metricflow.model.semantic_manifest_lookup import SemanticManifestLookup
  from metricflow.naming.object_builder_str import ObjectBuilderNameConverter
  from metricflow.query.group_by_item.candidate_push_down.push_down_visitor import DagTraversalPathTracker
  from metricflow.query.group_by_item.filter_spec_resolution.filter_location import WhereFilterLocation
  from metricflow.query.group_by_item.filter_spec_resolution.filter_pattern_factory import WhereFilterPatternFactory
  from metricflow.query.group_by_item.filter_spec_resolution.filter_spec_lookup import FilterSpecResolution, FilterSpecResolutionLookUp, NonParsableFilterResolution, PatternAssociationForWhereFilterGroupByItem, ResolvedSpecLookUpKey
  from metricflow.query.group_by_item.group_by_item_resolver import GroupByItemResolver
  from metricflow.query.group_by_item.resolution_dag.dag import GroupByItemResolutionDag, ResolutionDagSinkNode
  from metricflow.query.group_by_item.resolution_dag.resolution_nodes.base_node import GroupByItemResolutionNodeVisitor
  from metricflow.query.group_by_item.resolution_dag.resolution_nodes.measure_source_node import MeasureGroupByItemSourceNode
  from metricflow.query.group_by_item.resolution_dag.resolution_nodes.metric_resolution_node import MetricGroupByItemResolutionNode
  from metricflow.query.group_by_item.resolution_dag.resolution_nodes.no_metrics_query_source_node import NoMetricsGroupByItemSourceNode
  from metricflow.query.group_by_item.resolution_dag.resolution_nodes.query_resolution_node import QueryGroupByItemResolutionNode
  from metricflow.query.group_by_item.resolution_path import MetricFlowQueryResolutionPath
  from metricflow.query.issues.filter_spec_resolver.invalid_where import WhereFilterParsingIssue
  from metricflow.query.issues.issues_base import MetricFlowQueryResolutionIssueSet
label_desc: Use image node_id 9 for calling the _ResolveWhereFilterSpecVisitor obj's underlying member method code with example usage: obj._resolve_specs_for_where_filters(current_node, resolution_path, filter_location, where_filter_intersection) and returns: FilterSpecResolutionLookUp, FilterSpecResolutionLookUp