/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package thrift

import (
	"encoding/binary"
	"fmt"
	"io"
	"math"
)

const (
	COMPACT_PROTOCOL_ID       = 0x082
	COMPACT_VERSION           = 1
	COMPACT_VERSION_MASK      = 0x1f
	COMPACT_TYPE_MASK         = 0x0E0
	COMPACT_TYPE_BITS         = 0x07
	COMPACT_TYPE_SHIFT_AMOUNT = 5
)

type tCompactType byte

const (
	COMPACT_BOOLEAN_TRUE  = 0x01
	COMPACT_BOOLEAN_FALSE = 0x02
	COMPACT_BYTE          = 0x03
	COMPACT_I16           = 0x04
	COMPACT_I32           = 0x05
	COMPACT_I64           = 0x06
	COMPACT_DOUBLE        = 0x07
	COMPACT_BINARY        = 0x08
	COMPACT_LIST          = 0x09
	COMPACT_SET           = 0x0A
	COMPACT_MAP           = 0x0B
	COMPACT_STRUCT        = 0x0C
)

var (
	ttypeToCompactType map[TType]tCompactType
)

func init() {
	ttypeToCompactType = map[TType]tCompactType{
		STOP:   STOP,
		BOOL:   COMPACT_BOOLEAN_TRUE,
		BYTE:   COMPACT_BYTE,
		I16:    COMPACT_I16,
		I32:    COMPACT_I32,
		I64:    COMPACT_I64,
		DOUBLE: COMPACT_DOUBLE,
		STRING: COMPACT_BINARY,
		LIST:   COMPACT_LIST,
		SET:    COMPACT_SET,
		MAP:    COMPACT_MAP,
		STRUCT: COMPACT_STRUCT,
	}
}

type TCompactProtocolFactory struct{}

func NewTCompactProtocolFactory() *TCompactProtocolFactory {
	return &TCompactProtocolFactory{}
}

func (p *TCompactProtocolFactory) GetProtocol(trans TTransport) TProtocol {
	return NewTCompactProtocol(trans)
}

type TCompactProtocol struct {
	trans         TRichTransport
	origTransport TTransport

	// Used to keep track of the last field for the current and previous structs,
	// so we can do the delta stuff.
	lastField   []int
	lastFieldId int

	// If we encounter a boolean field begin, save the TField here so it can
	// have the value incorporated.
	booleanFieldName    string
	booleanFieldId      int16
	booleanFieldPending bool

	// If we read a field header, and it's a boolean field, save the boolean
	// value here so that readBool can use it.
	boolValue          bool
	boolValueIsNotNull bool
	buffer             [64]byte
}

// Create a TCompactProtocol given a TTransport
func NewTCompactProtocol(trans TTransport) *TCompactProtocol {
	p := &TCompactProtocol{origTransport: trans, lastField: []int{}}
	if et, ok := trans.(TRichTransport); ok {
		p.trans = et
	} else {
		p.trans = NewTRichTransport(trans)
	}

	return p

}

//
// Public Writing methods.
//

