// Autogenerated Go message buffer code.
// Source: clad/cloud/docs.clad
// Full command line: victor-clad/tools/message-buffers/emitters/Go_emitter.py -C src -o generated/cladgo/src clad/cloud/docs.clad

package cloud

import (
  "bytes"
  "encoding/binary"
  "errors"
  "anki/clad"
  "fmt"
)

// STRUCTURE Doc
type Doc struct {
  DocVersion uint64
  FmtVersion uint64
  Metadata string
  JsonDoc string
}

func (d *Doc) Size() uint32 {
  var result uint32
  result += 8 // DocVersion uint_64
  result += 8 // FmtVersion uint_64
  result += 1 // Metadata length (uint_8)
  result += uint32(len(d.Metadata)) // uint_8 array
  result += 4 // JsonDoc length (uint_32)
  result += uint32(len(d.JsonDoc)) // uint_8 array
  return result
}

func (d *Doc) Unpack(buf *bytes.Buffer) error {
  if err := binary.Read(buf, binary.LittleEndian, &d.DocVersion); err != nil {
    return err
  }
  if err := binary.Read(buf, binary.LittleEndian, &d.FmtVersion); err != nil {
    return err
  }
  var MetadataLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &MetadataLen); err != nil {
    return err
  }
  d.Metadata = string(buf.Next(int(MetadataLen)))
  if len(d.Metadata) != int(MetadataLen) {
    return errors.New("string byte mismatch")
  }
  var JsonDocLen uint32
  if err := binary.Read(buf, binary.LittleEndian, &JsonDocLen); err != nil {
    return err
  }
  d.JsonDoc = string(buf.Next(int(JsonDocLen)))
  if len(d.JsonDoc) != int(JsonDocLen) {
    return errors.New("string byte mismatch")
  }
  return nil
}

func (d *Doc) Pack(buf *bytes.Buffer) error {
  if err := binary.Write(buf, binary.LittleEndian, d.DocVersion); err != nil {
    return err
  }
  if err := binary.Write(buf, binary.LittleEndian, d.FmtVersion); err != nil {
    return err
  }
  if len(d.Metadata) > 255 {
    return errors.New("max_length overflow in field Metadata")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint8(len(d.Metadata))); err != nil {
    return err
  }
  if _, err := buf.WriteString(d.Metadata); err != nil {
    return err
  }
  if err := binary.Write(buf, binary.LittleEndian, uint32(len(d.JsonDoc))); err != nil {
    return err
  }
  if _, err := buf.WriteString(d.JsonDoc); err != nil {
    return err
  }
  return nil
}

func (d *Doc) String() string {
  return fmt.Sprint("DocVersion: {", d.DocVersion, "} ",
    "FmtVersion: {", d.FmtVersion, "} ",
    "Metadata: {", d.Metadata, "} ",
    "JsonDoc: {", d.JsonDoc, "}")
}


// STRUCTURE WriteRequest
type WriteRequest struct {
  Account string
  Thing string
  DocName string
  Doc Doc
}

func (w *WriteRequest) Size() uint32 {
  var result uint32
  result += 2 // Account length (uint_16)
  result += uint32(len(w.Account)) // uint_8 array
  result += 2 // Thing length (uint_16)
  result += uint32(len(w.Thing)) // uint_8 array
  result += 2 // DocName length (uint_16)
  result += uint32(len(w.DocName)) // uint_8 array
  result += w.Doc.Size()
  return result
}

func (w *WriteRequest) Unpack(buf *bytes.Buffer) error {
  var AccountLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &AccountLen); err != nil {
    return err
  }
  w.Account = string(buf.Next(int(AccountLen)))
  if len(w.Account) != int(AccountLen) {
    return errors.New("string byte mismatch")
  }
  var ThingLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &ThingLen); err != nil {
    return err
  }
  w.Thing = string(buf.Next(int(ThingLen)))
  if len(w.Thing) != int(ThingLen) {
    return errors.New("string byte mismatch")
  }
  var DocNameLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &DocNameLen); err != nil {
    return err
  }
  w.DocName = string(buf.Next(int(DocNameLen)))
  if len(w.DocName) != int(DocNameLen) {
    return errors.New("string byte mismatch")
  }
  if err := w.Doc.Unpack(buf); err != nil {
    return err
  }
  return nil
}

