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

package file

import (
	context "context"
	api "go.chromium.org/goma/server/proto/api"
	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

// FileServiceClient is the client API for FileService 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 FileServiceClient interface {
	StoreFile(ctx context.Context, in *api.StoreFileReq, opts ...grpc.CallOption) (*api.StoreFileResp, error)
	LookupFile(ctx context.Context, in *api.LookupFileReq, opts ...grpc.CallOption) (*api.LookupFileResp, error)
}

type fileServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewFileServiceClient(cc grpc.ClientConnInterface) FileServiceClient {
	return &fileServiceClient{cc}
}

func (c *fileServiceClient) StoreFile(ctx context.Context, in *api.StoreFileReq, opts ...grpc.CallOption) (*api.StoreFileResp, error) {
	out := new(api.StoreFileResp)
	err := c.cc.Invoke(ctx, "/devtools_goma.FileService/StoreFile", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *fileServiceClient) LookupFile(ctx context.Context, in *api.LookupFileReq, opts ...grpc.CallOption) (*api.LookupFileResp, error) {
	out := new(api.LookupFileResp)
	err := c.cc.Invoke(ctx, "/devtools_goma.FileService/LookupFile", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// FileServiceServer is the server API for FileService service.
// All implementations must embed UnimplementedFileServiceServer
// for forward compatibility
type FileServiceServer interface {
	StoreFile(context.Context, *api.StoreFileReq) (*api.StoreFileResp, error)
	LookupFile(context.Context, *api.LookupFileReq) (*api.LookupFileResp, error)
	mustEmbedUnimplementedFileServiceServer()
}

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

func (UnimplementedFileServiceServer) StoreFile(context.Context, *api.StoreFileReq) (*api.StoreFileResp, error) {
	return nil, status.Errorf(codes.Unimplemented, "method StoreFile not implemented")
}
func (UnimplementedFileServiceServer) LookupFile(context.Context, *api.LookupFileReq) (*api.LookupFileResp, error) {
	return nil, status.Errorf(codes.Unimplemented, "method LookupFile not implemented")
}
func (UnimplementedFileServiceServer) mustEmbedUnimplementedFileServiceServer() {}

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

func RegisterFileServiceServer(s grpc.ServiceRegistrar, srv FileServiceServer) {
	s.RegisterService(&FileService_ServiceDesc, srv)
}

func _FileService_StoreFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(api.StoreFileReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(FileServiceServer).StoreFile(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/devtools_goma.FileService/StoreFile",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(FileServiceServer).StoreFile(ctx, req.(*api.StoreFileReq))
	}
	return interceptor(ctx, in, info, handler)
}

func _FileService_LookupFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(api.LookupFileReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(FileServiceServer).LookupFile(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/devtools_goma.FileService/LookupFile",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(FileServiceServer).LookupFile(ctx, req.(*api.LookupFileReq))
	}
	return interceptor(ctx, in, info, handler)
}

// FileService_ServiceDesc is the grpc.ServiceDesc for FileService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var FileService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "devtools_goma.FileService",
	HandlerType: (*FileServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "StoreFile",
			Handler:    _FileService_StoreFile_Handler,
		},
		{
			MethodName: "LookupFile",
			Handler:    _FileService_LookupFile_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "file/file_service.proto",
}
