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

package cloud

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

// ENUM StreamType
type StreamType uint8

const (
  StreamType_Normal StreamType = iota
  StreamType_Blackjack               
  StreamType_KnowledgeGraph          
)

// ENUM ErrorType
type ErrorType uint8

const (
  ErrorType_Server ErrorType = iota
  ErrorType_Timeout                
  ErrorType_Json                   
  ErrorType_InvalidConfig          
  ErrorType_Connecting             
  ErrorType_NewStream              
  ErrorType_Token                  
  ErrorType_TLS                    
  ErrorType_Connectivity           
)

// ENUM ConnectionCode
type ConnectionCode uint8

const (
  ConnectionCode_Available ConnectionCode = iota
  ConnectionCode_Connectivity                   
  ConnectionCode_Tls                            
  ConnectionCode_Auth                           
  ConnectionCode_Bandwidth                      
)

// STRUCTURE StreamOpen
type StreamOpen struct {
  Session string
}

func (s *StreamOpen) Size() uint32 {
  var result uint32
  result += 1 // Session length (uint_8)
  result += uint32(len(s.Session)) // uint_8 array
  return result
}

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

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

func (s *StreamOpen) String() string {
  return fmt.Sprint("Session: {", s.Session, "}")
}


// STRUCTURE Hotword
type Hotword struct {
  Mode StreamType
  Locale string
  Timezone string
  NoLogging bool
}

func (h *Hotword) Size() uint32 {
  var result uint32
  result += 1 // Mode StreamType
  result += 1 // Locale length (uint_8)
  result += uint32(len(h.Locale)) // uint_8 array
  result += 1 // Timezone length (uint_8)
  result += uint32(len(h.Timezone)) // uint_8 array
  result += 1 // NoLogging bool
  return result
}

func (h *Hotword) Unpack(buf *bytes.Buffer) error {
  if err := binary.Read(buf, binary.LittleEndian, &h.Mode); err != nil {
    return err
  }
  var LocaleLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &LocaleLen); err != nil {
    return err
  }
  h.Locale = string(buf.Next(int(LocaleLen)))
  if len(h.Locale) != int(LocaleLen) {
    return errors.New("string byte mismatch")
  }
  var TimezoneLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &TimezoneLen); err != nil {
    return err
  }
  h.Timezone = string(buf.Next(int(TimezoneLen)))
  if len(h.Timezone) != int(TimezoneLen) {
    return errors.New("string byte mismatch")
  }
  if err := binary.Read(buf, binary.LittleEndian, &h.NoLogging); err != nil {
    return err
  }
  return nil
}

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

func (h *Hotword) String() string {
  return fmt.Sprint("Mode: {", h.Mode, "} ",
    "Locale: {", h.Locale, "} ",
    "Timezone: {", h.Timezone, "} ",
    "NoLogging: {", h.NoLogging, "}")
}


// STRUCTURE Filename
type Filename struct {
  File string
}

func (f *Filename) Size() uint32 {
  var result uint32
  result += 1 // File length (uint_8)
  result += uint32(len(f.File)) // uint_8 array
  return result
}

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

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

func (f *Filename) String() string {
  return fmt.Sprint("File: {", f.File, "}")
}


// STRUCTURE AudioData
type AudioData struct {
  Data []int16
}

func (a *AudioData) Size() uint32 {
  var result uint32
  result += 2 // Data length (uint_16)
  result += uint32(len(a.Data)) * 2 // int_16 array
  return result
}

func (a *AudioData) Unpack(buf *bytes.Buffer) error {
  var DataLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &DataLen); err != nil {
    return err
  }
  a.Data = make([]int16, DataLen)
  if err := binary.Read(buf, binary.LittleEndian, &a.Data); err != nil {
    return err
  }
  return nil
}

func (a *AudioData) Pack(buf *bytes.Buffer) error {
  if len(a.Data) > 65535 {
    return errors.New("max_length overflow in field Data")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(a.Data))); err != nil {
    return err
  }
  if err := binary.Write(buf, binary.LittleEndian, a.Data); err != nil {
    return err
  }
  return nil
}

func (a *AudioData) String() string {
  return fmt.Sprint("Data: {", a.Data, "}")
}


