def _AddMessageMethods(message_descriptor, cls):
  """Adds the methods to a protocol message class."""
  if message_descriptor.is_extendable:

    def ClearExtension(self, extension):
      self.Extensions.ClearExtension(extension)

    def HasExtension(self, extension):
      return self.Extensions.HasExtension(extension)

  def HasField(self, field_name):
    return self._cmsg.HasField(field_name)

  def ClearField(self, field_name):
    child_cmessage = None
    if field_name in self._composite_fields:
      child_field = self._composite_fields[field_name]
      del self._composite_fields[field_name]

      child_cdescriptor = self.__descriptors[field_name]
      # TODO(anuraag): Support clearing repeated message fields as well.
      if (child_cdescriptor.label != _LABEL_REPEATED and
          child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
        child_field._owner = None
        child_cmessage = child_field._cmsg

    if child_cmessage is not None:
      self._cmsg.ClearField(field_name, child_cmessage)
    else:
      self._cmsg.ClearField(field_name)

  def Clear(self):
    cmessages_to_release = []
    for field_name, child_field in list(self._composite_fields.items()):
      child_cdescriptor = self.__descriptors[field_name]
      # TODO(anuraag): Support clearing repeated message fields as well.
      if (child_cdescriptor.label != _LABEL_REPEATED and
          child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
        child_field._owner = None
        cmessages_to_release.append((child_cdescriptor, child_field._cmsg))
    self._composite_fields.clear()
    self._cmsg.Clear(cmessages_to_release)

  def IsInitialized(self, errors=None):
    if self._cmsg.IsInitialized():
      return True
    if errors is not None:
      errors.extend(self.FindInitializationErrors());
    return False

  def SerializeToString(self):
    if not self.IsInitialized():
      raise message.EncodeError(
          'Message %s is missing required fields: %s' % (
          self._cmsg.full_name, ','.join(self.FindInitializationErrors())))
    return self._cmsg.SerializeToString()

  def SerializePartialToString(self):
    return self._cmsg.SerializePartialToString()

  def ParseFromString(self, serialized):
    self.Clear()
    self.MergeFromString(serialized)

  def MergeFromString(self, serialized):
    byte_size = self._cmsg.MergeFromString(serialized)
    if byte_size < 0:
      raise message.DecodeError('Unable to merge from string.')
    return byte_size

  def MergeFrom(self, msg):
    if not isinstance(msg, cls):
      raise TypeError(
          "Parameter to MergeFrom() must be instance of same class: "
          "expected %s got %s." % (cls.__name__, type(msg).__name__))
    self._cmsg.MergeFrom(msg._cmsg)

  def CopyFrom(self, msg):
    self._cmsg.CopyFrom(msg._cmsg)

  def ByteSize(self):
    return self._cmsg.ByteSize()

  def SetInParent(self):
    return self._cmsg.SetInParent()

  def ListFields(self):
    all_fields = []
    field_list = self._cmsg.ListFields()
    fields_by_name = cls.DESCRIPTOR.fields_by_name
    for is_extension, field_name in field_list:
      if is_extension:
        extension = cls._extensions_by_name[field_name]
        all_fields.append((extension, self.Extensions[extension]))
      else:
        field_descriptor = fields_by_name[field_name]
        all_fields.append(
            (field_descriptor, getattr(self, field_name)))
    all_fields.sort(key=lambda item: item[0].number)
    return all_fields

  def FindInitializationErrors(self):
    return self._cmsg.FindInitializationErrors()

  def __str__(self):
    return str(self._cmsg)

  def __eq__(self, other):
    if self is other:
      return True
    if not isinstance(other, self.__class__):
      return False
    return self.ListFields() == other.ListFields()

  def __ne__(self, other):
    return not self == other

  def __hash__(self):
    raise TypeError('unhashable object')

  def __unicode__(self):
    # Lazy import to prevent circular import when text_format imports this file.
    from google.protobuf import text_format
    return text_format.MessageToString(self, as_utf8=True).decode('utf-8')

  # Attach the local methods to the message class.
  for key, value in list(locals().copy().items()):
    if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'):
      setattr(cls, key, value)

  # Static methods:

  def RegisterExtension(extension_handle):
    extension_handle.containing_type = cls.DESCRIPTOR
    cls._extensions_by_name[extension_handle.full_name] = extension_handle

    if _IsMessageSetExtension(extension_handle):
      # MessageSet extension.  Also register under type name.
      cls._extensions_by_name[
          extension_handle.message_type.full_name] = extension_handle
  cls.RegisterExtension = staticmethod(RegisterExtension)

  def FromString(string):
    msg = cls()
    msg.MergeFromString(string)
    return msg
  cls.FromString = staticmethod(FromString)
dataset/ETHPy150Open katharosada/botchallenge/client/google/protobuf/internal/cpp_message.py/_AddMessageMethods/original