code: def parse(self, buf: memoryview, params: Params) \
              -> Tuple[Command, memoryview]:
          
          try:
              tag, buf = Tag.parse(buf, params)
          except NotParseable as exc:
              return InvalidCommand(params, exc), buf[0:0]
          else:
              params = params.copy(tag=tag.value)
          cmd_parts: List[bytes] = []
          while True:
              try:
                  _, buf = Space.parse(buf, params)
                  atom, buf = Atom.parse(buf, params)
                  cmd_parts.append(atom.value.upper())
              except NotParseable as exc:
                  return InvalidCommand(params, exc), buf[0:0]
              command = b' '.join(cmd_parts)
              cmd_type = self.commands.get(command)
              if not cmd_type:
                  return InvalidCommand(params, None, command), buf[0:0]
              elif not cmd_type.compound:
                  break
          params = params.copy(command_name=command)
          try:
              return cmd_type.parse(buf, params)
          except NotParseable as exc:
              return InvalidCommand(params, exc, command, cmd_type), buf[0:0]
docs: Parse the given bytes into a command. The basic syntax is a tag
          string, a command name, possibly some arguments, and then an endline.
          If the command has a complete structure but cannot be parsed, an
          :class:`InvalidCommand` is returned.
  
          Args:
              buf: The bytes to parse.
              params: The parsing parameters.