// STRUCTURE IntentResult
type IntentResult struct {
  Intent string
  Parameters string
  Metadata string
}

func (i *IntentResult) Size() uint32 {
  var result uint32
  result += 1 // Intent length (uint_8)
  result += uint32(len(i.Intent)) // uint_8 array
  result += 2 // Parameters length (uint_16)
  result += uint32(len(i.Parameters)) // uint_8 array
  result += 2 // Metadata length (uint_16)
  result += uint32(len(i.Metadata)) // uint_8 array
  return result
}

func (i *IntentResult) Unpack(buf *bytes.Buffer) error {
  var IntentLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &IntentLen); err != nil {
    return err
  }
  i.Intent = string(buf.Next(int(IntentLen)))
  if len(i.Intent) != int(IntentLen) {
    return errors.New("string byte mismatch")
  }
  var ParametersLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &ParametersLen); err != nil {
    return err
  }
  i.Parameters = string(buf.Next(int(ParametersLen)))
  if len(i.Parameters) != int(ParametersLen) {
    return errors.New("string byte mismatch")
  }
  var MetadataLen uint16
  if err := binary.Read(buf, binary.LittleEndian, &MetadataLen); err != nil {
    return err
  }
  i.Metadata = string(buf.Next(int(MetadataLen)))
  if len(i.Metadata) != int(MetadataLen) {
    return errors.New("string byte mismatch")
  }
  return nil
}

func (i *IntentResult) Pack(buf *bytes.Buffer) error {
  if len(i.Intent) > 255 {
    return errors.New("max_length overflow in field Intent")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint8(len(i.Intent))); err != nil {
    return err
  }
  if _, err := buf.WriteString(i.Intent); err != nil {
    return err
  }
  if len(i.Parameters) > 65535 {
    return errors.New("max_length overflow in field Parameters")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(i.Parameters))); err != nil {
    return err
  }
  if _, err := buf.WriteString(i.Parameters); err != nil {
    return err
  }
  if len(i.Metadata) > 65535 {
    return errors.New("max_length overflow in field Metadata")
  }
  if err := binary.Write(buf, binary.LittleEndian, uint16(len(i.Metadata))); err != nil {
    return err
  }
  if _, err := buf.WriteString(i.Metadata); err != nil {
    return err
  }
  return nil
}

func (i *IntentResult) String() string {
  return fmt.Sprint("Intent: {", i.Intent, "} ",
    "Parameters: {", i.Parameters, "} ",
    "Metadata: {", i.Metadata, "}")
}


// STRUCTURE IntentError
type IntentError struct {
  Error ErrorType
  Extra string
}

func (i *IntentError) Size() uint32 {
  var result uint32
  result += 1 // Error ErrorType
  result += 1 // Extra length (uint_8)
  result += uint32(len(i.Extra)) // uint_8 array
  return result
}

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

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

func (i *IntentError) String() string {
  return fmt.Sprint("Error: {", i.Error, "} ",
    "Extra: {", i.Extra, "}")
}


// STRUCTURE ConnectionResult
type ConnectionResult struct {
  Code ConnectionCode
  Status string
  NumPackets uint8
  ExpectedPackets uint8
}

func (c *ConnectionResult) Size() uint32 {
  var result uint32
  result += 1 // Code ConnectionCode
  result += 1 // Status length (uint_8)
  result += uint32(len(c.Status)) // uint_8 array
  result += 1 // NumPackets uint_8
  result += 1 // ExpectedPackets uint_8
  return result
}

func (c *ConnectionResult) Unpack(buf *bytes.Buffer) error {
  if err := binary.Read(buf, binary.LittleEndian, &c.Code); err != nil {
    return err
  }
  var StatusLen uint8
  if err := binary.Read(buf, binary.LittleEndian, &StatusLen); err != nil {
    return err
  }
  c.Status = string(buf.Next(int(StatusLen)))
  if len(c.Status) != int(StatusLen) {
    return errors.New("string byte mismatch")
  }
  if err := binary.Read(buf, binary.LittleEndian, &c.NumPackets); err != nil {
    return err
  }
  if err := binary.Read(buf, binary.LittleEndian, &c.ExpectedPackets); err != nil {
    return err
  }
  return nil
}

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

