// Code generated by protoc-gen-go. DO NOT EDIT.
// source: cells.proto

package entities

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type Cells struct {
	Type Cell_Type `protobuf:"varint,1,opt,name=type,proto3,enum=entities.Cell_Type" json:"type,omitempty"`
	// Types that are valid to be assigned to List:
	//	*Cells_ServedCellInfos
	//	*Cells_ServedNrCells
	List                 isCells_List `protobuf_oneof:"list"`
	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
	XXX_unrecognized     []byte       `json:"-"`
	XXX_sizecache        int32        `json:"-"`
}

func (m *Cells) Reset()         { *m = Cells{} }
func (m *Cells) String() string { return proto.CompactTextString(m) }
func (*Cells) ProtoMessage()    {}
func (*Cells) Descriptor() ([]byte, []int) {
	return fileDescriptor_842e821272d22ff7, []int{0}
}

func (m *Cells) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Cells.Unmarshal(m, b)
}
func (m *Cells) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Cells.Marshal(b, m, deterministic)
}
func (m *Cells) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Cells.Merge(m, src)
}
func (m *Cells) XXX_Size() int {
	return xxx_messageInfo_Cells.Size(m)
}
func (m *Cells) XXX_DiscardUnknown() {
	xxx_messageInfo_Cells.DiscardUnknown(m)
}

var xxx_messageInfo_Cells proto.InternalMessageInfo

func (m *Cells) GetType() Cell_Type {
	if m != nil {
		return m.Type
	}
	return Cell_UNKNOWN_CELL
}

type isCells_List interface {
	isCells_List()
}

type Cells_ServedCellInfos struct {
	ServedCellInfos *ServedCellInfoList `protobuf:"bytes,2,opt,name=served_cell_infos,json=servedCellInfos,proto3,oneof"`
}

type Cells_ServedNrCells struct {
	ServedNrCells *ServedNRCellList `protobuf:"bytes,3,opt,name=served_nr_cells,json=servedNrCells,proto3,oneof"`
}

func (*Cells_ServedCellInfos) isCells_List() {}

func (*Cells_ServedNrCells) isCells_List() {}

func (m *Cells) GetList() isCells_List {
	if m != nil {
		return m.List
	}
	return nil
}

func (m *Cells) GetServedCellInfos() *ServedCellInfoList {
	if x, ok := m.GetList().(*Cells_ServedCellInfos); ok {
		return x.ServedCellInfos
	}
	return nil
}

func (m *Cells) GetServedNrCells() *ServedNRCellList {
	if x, ok := m.GetList().(*Cells_ServedNrCells); ok {
		return x.ServedNrCells
	}
	return nil
}

// XXX_OneofWrappers is for the internal use of the proto package.
func (*Cells) XXX_OneofWrappers() []interface{} {
	return []interface{}{
		(*Cells_ServedCellInfos)(nil),
		(*Cells_ServedNrCells)(nil),
	}
}

type ServedCellInfoList struct {
	ServedCells          []*ServedCellInfo `protobuf:"bytes,1,rep,name=served_cells,json=servedCells,proto3" json:"served_cells,omitempty"`
	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
	XXX_unrecognized     []byte            `json:"-"`
	XXX_sizecache        int32             `json:"-"`
}

func (m *ServedCellInfoList) Reset()         { *m = ServedCellInfoList{} }
func (m *ServedCellInfoList) String() string { return proto.CompactTextString(m) }
func (*ServedCellInfoList) ProtoMessage()    {}
func (*ServedCellInfoList) Descriptor() ([]byte, []int) {
	return fileDescriptor_842e821272d22ff7, []int{1}
}

func (m *ServedCellInfoList) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ServedCellInfoList.Unmarshal(m, b)
}
func (m *ServedCellInfoList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ServedCellInfoList.Marshal(b, m, deterministic)
}
func (m *ServedCellInfoList) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ServedCellInfoList.Merge(m, src)
}
func (m *ServedCellInfoList) XXX_Size() int {
	return xxx_messageInfo_ServedCellInfoList.Size(m)
}
func (m *ServedCellInfoList) XXX_DiscardUnknown() {
	xxx_messageInfo_ServedCellInfoList.DiscardUnknown(m)
}

var xxx_messageInfo_ServedCellInfoList proto.InternalMessageInfo

func (m *ServedCellInfoList) GetServedCells() []*ServedCellInfo {
	if m != nil {
		return m.ServedCells
	}
	return nil
}

