class_docstr: Model card field base class.
  
  This is an abstract class. All the model card fields should inherit this class
  and override the _proto_type property to the corresponding proto type. This
  abstract class provides methods `from_proto`, `merge_from_proto` and
  `to_proto` to convert the class from and to proto. The child class does not
  need to override this unless it needs some special process.
docstr: Convert proto to this class object.
docstr_tok: ["Convert","proto","to","this","class","object","."]
code: def _from_proto(self: T, proto: message.Message) -> T:
      """Convert proto to this class object."""
      if not isinstance(proto, self._proto_type):
          raise TypeError(
              "%s is expected. However %s is provided."
              % (self._proto_type, type(proto))
          )
  
      for field_descriptor in proto.DESCRIPTOR.fields:
          field_name = field_descriptor.name
          if not hasattr(self, field_name):
              raise ValueError(
                  '%s has no such field named "%s".'
                  % (self, field_name)
              )
  
          # Process Message type.
          if (
              field_descriptor.type
              == descriptor.FieldDescriptor.TYPE_MESSAGE
          ):
              if (
                  field_descriptor.label
                  == descriptor.FieldDescriptor.LABEL_REPEATED
              ):
                  # Clean the list first.
                  setattr(self, field_name, [])
                  for p in getattr(proto, field_name):
                      # To get the type hint of a list is not easy.
                      field = self.__annotations__[field_name].__args__[
                          0
                      ]()  # pytype: disable=attribute-error
                      field._from_proto(
                          p
                      )  # pylint: disable=protected-access
                      getattr(self, field_name).append(field)
  
              elif proto.HasField(field_name):
                  getattr(self, field_name)._from_proto(
                      getattr(proto, field_name)
                  )  # pylint: disable=protected-access
  
          # Process Non-Message type
          else:
              if (
                  field_descriptor.label
                  == descriptor.FieldDescriptor.LABEL_REPEATED
              ):
                  setattr(
                      self, field_name, getattr(proto, field_name)[:]
                  )
              elif proto.HasField(field_name):
                  setattr(self, field_name, getattr(proto, field_name))
  
      return self
  
imports: import abc
  import dataclasses
  import json
  from textwrap import dedent
  from typing import Any, Dict, Type, TypeVar
  from warnings import warn
  from google.protobuf import descriptor, message
  from model_card_toolkit.utils import json_utils
label_desc: Use image node_id 4 for calling the BaseModelCardField obj's underlying member method code with example usage: obj._from_proto(proto) and returns: self