func (c *ConnectionResult) String() string {
  return fmt.Sprint("Code: {", c.Code, "} ",
    "Status: {", c.Status, "} ",
    "NumPackets: {", c.NumPackets, "} ",
    "ExpectedPackets: {", c.ExpectedPackets, "}")
}


// UNION Message
type MessageTag uint8

const (
  MessageTag_Hotword          MessageTag = iota // 0
  MessageTag_Audio                              // 1
  MessageTag_AudioDone                          // 2
  MessageTag_ConnectionCheck                    // 3
  MessageTag_StopSignal                         // 4
  MessageTag_TestStarted                        // 5
  MessageTag_StreamTimeout                      // 6
  MessageTag_ConnectionResult                   // 7
  MessageTag_DebugFile                          // 8
  MessageTag_Result                             // 9
  MessageTag_Error                              // 10
  MessageTag_StreamOpen                         // 11
  MessageTag_INVALID          MessageTag = 255
)

type Message struct {
  tag *MessageTag
  value clad.Struct
}

func (m *Message) Tag() MessageTag {
  if m.tag == nil {
    return MessageTag_INVALID
  }
  return *m.tag
}

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

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

func (m *Message) unpackStruct(tag MessageTag, buf *bytes.Buffer) (clad.Struct, error) {
  switch tag {
  case MessageTag_Hotword:
    var ret Hotword
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_Audio:
    var ret AudioData
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_AudioDone:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_ConnectionCheck:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_StopSignal:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_TestStarted:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_StreamTimeout:
    var ret Void
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_ConnectionResult:
    var ret ConnectionResult
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_DebugFile:
    var ret Filename
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_Result:
    var ret IntentResult
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_Error:
    var ret IntentError
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  case MessageTag_StreamOpen:
    var ret StreamOpen
    if err := ret.Unpack(buf); err != nil {
      return nil, err
    }
    return &ret, nil
  default:
    return nil, errors.New("invalid tag to unpackStruct")
  }
}

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

func (t MessageTag) String() string {
  switch t {
  case MessageTag_Hotword:
    return "Hotword"
  case MessageTag_Audio:
    return "Audio"
  case MessageTag_AudioDone:
    return "AudioDone"
  case MessageTag_ConnectionCheck:
    return "ConnectionCheck"
  case MessageTag_StopSignal:
    return "StopSignal"
  case MessageTag_TestStarted:
    return "TestStarted"
  case MessageTag_StreamTimeout:
    return "StreamTimeout"
  case MessageTag_ConnectionResult:
    return "ConnectionResult"
  case MessageTag_DebugFile:
    return "DebugFile"
  case MessageTag_Result:
    return "Result"
  case MessageTag_Error:
    return "Error"
  case MessageTag_StreamOpen:
    return "StreamOpen"
  default:
    return "INVALID"
  }
}

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

func (m *Message) GetHotword() *Hotword {
  if m.tag == nil || *m.tag != MessageTag_Hotword {
    return nil
  }
  return m.value.(*Hotword)
}

func (m *Message) SetHotword(value *Hotword) {
  newTag := MessageTag_Hotword
  m.tag = &newTag
  m.value = value
}

func NewMessageWithHotword(value *Hotword) *Message {
  var ret Message
  ret.SetHotword(value)
  return &ret
}

func (m *Message) GetAudio() *AudioData {
  if m.tag == nil || *m.tag != MessageTag_Audio {
    return nil
  }
  return m.value.(*AudioData)
}

func (m *Message) SetAudio(value *AudioData) {
  newTag := MessageTag_Audio
  m.tag = &newTag
  m.value = value
}

func NewMessageWithAudio(value *AudioData) *Message {
  var ret Message
  ret.SetAudio(value)
  return &ret
}

func (m *Message) GetAudioDone() *Void {
  if m.tag == nil || *m.tag != MessageTag_AudioDone {
    return nil
  }
  return m.value.(*Void)
}

func (m *Message) SetAudioDone(value *Void) {
  newTag := MessageTag_AudioDone
  m.tag = &newTag
  m.value = value
}

func NewMessageWithAudioDone(value *Void) *Message {
  var ret Message
  ret.SetAudioDone(value)
  return &ret
}

