code: def make_proto(
      base_message: _T,
      **kwargs: _InputFieldValues,
  ) -> MakeProtoPlaceholder[_T]:
      """Returns a placeholder that resolves to a proto with the given fields.
  
      Basic usage:
      ```python
      flags=[
          (
              'my_proto_flag',
              ph.make_proto(
                  MyProtoType(),
                  field1='a plain value',
                  field2=ph.execution_invocation().pipeline_run_id,
                  field3=ph.make_proto(
                      MySubProtoType(inner_field1='fixed value'),
                      inner_field2=ph.input('foo').uri + '/somefile.txt',
                      ...
                  ),
                  ...
              ).serialize(ph.ProtoSerializationFormat.TEXT_FORMAT)
          ),
      ]
      ```
  
      It's important to note that proto creation placeholders are only allowed as
      sub-expressions. That is, you cannot pass their output directly to a flag.
      Instead, you always need to serialize the proto in some way, so that it
      becomes a string.
  
      Limitations:
      * Map fields only support string/placeholder keys, not integral types.
      * MessageSet is not yet supported.
      * Proto extension fields are not supported.
      * `bytes` fields can only populated through Python `str` values, so their
        contents must be valid strings and can't contain arbitrary bytes.
      * All constructed protos are final. You can use them as a submessage inside
        another ph.make_proto() expression, but you cannot update field values
        after receiving the instance from the factory. (And you shouldn't need to.)
  
      Args:
        base_message: An instance of the proto type that the constructed placeholder
          resolves to. This can already have some fields populated, which will be
          passed through to the output, though of course those can't contain any
          placeholders.
        **kwargs: Additional fields to populate in the output proto message, whereby
          the values may contain placeholders. These fields are merged on top of the
          fields present already in the `base_message`. Just like when constructing
          regular protos, repeated fields must be passed as lists and map fields
          must be passed either as dicts (if all keys are plain strings) or as lists
          of (key,value) tuples if some of the keys are placeholders. In all cases,
          the values can be placeholders or plain values (strings, protos) matching
          the respective field type. In particular, other MakeProtoPlaceholder
          instances can be passed to populate sub-message fields.
  
      Returns:
        A placeholder that, at runtime, will evaluate to a proto message of the
        same type as the `base_message`. It will have the `base_message`'s fields
        populated, but with the `kwargs` fields merged on top.
      """
      return MakeProtoPlaceholder(base_message, **kwargs)
  
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 1 for calling a global function with example usage: make_proto(base_message) and returns: MakeProtoPlaceholder