// Code generated by protoc-gen-go. DO NOT EDIT.
// source: lab/services/client.proto

package services

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

// Configuration information required by clients of Test Lab Services.
type ClientConfig struct {
	// Address where Test Lab Services is reachable.
	// This should be an IPv4 or IPv6 address to avoid name
	// resolution issues.
	// IPv4 addresses will be in standard dotted decimal notation.
	// IPv6 addresses will be formatted according to RFC4291, Section
	// 2.2, 1. (no zero compression)
	// If this is a hostname, the RTS should ensure that the hostname
	// can be resolved by the RTD via standard name resolution
	// facilities.
	TlsAddress string `protobuf:"bytes,1,opt,name=tls_address,json=tlsAddress,proto3" json:"tls_address,omitempty"`
	// Port on the tls_address where the service is reachable.
	TlsPort int32 `protobuf:"varint,2,opt,name=tls_port,json=tlsPort,proto3" json:"tls_port,omitempty"`
	// Address where Test Lab Services Wiring is reachable.
	// This has the same format as tls_address.
	TlwAddress string `protobuf:"bytes,3,opt,name=tlw_address,json=tlwAddress,proto3" json:"tlw_address,omitempty"`
	// Port on the tlw_address where the service is reachable.
	TlwPort              int32    `protobuf:"varint,4,opt,name=tlw_port,json=tlwPort,proto3" json:"tlw_port,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_ClientConfig proto.InternalMessageInfo

func (m *ClientConfig) GetTlsAddress() string {
	if m != nil {
		return m.TlsAddress
	}
	return ""
}

func (m *ClientConfig) GetTlsPort() int32 {
	if m != nil {
		return m.TlsPort
	}
	return 0
}

func (m *ClientConfig) GetTlwAddress() string {
	if m != nil {
		return m.TlwAddress
	}
	return ""
}

func (m *ClientConfig) GetTlwPort() int32 {
	if m != nil {
		return m.TlwPort
	}
	return 0
}

func init() {
	proto.RegisterType((*ClientConfig)(nil), "lab.services.ClientConfig")
}

func init() { proto.RegisterFile("lab/services/client.proto", fileDescriptor_cf54823844c81740) }

var fileDescriptor_cf54823844c81740 = []byte{
	// 191 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0xcf, 0xbf, 0x6e, 0x83, 0x30,
	0x10, 0x06, 0x70, 0xb9, 0xff, 0xeb, 0x32, 0x31, 0xc1, 0x54, 0xd4, 0x89, 0xc9, 0x1e, 0x2a, 0x55,
	0x5d, 0x13, 0x5e, 0x20, 0x62, 0xcc, 0x12, 0x19, 0x30, 0x8e, 0x25, 0xc3, 0xa1, 0x3b, 0x27, 0x7e,
	0x83, 0x3c, 0x77, 0x04, 0xc8, 0x51, 0x32, 0xde, 0xf7, 0xdd, 0x6f, 0xf8, 0x78, 0xee, 0x54, 0x23,
	0x49, 0xe3, 0xd9, 0xb6, 0x9a, 0x64, 0xeb, 0xac, 0x1e, 0xbd, 0x98, 0x10, 0x3c, 0xa4, 0x89, 0x53,
	0x8d, 0x88, 0xd5, 0xcf, 0x85, 0xf1, 0xa4, 0x5a, 0xea, 0x0a, 0xc6, 0xde, 0x9a, 0xf4, 0x9b, 0x7f,
	0x79, 0x47, 0x07, 0xd5, 0x75, 0xa8, 0x89, 0x32, 0x56, 0xb0, 0xf2, 0xb3, 0xe6, 0xde, 0xd1, 0x66,
	0x4d, 0xd2, 0x9c, 0x7f, 0xcc, 0x0f, 0x13, 0xa0, 0xcf, 0x9e, 0x0a, 0x56, 0xbe, 0xd6, 0xef, 0xde,
	0xd1, 0x0e, 0xd0, 0xaf, 0x36, 0xdc, 0xec, 0x73, 0xb4, 0xe1, 0xc1, 0x86, 0xd5, 0xbe, 0x44, 0x1b,
	0x66, 0xbb, 0xfd, 0xdf, 0xff, 0x19, 0x10, 0xed, 0x11, 0x61, 0xb0, 0xa7, 0x41, 0x00, 0x1a, 0x19,
	0x0f, 0x20, 0x69, 0xc7, 0x1e, 0x95, 0x5c, 0x06, 0x48, 0x03, 0xf2, 0x7e, 0x5d, 0xf3, 0xb6, 0xc4,
	0xbf, 0xd7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x58, 0xbd, 0xea, 0xf3, 0xf4, 0x00, 0x00, 0x00,
}
