code: def proto_fill_from_dict(message, data, clear=True):
      
      if not isinstance(message, _ProtoMessageType):
          raise TypeError("Expected `message` to be a instance of protobuf message")
      if not isinstance(data, dict):
          raise TypeError("Expected `data` to be of type `dict`")
  
      if clear: message.Clear()
      field_descs = message.DESCRIPTOR.fields_by_name
  
      for key, val in data.items():
          desc = field_descs[key]
  
          if desc.type == desc.TYPE_MESSAGE:
              if desc.label == desc.LABEL_REPEATED:
                  if not isinstance(val, _list_types):
                      raise TypeError("Expected %s to be of type list, got %s" % (repr(key), type(val)))
  
                  list_ref = getattr(message, key)
  
                  # Takes care of overwriting list fields when merging partial data (clear=False)
                  if not clear: del list_ref[:]  # clears the list
  
                  for item in val:
                      item_message = getattr(message, key).add()
                      proto_fill_from_dict(item_message, item)
              else:
                  if not isinstance(val, dict):
                      raise TypeError("Expected %s to be of type dict, got %s" % (repr(key), type(dict)))
  
                  proto_fill_from_dict(getattr(message, key), val)
          else:
              if isinstance(val, _list_types):
                  list_ref = getattr(message, key)
                  if not clear: del list_ref[:]  # clears the list
                  list_ref.extend(val)
              else:
                  setattr(message, key, val)
  
      return message
docs: Fills protobuf message parameters inplace from a :class:`dict`
  
      :param message: protobuf message instance
      :param data: parameters and values
      :type data: dict
      :param clear: whether clear exisiting values
      :type clear: bool
      :return: value of message paramater
      :raises: incorrect types or values will raise