func (w *WriteRequest) Pack(buf *bytes.Buffer) error {
  if len(w.Account) > 65535 {
    return errors.New("max_length overflow in field Account")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(w.Account))); err != nil {
    return err
  }
  if _, err := buf.WriteString(w.Account); err != nil {
    return err
  }
  if len(w.Thing) > 65535 {
    return errors.New("max_length overflow in field Thing")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(w.Thing))); err != nil {
    return err
  }
  if _, err := buf.WriteString(w.Thing); err != nil {
    return err
  }
  if len(w.DocName) > 65535 {
    return errors.New("max_length overflow in field DocName")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(w.DocName))); err != nil {
    return err
  }
  if _, err := buf.WriteString(w.DocName); err != nil {
    return err
  }
  if err := w.Doc.Pack(buf); err != nil {
    return err
  }
  return nil
}

func (w *WriteRequest) String() string {
  return fmt.Sprint("Account: {", w.Account, "} ",
    "Thing: {", w.Thing, "} ",
    "DocName: {", w.DocName, "} ",
    "Doc: {", w.Doc, "}")
}


// ENUM DocError
type DocError uint8

const (
  DocError_ErrorConnecting DocError = iota
)

// ENUM WriteStatus
type WriteStatus uint8

const (
  WriteStatus_Accepted WriteStatus = iota
  WriteStatus_RejectedDocVersion         
  WriteStatus_RejectedFmtVersion         
  WriteStatus_Error                      
)

// STRUCTURE WriteResponse
type WriteResponse struct {
  Status WriteStatus
  LatestVersion uint64
}

func (w *WriteResponse) Size() uint32 {
  var result uint32
  result += 1 // Status WriteStatus
  result += 8 // LatestVersion uint_64
  return result
}

func (w *WriteResponse) Unpack(buf *bytes.Buffer) error {
  if err := binary.Read(buf, binary.LittleEndian, &w.Status); err != nil {
    return err
  }
  if err := binary.Read(buf, binary.LittleEndian, &w.LatestVersion); err != nil {
    return err
  }
  return nil
}

func (w *WriteResponse) Pack(buf *bytes.Buffer) error {
  if err := binary.Write(buf, binary.LittleEndian, w.Status); err != nil {
    return err
  }
  if err := binary.Write(buf, binary.LittleEndian, w.LatestVersion); err != nil {
    return err
  }
  return nil
}

func (w *WriteResponse) String() string {
  return fmt.Sprint("Status: {", w.Status, "} ",
    "LatestVersion: {", w.LatestVersion, "}")
}


// STRUCTURE ReadItem
type ReadItem struct {
  DocName string
  MyDocVersion uint64
}

func (r *ReadItem) Size() uint32 {
  var result uint32
  result += 1 // DocName length (uint_8)
  result += uint32(len(r.DocName)) // uint_8 array
  result += 8 // MyDocVersion uint_64
  return result
}

func (r *ReadItem) Unpack(buf *bytes.Buffer) error {
  var DocNameLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &DocNameLen); err != nil {
    return err
  }
  r.DocName = string(buf.Next(int(DocNameLen)))
  if len(r.DocName) != int(DocNameLen) {
    return errors.New("string byte mismatch")
  }
  if err := binary.Read(buf, binary.LittleEndian, &r.MyDocVersion); err != nil {
    return err
  }
  return nil
}

func (r *ReadItem) Pack(buf *bytes.Buffer) error {
  if len(r.DocName) > 255 {
    return errors.New("max_length overflow in field DocName")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint8(len(r.DocName))); err != nil {
    return err
  }
  if _, err := buf.WriteString(r.DocName); err != nil {
    return err
  }
  if err := binary.Write(buf, binary.LittleEndian, r.MyDocVersion); err != nil {
    return err
  }
  return nil
}

func (r *ReadItem) String() string {
  return fmt.Sprint("DocName: {", r.DocName, "} ",
    "MyDocVersion: {", r.MyDocVersion, "}")
}


// STRUCTURE ReadRequest
type ReadRequest struct {
  Account string
  Thing string
  Items []ReadItem
}

