class_docstr: Figures out what linkable specs are valid for a given metric.
  
  e.g. Can you query the metric "bookings" by "listing__country_latest"?
docstr: Create elements for metric_time for a given measure in a semantic model.
  
  metric_time is a virtual dimension that is the same as aggregation time dimension for a measure, but with a
  different name. Because it doesn't actually exist in the semantic model, these elements need to be created based
  on what aggregation time dimension was used to define the measure.
docstr_tok: ["Create","elements","for","metric_time","for","a","given","measure","in","a","semantic","model",".","metric_time","is","a","virtual","dimension","that","is","the","same","as","aggregation","time","dimension","for","a","measure",",","but","with","a","different","name",".","Because","it","does","n't","actually","exist","in","the","semantic","model",",","these","elements","need","to","be","created","based","on","what","aggregation","time","dimension","was","used","to","define","the","measure","."]
code: def _get_metric_time_elements(
      self, measure_reference: MeasureReference
  ) -> LinkableElementSet:
      """Create elements for metric_time for a given measure in a semantic model.
  
      metric_time is a virtual dimension that is the same as aggregation time dimension for a measure, but with a
      different name. Because it doesn't actually exist in the semantic model, these elements need to be created based
      on what aggregation time dimension was used to define the measure.
      """
      measure_semantic_model = self._get_semantic_model_for_measure(
          measure_reference
      )
  
      measure_agg_time_dimension_reference = (
          measure_semantic_model.checked_agg_time_dimension_for_measure(
              measure_reference=measure_reference
          )
      )
  
      agg_time_dimension_granularity = ValidLinkableSpecResolver._get_time_granularity_for_dimension(
          semantic_model=measure_semantic_model,
          time_dimension_reference=measure_agg_time_dimension_reference,
      )
  
      # It's possible to aggregate measures to coarser time granularities (except with cumulative metrics).
      possible_metric_time_granularities = tuple(
          time_granularity
          for time_granularity in TimeGranularity
          if agg_time_dimension_granularity.is_smaller_than_or_equal(
              time_granularity
          )
      )
  
      # For each of the possible time granularities, create a LinkableDimension for each one.
  
      path_key_to_linkable_dimensions: Dict[
          ElementPathKey, List[LinkableDimension]
      ] = defaultdict(list)
      for time_granularity in possible_metric_time_granularities:
          possible_date_parts: Sequence[Optional[DatePart]] = (
              # No date part, just the metric time at a different grain.
              (None,)
              # date part of a metric time at a different grain.
              + tuple(
                  date_part
                  for date_part in DatePart
                  if time_granularity.to_int() <= date_part.to_int()
              )
          )
  
          for date_part in possible_date_parts:
              path_key = ElementPathKey(
                  element_name=DataSet.metric_time_dimension_name(),
                  entity_links=(),
                  time_granularity=time_granularity,
                  date_part=date_part,
              )
              path_key_to_linkable_dimensions[path_key].append(
                  LinkableDimension(
                      semantic_model_origin=measure_semantic_model.reference,
                      element_name=DataSet.metric_time_dimension_name(),
                      entity_links=(),
                      join_path=(),
                      # Anything that's not at the base time granularity of the measure's aggregation time dimension
                      # should be considered derived.
                      properties=frozenset(
                          {LinkableElementProperties.METRIC_TIME}
                      )
                      if time_granularity
                      is agg_time_dimension_granularity
                      and date_part is None
                      else frozenset(
                          {
                              LinkableElementProperties.METRIC_TIME,
                              LinkableElementProperties.DERIVED_TIME_GRANULARITY,
                          }
                      ),
                      time_granularity=time_granularity,
                      date_part=date_part,
                  )
              )
  
      return LinkableElementSet(
          path_key_to_linkable_dimensions={
              path_key: tuple(linkable_dimensions)
              for path_key, linkable_dimensions in path_key_to_linkable_dimensions.items()
          },
          path_key_to_linkable_entities={},
      )
  
imports: from __future__ import annotations
  import logging
  import time
  from collections import defaultdict
  from dataclasses import dataclass
  from typing import Dict, FrozenSet, List, Optional, Sequence, Set, Tuple
  from dbt_semantic_interfaces.enum_extension import assert_values_exhausted
  from dbt_semantic_interfaces.pretty_print import pformat_big_objects
  from dbt_semantic_interfaces.protocols.dimension import Dimension, DimensionType
  from dbt_semantic_interfaces.protocols.semantic_manifest import SemanticManifest
  from dbt_semantic_interfaces.protocols.semantic_model import SemanticModel
  from dbt_semantic_interfaces.references import DimensionReference, MeasureReference, MetricReference, SemanticModelReference, TimeDimensionReference
  from dbt_semantic_interfaces.type_enums import MetricType
  from dbt_semantic_interfaces.type_enums.date_part import DatePart
  from dbt_semantic_interfaces.type_enums.time_granularity import TimeGranularity
  from metricflow.dataset.dataset import DataSet
  from metricflow.errors.errors import UnknownMetricLinkingError
  from metricflow.model.semantics.linkable_element_properties import LinkableElementProperties
  from metricflow.model.semantics.semantic_model_join_evaluator import SemanticModelJoinEvaluator
  from metricflow.model.semantics.semantic_model_lookup import SemanticModelLookup
  from metricflow.protocols.semantics import SemanticModelAccessor
  from metricflow.specs.specs import DEFAULT_TIME_GRANULARITY, DimensionSpec, EntityReference, EntitySpec, LinkableSpecSet, TimeDimensionSpec
label_desc: Use image node_id 6 for calling the ValidLinkableSpecResolver obj's underlying member method code with example usage: obj._get_metric_time_elements(measure_reference) and returns: LinkableElementSet