// Copyright 2018-2024 Open Networking Foundation (ONF) and the ONF Contributors
//
// 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.6.0
// - protoc             v4.25.8
// source: voltha_protos/extensions.proto

package extension

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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9

const (
	Extension_GetExtValue_FullMethodName = "/extension.Extension/GetExtValue"
	Extension_SetExtValue_FullMethodName = "/extension.Extension/SetExtValue"
)

// ExtensionClient is the client API for Extension 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.
//
// Extension is a service to get and set specific attributes
type ExtensionClient interface {
	// Get a single attribute
	GetExtValue(ctx context.Context, in *SingleGetValueRequest, opts ...grpc.CallOption) (*SingleGetValueResponse, error)
	// Set a single attribute
	SetExtValue(ctx context.Context, in *SingleSetValueRequest, opts ...grpc.CallOption) (*SingleSetValueResponse, error)
}

type extensionClient struct {
	cc grpc.ClientConnInterface
}

func NewExtensionClient(cc grpc.ClientConnInterface) ExtensionClient {
	return &extensionClient{cc}
}

func (c *extensionClient) GetExtValue(ctx context.Context, in *SingleGetValueRequest, opts ...grpc.CallOption) (*SingleGetValueResponse, error) {
	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
	out := new(SingleGetValueResponse)
	err := c.cc.Invoke(ctx, Extension_GetExtValue_FullMethodName, in, out, cOpts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *extensionClient) SetExtValue(ctx context.Context, in *SingleSetValueRequest, opts ...grpc.CallOption) (*SingleSetValueResponse, error) {
	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
	out := new(SingleSetValueResponse)
	err := c.cc.Invoke(ctx, Extension_SetExtValue_FullMethodName, in, out, cOpts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// ExtensionServer is the server API for Extension service.
// All implementations must embed UnimplementedExtensionServer
// for forward compatibility.
//
// Extension is a service to get and set specific attributes
type ExtensionServer interface {
	// Get a single attribute
	GetExtValue(context.Context, *SingleGetValueRequest) (*SingleGetValueResponse, error)
	// Set a single attribute
	SetExtValue(context.Context, *SingleSetValueRequest) (*SingleSetValueResponse, error)
	mustEmbedUnimplementedExtensionServer()
}

// UnimplementedExtensionServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedExtensionServer struct{}

func (UnimplementedExtensionServer) GetExtValue(context.Context, *SingleGetValueRequest) (*SingleGetValueResponse, error) {
	return nil, status.Error(codes.Unimplemented, "method GetExtValue not implemented")
}
func (UnimplementedExtensionServer) SetExtValue(context.Context, *SingleSetValueRequest) (*SingleSetValueResponse, error) {
	return nil, status.Error(codes.Unimplemented, "method SetExtValue not implemented")
}
func (UnimplementedExtensionServer) mustEmbedUnimplementedExtensionServer() {}
func (UnimplementedExtensionServer) testEmbeddedByValue()                   {}

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

func RegisterExtensionServer(s grpc.ServiceRegistrar, srv ExtensionServer) {
	// If the following call panics, it indicates UnimplementedExtensionServer was
	// embedded by pointer and is nil.  This will cause panics if an
	// unimplemented method is ever invoked, so we test this at initialization
	// time to prevent it from happening at runtime later due to I/O.
	if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
		t.testEmbeddedByValue()
	}
	s.RegisterService(&Extension_ServiceDesc, srv)
}

func _Extension_GetExtValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SingleGetValueRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ExtensionServer).GetExtValue(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Extension_GetExtValue_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ExtensionServer).GetExtValue(ctx, req.(*SingleGetValueRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _Extension_SetExtValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SingleSetValueRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(ExtensionServer).SetExtValue(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: Extension_SetExtValue_FullMethodName,
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(ExtensionServer).SetExtValue(ctx, req.(*SingleSetValueRequest))
	}
	return interceptor(ctx, in, info, handler)
}

// Extension_ServiceDesc is the grpc.ServiceDesc for Extension service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Extension_ServiceDesc = grpc.ServiceDesc{
	ServiceName: "extension.Extension",
	HandlerType: (*ExtensionServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetExtValue",
			Handler:    _Extension_GetExtValue_Handler,
		},
		{
			MethodName: "SetExtValue",
			Handler:    _Extension_SetExtValue_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "voltha_protos/extensions.proto",
}
