// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/opencord/voltha-protos/v5/go/voltha (interfaces: VolthaServiceClient)
//
// Generated by this command:
//
//	mockgen -package=mocks -destination=mock_voltha.pb.go github.com/opencord/voltha-protos/v5/go/voltha VolthaServiceClient
//

// Package mocks is a generated GoMock package.
package mocks

import (
	context "context"
	reflect "reflect"

	common "github.com/opencord/voltha-protos/v5/go/common"
	extension "github.com/opencord/voltha-protos/v5/go/extension"
	omci "github.com/opencord/voltha-protos/v5/go/omci"
	openflow_13 "github.com/opencord/voltha-protos/v5/go/openflow_13"
	voip_system_profile "github.com/opencord/voltha-protos/v5/go/voip_system_profile"
	voip_user_profile "github.com/opencord/voltha-protos/v5/go/voip_user_profile"
	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
	gomock "go.uber.org/mock/gomock"
	grpc "google.golang.org/grpc"
	emptypb "google.golang.org/protobuf/types/known/emptypb"
)

// MockVolthaServiceClient is a mock of VolthaServiceClient interface.
type MockVolthaServiceClient struct {
	ctrl     *gomock.Controller
	recorder *MockVolthaServiceClientMockRecorder
	isgomock struct{}
}

// MockVolthaServiceClientMockRecorder is the mock recorder for MockVolthaServiceClient.
type MockVolthaServiceClientMockRecorder struct {
	mock *MockVolthaServiceClient
}

// NewMockVolthaServiceClient creates a new mock instance.
func NewMockVolthaServiceClient(ctrl *gomock.Controller) *MockVolthaServiceClient {
	mock := &MockVolthaServiceClient{ctrl: ctrl}
	mock.recorder = &MockVolthaServiceClientMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockVolthaServiceClient) EXPECT() *MockVolthaServiceClientMockRecorder {
	return m.recorder
}

// AbortImageUpgradeToDevice mocks base method.
func (m *MockVolthaServiceClient) AbortImageUpgradeToDevice(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "AbortImageUpgradeToDevice", varargs...)
	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// AbortImageUpgradeToDevice indicates an expected call of AbortImageUpgradeToDevice.
func (mr *MockVolthaServiceClientMockRecorder) AbortImageUpgradeToDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortImageUpgradeToDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).AbortImageUpgradeToDevice), varargs...)
}

// ActivateImage mocks base method.
func (m *MockVolthaServiceClient) ActivateImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ActivateImage", varargs...)
	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ActivateImage indicates an expected call of ActivateImage.
func (mr *MockVolthaServiceClientMockRecorder) ActivateImage(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).ActivateImage), varargs...)
}

// ActivateImageUpdate mocks base method.
func (m *MockVolthaServiceClient) ActivateImageUpdate(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ActivateImageUpdate", varargs...)
	ret0, _ := ret[0].(*common.OperationResp)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
func (mr *MockVolthaServiceClientMockRecorder) ActivateImageUpdate(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockVolthaServiceClient)(nil).ActivateImageUpdate), varargs...)
}

// CancelImageDownload mocks base method.
func (m *MockVolthaServiceClient) CancelImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CancelImageDownload", varargs...)
	ret0, _ := ret[0].(*common.OperationResp)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CancelImageDownload indicates an expected call of CancelImageDownload.
func (mr *MockVolthaServiceClientMockRecorder) CancelImageDownload(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockVolthaServiceClient)(nil).CancelImageDownload), varargs...)
}

// CommitImage mocks base method.
func (m *MockVolthaServiceClient) CommitImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CommitImage", varargs...)
	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CommitImage indicates an expected call of CommitImage.
func (mr *MockVolthaServiceClientMockRecorder) CommitImage(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).CommitImage), varargs...)
}

// CreateDevice mocks base method.
func (m *MockVolthaServiceClient) CreateDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*voltha.Device, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateDevice", varargs...)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateDevice indicates an expected call of CreateDevice.
func (mr *MockVolthaServiceClientMockRecorder) CreateDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).CreateDevice), varargs...)
}