func (r *ReadRequest) Size() uint32 {
  var result uint32
  result += 2 // Account length (uint_16)
  result += uint32(len(r.Account)) // uint_8 array
  result += 2 // Thing length (uint_16)
  result += uint32(len(r.Thing)) // uint_8 array
  result += 2 // Items length (uint_16)
  for idx := range r.Items {
    result += r.Items[idx].Size()
  }
  return result
}

func (r *ReadRequest) Unpack(buf *bytes.Buffer) error {
  var AccountLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &AccountLen); err != nil {
    return err
  }
  r.Account = string(buf.Next(int(AccountLen)))
  if len(r.Account) != int(AccountLen) {
    return errors.New("string byte mismatch")
  }
  var ThingLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &ThingLen); err != nil {
    return err
  }
  r.Thing = string(buf.Next(int(ThingLen)))
  if len(r.Thing) != int(ThingLen) {
    return errors.New("string byte mismatch")
  }
  var ItemsLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &ItemsLen); err != nil {
    return err
  }
  r.Items = make([]ReadItem, ItemsLen)
  for idx := range r.Items {
    if err := r.Items[idx].Unpack(buf); err != nil {
      return err
    }
  }
  return nil
}

func (r *ReadRequest) Pack(buf *bytes.Buffer) error {
  if len(r.Account) > 65535 {
    return errors.New("max_length overflow in field Account")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(r.Account))); err != nil {
    return err
  }
  if _, err := buf.WriteString(r.Account); err != nil {
    return err
  }
  if len(r.Thing) > 65535 {
    return errors.New("max_length overflow in field Thing")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(r.Thing))); err != nil {
    return err
  }
  if _, err := buf.WriteString(r.Thing); err != nil {
    return err
  }
  if len(r.Items) > 65535 {
    return errors.New("max_length overflow in field Items")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(r.Items))); err != nil {
    return err
  }
  for idx := range r.Items {
    if err := r.Items[idx].Pack(buf); err != nil {
      return err
    }
  }
  return nil
}

func (r *ReadRequest) String() string {
  return fmt.Sprint("Account: {", r.Account, "} ",
    "Thing: {", r.Thing, "} ",
    "Items: {", r.Items, "}")
}


// ENUM ReadStatus
type ReadStatus uint8

const (
  ReadStatus_Unchanged ReadStatus = iota
  ReadStatus_Changed                    
  ReadStatus_NotFound                   
  ReadStatus_PermissionDenied           
)

// STRUCTURE ResponseDoc
type ResponseDoc struct {
  Status ReadStatus
  Doc Doc
}

func (r *ResponseDoc) Size() uint32 {
  var result uint32
  result += 1 // Status ReadStatus
  result += r.Doc.Size()
  return result
}

func (r *ResponseDoc) Unpack(buf *bytes.Buffer) error {
  if err := binary.Read(buf, binary.LittleEndian, &r.Status); err != nil {
    return err
  }
  if err := r.Doc.Unpack(buf); err != nil {
    return err
  }
  return nil
}

func (r *ResponseDoc) Pack(buf *bytes.Buffer) error {
  if err := binary.Write(buf, binary.LittleEndian, r.Status); err != nil {
    return err
  }
  if err := r.Doc.Pack(buf); err != nil {
    return err
  }
  return nil
}

func (r *ResponseDoc) String() string {
  return fmt.Sprint("Status: {", r.Status, "} ",
    "Doc: {", r.Doc, "}")
}


// STRUCTURE ReadResponse
type ReadResponse struct {
  Items []ResponseDoc
}

func (r *ReadResponse) Size() uint32 {
  var result uint32
  result += 2 // Items length (uint_16)
  for idx := range r.Items {
    result += r.Items[idx].Size()
  }
  return result
}

func (r *ReadResponse) Unpack(buf *bytes.Buffer) error {
  var ItemsLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &ItemsLen); err != nil {
    return err
  }
  r.Items = make([]ResponseDoc, ItemsLen)
  for idx := range r.Items {
    if err := r.Items[idx].Unpack(buf); err != nil {
      return err
    }
  }
  return nil
}

