// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/cloud/servicedirectory/v1beta1/lookup_service.proto

package servicedirectory

import (
	context "context"
	fmt "fmt"
	math "math"

	proto "github.com/golang/protobuf/proto"
	_ "google.golang.org/genproto/googleapis/api/annotations"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// 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

// The request message for [LookupService.ResolveService][google.cloud.servicedirectory.v1beta1.LookupService.ResolveService].
// Looks up a service by its name, returns the service and its endpoints.
type ResolveServiceRequest struct {
	// Required. The name of the service to resolve.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// Optional. The maximum number of endpoints to return. Defaults to 25. Maximum is 100.
	// If a value less than one is specified, the Default is used.
	// If a value greater than the Maximum is specified, the Maximum is used.
	MaxEndpoints int32 `protobuf:"varint,2,opt,name=max_endpoints,json=maxEndpoints,proto3" json:"max_endpoints,omitempty"`
	// Optional. The filter applied to the endpoints of the resolved service.
	//
	// General filter string syntax:
	// <field> <operator> <value> (<logical connector>)
	// <field> can be "name" or "metadata.<key>" for map field.
	// <operator> can be "<, >, <=, >=, !=, =, :". Of which ":" means HAS and is
	// roughly the same as "=".
	// <value> must be the same data type as the field.
	// <logical connector> can be "AND, OR, NOT".
	//
	// Examples of valid filters:
	// * "metadata.owner" returns Endpoints that have a label with the
	//   key "owner", this is the same as "metadata:owner"
	// * "metadata.protocol=gRPC" returns Endpoints that have key/value
	//   "protocol=gRPC"
	// * "metadata.owner!=sd AND metadata.foo=bar" returns
	//   Endpoints that have "owner" field in metadata with a value that is not
	//   "sd" AND have the key/value foo=bar.
	EndpointFilter       string   `protobuf:"bytes,3,opt,name=endpoint_filter,json=endpointFilter,proto3" json:"endpoint_filter,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_ResolveServiceRequest proto.InternalMessageInfo

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

func (m *ResolveServiceRequest) GetMaxEndpoints() int32 {
	if m != nil {
		return m.MaxEndpoints
	}
	return 0
}

func (m *ResolveServiceRequest) GetEndpointFilter() string {
	if m != nil {
		return m.EndpointFilter
	}
	return ""
}

// The response message for [LookupService.ResolveService][google.cloud.servicedirectory.v1beta1.LookupService.ResolveService].
type ResolveServiceResponse struct {
	Service              *Service `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_ResolveServiceResponse proto.InternalMessageInfo

func (m *ResolveServiceResponse) GetService() *Service {
	if m != nil {
		return m.Service
	}
	return nil
}

func init() {
	proto.RegisterType((*ResolveServiceRequest)(nil), "google.cloud.servicedirectory.v1beta1.ResolveServiceRequest")
	proto.RegisterType((*ResolveServiceResponse)(nil), "google.cloud.servicedirectory.v1beta1.ResolveServiceResponse")
}

func init() {
	proto.RegisterFile("google/cloud/servicedirectory/v1beta1/lookup_service.proto", fileDescriptor_3fa925bc9d6d26cd)
}

var fileDescriptor_3fa925bc9d6d26cd = []byte{
	// 487 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcd, 0x8a, 0x13, 0x41,
	0x10, 0xa6, 0xb3, 0xfe, 0x60, 0xeb, 0xae, 0x30, 0xa0, 0xc6, 0x41, 0xd8, 0x25, 0x20, 0x66, 0x83,
	0x76, 0xb3, 0xbb, 0xb7, 0xe8, 0x1e, 0x12, 0x71, 0x11, 0xf4, 0xb0, 0x66, 0xf1, 0xe2, 0x25, 0x74,
	0x26, 0x95, 0x49, 0x6b, 0x4f, 0x57, 0xdb, 0xdd, 0x93, 0xac, 0x88, 0x17, 0x5f, 0xc1, 0xa3, 0xaf,
	0xe1, 0x3b, 0x08, 0x1e, 0xf5, 0x05, 0x72, 0xf0, 0x21, 0xc4, 0x93, 0x64, 0x7a, 0x46, 0x93, 0x28,
	0x6c, 0xf0, 0xd8, 0x7c, 0xf5, 0x7d, 0xf5, 0x55, 0xd5, 0xd7, 0xb4, 0x9d, 0x22, 0xa6, 0x0a, 0x78,
	0xa2, 0x30, 0x1f, 0x72, 0x07, 0x76, 0x22, 0x13, 0x18, 0x4a, 0x0b, 0x89, 0x47, 0xfb, 0x86, 0x4f,
	0xf6, 0x06, 0xe0, 0xc5, 0x1e, 0x57, 0x88, 0xaf, 0x72, 0xd3, 0x2f, 0x71, 0x66, 0x2c, 0x7a, 0x8c,
	0x6e, 0x07, 0x2e, 0x2b, 0xb8, 0x6c, 0x95, 0xcb, 0x4a, 0x6e, 0x7c, 0xab, 0x6c, 0x21, 0x8c, 0xe4,
	0x42, 0x6b, 0xf4, 0xc2, 0x4b, 0xd4, 0x2e, 0x88, 0xc4, 0xdb, 0x0b, 0xe8, 0x48, 0x82, 0x1a, 0xf6,
	0x07, 0x30, 0x16, 0x13, 0x89, 0xb6, 0x2c, 0xb8, 0xb9, 0x50, 0x60, 0xc1, 0x61, 0x6e, 0x2b, 0x03,
	0xf1, 0xc1, 0x7a, 0xe6, 0x97, 0x5c, 0xc7, 0x37, 0x16, 0xf4, 0x12, 0x25, 0x41, 0xfb, 0x00, 0x34,
	0x3e, 0x11, 0x7a, 0xad, 0x07, 0x0e, 0xd5, 0x04, 0x4e, 0x02, 0xa3, 0x07, 0xaf, 0x73, 0x70, 0x3e,
	0x7a, 0x48, 0xcf, 0x69, 0x91, 0x41, 0x9d, 0xec, 0x90, 0xe6, 0xa5, 0x2e, 0x9f, 0x75, 0x6a, 0x3f,
	0x3b, 0xbb, 0xf4, 0xce, 0x5f, 0x13, 0x07, 0x65, 0x61, 0xa4, 0x63, 0x09, 0x66, 0xbc, 0x52, 0x29,
	0xc8, 0x51, 0x93, 0x6e, 0x66, 0xe2, 0xb4, 0x0f, 0x7a, 0x68, 0x50, 0x6a, 0xef, 0xea, 0xb5, 0x1d,
	0xd2, 0x3c, 0xdf, 0xdd, 0x98, 0x75, 0x48, 0xef, 0x4a, 0x26, 0x4e, 0x1f, 0x55, 0x40, 0x74, 0x97,
	0x5e, 0xad, 0xaa, 0xfa, 0x23, 0xa9, 0x3c, 0xd8, 0xfa, 0x46, 0xd1, 0xb9, 0xa8, 0xdd, 0xaa, 0xb0,
	0xa3, 0x02, 0x6a, 0x0c, 0xe8, 0xf5, 0x55, 0xd7, 0xce, 0xa0, 0x76, 0x10, 0x3d, 0xa6, 0x17, 0x4b,
	0x8b, 0x85, 0xf3, 0xcb, 0xfb, 0x8c, 0xad, 0x75, 0x31, 0x56, 0x09, 0x55, 0xf4, 0xfd, 0xcf, 0x35,
	0xba, 0xf9, 0xb4, 0x88, 0x40, 0x09, 0x45, 0x33, 0x42, 0xb7, 0x96, 0xdb, 0x46, 0x0f, 0xd6, 0x54,
	0xff, 0xe7, 0x8e, 0xe3, 0xc3, 0xff, 0x64, 0x87, 0x59, 0x1b, 0xcf, 0xde, 0x7f, 0xfb, 0xfe, 0xa1,
	0xf6, 0xa4, 0x71, 0xf4, 0xfb, 0xea, 0x6f, 0xe7, 0x5b, 0x3f, 0x34, 0x16, 0x5f, 0x42, 0xe2, 0x1d,
	0x6f, 0x71, 0x85, 0x49, 0x48, 0x1e, 0x6f, 0xf1, 0x39, 0xe6, 0x8c, 0x48, 0x60, 0xfe, 0x28, 0x7b,
	0x39, 0xde, 0x7a, 0xd7, 0xb6, 0x41, 0xbe, 0x4d, 0x5a, 0xf1, 0xc9, 0x97, 0xce, 0xf6, 0x19, 0x27,
	0xfe, 0xda, 0x61, 0x63, 0xef, 0x8d, 0x6b, 0x73, 0x3e, 0x9d, 0x4e, 0x57, 0xef, 0x2f, 0x72, 0x3f,
	0x0e, 0xd9, 0xbc, 0x67, 0x94, 0xf0, 0x23, 0xb4, 0x59, 0xf7, 0x23, 0xa1, 0xbb, 0x09, 0x66, 0xeb,
	0x0d, 0xdb, 0x8d, 0x96, 0x96, 0x7e, 0x3c, 0x8f, 0xe9, 0x31, 0x79, 0xf1, 0xbc, 0x24, 0xa7, 0xa8,
	0x84, 0x4e, 0x19, 0xda, 0x94, 0xa7, 0xa0, 0x8b, 0x10, 0xf3, 0x3f, 0x16, 0xce, 0xf8, 0x15, 0xf7,
	0x57, 0x81, 0x1f, 0x84, 0x0c, 0x2e, 0x14, 0x22, 0x07, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x2e,
	0xca, 0x4c, 0x51, 0x16, 0x04, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6

// LookupServiceClient is the client API for LookupService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type LookupServiceClient interface {
	// Returns a [service][google.cloud.servicedirectory.v1beta1.Service] and its
	// associated endpoints.
	// Resolving a service is not considered an active developer method.
	ResolveService(ctx context.Context, in *ResolveServiceRequest, opts ...grpc.CallOption) (*ResolveServiceResponse, error)
}

type lookupServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewLookupServiceClient(cc grpc.ClientConnInterface) LookupServiceClient {
	return &lookupServiceClient{cc}
}

func (c *lookupServiceClient) ResolveService(ctx context.Context, in *ResolveServiceRequest, opts ...grpc.CallOption) (*ResolveServiceResponse, error) {
	out := new(ResolveServiceResponse)
	err := c.cc.Invoke(ctx, "/google.cloud.servicedirectory.v1beta1.LookupService/ResolveService", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// LookupServiceServer is the server API for LookupService service.
type LookupServiceServer interface {
	// Returns a [service][google.cloud.servicedirectory.v1beta1.Service] and its
	// associated endpoints.
	// Resolving a service is not considered an active developer method.
	ResolveService(context.Context, *ResolveServiceRequest) (*ResolveServiceResponse, error)
}

// UnimplementedLookupServiceServer can be embedded to have forward compatible implementations.
type UnimplementedLookupServiceServer struct {
}

func (*UnimplementedLookupServiceServer) ResolveService(ctx context.Context, req *ResolveServiceRequest) (*ResolveServiceResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ResolveService not implemented")
}

func RegisterLookupServiceServer(s *grpc.Server, srv LookupServiceServer) {
	s.RegisterService(&_LookupService_serviceDesc, srv)
}

func _LookupService_ResolveService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ResolveServiceRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(LookupServiceServer).ResolveService(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.cloud.servicedirectory.v1beta1.LookupService/ResolveService",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(LookupServiceServer).ResolveService(ctx, req.(*ResolveServiceRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _LookupService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "google.cloud.servicedirectory.v1beta1.LookupService",
	HandlerType: (*LookupServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "ResolveService",
			Handler:    _LookupService_ResolveService_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "google/cloud/servicedirectory/v1beta1/lookup_service.proto",
}