// CreateEventFilter mocks base method.
func (m *MockVolthaServiceClient) CreateEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*voltha.EventFilter, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "CreateEventFilter", varargs...)
	ret0, _ := ret[0].(*voltha.EventFilter)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// CreateEventFilter indicates an expected call of CreateEventFilter.
func (mr *MockVolthaServiceClientMockRecorder) CreateEventFilter(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).CreateEventFilter), varargs...)
}

// DeleteDevice mocks base method.
func (m *MockVolthaServiceClient) DeleteDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DeleteDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteDevice indicates an expected call of DeleteDevice.
func (mr *MockVolthaServiceClientMockRecorder) DeleteDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteDevice), varargs...)
}

// DeleteEventFilter mocks base method.
func (m *MockVolthaServiceClient) DeleteEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DeleteEventFilter", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteEventFilter indicates an expected call of DeleteEventFilter.
func (mr *MockVolthaServiceClientMockRecorder) DeleteEventFilter(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteEventFilter), varargs...)
}

// DeleteVoipSystemProfile mocks base method.
func (m *MockVolthaServiceClient) DeleteVoipSystemProfile(ctx context.Context, in *common.Key, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DeleteVoipSystemProfile", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteVoipSystemProfile indicates an expected call of DeleteVoipSystemProfile.
func (mr *MockVolthaServiceClientMockRecorder) DeleteVoipSystemProfile(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteVoipSystemProfile", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteVoipSystemProfile), varargs...)
}

// DeleteVoipUserProfile mocks base method.
func (m *MockVolthaServiceClient) DeleteVoipUserProfile(ctx context.Context, in *common.Key, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DeleteVoipUserProfile", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteVoipUserProfile indicates an expected call of DeleteVoipUserProfile.
func (mr *MockVolthaServiceClientMockRecorder) DeleteVoipUserProfile(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteVoipUserProfile", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteVoipUserProfile), varargs...)
}

// DisableDevice mocks base method.
func (m *MockVolthaServiceClient) DisableDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DisableDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableDevice indicates an expected call of DisableDevice.
func (mr *MockVolthaServiceClientMockRecorder) DisableDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableDevice), varargs...)
}

// DisableLogicalDevicePort mocks base method.
func (m *MockVolthaServiceClient) DisableLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DisableLogicalDevicePort", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableLogicalDevicePort indicates an expected call of DisableLogicalDevicePort.
func (mr *MockVolthaServiceClientMockRecorder) DisableLogicalDevicePort(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableLogicalDevicePort), varargs...)
}

// DisableOnuDevice mocks base method.
func (m *MockVolthaServiceClient) DisableOnuDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DisableOnuDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableOnuDevice indicates an expected call of DisableOnuDevice.
func (mr *MockVolthaServiceClientMockRecorder) DisableOnuDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableOnuDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableOnuDevice), varargs...)
}

// DisableOnuSerialNumber mocks base method.
func (m *MockVolthaServiceClient) DisableOnuSerialNumber(ctx context.Context, in *voltha.OnuSerialNumberOnOLTPon, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DisableOnuSerialNumber", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisableOnuSerialNumber indicates an expected call of DisableOnuSerialNumber.
func (mr *MockVolthaServiceClientMockRecorder) DisableOnuSerialNumber(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableOnuSerialNumber", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableOnuSerialNumber), varargs...)
}

// DisablePort mocks base method.
func (m *MockVolthaServiceClient) DisablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DisablePort", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DisablePort indicates an expected call of DisablePort.
func (mr *MockVolthaServiceClientMockRecorder) DisablePort(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisablePort), varargs...)
}

// DownloadImage mocks base method.
func (m *MockVolthaServiceClient) DownloadImage(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DownloadImage", varargs...)
	ret0, _ := ret[0].(*common.OperationResp)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DownloadImage indicates an expected call of DownloadImage.
func (mr *MockVolthaServiceClientMockRecorder) DownloadImage(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).DownloadImage), varargs...)
}

