// Copyright 2019 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.3.0
// - protoc             v4.22.0
// source: profiling/proto/service.proto

package proto

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

const (
	Profiling_Enable_FullMethodName         = "/grpc.go.profiling.v1alpha.Profiling/Enable"
	Profiling_GetStreamStats_FullMethodName = "/grpc.go.profiling.v1alpha.Profiling/GetStreamStats"
)

// ProfilingClient is the client API for Profiling 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 ProfilingClient interface {
	// Enable allows users to toggle profiling on and off remotely.
	Enable(ctx context.Context, in *EnableRequest, opts ...grpc.CallOption) (*EnableResponse, error)
	// GetStreamStats is used to retrieve an array of stream-level stats from a
	// gRPC client/server.
	GetStreamStats(ctx context.Context, in *GetStreamStatsRequest, opts ...grpc.CallOption) (*GetStreamStatsResponse, error)
}

type profilingClient struct {
	cc grpc.ClientConnInterface
}

func NewProfilingClient(cc grpc.ClientConnInterface) ProfilingClient {
	return &profilingClient{cc}
}

func (c *profilingClient) Enable(ctx context.Context, in *EnableRequest, opts ...grpc.CallOption) (*EnableResponse, error) {
	out := new(EnableResponse)
	err := c.cc.Invoke(ctx, Profiling_Enable_FullMethodName, in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *profilingClient) GetStreamStats(ctx context.Context, in *GetStreamStatsRequest, opts ...grpc.CallOption) (*GetStreamStatsResponse, error) {
	out := new(GetStreamStatsResponse)
	err := c.cc.Invoke(ctx, Profiling_GetStreamStats_FullMethodName, in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// ProfilingServer is the server API for Profiling service.
// All implementations should embed UnimplementedProfilingServer
// for forward compatibility
type ProfilingServer interface {
	// Enable allows users to toggle profiling on and off remotely.
	Enable(context.Context, *EnableRequest) (*EnableResponse, error)
	// GetStreamStats is used to retrieve an array of stream-level stats from a
	// gRPC client/server.
	GetStreamStats(context.Context, *GetStreamStatsRequest) (*GetStreamStatsResponse, error)
}

// UnimplementedProfilingServer should be embedded to have forward compatible implementations.
type UnimplementedProfilingServer struct {
}

func (UnimplementedProfilingServer) Enable(context.Context, *EnableRequest) (*EnableResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method Enable not implemented")
}
func (UnimplementedProfilingServer) GetStreamStats(context.Context, *GetStreamStatsRequest) (*GetStreamStatsResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetStreamStats not implemented")
}

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

func RegisterProfilingServer(s grpc.ServiceRegistrar, srv ProfilingServer) {
	s.RegisterService(&Profiling_ServiceDesc, srv)
}

func _Profiling_Enable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(EnableRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ProfilingServer).Enable(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Profiling_Enable_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ProfilingServer).Enable(ctx, req.(*EnableRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _Profiling_GetStreamStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetStreamStatsRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ProfilingServer).GetStreamStats(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Profiling_GetStreamStats_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ProfilingServer).GetStreamStats(ctx, req.(*GetStreamStatsRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// Profiling_ServiceDesc is the grpc.ServiceDesc for Profiling service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Profiling_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "grpc.go.profiling.v1alpha.Profiling",
	HandlerType: (*ProfilingServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "Enable",
			Handler:    _Profiling_Enable_Handler,
		},
		{
			MethodName: "GetStreamStats",
			Handler:    _Profiling_GetStreamStats_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "profiling/proto/service.proto",
}