func (m *Message) GetConnectionCheck() *Void {
  if m.tag == nil || *m.tag != MessageTag_ConnectionCheck {
    return nil
  }
  return m.value.(*Void)
}

func (m *Message) SetConnectionCheck(value *Void) {
  newTag := MessageTag_ConnectionCheck
  m.tag = &newTag
  m.value = value
}

func NewMessageWithConnectionCheck(value *Void) *Message {
  var ret Message
  ret.SetConnectionCheck(value)
  return &ret
}

func (m *Message) GetStopSignal() *Void {
  if m.tag == nil || *m.tag != MessageTag_StopSignal {
    return nil
  }
  return m.value.(*Void)
}

func (m *Message) SetStopSignal(value *Void) {
  newTag := MessageTag_StopSignal
  m.tag = &newTag
  m.value = value
}

func NewMessageWithStopSignal(value *Void) *Message {
  var ret Message
  ret.SetStopSignal(value)
  return &ret
}

func (m *Message) GetTestStarted() *Void {
  if m.tag == nil || *m.tag != MessageTag_TestStarted {
    return nil
  }
  return m.value.(*Void)
}

func (m *Message) SetTestStarted(value *Void) {
  newTag := MessageTag_TestStarted
  m.tag = &newTag
  m.value = value
}

func NewMessageWithTestStarted(value *Void) *Message {
  var ret Message
  ret.SetTestStarted(value)
  return &ret
}

func (m *Message) GetStreamTimeout() *Void {
  if m.tag == nil || *m.tag != MessageTag_StreamTimeout {
    return nil
  }
  return m.value.(*Void)
}

func (m *Message) SetStreamTimeout(value *Void) {
  newTag := MessageTag_StreamTimeout
  m.tag = &newTag
  m.value = value
}

func NewMessageWithStreamTimeout(value *Void) *Message {
  var ret Message
  ret.SetStreamTimeout(value)
  return &ret
}

func (m *Message) GetConnectionResult() *ConnectionResult {
  if m.tag == nil || *m.tag != MessageTag_ConnectionResult {
    return nil
  }
  return m.value.(*ConnectionResult)
}

func (m *Message) SetConnectionResult(value *ConnectionResult) {
  newTag := MessageTag_ConnectionResult
  m.tag = &newTag
  m.value = value
}

func NewMessageWithConnectionResult(value *ConnectionResult) *Message {
  var ret Message
  ret.SetConnectionResult(value)
  return &ret
}

func (m *Message) GetDebugFile() *Filename {
  if m.tag == nil || *m.tag != MessageTag_DebugFile {
    return nil
  }
  return m.value.(*Filename)
}

func (m *Message) SetDebugFile(value *Filename) {
  newTag := MessageTag_DebugFile
  m.tag = &newTag
  m.value = value
}

func NewMessageWithDebugFile(value *Filename) *Message {
  var ret Message
  ret.SetDebugFile(value)
  return &ret
}

func (m *Message) GetResult() *IntentResult {
  if m.tag == nil || *m.tag != MessageTag_Result {
    return nil
  }
  return m.value.(*IntentResult)
}

func (m *Message) SetResult(value *IntentResult) {
  newTag := MessageTag_Result
  m.tag = &newTag
  m.value = value
}

func NewMessageWithResult(value *IntentResult) *Message {
  var ret Message
  ret.SetResult(value)
  return &ret
}

func (m *Message) GetError() *IntentError {
  if m.tag == nil || *m.tag != MessageTag_Error {
    return nil
  }
  return m.value.(*IntentError)
}

func (m *Message) SetError(value *IntentError) {
  newTag := MessageTag_Error
  m.tag = &newTag
  m.value = value
}

func NewMessageWithError(value *IntentError) *Message {
  var ret Message
  ret.SetError(value)
  return &ret
}

func (m *Message) GetStreamOpen() *StreamOpen {
  if m.tag == nil || *m.tag != MessageTag_StreamOpen {
    return nil
  }
  return m.value.(*StreamOpen)
}

func (m *Message) SetStreamOpen(value *StreamOpen) {
  newTag := MessageTag_StreamOpen
  m.tag = &newTag
  m.value = value
}

func NewMessageWithStreamOpen(value *StreamOpen) *Message {
  var ret Message
  ret.SetStreamOpen(value)
  return &ret
}


