class_docstr: Utility class to resolve Placeholder expressions.
  
  Placeholder expression is defined as a proto structure
  placeholder_pb2.PlaceholderExpression. It can be resolved with
  ResolutionContext to a concrete value.
class_docstr_tok: ["Utility","class","to","resolve","Placeholder","expressions",".","Placeholder","expression","is","defined","as","a","proto","structure","placeholder_pb2.PlaceholderExpression",".","It","can","be","resolved","with","ResolutionContext","to","a","concrete","value","."]
docstr: Evaluates a placeholder using the contexts.
code: def _resolve_placeholder(
      self, placeholder: placeholder_pb2.Placeholder
  ) -> Any:
      """Evaluates a placeholder using the contexts."""
      try:
          context = self._resolution_values[placeholder.type]
      except KeyError as e:
          raise KeyError(
              f"Unsupported placeholder type: {placeholder.type}."
          ) from e
  
      # Handle the special case of EXEC_INVOCATION placeholders, which don't take
      # a key.
      if (
          placeholder.type
          == placeholder_pb2.Placeholder.Type.EXEC_INVOCATION
      ):
          return context
      # Handle the special case of ENVIRONMENT_VARIABLE and STRING_VALUE
      # placeholders, which needs to be resolved as a function call.
      elif (
          placeholder.type
          == placeholder_pb2.Placeholder.Type.ENVIRONMENT_VARIABLE
      ):
          return context(placeholder.key)
  
      # Handle remaining placeholder types.
      try:
          return context[placeholder.key]
      except KeyError as e:
          # Handle placeholders that access a missing optional channel or exec
          # property. In both cases the requested key will not be present in the
          # context. However this means we cannot distinguish between a correct
          # placeholder with an optional value vs. an incorrect placeholder.
          # TODO(b/172001324): Handle this at compile time.
          raise NullDereferenceError(placeholder) from e
  
imports: import base64
  import enum
  import functools
  import os
  import re
  from typing import Any, Callable, Dict, List, Set, Union, cast
  from absl import logging
  import attr
  from tfx.dsl.io import fileio
  from tfx.orchestration.portable import data_types
  from tfx.proto.orchestration import placeholder_pb2
  from tfx.types import artifact
  from tfx.types import artifact_utils
  from tfx.types import value_artifact
  from tfx.utils import json_utils
  from tfx.utils import proto_utils
  from google.protobuf import any_pb2
  from google.protobuf import descriptor
  from google.protobuf import json_format
  from google.protobuf import message
  from google.protobuf import text_format
label_desc: Use image node_id 3 for calling the _ExpressionResolver obj's underlying member method code with example usage: obj._resolve_placeholder(placeholder) and returns: context, context, context