/*
* Copyright 2022-present Open Networking Foundation
* 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 MockGen. DO NOT EDIT.
// Source: /home/vinod/go/src/gerrit.opencord.org/voltha-go-controller/vendor/github.com/google/gopacket/packet.go

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

import (
	reflect "reflect"

	gomock "github.com/golang/mock/gomock"
	gopacket "github.com/google/gopacket"
)

// MockPacket is a mock of Packet interface.
type MockPacket struct {
	ctrl     *gomock.Controller
	recorder *MockPacketMockRecorder
}

// MockPacketMockRecorder is the mock recorder for MockPacket.
type MockPacketMockRecorder struct {
	mock *MockPacket
}

// NewMockPacket creates a new mock instance.
func NewMockPacket(ctrl *gomock.Controller) *MockPacket {
	mock := &MockPacket{ctrl: ctrl}
	mock.recorder = &MockPacketMockRecorder{mock}
	return mock
}

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

// ApplicationLayer mocks base method.
func (m *MockPacket) ApplicationLayer() gopacket.ApplicationLayer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ApplicationLayer")
	ret0, _ := ret[0].(gopacket.ApplicationLayer)
	return ret0
}

// ApplicationLayer indicates an expected call of ApplicationLayer.
func (mr *MockPacketMockRecorder) ApplicationLayer() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplicationLayer", reflect.TypeOf((*MockPacket)(nil).ApplicationLayer))
}

// Data mocks base method.
func (m *MockPacket) Data() []byte {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Data")
	ret0, _ := ret[0].([]byte)
	return ret0
}

// Data indicates an expected call of Data.
func (mr *MockPacketMockRecorder) Data() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Data", reflect.TypeOf((*MockPacket)(nil).Data))
}

// Dump mocks base method.
func (m *MockPacket) Dump() string {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Dump")
	ret0, _ := ret[0].(string)
	return ret0
}

// Dump indicates an expected call of Dump.
func (mr *MockPacketMockRecorder) Dump() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Dump", reflect.TypeOf((*MockPacket)(nil).Dump))
}

// ErrorLayer mocks base method.
func (m *MockPacket) ErrorLayer() gopacket.ErrorLayer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ErrorLayer")
	ret0, _ := ret[0].(gopacket.ErrorLayer)
	return ret0
}

// ErrorLayer indicates an expected call of ErrorLayer.
func (mr *MockPacketMockRecorder) ErrorLayer() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ErrorLayer", reflect.TypeOf((*MockPacket)(nil).ErrorLayer))
}

// Layer mocks base method.
func (m *MockPacket) Layer(arg0 gopacket.LayerType) gopacket.Layer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Layer", arg0)
	ret0, _ := ret[0].(gopacket.Layer)
	return ret0
}

// Layer indicates an expected call of Layer.
func (mr *MockPacketMockRecorder) Layer(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Layer", reflect.TypeOf((*MockPacket)(nil).Layer), arg0)
}

// LayerClass mocks base method.
func (m *MockPacket) LayerClass(arg0 gopacket.LayerClass) gopacket.Layer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LayerClass", arg0)
	ret0, _ := ret[0].(gopacket.Layer)
	return ret0
}

// LayerClass indicates an expected call of LayerClass.
func (mr *MockPacketMockRecorder) LayerClass(arg0 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LayerClass", reflect.TypeOf((*MockPacket)(nil).LayerClass), arg0)
}

// Layers mocks base method.
func (m *MockPacket) Layers() []gopacket.Layer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Layers")
	ret0, _ := ret[0].([]gopacket.Layer)
	return ret0
}

// Layers indicates an expected call of Layers.
func (mr *MockPacketMockRecorder) Layers() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Layers", reflect.TypeOf((*MockPacket)(nil).Layers))
}

// LinkLayer mocks base method.
func (m *MockPacket) LinkLayer() gopacket.LinkLayer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "LinkLayer")
	ret0, _ := ret[0].(gopacket.LinkLayer)
	return ret0
}

// LinkLayer indicates an expected call of LinkLayer.
func (mr *MockPacketMockRecorder) LinkLayer() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LinkLayer", reflect.TypeOf((*MockPacket)(nil).LinkLayer))
}

// Metadata mocks base method.
func (m *MockPacket) Metadata() *gopacket.PacketMetadata {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Metadata")
	ret0, _ := ret[0].(*gopacket.PacketMetadata)
	return ret0
}

// Metadata indicates an expected call of Metadata.
func (mr *MockPacketMockRecorder) Metadata() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Metadata", reflect.TypeOf((*MockPacket)(nil).Metadata))
}

// NetworkLayer mocks base method.
func (m *MockPacket) NetworkLayer() gopacket.NetworkLayer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "NetworkLayer")
	ret0, _ := ret[0].(gopacket.NetworkLayer)
	return ret0
}

// NetworkLayer indicates an expected call of NetworkLayer.
func (mr *MockPacketMockRecorder) NetworkLayer() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetworkLayer", reflect.TypeOf((*MockPacket)(nil).NetworkLayer))
}

// String mocks base method.
func (m *MockPacket) String() string {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "String")
	ret0, _ := ret[0].(string)
	return ret0
}

// String indicates an expected call of String.
func (mr *MockPacketMockRecorder) String() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "String", reflect.TypeOf((*MockPacket)(nil).String))
}

// TransportLayer mocks base method.
func (m *MockPacket) TransportLayer() gopacket.TransportLayer {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "TransportLayer")
	ret0, _ := ret[0].(gopacket.TransportLayer)
	return ret0
}

// TransportLayer indicates an expected call of TransportLayer.
func (mr *MockPacketMockRecorder) TransportLayer() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransportLayer", reflect.TypeOf((*MockPacket)(nil).TransportLayer))
}

// MockDumper is a mock of Dumper interface.
type MockDumper struct {
	ctrl     *gomock.Controller
	recorder *MockDumperMockRecorder
}

// MockDumperMockRecorder is the mock recorder for MockDumper.
type MockDumperMockRecorder struct {
	mock *MockDumper
}

// NewMockDumper creates a new mock instance.
func NewMockDumper(ctrl *gomock.Controller) *MockDumper {
	mock := &MockDumper{ctrl: ctrl}
	mock.recorder = &MockDumperMockRecorder{mock}
	return mock
}

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

// Dump mocks base method.
func (m *MockDumper) Dump() string {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Dump")
	ret0, _ := ret[0].(string)
	return ret0
}

// Dump indicates an expected call of Dump.
func (mr *MockDumperMockRecorder) Dump() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Dump", reflect.TypeOf((*MockDumper)(nil).Dump))
}

// MockPacketDataSource is a mock of PacketDataSource interface.
type MockPacketDataSource struct {
	ctrl     *gomock.Controller
	recorder *MockPacketDataSourceMockRecorder
}

// MockPacketDataSourceMockRecorder is the mock recorder for MockPacketDataSource.
type MockPacketDataSourceMockRecorder struct {
	mock *MockPacketDataSource
}

// NewMockPacketDataSource creates a new mock instance.
func NewMockPacketDataSource(ctrl *gomock.Controller) *MockPacketDataSource {
	mock := &MockPacketDataSource{ctrl: ctrl}
	mock.recorder = &MockPacketDataSourceMockRecorder{mock}
	return mock
}

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

// ReadPacketData mocks base method.
func (m *MockPacketDataSource) ReadPacketData() ([]byte, gopacket.CaptureInfo, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ReadPacketData")
	ret0, _ := ret[0].([]byte)
	ret1, _ := ret[1].(gopacket.CaptureInfo)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// ReadPacketData indicates an expected call of ReadPacketData.
func (mr *MockPacketDataSourceMockRecorder) ReadPacketData() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPacketData", reflect.TypeOf((*MockPacketDataSource)(nil).ReadPacketData))
}

// MockZeroCopyPacketDataSource is a mock of ZeroCopyPacketDataSource interface.
type MockZeroCopyPacketDataSource struct {
	ctrl     *gomock.Controller
	recorder *MockZeroCopyPacketDataSourceMockRecorder
}

// MockZeroCopyPacketDataSourceMockRecorder is the mock recorder for MockZeroCopyPacketDataSource.
type MockZeroCopyPacketDataSourceMockRecorder struct {
	mock *MockZeroCopyPacketDataSource
}

// NewMockZeroCopyPacketDataSource creates a new mock instance.
func NewMockZeroCopyPacketDataSource(ctrl *gomock.Controller) *MockZeroCopyPacketDataSource {
	mock := &MockZeroCopyPacketDataSource{ctrl: ctrl}
	mock.recorder = &MockZeroCopyPacketDataSourceMockRecorder{mock}
	return mock
}

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

// ZeroCopyReadPacketData mocks base method.
func (m *MockZeroCopyPacketDataSource) ZeroCopyReadPacketData() ([]byte, gopacket.CaptureInfo, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ZeroCopyReadPacketData")
	ret0, _ := ret[0].([]byte)
	ret1, _ := ret[1].(gopacket.CaptureInfo)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// ZeroCopyReadPacketData indicates an expected call of ZeroCopyReadPacketData.
func (mr *MockZeroCopyPacketDataSourceMockRecorder) ZeroCopyReadPacketData() *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ZeroCopyReadPacketData", reflect.TypeOf((*MockZeroCopyPacketDataSource)(nil).ZeroCopyReadPacketData))
}