// DownloadImageToDevice mocks base method.
func (m *MockVolthaServiceClient) DownloadImageToDevice(ctx context.Context, in *voltha.DeviceImageDownloadRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "DownloadImageToDevice", varargs...)
	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DownloadImageToDevice indicates an expected call of DownloadImageToDevice.
func (mr *MockVolthaServiceClientMockRecorder) DownloadImageToDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImageToDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DownloadImageToDevice), varargs...)
}

// EnableDevice mocks base method.
func (m *MockVolthaServiceClient) EnableDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "EnableDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableDevice indicates an expected call of EnableDevice.
func (mr *MockVolthaServiceClientMockRecorder) EnableDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableDevice), varargs...)
}

// EnableLogicalDevicePort mocks base method.
func (m *MockVolthaServiceClient) EnableLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "EnableLogicalDevicePort", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableLogicalDevicePort indicates an expected call of EnableLogicalDevicePort.
func (mr *MockVolthaServiceClientMockRecorder) EnableLogicalDevicePort(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableLogicalDevicePort), varargs...)
}

// EnableOnuDevice mocks base method.
func (m *MockVolthaServiceClient) EnableOnuDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "EnableOnuDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableOnuDevice indicates an expected call of EnableOnuDevice.
func (mr *MockVolthaServiceClientMockRecorder) EnableOnuDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableOnuDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableOnuDevice), varargs...)
}

// EnableOnuSerialNumber mocks base method.
func (m *MockVolthaServiceClient) EnableOnuSerialNumber(ctx context.Context, in *voltha.OnuSerialNumberOnOLTPon, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "EnableOnuSerialNumber", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnableOnuSerialNumber indicates an expected call of EnableOnuSerialNumber.
func (mr *MockVolthaServiceClientMockRecorder) EnableOnuSerialNumber(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableOnuSerialNumber", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableOnuSerialNumber), varargs...)
}

// EnablePort mocks base method.
func (m *MockVolthaServiceClient) EnablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "EnablePort", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// EnablePort indicates an expected call of EnablePort.
func (mr *MockVolthaServiceClientMockRecorder) EnablePort(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnablePort), varargs...)
}

// ForceDeleteDevice mocks base method.
func (m *MockVolthaServiceClient) ForceDeleteDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ForceDeleteDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ForceDeleteDevice indicates an expected call of ForceDeleteDevice.
func (mr *MockVolthaServiceClientMockRecorder) ForceDeleteDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForceDeleteDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).ForceDeleteDevice), varargs...)
}

// GetAlarmDeviceData mocks base method.
func (m *MockVolthaServiceClient) GetAlarmDeviceData(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*omci.AlarmDeviceData, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetAlarmDeviceData", varargs...)
	ret0, _ := ret[0].(*omci.AlarmDeviceData)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetAlarmDeviceData indicates an expected call of GetAlarmDeviceData.
func (mr *MockVolthaServiceClientMockRecorder) GetAlarmDeviceData(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmDeviceData", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetAlarmDeviceData), varargs...)
}

// GetCoreInstance mocks base method.
func (m *MockVolthaServiceClient) GetCoreInstance(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.CoreInstance, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetCoreInstance", varargs...)
	ret0, _ := ret[0].(*voltha.CoreInstance)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetCoreInstance indicates an expected call of GetCoreInstance.
func (mr *MockVolthaServiceClientMockRecorder) GetCoreInstance(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreInstance", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetCoreInstance), varargs...)
}

// GetDevice mocks base method.
func (m *MockVolthaServiceClient) GetDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Device, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetDevice", varargs...)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetDevice indicates an expected call of GetDevice.
func (mr *MockVolthaServiceClientMockRecorder) GetDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetDevice), varargs...)
}