func (r *ReadResponse) Pack(buf *bytes.Buffer) error {
  if len(r.Items) > 65535 {
    return errors.New("max_length overflow in field Items")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(r.Items))); err != nil {
    return err
  }
  for idx := range r.Items {
    if err := r.Items[idx].Pack(buf); err != nil {
      return err
    }
  }
  return nil
}

func (r *ReadResponse) String() string {
  return fmt.Sprint("Items: {", r.Items, "}")
}


// STRUCTURE DeleteRequest
type DeleteRequest struct {
  Account string
  Thing string
  DocName string
}

func (d *DeleteRequest) Size() uint32 {
  var result uint32
  result += 2 // Account length (uint_16)
  result += uint32(len(d.Account)) // uint_8 array
  result += 2 // Thing length (uint_16)
  result += uint32(len(d.Thing)) // uint_8 array
  result += 2 // DocName length (uint_16)
  result += uint32(len(d.DocName)) // uint_8 array
  return result
}

func (d *DeleteRequest) Unpack(buf *bytes.Buffer) error {
  var AccountLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &AccountLen); err != nil {
    return err
  }
  d.Account = string(buf.Next(int(AccountLen)))
  if len(d.Account) != int(AccountLen) {
    return errors.New("string byte mismatch")
  }
  var ThingLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &ThingLen); err != nil {
    return err
  }
  d.Thing = string(buf.Next(int(ThingLen)))
  if len(d.Thing) != int(ThingLen) {
    return errors.New("string byte mismatch")
  }
  var DocNameLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &DocNameLen); err != nil {
    return err
  }
  d.DocName = string(buf.Next(int(DocNameLen)))
  if len(d.DocName) != int(DocNameLen) {
    return errors.New("string byte mismatch")
  }
  return nil
}

func (d *DeleteRequest) Pack(buf *bytes.Buffer) error {
  if len(d.Account) > 65535 {
    return errors.New("max_length overflow in field Account")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(d.Account))); err != nil {
    return err
  }
  if _, err := buf.WriteString(d.Account); err != nil {
    return err
  }
  if len(d.Thing) > 65535 {
    return errors.New("max_length overflow in field Thing")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(d.Thing))); err != nil {
    return err
  }
  if _, err := buf.WriteString(d.Thing); err != nil {
    return err
  }
  if len(d.DocName) > 65535 {
    return errors.New("max_length overflow in field DocName")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(d.DocName))); err != nil {
    return err
  }
  if _, err := buf.WriteString(d.DocName); err != nil {
    return err
  }
  return nil
}

func (d *DeleteRequest) String() string {
  return fmt.Sprint("Account: {", d.Account, "} ",
    "Thing: {", d.Thing, "} ",
    "DocName: {", d.DocName, "}")
}


// UNION DocRequest
type DocRequestTag uint8

const (
  DocRequestTag_Write     DocRequestTag = iota // 0
  DocRequestTag_Read                           // 1
  DocRequestTag_DeleteReq                      // 2
  DocRequestTag_User                           // 3
  DocRequestTag_Thing                          // 4
  DocRequestTag_INVALID   DocRequestTag = 255
)

type DocRequest struct {
  tag *DocRequestTag
  value clad.Struct
}

func (m *DocRequest) Tag() DocRequestTag {
  if m.tag == nil {
    return DocRequestTag_INVALID
  }
  return *m.tag
}

func (m *DocRequest) Size() uint32 {
  if m.tag == nil || *m.tag == DocRequestTag_INVALID {
    return 1
  }
  return 1 + m.value.Size()
}

func (m *DocRequest) Pack(buf *bytes.Buffer) error {
  tag := DocRequestTag_INVALID
  if m.tag != nil {
    tag = *m.tag
  }
  if err := binary.Write(buf, binary.LittleEndian, tag); err != nil {
    return err
  }
  if tag == DocRequestTag_INVALID {
    return nil
  }
  return m.value.Pack(buf)
}

func (m *DocRequest) unpackStruct(tag DocRequestTag, buf *bytes.Buffer) (clad.Struct, error) {
  switch tag {
  case DocRequestTag_Write:
    var ret WriteRequest
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocRequestTag_Read:
    var ret ReadRequest
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocRequestTag_DeleteReq:
    var ret DeleteRequest
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocRequestTag_User:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocRequestTag_Thing:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  default:
    return nil, errors.New("invalid tag to unpackStruct")
  }
}

