// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package api

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7

// TestMetadataServiceClient is the client API for TestMetadataService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type TestMetadataServiceClient interface {
	Get(ctx context.Context, in *TestMetadataRequest, opts ...grpc.CallOption) (*TestMetadataResponse, error)
}

type testMetadataServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewTestMetadataServiceClient(cc grpc.ClientConnInterface) TestMetadataServiceClient {
	return &testMetadataServiceClient{cc}
}

func (c *testMetadataServiceClient) Get(ctx context.Context, in *TestMetadataRequest, opts ...grpc.CallOption) (*TestMetadataResponse, error) {
	out := new(TestMetadataResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.TestMetadataService/Get", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// TestMetadataServiceServer is the server API for TestMetadataService service.
// All implementations must embed UnimplementedTestMetadataServiceServer
// for forward compatibility
type TestMetadataServiceServer interface {
	Get(context.Context, *TestMetadataRequest) (*TestMetadataResponse, error)
	mustEmbedUnimplementedTestMetadataServiceServer()
}

// UnimplementedTestMetadataServiceServer must be embedded to have forward compatible implementations.
type UnimplementedTestMetadataServiceServer struct {
}

func (UnimplementedTestMetadataServiceServer) Get(context.Context, *TestMetadataRequest) (*TestMetadataResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
}
func (UnimplementedTestMetadataServiceServer) mustEmbedUnimplementedTestMetadataServiceServer() {}

// UnsafeTestMetadataServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TestMetadataServiceServer will
// result in compilation errors.
type UnsafeTestMetadataServiceServer interface {
	mustEmbedUnimplementedTestMetadataServiceServer()
}

func RegisterTestMetadataServiceServer(s grpc.ServiceRegistrar, srv TestMetadataServiceServer) {
	s.RegisterService(&TestMetadataService_ServiceDesc, srv)
}

func _TestMetadataService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestMetadataRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestMetadataServiceServer).Get(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestMetadataService/Get",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestMetadataServiceServer).Get(ctx, req.(*TestMetadataRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// TestMetadataService_ServiceDesc is the grpc.ServiceDesc for TestMetadataService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var TestMetadataService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.TestMetadataService",
	HandlerType: (*TestMetadataServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Get",
			Handler:    _TestMetadataService_Get_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/test_metadata.proto",
}
