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

package config

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.ProtoPackageIsVersion2 // please upgrade the proto package

type Switch_Connector int32

const (
	Switch_CONNECTOR_INVALID Switch_Connector = 0
	Switch_CONNECTOR_M6220   Switch_Connector = 1
	Switch_CONNECTOR_ARISTA  Switch_Connector = 2
)

var Switch_Connector_name = map[int32]string{
	0: "CONNECTOR_INVALID",
	1: "CONNECTOR_M6220",
	2: "CONNECTOR_ARISTA",
}

var Switch_Connector_value = map[string]int32{
	"CONNECTOR_INVALID": 0,
	"CONNECTOR_M6220":   1,
	"CONNECTOR_ARISTA":  2,
}

func (x Switch_Connector) String() string {
	return proto.EnumName(Switch_Connector_name, int32(x))
}

func (Switch_Connector) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_3eaf2c85e69e9ea4, []int{1, 0}
}

type Switch_Segment_Type int32

const (
	Switch_Segment_TYPE_INVALID Switch_Segment_Type = 0
	Switch_Segment_TYPE_VLAN    Switch_Segment_Type = 1
)

var Switch_Segment_Type_name = map[int32]string{
	0: "TYPE_INVALID",
	1: "TYPE_VLAN",
}

var Switch_Segment_Type_value = map[string]int32{
	"TYPE_INVALID": 0,
	"TYPE_VLAN":    1,
}

func (x Switch_Segment_Type) String() string {
	return proto.EnumName(Switch_Segment_Type_name, int32(x))
}

func (Switch_Segment_Type) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_3eaf2c85e69e9ea4, []int{1, 1, 0}
}

type Config struct {
	Switch               []*Switch  `protobuf:"bytes,1,rep,name=switch,proto3" json:"switch,omitempty"`
	Machine              []*Machine `protobuf:"bytes,2,rep,name=machine,proto3" json:"machine,omitempty"`
	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
	XXX_unrecognized     []byte     `json:"-"`
	XXX_sizecache        int32      `json:"-"`
}

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

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

var xxx_messageInfo_Config proto.InternalMessageInfo

func (m *Config) GetSwitch() []*Switch {
	if m != nil {
		return m.Switch
	}
	return nil
}

func (m *Config) GetMachine() []*Machine {
	if m != nil {
		return m.Machine
	}
	return nil
}

type Switch struct {
	Name                 string               `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Connector            Switch_Connector     `protobuf:"varint,2,opt,name=connector,proto3,enum=Switch_Connector" json:"connector,omitempty"`
	Address              string               `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
	ManagedPort          []*Switch_SwitchPort `protobuf:"bytes,4,rep,name=managed_port,json=managedPort,proto3" json:"managed_port,omitempty"`
	AvailableSegment     []*Switch_Segment    `protobuf:"bytes,5,rep,name=available_segment,json=availableSegment,proto3" json:"available_segment,omitempty"`
	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
	XXX_unrecognized     []byte               `json:"-"`
	XXX_sizecache        int32                `json:"-"`
}

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

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

var xxx_messageInfo_Switch proto.InternalMessageInfo

func (m *Switch) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *Switch) GetConnector() Switch_Connector {
	if m != nil {
		return m.Connector
	}
	return Switch_CONNECTOR_INVALID
}

func (m *Switch) GetAddress() string {
	if m != nil {
		return m.Address
	}
	return ""
}

func (m *Switch) GetManagedPort() []*Switch_SwitchPort {
	if m != nil {
		return m.ManagedPort
	}
	return nil
}

func (m *Switch) GetAvailableSegment() []*Switch_Segment {
	if m != nil {
		return m.AvailableSegment
	}
	return nil
}