// GetDeviceType mocks base method.
func (m *MockVolthaServiceClient) GetDeviceType(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.DeviceType, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetDeviceType", varargs...)
	ret0, _ := ret[0].(*voltha.DeviceType)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetDeviceType indicates an expected call of GetDeviceType.
func (mr *MockVolthaServiceClientMockRecorder) GetDeviceType(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceType", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetDeviceType), varargs...)
}

// GetEventFilter mocks base method.
func (m *MockVolthaServiceClient) GetEventFilter(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.EventFilters, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetEventFilter", varargs...)
	ret0, _ := ret[0].(*voltha.EventFilters)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetEventFilter indicates an expected call of GetEventFilter.
func (mr *MockVolthaServiceClientMockRecorder) GetEventFilter(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetEventFilter), varargs...)
}

// GetExtValue mocks base method.
func (m *MockVolthaServiceClient) GetExtValue(ctx context.Context, in *extension.ValueSpecifier, opts ...grpc.CallOption) (*extension.ReturnValues, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetExtValue", varargs...)
	ret0, _ := ret[0].(*extension.ReturnValues)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetExtValue indicates an expected call of GetExtValue.
func (mr *MockVolthaServiceClientMockRecorder) GetExtValue(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetExtValue), varargs...)
}

// GetImageDownload mocks base method.
func (m *MockVolthaServiceClient) GetImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImageDownload", varargs...)
	ret0, _ := ret[0].(*voltha.ImageDownload)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetImageDownload indicates an expected call of GetImageDownload.
func (mr *MockVolthaServiceClientMockRecorder) GetImageDownload(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownload", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageDownload), varargs...)
}

// GetImageDownloadStatus mocks base method.
func (m *MockVolthaServiceClient) GetImageDownloadStatus(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImageDownloadStatus", varargs...)
	ret0, _ := ret[0].(*voltha.ImageDownload)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
func (mr *MockVolthaServiceClientMockRecorder) GetImageDownloadStatus(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageDownloadStatus), varargs...)
}

// GetImageStatus mocks base method.
func (m *MockVolthaServiceClient) GetImageStatus(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImageStatus", varargs...)
	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetImageStatus indicates an expected call of GetImageStatus.
func (mr *MockVolthaServiceClientMockRecorder) GetImageStatus(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStatus", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageStatus), varargs...)
}

// GetImages mocks base method.
func (m *MockVolthaServiceClient) GetImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Images, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetImages", varargs...)
	ret0, _ := ret[0].(*voltha.Images)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetImages indicates an expected call of GetImages.
func (mr *MockVolthaServiceClientMockRecorder) GetImages(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImages", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImages), varargs...)
}

// GetLogicalDevice mocks base method.
func (m *MockVolthaServiceClient) GetLogicalDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.LogicalDevice, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetLogicalDevice", varargs...)
	ret0, _ := ret[0].(*voltha.LogicalDevice)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetLogicalDevice indicates an expected call of GetLogicalDevice.
func (mr *MockVolthaServiceClientMockRecorder) GetLogicalDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetLogicalDevice), varargs...)
}

// GetLogicalDevicePort mocks base method.
func (m *MockVolthaServiceClient) GetLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*voltha.LogicalPort, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetLogicalDevicePort", varargs...)
	ret0, _ := ret[0].(*voltha.LogicalPort)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetLogicalDevicePort indicates an expected call of GetLogicalDevicePort.
func (mr *MockVolthaServiceClientMockRecorder) GetLogicalDevicePort(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetLogicalDevicePort), varargs...)
}

// GetMibDeviceData mocks base method.
func (m *MockVolthaServiceClient) GetMibDeviceData(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*omci.MibDeviceData, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetMibDeviceData", varargs...)
	ret0, _ := ret[0].(*omci.MibDeviceData)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetMibDeviceData indicates an expected call of GetMibDeviceData.
func (mr *MockVolthaServiceClientMockRecorder) GetMibDeviceData(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMibDeviceData", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetMibDeviceData), varargs...)
}

// GetOnuImages mocks base method.
func (m *MockVolthaServiceClient) GetOnuImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.OnuImages, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetOnuImages", varargs...)
	ret0, _ := ret[0].(*voltha.OnuImages)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetOnuImages indicates an expected call of GetOnuImages.
func (mr *MockVolthaServiceClientMockRecorder) GetOnuImages(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetOnuImages), varargs...)
}

