class_docstr: Tracks semantic information for semantic model held in a set of SemanticModelContainers.
  
  This implements both the SemanticModelAccessors protocol, the interface type we use throughout the codebase.
  That interface prevents unwanted calls to methods for adding semantic models to the container.
class_docstr_tok: ["Tracks","semantic","information","for","semantic","model","held","in","a","set","of","SemanticModelContainers",".","This","implements","both","the","SemanticModelAccessors","protocol",",","the","interface","type","we","use","throughout","the","codebase",".","That","interface","prevents","unwanted","calls","to","methods","for","adding","semantic","models","to","the","container","."]
docstr: Return the primary entity for dimensions in the model.
code: def _resolved_primary_entity(
      semantic_model: SemanticModel,
  ) -> Optional[EntityReference]:
      """Return the primary entity for dimensions in the model."""
      primary_entity_reference = semantic_model.primary_entity_reference
  
      entities_with_type_primary = tuple(
          entity
          for entity in semantic_model.entities
          if entity.type == EntityType.PRIMARY
      )
  
      # This should be caught by the validation, but adding a sanity check.
      assert (
          len(entities_with_type_primary) <= 1
      ), f"Found >1 primary entity in {semantic_model}"
      if primary_entity_reference is not None:
          assert len(entities_with_type_primary) == 0, (
              f"The primary_entity field was set to {primary_entity_reference}, but there are non-zero entities with "
              f"type {EntityType.PRIMARY} in {semantic_model}"
          )
  
      if primary_entity_reference is not None:
          return primary_entity_reference
  
      if len(entities_with_type_primary) > 0:
          return entities_with_type_primary[0].reference
  
      return None
  
imports: from __future__ import annotations
  import logging
  from collections import defaultdict
  from copy import deepcopy
  from typing import Dict, List, Optional, Sequence, Set
  from dbt_semantic_interfaces.pretty_print import pformat_big_objects
  from dbt_semantic_interfaces.protocols.dimension import Dimension
  from dbt_semantic_interfaces.protocols.entity import Entity
  from dbt_semantic_interfaces.protocols.measure import Measure
  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, EntityReference, LinkableElementReference, MeasureReference, SemanticModelElementReference, SemanticModelReference, TimeDimensionReference
  from dbt_semantic_interfaces.type_enums import DimensionType, EntityType
  from dbt_semantic_interfaces.type_enums.aggregation_type import AggregationType
  from typing_extensions import override
  from metricflow.errors.errors import InvalidSemanticModelError
  from metricflow.model.semantics.element_group import ElementGrouper
  from metricflow.model.spec_converters import MeasureConverter
  from metricflow.protocols.semantics import SemanticModelAccessor
  from metricflow.specs.specs import DimensionSpec, EntitySpec, LinkableInstanceSpec, MeasureSpec, NonAdditiveDimensionSpec, TimeDimensionSpec
label_desc: Use image node_id 20 for calling the SemanticModelLookup obj's underlying member method code with example usage: obj._resolved_primary_entity(semantic_model) and returns: None, primary_entity_reference, entities_with_type_primary