public function readRows(array $options = [])
    {
        $rowKeys = $this->pluck('rowKeys', $options, false) ?: [];
        $ranges = $this->pluck('rowRanges', $options, false) ?: [];
        $filter = $this->pluck('filter', $options, false) ?: null;

        array_walk($ranges, function (&$range) {
            $range = $this->serializer->decodeMessage(
                new RowRange(),
                $range
            );
        });
        if (!is_array($rowKeys)) {
            throw new \InvalidArgumentException(
                sprintf(
                    'Expected rowKeys to be of type array, instead got \'%s\'.',
                    gettype($rowKeys)
                )
            );
        }
        if ($ranges || $rowKeys) {
            $options['rows'] = $this->serializer->decodeMessage(
                new RowSet,
                [
                    'rowKeys' => $rowKeys,
                    'rowRanges' => $ranges
                ]
            );
        }
        if ($filter !== null) {
            if (!$filter instanceof FilterInterface) {
                throw new \InvalidArgumentException(
                    sprintf(
                        'Expected filter to be of type \'%s\', instead got \'%s\'.',
                        FilterInterface::class,
                        gettype($filter)
                    )
                );
            }
            $options['filter'] = $filter->toProto();
        }
        return new ChunkFormatter(
            [$this->gapicClient, 'readRows'],
            $this->tableName,
            $options + $this->options
        );
    }