// GetVoltha mocks base method.
func (m *MockVolthaServiceClient) GetVoltha(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*voltha.Voltha, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetVoltha", varargs...)
	ret0, _ := ret[0].(*voltha.Voltha)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetVoltha indicates an expected call of GetVoltha.
func (mr *MockVolthaServiceClientMockRecorder) GetVoltha(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVoltha", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetVoltha), varargs...)
}

// ListAdapters mocks base method.
func (m *MockVolthaServiceClient) ListAdapters(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*voltha.Adapters, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListAdapters", varargs...)
	ret0, _ := ret[0].(*voltha.Adapters)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListAdapters indicates an expected call of ListAdapters.
func (mr *MockVolthaServiceClientMockRecorder) ListAdapters(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAdapters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListAdapters), varargs...)
}

// ListCoreInstances mocks base method.
func (m *MockVolthaServiceClient) ListCoreInstances(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*voltha.CoreInstances, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListCoreInstances", varargs...)
	ret0, _ := ret[0].(*voltha.CoreInstances)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListCoreInstances indicates an expected call of ListCoreInstances.
func (mr *MockVolthaServiceClientMockRecorder) ListCoreInstances(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCoreInstances", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListCoreInstances), varargs...)
}

// ListDeviceFlowGroups mocks base method.
func (m *MockVolthaServiceClient) ListDeviceFlowGroups(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.FlowGroups, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListDeviceFlowGroups", varargs...)
	ret0, _ := ret[0].(*openflow_13.FlowGroups)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDeviceFlowGroups indicates an expected call of ListDeviceFlowGroups.
func (mr *MockVolthaServiceClientMockRecorder) ListDeviceFlowGroups(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceFlowGroups), varargs...)
}

// ListDeviceFlows mocks base method.
func (m *MockVolthaServiceClient) ListDeviceFlows(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Flows, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListDeviceFlows", varargs...)
	ret0, _ := ret[0].(*openflow_13.Flows)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDeviceFlows indicates an expected call of ListDeviceFlows.
func (mr *MockVolthaServiceClientMockRecorder) ListDeviceFlows(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlows", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceFlows), varargs...)
}

// ListDeviceIds mocks base method.
func (m *MockVolthaServiceClient) ListDeviceIds(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*common.IDs, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListDeviceIds", varargs...)
	ret0, _ := ret[0].(*common.IDs)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDeviceIds indicates an expected call of ListDeviceIds.
func (mr *MockVolthaServiceClientMockRecorder) ListDeviceIds(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceIds", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceIds), varargs...)
}

// ListDevicePmConfigs mocks base method.
func (m *MockVolthaServiceClient) ListDevicePmConfigs(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.PmConfigs, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListDevicePmConfigs", varargs...)
	ret0, _ := ret[0].(*voltha.PmConfigs)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDevicePmConfigs indicates an expected call of ListDevicePmConfigs.
func (mr *MockVolthaServiceClientMockRecorder) ListDevicePmConfigs(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevicePmConfigs), varargs...)
}

// ListDevicePorts mocks base method.
func (m *MockVolthaServiceClient) ListDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Ports, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListDevicePorts", varargs...)
	ret0, _ := ret[0].(*voltha.Ports)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDevicePorts indicates an expected call of ListDevicePorts.
func (mr *MockVolthaServiceClientMockRecorder) ListDevicePorts(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevicePorts), varargs...)
}

// ListDeviceTypes mocks base method.
func (m *MockVolthaServiceClient) ListDeviceTypes(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*voltha.DeviceTypes, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListDeviceTypes", varargs...)
	ret0, _ := ret[0].(*voltha.DeviceTypes)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDeviceTypes indicates an expected call of ListDeviceTypes.
func (mr *MockVolthaServiceClientMockRecorder) ListDeviceTypes(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceTypes", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceTypes), varargs...)
}

// ListDevices mocks base method.
func (m *MockVolthaServiceClient) ListDevices(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*voltha.Devices, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListDevices", varargs...)
	ret0, _ := ret[0].(*voltha.Devices)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListDevices indicates an expected call of ListDevices.
func (mr *MockVolthaServiceClientMockRecorder) ListDevices(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevices), varargs...)
}