// Write a message header to the wire. Compact Protocol messages contain the
// protocol version so we can migrate forwards in the future if need be.
func (p *TCompactProtocol) WriteMessageBegin(name string, typeId TMessageType, seqid int32) error {
	err := p.writeByteDirect(COMPACT_PROTOCOL_ID)
	if err != nil {
		return NewTProtocolException(err)
	}
	err = p.writeByteDirect((COMPACT_VERSION & COMPACT_VERSION_MASK) | ((byte(typeId) << COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_MASK))
	if err != nil {
		return NewTProtocolException(err)
	}
	_, err = p.writeVarint32(seqid)
	if err != nil {
		return NewTProtocolException(err)
	}
	e := p.WriteString(name)
	return e

}

func (p *TCompactProtocol) WriteMessageEnd() error { return nil }

// Write a struct begin. This doesn't actually put anything on the wire. We
// use it as an opportunity to put special placeholder markers on the field
// stack so we can get the field id deltas correct.
func (p *TCompactProtocol) WriteStructBegin(name string) error {
	p.lastField = append(p.lastField, p.lastFieldId)
	p.lastFieldId = 0
	return nil
}

// Write a struct end. This doesn't actually put anything on the wire. We use
// this as an opportunity to pop the last field from the current struct off
// of the field stack.
func (p *TCompactProtocol) WriteStructEnd() error {
	p.lastFieldId = p.lastField[len(p.lastField)-1]
	p.lastField = p.lastField[:len(p.lastField)-1]
	return nil
}

func (p *TCompactProtocol) WriteFieldBegin(name string, typeId TType, id int16) error {
	if typeId == BOOL {
		// we want to possibly include the value, so we'll wait.
		p.booleanFieldName, p.booleanFieldId, p.booleanFieldPending = name, id, true
		return nil
	}
	_, err := p.writeFieldBeginInternal(name, typeId, id, 0xFF)
	return NewTProtocolException(err)
}

// The workhorse of writeFieldBegin. It has the option of doing a
// 'type override' of the type header. This is used specifically in the
// boolean field case.
func (p *TCompactProtocol) writeFieldBeginInternal(name string, typeId TType, id int16, typeOverride byte) (int, error) {
	// short lastField = lastField_.pop();

	// if there's a type override, use that.
	var typeToWrite byte
	if typeOverride == 0xFF {
		typeToWrite = byte(p.getCompactType(typeId))
	} else {
		typeToWrite = typeOverride
	}
	// check if we can use delta encoding for the field id
	fieldId := int(id)
	written := 0
	if fieldId > p.lastFieldId && fieldId-p.lastFieldId <= 15 {
		// write them together
		err := p.writeByteDirect(byte((fieldId-p.lastFieldId)<<4) | typeToWrite)
		if err != nil {
			return 0, err
		}
	} else {
		// write them separate
		err := p.writeByteDirect(typeToWrite)
		if err != nil {
			return 0, err
		}
		err = p.WriteI16(id)
		written = 1 + 2
		if err != nil {
			return 0, err
		}
	}

	p.lastFieldId = fieldId
	// p.lastField.Push(field.id);
	return written, nil
}

func (p *TCompactProtocol) WriteFieldEnd() error { return nil }

func (p *TCompactProtocol) WriteFieldStop() error {
	err := p.writeByteDirect(STOP)
	return NewTProtocolException(err)
}

func (p *TCompactProtocol) WriteMapBegin(keyType TType, valueType TType, size int) error {
	if size == 0 {
		err := p.writeByteDirect(0)
		return NewTProtocolException(err)
	}
	_, err := p.writeVarint32(int32(size))
	if err != nil {
		return NewTProtocolException(err)
	}
	err = p.writeByteDirect(byte(p.getCompactType(keyType))<<4 | byte(p.getCompactType(valueType)))
	return NewTProtocolException(err)
}

func (p *TCompactProtocol) WriteMapEnd() error { return nil }

// Write a list header.
func (p *TCompactProtocol) WriteListBegin(elemType TType, size int) error {
	_, err := p.writeCollectionBegin(elemType, size)
	return NewTProtocolException(err)
}

func (p *TCompactProtocol) WriteListEnd() error { return nil }

// Write a set header.
func (p *TCompactProtocol) WriteSetBegin(elemType TType, size int) error {
	_, err := p.writeCollectionBegin(elemType, size)
	return NewTProtocolException(err)
}

func (p *TCompactProtocol) WriteSetEnd() error { return nil }

func (p *TCompactProtocol) WriteBool(value bool) error {
	v := byte(COMPACT_BOOLEAN_FALSE)
	if value {
		v = byte(COMPACT_BOOLEAN_TRUE)
	}
	if p.booleanFieldPending {
		// we haven't written the field header yet
		_, err := p.writeFieldBeginInternal(p.booleanFieldName, BOOL, p.booleanFieldId, v)
		p.booleanFieldPending = false
		return NewTProtocolException(err)
	}
	// we're not part of a field, so just write the value.
	err := p.writeByteDirect(v)
	return NewTProtocolException(err)
}

// Write a byte. Nothing to see here!
func (p *TCompactProtocol) WriteByte(value int8) error {
	err := p.writeByteDirect(byte(value))
	return NewTProtocolException(err)
}

// Write an I16 as a zigzag varint.
func (p *TCompactProtocol) WriteI16(value int16) error {
	_, err := p.writeVarint32(p.int32ToZigzag(int32(value)))
	return NewTProtocolException(err)
}

// Write an i32 as a zigzag varint.
func (p *TCompactProtocol) WriteI32(value int32) error {
	_, err := p.writeVarint32(p.int32ToZigzag(value))
	return NewTProtocolException(err)
}

// Write an i64 as a zigzag varint.
func (p *TCompactProtocol) WriteI64(value int64) error {
	_, err := p.writeVarint64(p.int64ToZigzag(value))
	return NewTProtocolException(err)
}

// Write a double to the wire as 8 bytes.
func (p *TCompactProtocol) WriteDouble(value float64) error {
	buf := p.buffer[0:8]
	binary.LittleEndian.PutUint64(buf, math.Float64bits(value))
	_, err := p.trans.Write(buf)
	return NewTProtocolException(err)
}

// Write a string to the wire with a varint size preceding.
func (p *TCompactProtocol) WriteString(value string) error {
	_, e := p.writeVarint32(int32(len(value)))
	if e != nil {
		return NewTProtocolException(e)
	}
	if len(value) > 0 {
	}
	_, e = p.trans.WriteString(value)
	return e
}

// Write a byte array, using a varint for the size.
func (p *TCompactProtocol) WriteBinary(bin []byte) error {
	_, e := p.writeVarint32(int32(len(bin)))
	if e != nil {
		return NewTProtocolException(e)
	}
	if len(bin) > 0 {
		_, e = p.trans.Write(bin)
		return NewTProtocolException(e)
	}
	return nil
}

//
// Reading methods.
//

// Read a message header.
func (p *TCompactProtocol) ReadMessageBegin() (name string, typeId TMessageType, seqId int32, err error) {

	protocolId, err := p.readByteDirect()
	if err != nil {
		return
	}

	if protocolId != COMPACT_PROTOCOL_ID {
		e := fmt.Errorf("Expected protocol id %02x but got %02x", COMPACT_PROTOCOL_ID, protocolId)
		return "", typeId, seqId, NewTProtocolExceptionWithType(BAD_VERSION, e)
	}

	versionAndType, err := p.readByteDirect()
	if err != nil {
		return
	}

	version := versionAndType & COMPACT_VERSION_MASK
	typeId = TMessageType((versionAndType >> COMPACT_TYPE_SHIFT_AMOUNT) & COMPACT_TYPE_BITS)
	if version != COMPACT_VERSION {
		e := fmt.Errorf("Expected version %02x but got %02x", COMPACT_VERSION, version)
		err = NewTProtocolExceptionWithType(BAD_VERSION, e)
		return
	}
	seqId, e := p.readVarint32()
	if e != nil {
		err = NewTProtocolException(e)
		return
	}
	name, err = p.ReadString()
	return
}

func (p *TCompactProtocol) ReadMessageEnd() error { return nil }

// Read a struct begin. There's nothing on the wire for this, but it is our
// opportunity to push a new struct begin marker onto the field stack.
func (p *TCompactProtocol) ReadStructBegin() (name string, err error) {
	p.lastField = append(p.lastField, p.lastFieldId)
	p.lastFieldId = 0
	return
}

// Doesn't actually consume any wire data, just removes the last field for
// this struct from the field stack.
func (p *TCompactProtocol) ReadStructEnd() error {
	// consume the last field we read off the wire.
	p.lastFieldId = p.lastField[len(p.lastField)-1]
	p.lastField = p.lastField[:len(p.lastField)-1]
	return nil
}

// Read a field header off the wire.
func (p *TCompactProtocol) ReadFieldBegin() (name string, typeId TType, id int16, err error) {
	t, err := p.readByteDirect()
	if err != nil {
		return
	}

	// if it's a stop, then we can return immediately, as the struct is over.
	if (t & 0x0f) == STOP {
		return "", STOP, 0, nil
	}

	// mask off the 4 MSB of the type header. it could contain a field id delta.
	modifier := int16((t & 0xf0) >> 4)
	if modifier == 0 {
		// not a delta. look ahead for the zigzag varint field id.
		id, err = p.ReadI16()
		if err != nil {
			return
		}
	} else {
		// has a delta. add the delta to the last read field id.
		id = int16(p.lastFieldId) + modifier
	}
	typeId, e := p.getTType(tCompactType(t & 0x0f))
	if e != nil {
		err = NewTProtocolException(e)
		return
	}

	// if this happens to be a boolean field, the value is encoded in the type
	if p.isBoolType(t) {
		// save the boolean value in a special instance variable.
		p.boolValue = (byte(t)&0x0f == COMPACT_BOOLEAN_TRUE)
		p.boolValueIsNotNull = true
	}

	// push the new field onto the field stack so we can keep the deltas going.
	p.lastFieldId = int(id)
	return
}

func (p *TCompactProtocol) ReadFieldEnd() error { return nil }

// Read a map header off the wire. If the size is zero, skip reading the key
// and value type. This means that 0-length maps will yield TMaps without the
// "correct" types.
func (p *TCompactProtocol) ReadMapBegin() (keyType TType, valueType TType, size int, err error) {
	size32, e := p.readVarint32()
	if e != nil {
		err = NewTProtocolException(e)
		return
	}
	if size32 < 0 {
		err = invalidDataLength
		return
	}
	size = int(size32)

	keyAndValueType := byte(STOP)
	if size != 0 {
		keyAndValueType, err = p.readByteDirect()
		if err != nil {
			return
		}
	}
	keyType, _ = p.getTType(tCompactType(keyAndValueType >> 4))
	valueType, _ = p.getTType(tCompactType(keyAndValueType & 0xf))
	return
}

func (p *TCompactProtocol) ReadMapEnd() error { return nil }

// Read a list header off the wire. If the list size is 0-14, the size will
// be packed into the element type header. If it's a longer list, the 4 MSB
// of the element type header will be 0xF, and a varint will follow with the
// true size.
func (p *TCompactProtocol) ReadListBegin() (elemType TType, size int, err error) {
	size_and_type, err := p.readByteDirect()
	if err != nil {
		return
	}
	size = int((size_and_type >> 4) & 0x0f)
	if size == 15 {
		size2, e := p.readVarint32()
		if e != nil {
			err = NewTProtocolException(e)
			return
		}
		if size2 < 0 {
			err = invalidDataLength
			return
		}
		size = int(size2)
	}
	elemType, e := p.getTType(tCompactType(size_and_type))
	if e != nil {
		err = NewTProtocolException(e)
		return
	}
	return
}

func (p *TCompactProtocol) ReadListEnd() error { return nil }

// Read a set header off the wire. If the set size is 0-14, the size will
// be packed into the element type header. If it's a longer set, the 4 MSB
// of the element type header will be 0xF, and a varint will follow with the
// true size.
func (p *TCompactProtocol) ReadSetBegin() (elemType TType, size int, err error) {
	return p.ReadListBegin()
}

func (p *TCompactProtocol) ReadSetEnd() error { return nil }

// Read a boolean off the wire. If this is a boolean field, the value should
// already have been read during readFieldBegin, so we'll just consume the
// pre-stored value. Otherwise, read a byte.
func (p *TCompactProtocol) ReadBool() (value bool, err error) {
	if p.boolValueIsNotNull {
		p.boolValueIsNotNull = false
		return p.boolValue, nil
	}
	v, err := p.readByteDirect()
	return v == COMPACT_BOOLEAN_TRUE, err
}

// Read a single byte off the wire. Nothing interesting here.
func (p *TCompactProtocol) ReadByte() (int8, error) {
	v, err := p.readByteDirect()
	if err != nil {
		return 0, NewTProtocolException(err)
	}
	return int8(v), err
}

// Read an i16 from the wire as a zigzag varint.
func (p *TCompactProtocol) ReadI16() (value int16, err error) {
	v, err := p.ReadI32()
	return int16(v), err
}

// Read an i32 from the wire as a zigzag varint.
func (p *TCompactProtocol) ReadI32() (value int32, err error) {
	v, e := p.readVarint32()
	if e != nil {
		return 0, NewTProtocolException(e)
	}
	value = p.zigzagToInt32(v)
	return value, nil
}

// Read an i64 from the wire as a zigzag varint.
func (p *TCompactProtocol) ReadI64() (value int64, err error) {
	v, e := p.readVarint64()
	if e != nil {
		return 0, NewTProtocolException(e)
	}
	value = p.zigzagToInt64(v)
	return value, nil
}

// No magic here - just read a double off the wire.
func (p *TCompactProtocol) ReadDouble() (value float64, err error) {
	longBits := p.buffer[0:8]
	_, e := io.ReadFull(p.trans, longBits)
	if e != nil {
		return 0.0, NewTProtocolException(e)
	}
	return math.Float64frombits(p.bytesToUint64(longBits)), nil
}

// Reads a []byte (via readBinary), and then UTF-8 decodes it.
func (p *TCompactProtocol) ReadString() (value string, err error) {
	length, e := p.readVarint32()
	if e != nil {
		return "", NewTProtocolException(e)
	}
	if length < 0 {
		return "", invalidDataLength
	}
	if uint64(length) > p.trans.RemainingBytes() {
		return "", invalidDataLength
	}

	if length == 0 {
		return "", nil
	}
	var buf []byte
	if length <= int32(len(p.buffer)) {
		buf = p.buffer[0:length]
	} else {
		buf = make([]byte, length)
	}
	_, e = io.ReadFull(p.trans, buf)
	return string(buf), NewTProtocolException(e)
}

// Read a []byte from the wire.
func (p *TCompactProtocol) ReadBinary() (value []byte, err error) {
	length, e := p.readVarint32()
	if e != nil {
		return nil, NewTProtocolException(e)
	}
	if length == 0 {
		return []byte{}, nil
	}
	if length < 0 {
		return nil, invalidDataLength
	}
	if uint64(length) > p.trans.RemainingBytes() {
		return nil, invalidDataLength
	}

	buf := make([]byte, length)
	_, e = io.ReadFull(p.trans, buf)
	return buf, NewTProtocolException(e)
}

func (p *TCompactProtocol) Flush() (err error) {
	return NewTProtocolException(p.trans.Flush())
}

func (p *TCompactProtocol) Skip(fieldType TType) (err error) {
	return SkipDefaultDepth(p, fieldType)
}

func (p *TCompactProtocol) Transport() TTransport {
	return p.origTransport
}

//
// Internal writing methods
//

// Abstract method for writing the start of lists and sets. List and sets on
// the wire differ only by the type indicator.
func (p *TCompactProtocol) writeCollectionBegin(elemType TType, size int) (int, error) {
	if size <= 14 {
		return 1, p.writeByteDirect(byte(int32(size<<4) | int32(p.getCompactType(elemType))))
	}
	err := p.writeByteDirect(0xf0 | byte(p.getCompactType(elemType)))
	if err != nil {
		return 0, err
	}
	m, err := p.writeVarint32(int32(size))
	return 1 + m, err
}

// Write an i32 as a varint. Results in 1-5 bytes on the wire.
// TODO(pomack): make a permanent buffer like writeVarint64?
func (p *TCompactProtocol) writeVarint32(n int32) (int, error) {
	i32buf := p.buffer[0:5]
	idx := 0
	for {
		if (n & ^0x7F) == 0 {
			i32buf[idx] = byte(n)
			idx++
			// p.writeByteDirect(byte(n));
			break
			// return;
		} else {
			i32buf[idx] = byte((n & 0x7F) | 0x80)
			idx++
			// p.writeByteDirect(byte(((n & 0x7F) | 0x80)));
			u := uint32(n)
			n = int32(u >> 7)
		}
	}
	return p.trans.Write(i32buf[0:idx])
}

// Write an i64 as a varint. Results in 1-10 bytes on the wire.
func (p *TCompactProtocol) writeVarint64(n int64) (int, error) {
	varint64out := p.buffer[0:10]
	idx := 0
	for {
		if (n & ^0x7F) == 0 {
			varint64out[idx] = byte(n)
			idx++
			break
		} else {
			varint64out[idx] = byte((n & 0x7F) | 0x80)
			idx++
			u := uint64(n)
			n = int64(u >> 7)
		}
	}
	return p.trans.Write(varint64out[0:idx])
}

// Convert l into a zigzag long. This allows negative numbers to be
// represented compactly as a varint.
func (p *TCompactProtocol) int64ToZigzag(l int64) int64 {
	return (l << 1) ^ (l >> 63)
}

// Convert l into a zigzag long. This allows negative numbers to be
// represented compactly as a varint.
func (p *TCompactProtocol) int32ToZigzag(n int32) int32 {
	return (n << 1) ^ (n >> 31)
}

func (p *TCompactProtocol) fixedUint64ToBytes(n uint64, buf []byte) {
	binary.LittleEndian.PutUint64(buf, n)
}

func (p *TCompactProtocol) fixedInt64ToBytes(n int64, buf []byte) {
	binary.LittleEndian.PutUint64(buf, uint64(n))
}

// Writes a byte without any possibility of all that field header nonsense.
// Used internally by other writing methods that know they need to write a byte.
func (p *TCompactProtocol) writeByteDirect(b byte) error {
	return p.trans.WriteByte(b)
}

// Writes a byte without any possibility of all that field header nonsense.
func (p *TCompactProtocol) writeIntAsByteDirect(n int) (int, error) {
	return 1, p.writeByteDirect(byte(n))
}

//
// Internal reading methods
//

// Read an i32 from the wire as a varint. The MSB of each byte is set
// if there is another byte to follow. This can read up to 5 bytes.
func (p *TCompactProtocol) readVarint32() (int32, error) {
	// if the wire contains the right stuff, this will just truncate the i64 we
	// read and get us the right sign.
	v, err := p.readVarint64()
	return int32(v), err
}

// Read an i64 from the wire as a proper varint. The MSB of each byte is set
// if there is another byte to follow. This can read up to 10 bytes.
func (p *TCompactProtocol) readVarint64() (int64, error) {
	shift := uint(0)
	result := int64(0)
	for {
		b, err := p.readByteDirect()
		if err != nil {
			return 0, err
		}
		result |= int64(b&0x7f) << shift
		if (b & 0x80) != 0x80 {
			break
		}
		shift += 7
	}
	return result, nil
}

// Read a byte, unlike ReadByte that reads Thrift-byte that is i8.
func (p *TCompactProtocol) readByteDirect() (byte, error) {
	return p.trans.ReadByte()
}

//
// encoding helpers
//

// Convert from zigzag int to int.
func (p *TCompactProtocol) zigzagToInt32(n int32) int32 {
	u := uint32(n)
	return int32(u>>1) ^ -(n & 1)
}

// Convert from zigzag long to long.
func (p *TCompactProtocol) zigzagToInt64(n int64) int64 {
	u := uint64(n)
	return int64(u>>1) ^ -(n & 1)
}

// Note that it's important that the mask bytes are long literals,
// otherwise they'll default to ints, and when you shift an int left 56 bits,
// you just get a messed up int.
func (p *TCompactProtocol) bytesToInt64(b []byte) int64 {
	return int64(binary.LittleEndian.Uint64(b))
}

// Note that it's important that the mask bytes are long literals,
// otherwise they'll default to ints, and when you shift an int left 56 bits,
// you just get a messed up int.
func (p *TCompactProtocol) bytesToUint64(b []byte) uint64 {
	return binary.LittleEndian.Uint64(b)
}

//
// type testing and converting
//

func (p *TCompactProtocol) isBoolType(b byte) bool {
	return (b&0x0f) == COMPACT_BOOLEAN_TRUE || (b&0x0f) == COMPACT_BOOLEAN_FALSE
}

// Given a tCompactType constant, convert it to its corresponding
// TType value.
func (p *TCompactProtocol) getTType(t tCompactType) (TType, error) {
	switch byte(t) & 0x0f {
	case STOP:
		return STOP, nil
	case COMPACT_BOOLEAN_FALSE, COMPACT_BOOLEAN_TRUE:
		return BOOL, nil
	case COMPACT_BYTE:
		return BYTE, nil
	case COMPACT_I16:
		return I16, nil
	case COMPACT_I32:
		return I32, nil
	case COMPACT_I64:
		return I64, nil
	case COMPACT_DOUBLE:
		return DOUBLE, nil
	case COMPACT_BINARY:
		return STRING, nil
	case COMPACT_LIST:
		return LIST, nil
	case COMPACT_SET:
		return SET, nil
	case COMPACT_MAP:
		return MAP, nil
	case COMPACT_STRUCT:
		return STRUCT, nil
	}
	return STOP, TException(fmt.Errorf("don't know what type: %d", t&0x0f))
}

// Given a TType value, find the appropriate TCompactProtocol.Types constant.
func (p *TCompactProtocol) getCompactType(t TType) tCompactType {
	return ttypeToCompactType[t]
}
