//
// Copyright 2019 AT&T Intellectual Property
// Copyright 2019 Nokia
//
// 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.

//
// This source code is part of the near-RT RIC (RAN Intelligent Controller)
// platform project (RICP).

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.26.0
// 	protoc        v3.15.8
// source: ran_function.proto

package entities

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type RanFunction struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	RanFunctionId         uint32 `protobuf:"varint,1,opt,name=ran_function_id,json=ranFunctionId,proto3" json:"ran_function_id,omitempty"`
	RanFunctionDefinition string `protobuf:"bytes,2,opt,name=ran_function_definition,json=ranFunctionDefinition,proto3" json:"ran_function_definition,omitempty"`
	RanFunctionRevision   uint32 `protobuf:"varint,3,opt,name=ran_function_revision,json=ranFunctionRevision,proto3" json:"ran_function_revision,omitempty"`
	RanFunctionOid        string `protobuf:"bytes,4,opt,name=ran_function_oid,json=ranFunctionOid,proto3" json:"ran_function_oid,omitempty"`
}

func (x *RanFunction) Reset() {
	*x = RanFunction{}
	if protoimpl.UnsafeEnabled {
		mi := &file_ran_function_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *RanFunction) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*RanFunction) ProtoMessage() {}

func (x *RanFunction) ProtoReflect() protoreflect.Message {
	mi := &file_ran_function_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use RanFunction.ProtoReflect.Descriptor instead.
func (*RanFunction) Descriptor() ([]byte, []int) {
	return file_ran_function_proto_rawDescGZIP(), []int{0}
}

func (x *RanFunction) GetRanFunctionId() uint32 {
	if x != nil {
		return x.RanFunctionId
	}
	return 0
}

func (x *RanFunction) GetRanFunctionDefinition() string {
	if x != nil {
		return x.RanFunctionDefinition
	}
	return ""
}

func (x *RanFunction) GetRanFunctionRevision() uint32 {
	if x != nil {
		return x.RanFunctionRevision
	}
	return 0
}

func (x *RanFunction) GetRanFunctionOid() string {
	if x != nil {
		return x.RanFunctionOid
	}
	return ""
}

var File_ran_function_proto protoreflect.FileDescriptor

var file_ran_function_proto_rawDesc = []byte{
	0x0a, 0x12, 0x72, 0x61, 0x6e, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xcb,
	0x01, 0x0a, 0x0b, 0x52, 0x61, 0x6e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26,
	0x0a, 0x0f, 0x72, 0x61, 0x6e, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x72, 0x61, 0x6e, 0x46, 0x75, 0x6e, 0x63,
	0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x61, 0x6e, 0x5f, 0x66, 0x75,
	0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f,
	0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x72, 0x61, 0x6e, 0x46, 0x75, 0x6e, 0x63,
	0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32,
	0x0a, 0x15, 0x72, 0x61, 0x6e, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72,
	0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x72,
	0x61, 0x6e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69,
	0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x72, 0x61, 0x6e, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
	0x6f, 0x6e, 0x5f, 0x6f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x61,
	0x6e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x69, 0x64, 0x42, 0x33, 0x5a, 0x31,
	0x67, 0x65, 0x72, 0x72, 0x69, 0x74, 0x2e, 0x6f, 0x2d, 0x72, 0x61, 0x6e, 0x2d, 0x73, 0x63, 0x2e,
	0x6f, 0x72, 0x67, 0x2f, 0x72, 0x2f, 0x72, 0x69, 0x63, 0x2d, 0x70, 0x6c, 0x74, 0x2f, 0x6e, 0x6f,
	0x64, 0x65, 0x62, 0x2d, 0x72, 0x6e, 0x69, 0x62, 0x2f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65,
	0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_ran_function_proto_rawDescOnce sync.Once
	file_ran_function_proto_rawDescData = file_ran_function_proto_rawDesc
)

func file_ran_function_proto_rawDescGZIP() []byte {
	file_ran_function_proto_rawDescOnce.Do(func() {
		file_ran_function_proto_rawDescData = protoimpl.X.CompressGZIP(file_ran_function_proto_rawDescData)
	})
	return file_ran_function_proto_rawDescData
}

var file_ran_function_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_ran_function_proto_goTypes = []interface{}{
	(*RanFunction)(nil), // 0: entities.RanFunction
}
var file_ran_function_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_ran_function_proto_init() }
func file_ran_function_proto_init() {
	if File_ran_function_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_ran_function_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RanFunction); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_ran_function_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_ran_function_proto_goTypes,
		DependencyIndexes: file_ran_function_proto_depIdxs,
		MessageInfos:      file_ran_function_proto_msgTypes,
	}.Build()
	File_ran_function_proto = out.File
	file_ran_function_proto_rawDesc = nil
	file_ran_function_proto_goTypes = nil
	file_ran_function_proto_depIdxs = nil
}