func (m *DocRequest) Unpack(buf *bytes.Buffer) error {
  tag := DocRequestTag_INVALID
  if err := binary.Read(buf, binary.LittleEndian, &tag); err != nil {
    return err
  }
  m.tag = &tag
  if tag == DocRequestTag_INVALID {
    m.value = nil
    return nil
  }
  val, err := m.unpackStruct(tag, buf)
  if err != nil {
    *m.tag = DocRequestTag_INVALID
    return err
  }
  m.value = val
  return nil
}

func (t DocRequestTag) String() string {
  switch t {
  case DocRequestTag_Write:
    return "Write"
  case DocRequestTag_Read:
    return "Read"
  case DocRequestTag_DeleteReq:
    return "DeleteReq"
  case DocRequestTag_User:
    return "User"
  case DocRequestTag_Thing:
    return "Thing"
  default:
    return "INVALID"
  }
}

func (m *DocRequest) String() string {
  if m.tag == nil {
    return "nil"
  }
  if *m.tag == DocRequestTag_INVALID {
    return "INVALID"
  }
  return fmt.Sprintf("%s: {%s}", *m.tag, m.value)
}

func (m *DocRequest) GetWrite() *WriteRequest {
  if m.tag == nil || *m.tag != DocRequestTag_Write {
    return nil
  }
  return m.value.(*WriteRequest)
}

func (m *DocRequest) SetWrite(value *WriteRequest) {
  newTag := DocRequestTag_Write
  m.tag = &newTag
  m.value = value
}

func NewDocRequestWithWrite(value *WriteRequest) *DocRequest {
  var ret DocRequest
  ret.SetWrite(value)
  return &ret
}

func (m *DocRequest) GetRead() *ReadRequest {
  if m.tag == nil || *m.tag != DocRequestTag_Read {
    return nil
  }
  return m.value.(*ReadRequest)
}

func (m *DocRequest) SetRead(value *ReadRequest) {
  newTag := DocRequestTag_Read
  m.tag = &newTag
  m.value = value
}

func NewDocRequestWithRead(value *ReadRequest) *DocRequest {
  var ret DocRequest
  ret.SetRead(value)
  return &ret
}

func (m *DocRequest) GetDeleteReq() *DeleteRequest {
  if m.tag == nil || *m.tag != DocRequestTag_DeleteReq {
    return nil
  }
  return m.value.(*DeleteRequest)
}

func (m *DocRequest) SetDeleteReq(value *DeleteRequest) {
  newTag := DocRequestTag_DeleteReq
  m.tag = &newTag
  m.value = value
}

func NewDocRequestWithDeleteReq(value *DeleteRequest) *DocRequest {
  var ret DocRequest
  ret.SetDeleteReq(value)
  return &ret
}

func (m *DocRequest) GetUser() *Void {
  if m.tag == nil || *m.tag != DocRequestTag_User {
    return nil
  }
  return m.value.(*Void)
}

func (m *DocRequest) SetUser(value *Void) {
  newTag := DocRequestTag_User
  m.tag = &newTag
  m.value = value
}

func NewDocRequestWithUser(value *Void) *DocRequest {
  var ret DocRequest
  ret.SetUser(value)
  return &ret
}

func (m *DocRequest) GetThing() *Void {
  if m.tag == nil || *m.tag != DocRequestTag_Thing {
    return nil
  }
  return m.value.(*Void)
}

func (m *DocRequest) SetThing(value *Void) {
  newTag := DocRequestTag_Thing
  m.tag = &newTag
  m.value = value
}

func NewDocRequestWithThing(value *Void) *DocRequest {
  var ret DocRequest
  ret.SetThing(value)
  return &ret
}


// STRUCTURE ErrorResponse
type ErrorResponse struct {
  Err DocError
}

func (e *ErrorResponse) Size() uint32 {
  var result uint32
  result += 1 // Err DocError
  return result
}

func (e *ErrorResponse) Unpack(buf *bytes.Buffer) error {
  if err := binary.Read(buf, binary.LittleEndian, &e.Err); err != nil {
    return err
  }
  return nil
}

