// Code generated by protoc-gen-go. DO NOT EDIT.
// source: prototype/src/overlays/config.proto

package prototype

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type AudioConfig struct {
	CardName             string   `protobuf:"bytes,1,opt,name=card_name,json=cardName,proto3" json:"card_name,omitempty"`
	CardSettingsFile     string   `protobuf:"bytes,2,opt,name=card_settings_file,json=cardSettingsFile,proto3" json:"card_settings_file,omitempty"`
	DspConfigFile        string   `protobuf:"bytes,3,opt,name=dsp_config_file,json=dspConfigFile,proto3" json:"dsp_config_file,omitempty"`
	UcmConfigFile        string   `protobuf:"bytes,4,opt,name=ucm_config_file,json=ucmConfigFile,proto3" json:"ucm_config_file,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *AudioConfig) Reset()         { *m = AudioConfig{} }
func (m *AudioConfig) String() string { return proto.CompactTextString(m) }
func (*AudioConfig) ProtoMessage()    {}
func (*AudioConfig) Descriptor() ([]byte, []int) {
	return fileDescriptor_6afdcbbf32062cf7, []int{0}
}

func (m *AudioConfig) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_AudioConfig.Unmarshal(m, b)
}
func (m *AudioConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_AudioConfig.Marshal(b, m, deterministic)
}
func (m *AudioConfig) XXX_Merge(src proto.Message) {
	xxx_messageInfo_AudioConfig.Merge(m, src)
}
func (m *AudioConfig) XXX_Size() int {
	return xxx_messageInfo_AudioConfig.Size(m)
}
func (m *AudioConfig) XXX_DiscardUnknown() {
	xxx_messageInfo_AudioConfig.DiscardUnknown(m)
}

var xxx_messageInfo_AudioConfig proto.InternalMessageInfo

func (m *AudioConfig) GetCardName() string {
	if m != nil {
		return m.CardName
	}
	return ""
}

func (m *AudioConfig) GetCardSettingsFile() string {
	if m != nil {
		return m.CardSettingsFile
	}
	return ""
}

func (m *AudioConfig) GetDspConfigFile() string {
	if m != nil {
		return m.DspConfigFile
	}
	return ""
}

func (m *AudioConfig) GetUcmConfigFile() string {
	if m != nil {
		return m.UcmConfigFile
	}
	return ""
}

type OverlayConfig struct {
	AudioConfig          *AudioConfig     `protobuf:"bytes,1,opt,name=audio_config,json=audioConfig,proto3" json:"audio_config,omitempty"`
	Platform2Config      *Platform2Config `protobuf:"bytes,2,opt,name=platform2_config,json=platform2Config,proto3" json:"platform2_config,omitempty"`
	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
	XXX_unrecognized     []byte           `json:"-"`
	XXX_sizecache        int32            `json:"-"`
}

func (m *OverlayConfig) Reset()         { *m = OverlayConfig{} }
func (m *OverlayConfig) String() string { return proto.CompactTextString(m) }
func (*OverlayConfig) ProtoMessage()    {}
func (*OverlayConfig) Descriptor() ([]byte, []int) {
	return fileDescriptor_6afdcbbf32062cf7, []int{1}
}

func (m *OverlayConfig) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_OverlayConfig.Unmarshal(m, b)
}
func (m *OverlayConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_OverlayConfig.Marshal(b, m, deterministic)
}
func (m *OverlayConfig) XXX_Merge(src proto.Message) {
	xxx_messageInfo_OverlayConfig.Merge(m, src)
}
func (m *OverlayConfig) XXX_Size() int {
	return xxx_messageInfo_OverlayConfig.Size(m)
}
func (m *OverlayConfig) XXX_DiscardUnknown() {
	xxx_messageInfo_OverlayConfig.DiscardUnknown(m)
}

var xxx_messageInfo_OverlayConfig proto.InternalMessageInfo

func (m *OverlayConfig) GetAudioConfig() *AudioConfig {
	if m != nil {
		return m.AudioConfig
	}
	return nil
}

func (m *OverlayConfig) GetPlatform2Config() *Platform2Config {
	if m != nil {
		return m.Platform2Config
	}
	return nil
}

func init() {
	proto.RegisterType((*AudioConfig)(nil), "prototype.AudioConfig")
	proto.RegisterType((*OverlayConfig)(nil), "prototype.OverlayConfig")
}

func init() {
	proto.RegisterFile("prototype/src/overlays/config.proto", fileDescriptor_6afdcbbf32062cf7)
}

var fileDescriptor_6afdcbbf32062cf7 = []byte{
	// 281 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xc1, 0x4b, 0xc3, 0x30,
	0x14, 0xc6, 0xe9, 0x14, 0x71, 0xa9, 0x63, 0x23, 0x07, 0x19, 0xf3, 0x22, 0x53, 0xc4, 0x83, 0x24,
	0xb0, 0xe1, 0xc1, 0xa3, 0x8a, 0x1e, 0x55, 0xe6, 0xcd, 0x4b, 0x89, 0x69, 0x1a, 0x03, 0x4d, 0x5f,
	0x48, 0x52, 0x61, 0x7f, 0x86, 0xff, 0x85, 0x7f, 0xa6, 0x34, 0x69, 0x6b, 0x7b, 0x6b, 0xdf, 0xf7,
	0xfb, 0xde, 0xfb, 0xbe, 0xa0, 0x0b, 0x63, 0xc1, 0x83, 0xdf, 0x1b, 0x41, 0x9d, 0xe5, 0x14, 0xbe,
	0x85, 0x2d, 0xd9, 0xde, 0x51, 0x0e, 0x55, 0xa1, 0x24, 0x09, 0x2a, 0x9e, 0xf6, 0xd0, 0xea, 0x72,
	0xcc, 0x9b, 0x92, 0xf9, 0x02, 0xac, 0xde, 0x8c, 0x0c, 0xeb, 0xdf, 0x04, 0xa5, 0xf7, 0x75, 0xae,
	0xe0, 0x31, 0x4c, 0xf1, 0x19, 0x9a, 0x72, 0x66, 0xf3, 0xac, 0x62, 0x5a, 0x2c, 0x93, 0xf3, 0xe4,
	0x7a, 0xba, 0x3b, 0x6e, 0x06, 0x2f, 0x4c, 0x0b, 0x7c, 0x83, 0x70, 0x10, 0x9d, 0xf0, 0x5e, 0x55,
	0xd2, 0x65, 0x85, 0x2a, 0xc5, 0x72, 0x12, 0xa8, 0x45, 0xa3, 0xbc, 0xb7, 0xc2, 0xb3, 0x2a, 0x05,
	0xbe, 0x42, 0xf3, 0xdc, 0x99, 0x2c, 0x9e, 0x8b, 0xe8, 0x41, 0x40, 0x67, 0xb9, 0x33, 0xf1, 0x5c,
	0xc7, 0xd5, 0x5c, 0x8f, 0xb8, 0xc3, 0xc8, 0xd5, 0x5c, 0xff, 0x73, 0xeb, 0x9f, 0x04, 0xcd, 0x5e,
	0x63, 0xeb, 0x36, 0xec, 0x1d, 0x3a, 0x61, 0x4d, 0xf6, 0xd6, 0x1b, 0xf2, 0xa6, 0x9b, 0x53, 0xd2,
	0x37, 0x27, 0x83, 0x6a, 0xbb, 0x94, 0x0d, 0x7a, 0x3e, 0xa1, 0x45, 0xff, 0x22, 0x9d, 0x7d, 0x12,
	0xec, 0xab, 0x81, 0xfd, 0xad, 0x43, 0xda, 0x15, 0x73, 0x33, 0x1e, 0x3c, 0xdc, 0x7e, 0x6c, 0x25,
	0x10, 0xfe, 0x65, 0x41, 0xab, 0x5a, 0x13, 0xb0, 0x92, 0x76, 0x3f, 0xe0, 0xa8, 0xaa, 0x0a, 0xcb,
	0x68, 0x58, 0x47, 0x25, 0xd0, 0x7e, 0xef, 0xe7, 0x51, 0xf8, 0xdc, 0xfe, 0x05, 0x00, 0x00, 0xff,
	0xff, 0x1b, 0x4d, 0x6e, 0xc4, 0xd4, 0x01, 0x00, 0x00,
}
