func (m *multi) Context() context.Context {
	return m.ctx
}
Context is not supported for Multi.
package region
import (
	"context"
	"errors"
	"fmt"
	"sync"
	"github.com/tsuna/gohbase/hrpc"
	"github.com/tsuna/gohbase/pb"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/trace"
	"google.golang.org/protobuf/proto"
)
var multiPool = sync.Pool{
	New: func() interface{} {
		return &multi{}
	},
}
func freeMulti(m *multi) {
	m.calls = m.calls[:0]
	m.regions = m.regions[:0]
	m.size = 0
	multiPool.Put(m)
}
type multi struct {
	ctx   context.Context
	size  int
	calls []hrpc.Call
	regions []hrpc.RegionInfo
}
func newMulti(ctx context.Context, queueSize int) *multi {
	m := multiPool.Get().(*multi)
	m.ctx = ctx
	m.size = queueSize
	return m
}
func (m *multi) Name() string {
	return "Multi"
}
func (m *multi) Description() string {
	return m.Name()
}
func (m *multi) ToProto() proto.Message {
	msg, _, _ := m.toProto(false)
	return msg
}
type actions struct {
	pbs        []*pb.Action
	cellblocks [][]byte
}
func (m *multi) toProto(isCellblocks bool) (proto.Message, [][]byte, uint32) {
	actionsPerReg := map[hrpc.RegionInfo]actions{}
	var size uint32
	for i, c := range m.calls {
		select {
		case <-c.Context().Done():
			m.calls[i] = nil
			continue
		default:
		}
		var msg proto.Message
		var cellblocks [][]byte
		if s, ok := c.(canSerializeCellBlocks); isCellblocks && ok && s.CellBlocksEnabled() {
			var sz uint32
			msg, cellblocks, sz = s.SerializeCellBlocks()
			size += sz
		} else {
			msg = c.ToProto()
		}
		a := &pb.Action{
			Index: proto.Uint32(uint32(i) + 1),  
		}
		switch r := msg.(type) {
		case *pb.GetRequest:
			a.Get = r.Get
		case *pb.MutateRequest:
			a.Mutation = r.Mutation
		default:
			panic(fmt.Sprintf("unsupported call type for Multi: %T", c))
		}
		as, ok := actionsPerReg[c.Region()]
		if !ok {
			as = actions{}
		}
		as.pbs = append(as.pbs, a)
		as.cellblocks = append(as.cellblocks, cellblocks...)
		actionsPerReg[c.Region()] = as
	}
	ra := make([]*pb.RegionAction, len(actionsPerReg))
	m.regions = make([]hrpc.RegionInfo, len(actionsPerReg))
	var cellblocks [][]byte
	i := 0
	for r, as := range actionsPerReg {
		ra[i] = &pb.RegionAction{
			Region: &pb.RegionSpecifier{
				Type:  pb.RegionSpecifier_REGION_NAME.Enum(),
				Value: r.Name(),
			},
			Action: as.pbs,
		}
		cellblocks = append(cellblocks, as.cellblocks...)
		m.regions[i] = r
		i++
	}
	return &pb.MultiRequest{RegionAction: ra}, cellblocks, size
}
func (m *multi) SerializeCellBlocks() (proto.Message, [][]byte, uint32) {
	return m.toProto(true)
}
func (m *multi) CellBlocksEnabled() bool {
	return true
}
func (m *multi) NewResponse() proto.Message {
	return &pb.MultiResponse{}
}
func (m *multi) DeserializeCellBlocks(msg proto.Message, b []byte) (uint32, error) {
	mr := msg.(*pb.MultiResponse)
	var nread uint32
	for _, rar := range mr.GetRegionActionResult() {
		if e := rar.GetException(); e != nil {
			if l := len(rar.GetResultOrException()); l != 0 {
				return 0, fmt.Errorf(
					"got exception for region, but still have %d result(s) returned from it", l)
			}
			continue
		}
		for _, roe := range rar.GetResultOrException() {
			e := roe.GetException()
			r := roe.GetResult()
			i := roe.GetIndex()
			if i == 0 {
				return 0, errors.New("no index for result in multi response")
			} else if r == nil && e == nil {
				return 0, errors.New("no result or exception for action in multi response")
			} else if r != nil && e != nil {
				return 0, errors.New("got result and exception for action in multi response")
			} else if e != nil {
				continue
			}
			c := m.get(i)                      
			d := c.(canDeserializeCellBlocks)  
			response := c.NewResponse()
			switch rsp := response.(type) {
			case *pb.GetResponse:
				rsp.Result = r
			case *pb.MutateResponse:
				rsp.Result = r
			default:
				panic(fmt.Sprintf("unsupported response type for Multi: %T", response))
			}
			n, err := d.DeserializeCellBlocks(response, b[nread:])
			if err != nil {
				return 0, fmt.Errorf(
					"error deserializing cellblocks for %q call as part of MultiResponse: %v",
					c.Name(), err)
			}
			nread += n
		}
	}
	return nread, nil
}
func (m *multi) returnResults(msg proto.Message, err error) {
	defer freeMulti(m)
	if err != nil {
		for _, c := range m.calls {
			if c == nil {
				continue
			}
			c.ResultChan() <- hrpc.RPCResult{Error: err}
		}
		return
	}
	mr := msg.(*pb.MultiResponse)
	for i, rar := range mr.GetRegionActionResult() {
		if e := rar.GetException(); e != nil {
			reg := m.regions[i]
			err := exceptionToError(*e.Name, string(e.Value))
			for _, c := range m.calls {
				if c == nil {
					continue
				}
				if c.Region() == reg {
					c.ResultChan() <- hrpc.RPCResult{Error: err}
				}
			}
			continue
		}
		for _, roe := range rar.GetResultOrException() {
			i := roe.GetIndex()
			e := roe.GetException()
			r := roe.GetResult()
			c := m.get(i)
			if e != nil {
				c.ResultChan() <- hrpc.RPCResult{
					Error: exceptionToError(*e.Name, string(e.Value)),
				}
				continue
			}
			response := c.NewResponse()
			switch rsp := response.(type) {
			case *pb.GetResponse:
				rsp.Result = r
			case *pb.MutateResponse:
				rsp.Result = r
			default:
				panic(fmt.Sprintf("unsupported response type for Multi: %T", response))
			}
			c.ResultChan() <- hrpc.RPCResult{Msg: response}
		}
	}
}
func (m *multi) add(call hrpc.Call) bool {
	msp := trace.SpanFromContext(m.Context())
	if msp.IsRecording() {
		csp := trace.SpanContextFromContext(call.Context())
		if csp.HasTraceID() {
			msp.AddEvent("enqueue", trace.WithAttributes(
				attribute.String("traceid", csp.TraceID().String()),
			))
		}
	}
	m.calls = append(m.calls, call)
	return len(m.calls) == m.size
}
func (m *multi) len() int {
	return len(m.calls)
}
func (m *multi) get(i uint32) hrpc.Call {
	if i == 0 {
		panic("index cannot be 0")
	}
	return m.calls[i-1]
}
func (m *multi) Table() []byte {
	panic("'Table' is not supported for 'Multi'")
}
func (m *multi) Region() hrpc.RegionInfo {
	panic("'Region' is not supported for 'Multi'")
}
func (m *multi) SetRegion(r hrpc.RegionInfo) {
	panic("'SetRegion' is not supported for 'Multi'")
}
func (m *multi) ResultChan() chan hrpc.RPCResult {
	panic("'ResultChan' is not supported for 'Multi'")
}