// ListEventFilters mocks base method.
func (m *MockVolthaServiceClient) ListEventFilters(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*voltha.EventFilters, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListEventFilters", varargs...)
	ret0, _ := ret[0].(*voltha.EventFilters)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListEventFilters indicates an expected call of ListEventFilters.
func (mr *MockVolthaServiceClientMockRecorder) ListEventFilters(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEventFilters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListEventFilters), varargs...)
}

// ListImageDownloads mocks base method.
func (m *MockVolthaServiceClient) ListImageDownloads(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.ImageDownloads, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListImageDownloads", varargs...)
	ret0, _ := ret[0].(*voltha.ImageDownloads)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListImageDownloads indicates an expected call of ListImageDownloads.
func (mr *MockVolthaServiceClientMockRecorder) ListImageDownloads(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImageDownloads", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListImageDownloads), varargs...)
}

// ListLogicalDeviceFlowGroups mocks base method.
func (m *MockVolthaServiceClient) ListLogicalDeviceFlowGroups(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.FlowGroups, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListLogicalDeviceFlowGroups", varargs...)
	ret0, _ := ret[0].(*openflow_13.FlowGroups)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListLogicalDeviceFlowGroups indicates an expected call of ListLogicalDeviceFlowGroups.
func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceFlowGroups(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceFlowGroups), varargs...)
}

// ListLogicalDeviceFlows mocks base method.
func (m *MockVolthaServiceClient) ListLogicalDeviceFlows(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Flows, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListLogicalDeviceFlows", varargs...)
	ret0, _ := ret[0].(*openflow_13.Flows)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListLogicalDeviceFlows indicates an expected call of ListLogicalDeviceFlows.
func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceFlows(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlows", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceFlows), varargs...)
}

// ListLogicalDeviceMeters mocks base method.
func (m *MockVolthaServiceClient) ListLogicalDeviceMeters(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Meters, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListLogicalDeviceMeters", varargs...)
	ret0, _ := ret[0].(*openflow_13.Meters)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListLogicalDeviceMeters indicates an expected call of ListLogicalDeviceMeters.
func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceMeters(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceMeters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceMeters), varargs...)
}

// ListLogicalDevicePorts mocks base method.
func (m *MockVolthaServiceClient) ListLogicalDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.LogicalPorts, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListLogicalDevicePorts", varargs...)
	ret0, _ := ret[0].(*voltha.LogicalPorts)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListLogicalDevicePorts indicates an expected call of ListLogicalDevicePorts.
func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDevicePorts(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevicePorts", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDevicePorts), varargs...)
}

// ListLogicalDevices mocks base method.
func (m *MockVolthaServiceClient) ListLogicalDevices(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*voltha.LogicalDevices, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ListLogicalDevices", varargs...)
	ret0, _ := ret[0].(*voltha.LogicalDevices)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ListLogicalDevices indicates an expected call of ListLogicalDevices.
func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDevices(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDevices), varargs...)
}

// PutVoipSystemProfile mocks base method.
func (m *MockVolthaServiceClient) PutVoipSystemProfile(ctx context.Context, in *voip_system_profile.VoipSystemProfileRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "PutVoipSystemProfile", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PutVoipSystemProfile indicates an expected call of PutVoipSystemProfile.
func (mr *MockVolthaServiceClientMockRecorder) PutVoipSystemProfile(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutVoipSystemProfile", reflect.TypeOf((*MockVolthaServiceClient)(nil).PutVoipSystemProfile), varargs...)
}

// PutVoipUserProfile mocks base method.
func (m *MockVolthaServiceClient) PutVoipUserProfile(ctx context.Context, in *voip_user_profile.VoipUserProfileRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "PutVoipUserProfile", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PutVoipUserProfile indicates an expected call of PutVoipUserProfile.
func (mr *MockVolthaServiceClientMockRecorder) PutVoipUserProfile(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutVoipUserProfile", reflect.TypeOf((*MockVolthaServiceClient)(nil).PutVoipUserProfile), varargs...)
}

// RebootDevice mocks base method.
func (m *MockVolthaServiceClient) RebootDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "RebootDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// RebootDevice indicates an expected call of RebootDevice.
func (mr *MockVolthaServiceClientMockRecorder) RebootDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).RebootDevice), varargs...)
}

