class_docstr: A placeholder that evaluates to a proto message.
class_docstr_tok: ["A","placeholder","that","evaluates","to","a","proto","message","."]
code: def _validate_and_transform_value(
      self,
      field_name: str,
      descriptor: descriptor_lib.FieldDescriptor,
      value: _InputValues,
  ) -> Optional[_PlainValues]:
      if value is None:
          if (
              descriptor.label
              == descriptor_lib.FieldDescriptor.LABEL_OPTIONAL
          ):
              return None
          raise ValueError(
              f"Expected value for non-optional field {field_name}, got None."
          )
  
      # Deal with sub-message fields first.
      if descriptor.type == descriptor_lib.FieldDescriptor.TYPE_MESSAGE:
          if isinstance(value, message.Message):
              value = MakeProtoPlaceholder(value)
          elif (
              not isinstance(value, placeholder_base.Placeholder)
              or not value._is_maybe_proto_valued()  # pylint: disable=protected-access
          ):
              raise ValueError(
                  f"Expected submessage proto or placeholder for field {field_name}, "
                  f"got {value!r}."
              )
  
          # Some best-effort validation for the proto type.
          submsg_type = value.expected_type
          if isinstance(submsg_type, type) and issubclass(
              submsg_type, message.Message
          ):
              # The proto placeholder knows exactly which proto type it will resolve
              # to. So we can verify that it's the right one.
              if descriptor.message_type.full_name not in (
                  submsg_type.DESCRIPTOR.full_name,
                  any_pb2.Any.DESCRIPTOR.full_name,
              ):
                  raise ValueError(
                      f"Expected message of type {descriptor.message_type.full_name} "
                      f"for field {field_name}, got {submsg_type.DESCRIPTOR.full_name}."
                  )
          return value
  
      # Now we know it's a scalar field.
      if isinstance(value, (message.Message, MakeProtoPlaceholder)):
          raise ValueError(
              f"Expected scalar value for field {field_name}, got {value!r}."
          )
      if descriptor.type not in _PROTO_TO_PY_TYPE:
          raise ValueError(
              f"Unsupported proto field type {descriptor.type} on {field_name}."
          )
      expected_type = _PROTO_TO_PY_TYPE[descriptor.type]
      if not isinstance(
          value, (expected_type, placeholder_base.Placeholder)
      ):
          raise ValueError(
              f"Expected {expected_type} for {field_name}, got {value!r}."
          )
      return value
  
file_path: tfx/tfx/dsl/placeholder/proto_placeholder.py
imports: from __future__ import annotations
  from typing import Dict, Generic, Iterator, List, Optional, Tuple, Type, TypeVar, Union
  from tfx.dsl.placeholder import placeholder_base
  from tfx.proto.orchestration import placeholder_pb2
  from tfx.utils import proto_utils
  from google.protobuf import any_pb2
  from google.protobuf import descriptor
  from google.protobuf import message
label_desc: Use image node_id 3 for calling the MakeProtoPlaceholder obj's underlying member method code with example usage: obj._validate_and_transform_value(field_name, descriptor, value) and returns: value, value, None