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

package v3

import (
	context "context"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	v3 "skywalking.apache.org/repo/goapi/collect/common/v3"
)

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

// ConfigurationDiscoveryServiceClient is the client API for ConfigurationDiscoveryService 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 ConfigurationDiscoveryServiceClient interface {
	// fetchConfigurations service requests the latest configuration.
	// Expect command of Commands is:
	//    command: CDS # meaning ConfigurationDiscoveryService's response
	//    args: Include string key and string value pair.
	//          The key depends on the agent implementation.
	//          The value is the latest value in String value. The watcher of key owner takes the responsibility to convert it to the correct type or format.
	//          One reserved key is `UUID`. The value would help reducing the traffic load between agent and OAP if there is no change.
	// Commands could be empty if no change detected based on ConfigurationSyncRequest.
	FetchConfigurations(ctx context.Context, in *ConfigurationSyncRequest, opts ...grpc.CallOption) (*v3.Commands, error)
}

type configurationDiscoveryServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewConfigurationDiscoveryServiceClient(cc grpc.ClientConnInterface) ConfigurationDiscoveryServiceClient {
	return &configurationDiscoveryServiceClient{cc}
}

func (c *configurationDiscoveryServiceClient) FetchConfigurations(ctx context.Context, in *ConfigurationSyncRequest, opts ...grpc.CallOption) (*v3.Commands, error) {
	out := new(v3.Commands)
	err := c.cc.Invoke(ctx, "/skywalking.v3.ConfigurationDiscoveryService/fetchConfigurations", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// ConfigurationDiscoveryServiceServer is the server API for ConfigurationDiscoveryService service.
// All implementations must embed UnimplementedConfigurationDiscoveryServiceServer
// for forward compatibility
type ConfigurationDiscoveryServiceServer interface {
	// fetchConfigurations service requests the latest configuration.
	// Expect command of Commands is:
	//    command: CDS # meaning ConfigurationDiscoveryService's response
	//    args: Include string key and string value pair.
	//          The key depends on the agent implementation.
	//          The value is the latest value in String value. The watcher of key owner takes the responsibility to convert it to the correct type or format.
	//          One reserved key is `UUID`. The value would help reducing the traffic load between agent and OAP if there is no change.
	// Commands could be empty if no change detected based on ConfigurationSyncRequest.
	FetchConfigurations(context.Context, *ConfigurationSyncRequest) (*v3.Commands, error)
	mustEmbedUnimplementedConfigurationDiscoveryServiceServer()
}

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

func (UnimplementedConfigurationDiscoveryServiceServer) FetchConfigurations(context.Context, *ConfigurationSyncRequest) (*v3.Commands, error) {
	return nil, status.Errorf(codes.Unimplemented, "method FetchConfigurations not implemented")
}
func (UnimplementedConfigurationDiscoveryServiceServer) mustEmbedUnimplementedConfigurationDiscoveryServiceServer() {
}

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

func RegisterConfigurationDiscoveryServiceServer(s grpc.ServiceRegistrar, srv ConfigurationDiscoveryServiceServer) {
	s.RegisterService(&ConfigurationDiscoveryService_ServiceDesc, srv)
}

func _ConfigurationDiscoveryService_FetchConfigurations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ConfigurationSyncRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ConfigurationDiscoveryServiceServer).FetchConfigurations(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/skywalking.v3.ConfigurationDiscoveryService/fetchConfigurations",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ConfigurationDiscoveryServiceServer).FetchConfigurations(ctx, req.(*ConfigurationSyncRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// ConfigurationDiscoveryService_ServiceDesc is the grpc.ServiceDesc for ConfigurationDiscoveryService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var ConfigurationDiscoveryService_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "skywalking.v3.ConfigurationDiscoveryService",
	HandlerType: (*ConfigurationDiscoveryServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "fetchConfigurations",
			Handler:    _ConfigurationDiscoveryService_FetchConfigurations_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "language-agent/ConfigurationDiscoveryService.proto",
}