func (e *ErrorResponse) Pack(buf *bytes.Buffer) error {
  if err := binary.Write(buf, binary.LittleEndian, e.Err); err != nil {
    return err
  }
  return nil
}

func (e *ErrorResponse) String() string {
  return fmt.Sprint("Err: {", e.Err, "}")
}


// STRUCTURE UserResponse
type UserResponse struct {
  UserId string
}

func (u *UserResponse) Size() uint32 {
  var result uint32
  result += 1 // UserId length (uint_8)
  result += uint32(len(u.UserId)) // uint_8 array
  return result
}

func (u *UserResponse) Unpack(buf *bytes.Buffer) error {
  var UserIdLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &UserIdLen); err != nil {
    return err
  }
  u.UserId = string(buf.Next(int(UserIdLen)))
  if len(u.UserId) != int(UserIdLen) {
    return errors.New("string byte mismatch")
  }
  return nil
}

func (u *UserResponse) Pack(buf *bytes.Buffer) error {
  if len(u.UserId) > 255 {
    return errors.New("max_length overflow in field UserId")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint8(len(u.UserId))); err != nil {
    return err
  }
  if _, err := buf.WriteString(u.UserId); err != nil {
    return err
  }
  return nil
}

func (u *UserResponse) String() string {
  return fmt.Sprint("UserId: {", u.UserId, "}")
}


// STRUCTURE ThingResponse
type ThingResponse struct {
  ThingName string
}

func (t *ThingResponse) Size() uint32 {
  var result uint32
  result += 1 // ThingName length (uint_8)
  result += uint32(len(t.ThingName)) // uint_8 array
  return result
}

func (t *ThingResponse) Unpack(buf *bytes.Buffer) error {
  var ThingNameLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &ThingNameLen); err != nil {
    return err
  }
  t.ThingName = string(buf.Next(int(ThingNameLen)))
  if len(t.ThingName) != int(ThingNameLen) {
    return errors.New("string byte mismatch")
  }
  return nil
}

func (t *ThingResponse) Pack(buf *bytes.Buffer) error {
  if len(t.ThingName) > 255 {
    return errors.New("max_length overflow in field ThingName")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint8(len(t.ThingName))); err != nil {
    return err
  }
  if _, err := buf.WriteString(t.ThingName); err != nil {
    return err
  }
  return nil
}

func (t *ThingResponse) String() string {
  return fmt.Sprint("ThingName: {", t.ThingName, "}")
}


// UNION DocResponse
type DocResponseTag uint8

const (
  DocResponseTag_Write      DocResponseTag = iota // 0
  DocResponseTag_Read                             // 1
  DocResponseTag_DeleteResp                       // 2
  DocResponseTag_Err                              // 3
  DocResponseTag_User                             // 4
  DocResponseTag_Thing                            // 5
  DocResponseTag_INVALID    DocResponseTag = 255
)

type DocResponse struct {
  tag *DocResponseTag
  value clad.Struct
}

func (m *DocResponse) Tag() DocResponseTag {
  if m.tag == nil {
    return DocResponseTag_INVALID
  }
  return *m.tag
}

func (m *DocResponse) Size() uint32 {
  if m.tag == nil || *m.tag == DocResponseTag_INVALID {
    return 1
  }
  return 1 + m.value.Size()
}

func (m *DocResponse) Pack(buf *bytes.Buffer) error {
  tag := DocResponseTag_INVALID
  if m.tag != nil {
    tag = *m.tag
  }
  if err := binary.Write(buf, binary.LittleEndian, tag); err != nil {
    return err
  }
  if tag == DocResponseTag_INVALID {
    return nil
  }
  return m.value.Pack(buf)
}

func (m *DocResponse) unpackStruct(tag DocResponseTag, buf *bytes.Buffer) (clad.Struct, error) {
  switch tag {
  case DocResponseTag_Write:
    var ret WriteResponse
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocResponseTag_Read:
    var ret ReadResponse
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocResponseTag_DeleteResp:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocResponseTag_Err:
    var ret ErrorResponse
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocResponseTag_User:
    var ret UserResponse
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case DocResponseTag_Thing:
    var ret ThingResponse
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  default:
    return nil, errors.New("invalid tag to unpackStruct")
  }
}