type Switch_SwitchPort struct {
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_Switch_SwitchPort proto.InternalMessageInfo

func (m *Switch_SwitchPort) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

type Switch_Segment struct {
	SegmentType          Switch_Segment_Type `protobuf:"varint,1,opt,name=segment_type,json=segmentType,proto3,enum=Switch_Segment_Type" json:"segment_type,omitempty"`
	VlanId               int32               `protobuf:"varint,2,opt,name=vlan_id,json=vlanId,proto3" json:"vlan_id,omitempty"`
	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
	XXX_unrecognized     []byte              `json:"-"`
	XXX_sizecache        int32               `json:"-"`
}

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

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

var xxx_messageInfo_Switch_Segment proto.InternalMessageInfo

func (m *Switch_Segment) GetSegmentType() Switch_Segment_Type {
	if m != nil {
		return m.SegmentType
	}
	return Switch_Segment_TYPE_INVALID
}

func (m *Switch_Segment) GetVlanId() int32 {
	if m != nil {
		return m.VlanId
	}
	return 0
}

type Machine struct {
	Name                 string          `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	ManagedPort          []*Machine_Port `protobuf:"bytes,2,rep,name=managed_port,json=managedPort,proto3" json:"managed_port,omitempty"`
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

func (m *Machine) Reset()         { *m = Machine{} }
func (m *Machine) String() string { return proto.CompactTextString(m) }
func (*Machine) ProtoMessage()    {}
func (*Machine) Descriptor() ([]byte, []int) {
	return fileDescriptor_3eaf2c85e69e9ea4, []int{2}
}

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

var xxx_messageInfo_Machine proto.InternalMessageInfo

func (m *Machine) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *Machine) GetManagedPort() []*Machine_Port {
	if m != nil {
		return m.ManagedPort
	}
	return nil
}

type Machine_Port struct {
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_Machine_Port proto.InternalMessageInfo

func (m *Machine_Port) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func init() {
	proto.RegisterEnum("Switch_Connector", Switch_Connector_name, Switch_Connector_value)
	proto.RegisterEnum("Switch_Segment_Type", Switch_Segment_Type_name, Switch_Segment_Type_value)
	proto.RegisterType((*Config)(nil), "Config")
	proto.RegisterType((*Switch)(nil), "Switch")
	proto.RegisterType((*Switch_SwitchPort)(nil), "Switch.SwitchPort")
	proto.RegisterType((*Switch_Segment)(nil), "Switch.Segment")
	proto.RegisterType((*Machine)(nil), "Machine")
	proto.RegisterType((*Machine_Port)(nil), "Machine.Port")
}

func init() { proto.RegisterFile("config.proto", fileDescriptor_3eaf2c85e69e9ea4) }

var fileDescriptor_3eaf2c85e69e9ea4 = []byte{
	// 394 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xc1, 0x6e, 0x9b, 0x40,
	0x10, 0x86, 0x8b, 0x4d, 0xa0, 0x8c, 0x49, 0x82, 0xb7, 0xa9, 0xba, 0xe2, 0x52, 0xc4, 0xa5, 0x3e,
	0xd1, 0x88, 0xaa, 0xed, 0xa5, 0x17, 0x44, 0x73, 0x40, 0x0a, 0x24, 0xda, 0xa0, 0x48, 0x3d, 0xa1,
	0x0d, 0x6c, 0x1d, 0x54, 0xb3, 0x20, 0x40, 0xae, 0x7c, 0xef, 0x23, 0xf6, 0x81, 0x2a, 0x2f, 0x8b,
	0xa9, 0x5c, 0xf7, 0x04, 0xff, 0x3f, 0xdf, 0xcc, 0xc0, 0xcc, 0x80, 0x99, 0xd7, 0xfc, 0x7b, 0xb9,
	0xf6, 0x9a, 0xb6, 0xee, 0x6b, 0x37, 0x06, 0x2d, 0x14, 0x1a, 0xbd, 0x05, 0xad, 0xfb, 0x59, 0xf6,
	0xf9, 0x33, 0x56, 0x9c, 0xf9, 0x6a, 0xe1, 0xeb, 0xde, 0x83, 0x90, 0x44, 0xda, 0xc8, 0x05, 0xbd,
	0xa2, 0xf9, 0x73, 0xc9, 0x19, 0x9e, 0x09, 0xe2, 0xa5, 0x17, 0x0f, 0x9a, 0x8c, 0x01, 0xf7, 0xf7,
	0x1c, 0xb4, 0x21, 0x0d, 0x21, 0x50, 0x39, 0xad, 0x18, 0x56, 0x1c, 0x65, 0x65, 0x10, 0xf1, 0x8e,
	0xde, 0x83, 0x91, 0xd7, 0x9c, 0xb3, 0xbc, 0xaf, 0x5b, 0x3c, 0x73, 0x94, 0xd5, 0x85, 0xbf, 0x94,
	0x6d, 0xbc, 0x70, 0x0c, 0x90, 0x89, 0x41, 0x18, 0x74, 0x5a, 0x14, 0x2d, 0xeb, 0x3a, 0x3c, 0x17,
	0x75, 0x46, 0x89, 0x3e, 0x82, 0x59, 0x51, 0x4e, 0xd7, 0xac, 0xc8, 0x9a, 0xba, 0xed, 0xb1, 0x2a,
	0x3e, 0x09, 0x8d, 0xd5, 0x86, 0xc7, 0x7d, 0xdd, 0xf6, 0x64, 0x21, 0xb9, 0xbd, 0x40, 0x5f, 0x60,
	0x49, 0xb7, 0xb4, 0xdc, 0xd0, 0xa7, 0x0d, 0xcb, 0x3a, 0xb6, 0xae, 0x18, 0xef, 0xf1, 0x99, 0xc8,
	0xbd, 0x3c, 0xe4, 0x0e, 0x36, 0xb1, 0x0e, 0xa4, 0x74, 0x6c, 0x07, 0x60, 0x2a, 0x7c, 0xea, 0x0f,
	0xed, 0x5f, 0x0a, 0xe8, 0x92, 0x46, 0x9f, 0xc1, 0x94, 0x1d, 0xb2, 0x7e, 0xd7, 0x0c, 0xdc, 0x85,
	0x7f, 0x75, 0xd4, 0xc6, 0x4b, 0x77, 0x0d, 0x23, 0x0b, 0x49, 0xee, 0x05, 0x7a, 0x03, 0xfa, 0x76,
	0x43, 0x79, 0x56, 0x16, 0x62, 0x48, 0x67, 0x44, 0xdb, 0xcb, 0xa8, 0x70, 0xdf, 0x81, 0x2a, 0x00,
	0x0b, 0xcc, 0xf4, 0xdb, 0xfd, 0x4d, 0x16, 0x25, 0x8f, 0xc1, 0x6d, 0xf4, 0xd5, 0x7a, 0x81, 0xce,
	0xc1, 0x10, 0xce, 0xe3, 0x6d, 0x90, 0x58, 0x8a, 0x1b, 0x83, 0x71, 0x98, 0x27, 0x7a, 0x0d, 0xcb,
	0xf0, 0x2e, 0x49, 0x6e, 0xc2, 0xf4, 0x8e, 0xfc, 0x95, 0xf2, 0x0a, 0x2e, 0x27, 0x3b, 0xfe, 0xe4,
	0xfb, 0xd7, 0x96, 0x82, 0xae, 0xc0, 0x9a, 0xcc, 0x80, 0x44, 0x0f, 0x69, 0x60, 0xcd, 0xdc, 0x1f,
	0xa0, 0xcb, 0x55, 0x9f, 0x5c, 0xeb, 0xf5, 0xd1, 0x2e, 0x86, 0xf3, 0x38, 0x1f, 0xcf, 0xc3, 0xfb,
	0x67, 0x0d, 0xb6, 0x0d, 0xea, 0xff, 0x46, 0xf8, 0xa4, 0x89, 0xcb, 0xfc, 0xf0, 0x27, 0x00, 0x00,
	0xff, 0xff, 0x30, 0x75, 0x6a, 0x03, 0xa9, 0x02, 0x00, 0x00,
}