// ReceiveChangeEvents mocks base method.
func (m *MockVolthaServiceClient) ReceiveChangeEvents(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[openflow_13.ChangeEvent], error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ReceiveChangeEvents", varargs...)
	ret0, _ := ret[0].(grpc.ServerStreamingClient[openflow_13.ChangeEvent])
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ReceiveChangeEvents indicates an expected call of ReceiveChangeEvents.
func (mr *MockVolthaServiceClientMockRecorder) ReceiveChangeEvents(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveChangeEvents", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReceiveChangeEvents), varargs...)
}

// ReceivePacketsIn mocks base method.
func (m *MockVolthaServiceClient) ReceivePacketsIn(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (grpc.ServerStreamingClient[openflow_13.PacketIn], error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ReceivePacketsIn", varargs...)
	ret0, _ := ret[0].(grpc.ServerStreamingClient[openflow_13.PacketIn])
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ReceivePacketsIn indicates an expected call of ReceivePacketsIn.
func (mr *MockVolthaServiceClientMockRecorder) ReceivePacketsIn(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivePacketsIn", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReceivePacketsIn), varargs...)
}

// ReconcileDevices mocks base method.
func (m *MockVolthaServiceClient) ReconcileDevices(ctx context.Context, in *common.IDs, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "ReconcileDevices", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ReconcileDevices indicates an expected call of ReconcileDevices.
func (mr *MockVolthaServiceClientMockRecorder) ReconcileDevices(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReconcileDevices), varargs...)
}

// RevertImageUpdate mocks base method.
func (m *MockVolthaServiceClient) RevertImageUpdate(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "RevertImageUpdate", varargs...)
	ret0, _ := ret[0].(*common.OperationResp)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// RevertImageUpdate indicates an expected call of RevertImageUpdate.
func (mr *MockVolthaServiceClientMockRecorder) RevertImageUpdate(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockVolthaServiceClient)(nil).RevertImageUpdate), varargs...)
}

// SelfTest mocks base method.
func (m *MockVolthaServiceClient) SelfTest(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.SelfTestResponse, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "SelfTest", varargs...)
	ret0, _ := ret[0].(*voltha.SelfTestResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// SelfTest indicates an expected call of SelfTest.
func (mr *MockVolthaServiceClientMockRecorder) SelfTest(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTest", reflect.TypeOf((*MockVolthaServiceClient)(nil).SelfTest), varargs...)
}

// SetExtValue mocks base method.
func (m *MockVolthaServiceClient) SetExtValue(ctx context.Context, in *extension.ValueSet, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "SetExtValue", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// SetExtValue indicates an expected call of SetExtValue.
func (mr *MockVolthaServiceClientMockRecorder) SetExtValue(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockVolthaServiceClient)(nil).SetExtValue), varargs...)
}

// SimulateAlarm mocks base method.
func (m *MockVolthaServiceClient) SimulateAlarm(ctx context.Context, in *voltha.SimulateAlarmRequest, opts ...grpc.CallOption) (*common.OperationResp, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "SimulateAlarm", varargs...)
	ret0, _ := ret[0].(*common.OperationResp)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// SimulateAlarm indicates an expected call of SimulateAlarm.
func (mr *MockVolthaServiceClientMockRecorder) SimulateAlarm(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockVolthaServiceClient)(nil).SimulateAlarm), varargs...)
}