func (m *DocResponse) Unpack(buf *bytes.Buffer) error {
  tag := DocResponseTag_INVALID
  if err := binary.Read(buf, binary.LittleEndian, &tag); err != nil {
    return err
  }
  m.tag = &tag
  if tag == DocResponseTag_INVALID {
    m.value = nil
    return nil
  }
  val, err := m.unpackStruct(tag, buf)
  if err != nil {
    *m.tag = DocResponseTag_INVALID
    return err
  }
  m.value = val
  return nil
}

func (t DocResponseTag) String() string {
  switch t {
  case DocResponseTag_Write:
    return "Write"
  case DocResponseTag_Read:
    return "Read"
  case DocResponseTag_DeleteResp:
    return "DeleteResp"
  case DocResponseTag_Err:
    return "Err"
  case DocResponseTag_User:
    return "User"
  case DocResponseTag_Thing:
    return "Thing"
  default:
    return "INVALID"
  }
}

func (m *DocResponse) String() string {
  if m.tag == nil {
    return "nil"
  }
  if *m.tag == DocResponseTag_INVALID {
    return "INVALID"
  }
  return fmt.Sprintf("%s: {%s}", *m.tag, m.value)
}

func (m *DocResponse) GetWrite() *WriteResponse {
  if m.tag == nil || *m.tag != DocResponseTag_Write {
    return nil
  }
  return m.value.(*WriteResponse)
}

func (m *DocResponse) SetWrite(value *WriteResponse) {
  newTag := DocResponseTag_Write
  m.tag = &newTag
  m.value = value
}

func NewDocResponseWithWrite(value *WriteResponse) *DocResponse {
  var ret DocResponse
  ret.SetWrite(value)
  return &ret
}

func (m *DocResponse) GetRead() *ReadResponse {
  if m.tag == nil || *m.tag != DocResponseTag_Read {
    return nil
  }
  return m.value.(*ReadResponse)
}

func (m *DocResponse) SetRead(value *ReadResponse) {
  newTag := DocResponseTag_Read
  m.tag = &newTag
  m.value = value
}

func NewDocResponseWithRead(value *ReadResponse) *DocResponse {
  var ret DocResponse
  ret.SetRead(value)
  return &ret
}

func (m *DocResponse) GetDeleteResp() *Void {
  if m.tag == nil || *m.tag != DocResponseTag_DeleteResp {
    return nil
  }
  return m.value.(*Void)
}

func (m *DocResponse) SetDeleteResp(value *Void) {
  newTag := DocResponseTag_DeleteResp
  m.tag = &newTag
  m.value = value
}

func NewDocResponseWithDeleteResp(value *Void) *DocResponse {
  var ret DocResponse
  ret.SetDeleteResp(value)
  return &ret
}

func (m *DocResponse) GetErr() *ErrorResponse {
  if m.tag == nil || *m.tag != DocResponseTag_Err {
    return nil
  }
  return m.value.(*ErrorResponse)
}

func (m *DocResponse) SetErr(value *ErrorResponse) {
  newTag := DocResponseTag_Err
  m.tag = &newTag
  m.value = value
}

func NewDocResponseWithErr(value *ErrorResponse) *DocResponse {
  var ret DocResponse
  ret.SetErr(value)
  return &ret
}

func (m *DocResponse) GetUser() *UserResponse {
  if m.tag == nil || *m.tag != DocResponseTag_User {
    return nil
  }
  return m.value.(*UserResponse)
}

func (m *DocResponse) SetUser(value *UserResponse) {
  newTag := DocResponseTag_User
  m.tag = &newTag
  m.value = value
}

func NewDocResponseWithUser(value *UserResponse) *DocResponse {
  var ret DocResponse
  ret.SetUser(value)
  return &ret
}

func (m *DocResponse) GetThing() *ThingResponse {
  if m.tag == nil || *m.tag != DocResponseTag_Thing {
    return nil
  }
  return m.value.(*ThingResponse)
}

func (m *DocResponse) SetThing(value *ThingResponse) {
  newTag := DocResponseTag_Thing
  m.tag = &newTag
  m.value = value
}

func NewDocResponseWithThing(value *ThingResponse) *DocResponse {
  var ret DocResponse
  ret.SetThing(value)
  return &ret
}


