def schema_as_feature_spec(
    schema_proto: schema_pb2.Schema) -> SchemaAsFeatureSpecResult:
  """Generates a feature spec from a Schema proto.

  For a Feature with a FixedShape we generate a FixedLenFeature with no default.
  For a Feature without a FixedShape we generate a VarLenFeature.  For a
  SparseFeature we generate a SparseFeature.
  If schema contains struct feature, then it must also contain
  TensorRepresentations and is assumed to describe SequenceExample data. The
  result in such case is union of context and sequence feature specs.

  Args:
    schema_proto: A Schema proto.

  Returns:
    A pair (feature spec, domains) where feature spec is a dict whose keys are
        feature names and values are instances of FixedLenFeature,
        VarLenFeature, SparseFeature or RaggedFeature, and `domains` is a dict
        whose keys are feature names and values are one of the `domain_info`
        oneof, e.g. IntDomain.

  Raises:
    ValueError: If the schema proto is invalid.
  """

  # Presence of a struct means that data's physical format is tf.SequenceExample
  # and the struct contains sequence features.
  if any(feature.type == schema_pb2.STRUCT for feature in schema_proto.feature):
    return _sequence_schema_as_feature_spec(schema_proto)

  tensor_representations = (
      tensor_representation_util.InferTensorRepresentationsFromMixedSchema(
          schema_proto))

  feature_spec = {}
  # Will hold the domain_info (IntDomain, FloatDomain etc.) of the feature.  For
  # sparse features, will hold the domain_info of the values feature.  Features
  # that do not have a domain set will not be present in `domains`.
  domains = {}
  string_domains = _get_string_domains(schema_proto)
  feature_by_name = {feature.name: feature for feature in schema_proto.feature}
  for name, tensor_representation in tensor_representations.items():
    value_feature = str(
        tensor_representation_util.GetSourceValueColumnFromTensorRepresentation(
            tensor_representation))
    spec = (
        tensor_representation_util.CreateTfExampleParserConfig(
            tensor_representation, feature_by_name[value_feature].type))
    if isinstance(spec, tf.io.FixedLenFeature):
      spec = _standardize_default_value(spec)
    feature_spec[name] = spec
    domain = _get_domain(feature_by_name[value_feature], string_domains)
    if domain is not None:
      domains[name] = domain
  return SchemaAsFeatureSpecResult(feature_spec, domains)
Generates a feature spec from a Schema proto.

  For a Feature with a FixedShape we generate a FixedLenFeature with no default.
  For a Feature without a FixedShape we generate a VarLenFeature.  For a
  SparseFeature we generate a SparseFeature.
  If schema contains struct feature, then it must also contain
  TensorRepresentations and is assumed to describe SequenceExample data. The
  result in such case is union of context and sequence feature specs.

  Args:
    schema_proto: A Schema proto.

  Returns:
    A pair (feature spec, domains) where feature spec is a dict whose keys are
        feature names and values are instances of FixedLenFeature,
        VarLenFeature, SparseFeature or RaggedFeature, and `domains` is a dict
        whose keys are feature names and values are one of the `domain_info`
        oneof, e.g. IntDomain.

  Raises:
    ValueError: If the schema proto is invalid.
  
tensorflow_transform/tf_metadata/schema_utils.py