// StartOmciTestAction mocks base method.
func (m *MockVolthaServiceClient) StartOmciTestAction(ctx context.Context, in *omci.OmciTestRequest, opts ...grpc.CallOption) (*omci.TestResponse, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "StartOmciTestAction", varargs...)
	ret0, _ := ret[0].(*omci.TestResponse)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// StartOmciTestAction indicates an expected call of StartOmciTestAction.
func (mr *MockVolthaServiceClientMockRecorder) StartOmciTestAction(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTestAction", reflect.TypeOf((*MockVolthaServiceClient)(nil).StartOmciTestAction), varargs...)
}

// StreamPacketsOut mocks base method.
func (m *MockVolthaServiceClient) StreamPacketsOut(ctx context.Context, opts ...grpc.CallOption) (grpc.ClientStreamingClient[openflow_13.PacketOut, emptypb.Empty], error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "StreamPacketsOut", varargs...)
	ret0, _ := ret[0].(grpc.ClientStreamingClient[openflow_13.PacketOut, emptypb.Empty])
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// StreamPacketsOut indicates an expected call of StreamPacketsOut.
func (mr *MockVolthaServiceClientMockRecorder) StreamPacketsOut(ctx any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamPacketsOut", reflect.TypeOf((*MockVolthaServiceClient)(nil).StreamPacketsOut), varargs...)
}

// UpdateDevice mocks base method.
func (m *MockVolthaServiceClient) UpdateDevice(ctx context.Context, in *voltha.UpdateDevice, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateDevice", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateDevice indicates an expected call of UpdateDevice.
func (mr *MockVolthaServiceClientMockRecorder) UpdateDevice(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateDevice), varargs...)
}

// UpdateDevicePmConfigs mocks base method.
func (m *MockVolthaServiceClient) UpdateDevicePmConfigs(ctx context.Context, in *voltha.PmConfigs, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateDevicePmConfigs", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateDevicePmConfigs indicates an expected call of UpdateDevicePmConfigs.
func (mr *MockVolthaServiceClientMockRecorder) UpdateDevicePmConfigs(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateDevicePmConfigs), varargs...)
}

// UpdateEventFilter mocks base method.
func (m *MockVolthaServiceClient) UpdateEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*voltha.EventFilter, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateEventFilter", varargs...)
	ret0, _ := ret[0].(*voltha.EventFilter)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateEventFilter indicates an expected call of UpdateEventFilter.
func (mr *MockVolthaServiceClientMockRecorder) UpdateEventFilter(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateEventFilter), varargs...)
}

// UpdateLogicalDeviceFlowGroupTable mocks base method.
func (m *MockVolthaServiceClient) UpdateLogicalDeviceFlowGroupTable(ctx context.Context, in *openflow_13.FlowGroupTableUpdate, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowGroupTable", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateLogicalDeviceFlowGroupTable indicates an expected call of UpdateLogicalDeviceFlowGroupTable.
func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceFlowGroupTable(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowGroupTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceFlowGroupTable), varargs...)
}

// UpdateLogicalDeviceFlowTable mocks base method.
func (m *MockVolthaServiceClient) UpdateLogicalDeviceFlowTable(ctx context.Context, in *openflow_13.FlowTableUpdate, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowTable", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateLogicalDeviceFlowTable indicates an expected call of UpdateLogicalDeviceFlowTable.
func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceFlowTable(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceFlowTable), varargs...)
}

// UpdateLogicalDeviceMeterTable mocks base method.
func (m *MockVolthaServiceClient) UpdateLogicalDeviceMeterTable(ctx context.Context, in *openflow_13.MeterModUpdate, opts ...grpc.CallOption) (*emptypb.Empty, error) {
	m.ctrl.T.Helper()
	varargs := []any{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "UpdateLogicalDeviceMeterTable", varargs...)
	ret0, _ := ret[0].(*emptypb.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateLogicalDeviceMeterTable indicates an expected call of UpdateLogicalDeviceMeterTable.
func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceMeterTable(ctx, in any, opts ...any) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{ctx, in}, opts...)
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceMeterTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceMeterTable), varargs...)
}