type ServedNRCellList struct {
	ServedCells          []*ServedNRCell `protobuf:"bytes,1,rep,name=served_cells,json=servedCells,proto3" json:"served_cells,omitempty"`
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

func (m *ServedNRCellList) Reset()         { *m = ServedNRCellList{} }
func (m *ServedNRCellList) String() string { return proto.CompactTextString(m) }
func (*ServedNRCellList) ProtoMessage()    {}
func (*ServedNRCellList) Descriptor() ([]byte, []int) {
	return fileDescriptor_842e821272d22ff7, []int{2}
}

func (m *ServedNRCellList) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ServedNRCellList.Unmarshal(m, b)
}
func (m *ServedNRCellList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ServedNRCellList.Marshal(b, m, deterministic)
}
func (m *ServedNRCellList) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ServedNRCellList.Merge(m, src)
}
func (m *ServedNRCellList) XXX_Size() int {
	return xxx_messageInfo_ServedNRCellList.Size(m)
}
func (m *ServedNRCellList) XXX_DiscardUnknown() {
	xxx_messageInfo_ServedNRCellList.DiscardUnknown(m)
}

var xxx_messageInfo_ServedNRCellList proto.InternalMessageInfo

func (m *ServedNRCellList) GetServedCells() []*ServedNRCell {
	if m != nil {
		return m.ServedCells
	}
	return nil
}

func init() {
	proto.RegisterType((*Cells)(nil), "entities.Cells")
	proto.RegisterType((*ServedCellInfoList)(nil), "entities.ServedCellInfoList")
	proto.RegisterType((*ServedNRCellList)(nil), "entities.ServedNRCellList")
}

func init() { proto.RegisterFile("cells.proto", fileDescriptor_842e821272d22ff7) }

var fileDescriptor_842e821272d22ff7 = []byte{
	// 241 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0x4e, 0xcd, 0xc9,
	0x29, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x48, 0xcd, 0x2b, 0xc9, 0x2c, 0xc9, 0x4c,
	0x2d, 0x96, 0xe2, 0x02, 0x09, 0x43, 0x44, 0xa5, 0x38, 0xd3, 0xf3, 0x92, 0x60, 0xcc, 0x54, 0x18,
	0x53, 0xe9, 0x14, 0x23, 0x17, 0xab, 0x33, 0x48, 0xaf, 0x90, 0x3a, 0x17, 0x4b, 0x49, 0x65, 0x41,
	0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x9f, 0x91, 0xb0, 0x1e, 0xcc, 0x10, 0x3d, 0x90, 0xb4, 0x5e,
	0x48, 0x65, 0x41, 0x6a, 0x10, 0x58, 0x81, 0x90, 0x17, 0x97, 0x60, 0x71, 0x6a, 0x51, 0x59, 0x6a,
	0x4a, 0x3c, 0xc8, 0xf4, 0xf8, 0xcc, 0xbc, 0xb4, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46, 0x0d, 0x6e,
	0x23, 0x19, 0x84, 0xae, 0x60, 0xb0, 0x12, 0x90, 0x5e, 0xcf, 0xbc, 0xb4, 0x7c, 0x9f, 0xcc, 0xe2,
	0x12, 0x0f, 0x86, 0x20, 0xfe, 0x62, 0x14, 0xd1, 0x62, 0x21, 0x17, 0x2e, 0xa8, 0x50, 0x7c, 0x5e,
	0x11, 0xd8, 0xb8, 0x62, 0x09, 0x66, 0xb0, 0x49, 0x52, 0xe8, 0x26, 0xf9, 0x05, 0x81, 0x74, 0x41,
	0xcd, 0xe1, 0x85, 0x68, 0xf2, 0x2b, 0x02, 0x3b, 0xdd, 0x89, 0x8d, 0x8b, 0x25, 0x27, 0xb3, 0xb8,
	0x44, 0x29, 0x90, 0x4b, 0x08, 0xd3, 0x5a, 0x21, 0x6b, 0x2e, 0x1e, 0x24, 0xf7, 0x16, 0x4b, 0x30,
	0x2a, 0x30, 0x6b, 0x70, 0x1b, 0x49, 0xe0, 0x72, 0x6a, 0x10, 0x37, 0xc2, 0x91, 0xc5, 0x4a, 0xbe,
	0x5c, 0x02, 0xe8, 0xf6, 0x0b, 0x59, 0x62, 0x35, 0x50, 0x0c, 0xbb, 0x8b, 0x51, 0x8c, 0x4b, 0x62,
	0x03, 0x87, 0xba, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xde, 0x2b, 0x35, 0x7d, 0xb0, 0x01, 0x00,
	0x00,
}
