repo_description: Staging repo for development of native port of TypeScript
code: package api
  
  import (
  	"bufio"
  	"encoding/binary"
  	"fmt"
  	"io"
  
  	"github.com/microsoft/typescript-go/internal/json"
  	"github.com/microsoft/typescript-go/internal/jsonrpc"
  )
  
  // MessageType represents the type of message in the msgpack protocol.
  type MessageType uint8
  
  const (
  	MessageTypeUnknown MessageType = iota
  	MessageTypeRequest
  	MessageTypeCallResponse
  	MessageTypeCallError
  	MessageTypeResponse
  	MessageTypeError
  	MessageTypeCall
  )
  
  func (m MessageType) IsValid() bool {
  	return m >= MessageTypeRequest && m <= MessageTypeCall
  }
  
  // MessagePack format constants
  const (
  	msgpackFixedArray3 byte = 0x93
  	msgpackBin8        byte = 0xC4
  	msgpackBin16       byte = 0xC5
  	msgpackBin32       byte = 0xC6
  	msgpackU8          byte = 0xCC
  )
  
  // MessagePackProtocol implements the Protocol interface using a custom
  // msgpack-based tuple format: [MessageType, method, payload].
  type MessagePackProtocol struct {
  	r *bufio.Reader
  	w *bufio.Writer
  }
  
  var _ Protocol = (*MessagePackProtocol)(nil)
  
  // NewMessagePackProtocol creates a new msgpack protocol handler.
  func NewMessagePackProtocol(rw io.ReadWriter) *MessagePackProtocol {
  	return &MessagePackProtocol{
  		r: bufio.NewReader(rw),
  		w: bufio.NewWriter(rw),
  	}
  }
  
  // ReadMessage implements Protocol.
  func (p *MessagePackProtocol) ReadMessage() (*Message, error) {
  	msgType, method, payload, err := p.readTuple()
  	if err != nil {
  		return nil, err
  	}
  
  	// Convert msgpack message type to JSON-RPC message
  	msg := &Message{}
  
  	switch msgType {
  	case MessageTypeRequest:
  		// Client request - needs an ID for response
  		// We use the method as a pseudo-ID since this protocol doesn't have explicit IDs
  		id := jsonrpc.NewIDString(method)
  		msg.ID = id
  		msg.Method = method
  		msg.Params = payload
  	case MessageTypeCallResponse:
  		// Response to our Call - use method as ID
  		// Note: Method must be empty for IsResponse() to return true
  		id := jsonrpc.NewIDString(method)
  		msg.ID = id
  		msg.Result = payload
  	case MessageTypeCallError:
  		// Error response to our Call
  		// Note: Method must be empty for IsResponse() to return true
  		id := jsonrpc.NewIDString(method)
  		msg.ID = id
  		msg.Error = &jsonrpc.ResponseError{
  			Code:    jsonrpc.CodeInternalError,
  			Message: string(payload),
  		}
  	default:
  		return nil, fmt.Errorf("unexpected message type: %d", msgType)
  	}
  
  	return msg, nil
  }
  
  func (p *MessagePackProtocol) readTuple() (MessageType, string, []byte, error) {
  	// Read fixed array marker (0x93 = 3-element array)
  	t, err := p.r.ReadByte()
  	if err != nil {
  		return 0, "", nil, err
  	}
  	if t != msgpackFixedArray3 {
  		return 0, "", nil, fmt.Errorf("%w: expected fixed 3-element array (0x93), received: 0x%02x", ErrInvalidRequest, t)
  	}
  
  	// Read message type - can be positive fixint (0x00-0x7F) or uint8 (0xCC + value)
  	t, err = p.r.ReadByte()
  	if err != nil {
  		return 0, "", nil, err
  	}
  	var rawType byte
  	if t <= 0x7F {
  		// Positive fixint - the byte IS the value
  		rawType = t
  	} else if t == msgpackU8 {
  		// uint8 marker - next byte is the value
  		rawType, err = p.r.ReadByte()
  		if err != nil {
  			return 0, "", nil, err
  		}
  	} else {
  		return 0, "", nil, fmt.Errorf("%w: expected positive fixint or uint8 marker, received: 0x%02x", ErrInvalidRequest, t)
  	}
  	msgType := MessageType(rawType)
  	if !msgType.IsValid() {
  		return 0, "", nil, fmt.Errorf("%w: unknown message type: %d", ErrInvalidRequest, msgType)
  	}
  
  	// Read method (binary)
  	methodBytes, err := p.readBin()
  	if err != nil {
  		return 0, "", nil, err
  	}
  	method := string(methodBytes)
  
  	// Read payload (binary)
  	payload, err := p.readBin()
  	if err != nil {
  		return 0, "", nil, err
  	}
  
  	return msgType, method, payload, nil
  }
  
  func (p *MessagePackProtocol) readBin() ([]byte, error) {
  	t, err := p.r.ReadByte()
  	if err != nil {
  		return nil, err
  	}
  
  	var size uint
  	switch t {
  	case msgpackBin8:
  		var size8 uint8
  		if err = binary.Read(p.r, binary.BigEndian, &size8); err != nil {
  			return nil, err
  		}
  		size = uint(size8)
  	case msgpackBin16:
  		var size16 uint16
  		if err = binary.Read(p.r, binary.BigEndian, &size16); err != nil {
  			return nil, err
  		}
  		size = uint(size16)
  	case msgpackBin32:
  		var size32 uint32
  		if err = binary.Read(p.r, binary.BigEndian, &size32); err != nil {
  			return nil, err
  		}
  		size = uint(size32)
  	default:
  		return nil, fmt.Errorf("%w: expected binary data (0xc4-0xc6), received: 0x%02x", ErrInvalidRequest, t)
  	}
  
  	payload := make([]byte, size)
  	if _, err := io.ReadFull(p.r, payload); err != nil {
  		return nil, err
  	}
  	return payload, nil
  }
  
  // WriteRequest implements Protocol.
  func (p *MessagePackProtocol) WriteRequest(id *jsonrpc.ID, method string, params any) error {
  	// For msgpack protocol, requests from server are "Call" type
  	payload, err := json.Marshal(params)
  	if err != nil {
  		return err
  	}
  	return p.writeTuple(MessageTypeCall, method, payload)
  }
  
  // WriteNotification implements Protocol.
  func (p *MessagePackProtocol) WriteNotification(method string, params any) error {
  	// Msgpack protocol doesn't distinguish notifications from calls
  	return p.WriteRequest(nil, method, params)
  }
  
  // WriteResponse implements Protocol.
  func (p *MessagePackProtocol) WriteResponse(id *jsonrpc.ID, result any) error {
  	method := ""
  	if id != nil {
  		method = id.String()
  	}
  
  	var payload []byte
  	var err error
  
  	// Check if result is raw binary (for efficient binary transport)
  	if raw, ok := result.(RawBinary); ok {
  		payload = []byte(raw)
  	} else {
  		payload, err = json.Marshal(result)
  		if err != nil {
  			return err
  		}
  	}
  
  	return p.writeTuple(MessageTypeResponse, method, payload)
  }
  
  // WriteError implements Protocol.
  func (p *MessagePackProtocol) WriteError(id *jsonrpc.ID, respErr *jsonrpc.ResponseError) error {
  	method := ""
  	if id != nil {
  		method = id.String()
  	}
  	return p.writeTuple(MessageTypeError, method, []byte(respErr.Message))
  }
  
  func (p *MessagePackProtocol) writeTuple(msgType MessageType, method string, payload []byte) error {
  	// Write fixed array marker
  	if err := p.w.WriteByte(msgpackFixedArray3); err != nil {
  		return err
  	}
  	// Write message type as positive fixint (values 0-127 are written directly)
  	if err := p.w.WriteByte(byte(msgType)); err != nil {
  		return err
  	}
  	// Write method
  	if err := p.writeBin([]byte(method)); err != nil {
  		return err
  	}
  	// Write payload
  	if err := p.writeBin(payload); err != nil {
  		return err
  	}
  	return p.w.Flush()
  }
  
  func (p *MessagePackProtocol) writeBin(data []byte) error {
  	length := len(data)
  	if length < 256 {
  		if err := p.w.WriteByte(msgpackBin8); err != nil {
  			return err
  		}
  		if err := p.w.WriteByte(byte(length)); err != nil {
  			return err
  		}
  	} else if length < 1<<16 {
  		if err := p.w.WriteByte(msgpackBin16); err != nil {
  			return err
  		}
  		if err := binary.Write(p.w, binary.BigEndian, uint16(length)); err != nil {
  			return err
  		}
  	} else {
  		if err := p.w.WriteByte(msgpackBin32); err != nil {
  			return err
  		}
  		if err := binary.Write(p.w, binary.BigEndian, uint32(length)); err != nil {
  			return err
  		}
  	}
  	_, err := p.w.Write(data)
  	return err
  }
  
  // RawBinary is a marker type for binary data that should be written
  // directly by MessagePackProtocol instead of being JSON-encoded.
  type RawBinary []byte
  