package yu_proto

func (t *Protobuf) Bytes() []byte {
	t.tmp_buf = nil
	if t.list.id == 0 {
		return nil
	}
	return t.bytes_obj(t.list)
}

func (t *Protobuf) bytes_obj(list *node) []byte {
	var j_buf []byte
	for {
		if list.id != 0 {
			j_buf = append(j_buf, t.bytes_value(list.id, list.value)...)
		}
		if list._next == nil {
			break
		}
		list = list._next
	}
	return j_buf
}

func (t *Protobuf) bytes_value(id uint64, value any) []byte {
	var j_buf []byte
	switch j_value := value.(type) {
	case bool:
		j_buf = make([]byte, 0, maxVarintLen64+1)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		if j_value {
			j_buf = appendUint64(j_buf, 1)
		} else {
			j_buf = appendUint64(j_buf, 0)
		}
	case byte:
		j_buf = make([]byte, 0, maxVarintLen64+1)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendUint64(j_buf, uint64(j_value))
	case int8:
		j_buf = make([]byte, 0, maxVarintLen64+1)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendInt64(j_buf, int64(j_value))
	case int16:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen16)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendInt64(j_buf, int64(j_value))
	case uint16:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen16)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendUint64(j_buf, uint64(j_value))
	case int32:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen32)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendInt64(j_buf, int64(j_value))
	case uint32:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen32)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendUint64(j_buf, uint64(j_value))
	case int64:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen64)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendInt64(j_buf, j_value)
	case uint64:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen64)
		j_buf = appendUint64(j_buf, (id<<3)|0)
		j_buf = appendUint64(j_buf, j_value)
	case float32:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen32)
		j_buf = appendUint64(j_buf, (id<<3)|5)
		j_buf = appendFloat32(j_buf, j_value)
	case float64:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen64)
		j_buf = appendUint64(j_buf, (id<<3)|1)
		j_buf = appendFloat64(j_buf, j_value)
	case []byte:
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen64)
		j_buf = appendUint64(j_buf, (id<<3)|2)
		j_buf = appendUint64(j_buf, uint64(len(j_value)))
		j_buf = append(j_buf, j_value...)
	case *node:
		j_node := t.bytes_obj(j_value)
		j_buf = make([]byte, 0, maxVarintLen64+maxVarintLen64)
		j_buf = appendUint64(j_buf, (id<<3)|2)
		j_buf = appendUint64(j_buf, uint64(len(j_node)))
		j_buf = append(j_buf, j_node...)
	case *[]*node:
		for _, j_item := range *j_value {
			if j_item == nil {
				j_buf = appendUint64(j_buf, (id<<3)|2)
				j_buf = appendUint64(j_buf, 0)
				continue
			}
			j_buf = append(j_buf, t.bytes_value(id, j_item.value)...)
		}
	default:
		panic("不支持的数据类型")
	}
	return j_buf
}
