// Copyright 2020-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. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.36.11
// 	protoc        v4.25.8
// source: voltha_protos/ext_config.proto

package config

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

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 OnuItuPonAlarm_AlarmID int32

const (
	OnuItuPonAlarm_RDI_ERRORS OnuItuPonAlarm_AlarmID = 0 // RDI errors
)

// Enum value maps for OnuItuPonAlarm_AlarmID.
var (
	OnuItuPonAlarm_AlarmID_name = map[int32]string{
		0: "RDI_ERRORS",
	}
	OnuItuPonAlarm_AlarmID_value = map[string]int32{
		"RDI_ERRORS": 0,
	}
)

func (x OnuItuPonAlarm_AlarmID) Enum() *OnuItuPonAlarm_AlarmID {
	p := new(OnuItuPonAlarm_AlarmID)
	*p = x
	return p
}

func (x OnuItuPonAlarm_AlarmID) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (OnuItuPonAlarm_AlarmID) Descriptor() protoreflect.EnumDescriptor {
	return file_voltha_protos_ext_config_proto_enumTypes[0].Descriptor()
}

func (OnuItuPonAlarm_AlarmID) Type() protoreflect.EnumType {
	return &file_voltha_protos_ext_config_proto_enumTypes[0]
}

func (x OnuItuPonAlarm_AlarmID) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use OnuItuPonAlarm_AlarmID.Descriptor instead.
func (OnuItuPonAlarm_AlarmID) EnumDescriptor() ([]byte, []int) {
	return file_voltha_protos_ext_config_proto_rawDescGZIP(), []int{1, 0}
}

type OnuItuPonAlarm_AlarmReportingCondition int32

const (
	OnuItuPonAlarm_RATE_THRESHOLD  OnuItuPonAlarm_AlarmReportingCondition = 0 // The alarm is triggered if the stats delta value between samples crosses the configured threshold boundary
	OnuItuPonAlarm_RATE_RANGE      OnuItuPonAlarm_AlarmReportingCondition = 1 // The alarm is triggered if the stats delta value between samples deviates from the configured range
	OnuItuPonAlarm_VALUE_THRESHOLD OnuItuPonAlarm_AlarmReportingCondition = 2 // The alarm is raised if the stats sample value becomes greater than this level.  The alarm is cleared when the host read the stats
)

// Enum value maps for OnuItuPonAlarm_AlarmReportingCondition.
var (
	OnuItuPonAlarm_AlarmReportingCondition_name = map[int32]string{
		0: "RATE_THRESHOLD",
		1: "RATE_RANGE",
		2: "VALUE_THRESHOLD",
	}
	OnuItuPonAlarm_AlarmReportingCondition_value = map[string]int32{
		"RATE_THRESHOLD":  0,
		"RATE_RANGE":      1,
		"VALUE_THRESHOLD": 2,
	}
)

func (x OnuItuPonAlarm_AlarmReportingCondition) Enum() *OnuItuPonAlarm_AlarmReportingCondition {
	p := new(OnuItuPonAlarm_AlarmReportingCondition)
	*p = x
	return p
}

func (x OnuItuPonAlarm_AlarmReportingCondition) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (OnuItuPonAlarm_AlarmReportingCondition) Descriptor() protoreflect.EnumDescriptor {
	return file_voltha_protos_ext_config_proto_enumTypes[1].Descriptor()
}

func (OnuItuPonAlarm_AlarmReportingCondition) Type() protoreflect.EnumType {
	return &file_voltha_protos_ext_config_proto_enumTypes[1]
}

func (x OnuItuPonAlarm_AlarmReportingCondition) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use OnuItuPonAlarm_AlarmReportingCondition.Descriptor instead.
func (OnuItuPonAlarm_AlarmReportingCondition) EnumDescriptor() ([]byte, []int) {
	return file_voltha_protos_ext_config_proto_rawDescGZIP(), []int{1, 1}
}

type AlarmConfig struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// Types that are valid to be assigned to Config:
	//
	//	*AlarmConfig_OnuItuPonAlarmConfig
	Config        isAlarmConfig_Config `protobuf_oneof:"config"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *AlarmConfig) Reset() {
	*x = AlarmConfig{}
	mi := &file_voltha_protos_ext_config_proto_msgTypes[0]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*AlarmConfig) ProtoMessage() {}

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

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

func (x *AlarmConfig) GetConfig() isAlarmConfig_Config {
	if x != nil {
		return x.Config
	}
	return nil
}

func (x *AlarmConfig) GetOnuItuPonAlarmConfig() *OnuItuPonAlarm {
	if x != nil {
		if x, ok := x.Config.(*AlarmConfig_OnuItuPonAlarmConfig); ok {
			return x.OnuItuPonAlarmConfig
		}
	}
	return nil
}

type isAlarmConfig_Config interface {
	isAlarmConfig_Config()
}

type AlarmConfig_OnuItuPonAlarmConfig struct {
	OnuItuPonAlarmConfig *OnuItuPonAlarm `protobuf:"bytes,1,opt,name=onu_itu_pon_alarm_config,json=onuItuPonAlarmConfig,proto3,oneof"`
}

func (*AlarmConfig_OnuItuPonAlarmConfig) isAlarmConfig_Config() {}

type OnuItuPonAlarm struct {
	state                   protoimpl.MessageState                 `protogen:"open.v1"`
	PonNi                   uint32                                 `protobuf:"fixed32,1,opt,name=pon_ni,json=ponNi,proto3" json:"pon_ni,omitempty"`
	OnuId                   uint32                                 `protobuf:"fixed32,2,opt,name=onu_id,json=onuId,proto3" json:"onu_id,omitempty"`
	AlarmId                 OnuItuPonAlarm_AlarmID                 `protobuf:"varint,3,opt,name=alarm_id,json=alarmId,proto3,enum=config.OnuItuPonAlarm_AlarmID" json:"alarm_id,omitempty"`
	AlarmReportingCondition OnuItuPonAlarm_AlarmReportingCondition `protobuf:"varint,4,opt,name=alarm_reporting_condition,json=alarmReportingCondition,proto3,enum=config.OnuItuPonAlarm_AlarmReportingCondition" json:"alarm_reporting_condition,omitempty"`
	// Types that are valid to be assigned to Config:
	//
	//	*OnuItuPonAlarm_RateThresholdConfig_
	//	*OnuItuPonAlarm_RateRangeConfig_
	//	*OnuItuPonAlarm_ValueThresholdConfig_
	Config        isOnuItuPonAlarm_Config `protobuf_oneof:"config"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *OnuItuPonAlarm) Reset() {
	*x = OnuItuPonAlarm{}
	mi := &file_voltha_protos_ext_config_proto_msgTypes[1]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*OnuItuPonAlarm) ProtoMessage() {}

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

// Deprecated: Use OnuItuPonAlarm.ProtoReflect.Descriptor instead.
func (*OnuItuPonAlarm) Descriptor() ([]byte, []int) {
	return file_voltha_protos_ext_config_proto_rawDescGZIP(), []int{1}
}

func (x *OnuItuPonAlarm) GetPonNi() uint32 {
	if x != nil {
		return x.PonNi
	}
	return 0
}

func (x *OnuItuPonAlarm) GetOnuId() uint32 {
	if x != nil {
		return x.OnuId
	}
	return 0
}

func (x *OnuItuPonAlarm) GetAlarmId() OnuItuPonAlarm_AlarmID {
	if x != nil {
		return x.AlarmId
	}
	return OnuItuPonAlarm_RDI_ERRORS
}

func (x *OnuItuPonAlarm) GetAlarmReportingCondition() OnuItuPonAlarm_AlarmReportingCondition {
	if x != nil {
		return x.AlarmReportingCondition
	}
	return OnuItuPonAlarm_RATE_THRESHOLD
}

func (x *OnuItuPonAlarm) GetConfig() isOnuItuPonAlarm_Config {
	if x != nil {
		return x.Config
	}
	return nil
}

func (x *OnuItuPonAlarm) GetRateThresholdConfig() *OnuItuPonAlarm_RateThresholdConfig {
	if x != nil {
		if x, ok := x.Config.(*OnuItuPonAlarm_RateThresholdConfig_); ok {
			return x.RateThresholdConfig
		}
	}
	return nil
}

func (x *OnuItuPonAlarm) GetRateRangeConfig() *OnuItuPonAlarm_RateRangeConfig {
	if x != nil {
		if x, ok := x.Config.(*OnuItuPonAlarm_RateRangeConfig_); ok {
			return x.RateRangeConfig
		}
	}
	return nil
}

func (x *OnuItuPonAlarm) GetValueThresholdConfig() *OnuItuPonAlarm_ValueThresholdConfig {
	if x != nil {
		if x, ok := x.Config.(*OnuItuPonAlarm_ValueThresholdConfig_); ok {
			return x.ValueThresholdConfig
		}
	}
	return nil
}

type isOnuItuPonAlarm_Config interface {
	isOnuItuPonAlarm_Config()
}

type OnuItuPonAlarm_RateThresholdConfig_ struct {
	RateThresholdConfig *OnuItuPonAlarm_RateThresholdConfig `protobuf:"bytes,5,opt,name=rate_threshold_config,json=rateThresholdConfig,proto3,oneof"`
}

type OnuItuPonAlarm_RateRangeConfig_ struct {
	RateRangeConfig *OnuItuPonAlarm_RateRangeConfig `protobuf:"bytes,6,opt,name=rate_range_config,json=rateRangeConfig,proto3,oneof"`
}

type OnuItuPonAlarm_ValueThresholdConfig_ struct {
	ValueThresholdConfig *OnuItuPonAlarm_ValueThresholdConfig `protobuf:"bytes,7,opt,name=value_threshold_config,json=valueThresholdConfig,proto3,oneof"`
}

func (*OnuItuPonAlarm_RateThresholdConfig_) isOnuItuPonAlarm_Config() {}

func (*OnuItuPonAlarm_RateRangeConfig_) isOnuItuPonAlarm_Config() {}

func (*OnuItuPonAlarm_ValueThresholdConfig_) isOnuItuPonAlarm_Config() {}

type OnuItuPonAlarm_SoakTime struct {
	state          protoimpl.MessageState `protogen:"open.v1"`
	ActiveSoakTime uint32                 `protobuf:"fixed32,1,opt,name=active_soak_time,json=activeSoakTime,proto3" json:"active_soak_time,omitempty"`
	ClearSoakTime  uint32                 `protobuf:"fixed32,2,opt,name=clear_soak_time,json=clearSoakTime,proto3" json:"clear_soak_time,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *OnuItuPonAlarm_SoakTime) Reset() {
	*x = OnuItuPonAlarm_SoakTime{}
	mi := &file_voltha_protos_ext_config_proto_msgTypes[2]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*OnuItuPonAlarm_SoakTime) ProtoMessage() {}

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

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

func (x *OnuItuPonAlarm_SoakTime) GetActiveSoakTime() uint32 {
	if x != nil {
		return x.ActiveSoakTime
	}
	return 0
}

func (x *OnuItuPonAlarm_SoakTime) GetClearSoakTime() uint32 {
	if x != nil {
		return x.ClearSoakTime
	}
	return 0
}

type OnuItuPonAlarm_RateThresholdConfig struct {
	state                protoimpl.MessageState   `protogen:"open.v1"`
	RateThresholdRising  uint64                   `protobuf:"fixed64,1,opt,name=rate_threshold_rising,json=rateThresholdRising,proto3" json:"rate_threshold_rising,omitempty"`
	RateThresholdFalling uint64                   `protobuf:"fixed64,2,opt,name=rate_threshold_falling,json=rateThresholdFalling,proto3" json:"rate_threshold_falling,omitempty"`
	SoakTime             *OnuItuPonAlarm_SoakTime `protobuf:"bytes,3,opt,name=soak_time,json=soakTime,proto3" json:"soak_time,omitempty"`
	unknownFields        protoimpl.UnknownFields
	sizeCache            protoimpl.SizeCache
}

func (x *OnuItuPonAlarm_RateThresholdConfig) Reset() {
	*x = OnuItuPonAlarm_RateThresholdConfig{}
	mi := &file_voltha_protos_ext_config_proto_msgTypes[3]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*OnuItuPonAlarm_RateThresholdConfig) ProtoMessage() {}

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

// Deprecated: Use OnuItuPonAlarm_RateThresholdConfig.ProtoReflect.Descriptor instead.
func (*OnuItuPonAlarm_RateThresholdConfig) Descriptor() ([]byte, []int) {
	return file_voltha_protos_ext_config_proto_rawDescGZIP(), []int{1, 1}
}

func (x *OnuItuPonAlarm_RateThresholdConfig) GetRateThresholdRising() uint64 {
	if x != nil {
		return x.RateThresholdRising
	}
	return 0
}

func (x *OnuItuPonAlarm_RateThresholdConfig) GetRateThresholdFalling() uint64 {
	if x != nil {
		return x.RateThresholdFalling
	}
	return 0
}

func (x *OnuItuPonAlarm_RateThresholdConfig) GetSoakTime() *OnuItuPonAlarm_SoakTime {
	if x != nil {
		return x.SoakTime
	}
	return nil
}

type OnuItuPonAlarm_RateRangeConfig struct {
	state          protoimpl.MessageState   `protogen:"open.v1"`
	RateRangeLower uint64                   `protobuf:"fixed64,1,opt,name=rate_range_lower,json=rateRangeLower,proto3" json:"rate_range_lower,omitempty"`
	RateRangeUpper uint64                   `protobuf:"fixed64,2,opt,name=rate_range_upper,json=rateRangeUpper,proto3" json:"rate_range_upper,omitempty"`
	SoakTime       *OnuItuPonAlarm_SoakTime `protobuf:"bytes,3,opt,name=soak_time,json=soakTime,proto3" json:"soak_time,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *OnuItuPonAlarm_RateRangeConfig) Reset() {
	*x = OnuItuPonAlarm_RateRangeConfig{}
	mi := &file_voltha_protos_ext_config_proto_msgTypes[4]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*OnuItuPonAlarm_RateRangeConfig) ProtoMessage() {}

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

// Deprecated: Use OnuItuPonAlarm_RateRangeConfig.ProtoReflect.Descriptor instead.
func (*OnuItuPonAlarm_RateRangeConfig) Descriptor() ([]byte, []int) {
	return file_voltha_protos_ext_config_proto_rawDescGZIP(), []int{1, 2}
}

func (x *OnuItuPonAlarm_RateRangeConfig) GetRateRangeLower() uint64 {
	if x != nil {
		return x.RateRangeLower
	}
	return 0
}

func (x *OnuItuPonAlarm_RateRangeConfig) GetRateRangeUpper() uint64 {
	if x != nil {
		return x.RateRangeUpper
	}
	return 0
}

func (x *OnuItuPonAlarm_RateRangeConfig) GetSoakTime() *OnuItuPonAlarm_SoakTime {
	if x != nil {
		return x.SoakTime
	}
	return nil
}

type OnuItuPonAlarm_ValueThresholdConfig struct {
	state          protoimpl.MessageState   `protogen:"open.v1"`
	ThresholdLimit uint64                   `protobuf:"fixed64,1,opt,name=threshold_limit,json=thresholdLimit,proto3" json:"threshold_limit,omitempty"`
	SoakTime       *OnuItuPonAlarm_SoakTime `protobuf:"bytes,2,opt,name=soak_time,json=soakTime,proto3" json:"soak_time,omitempty"`
	unknownFields  protoimpl.UnknownFields
	sizeCache      protoimpl.SizeCache
}

func (x *OnuItuPonAlarm_ValueThresholdConfig) Reset() {
	*x = OnuItuPonAlarm_ValueThresholdConfig{}
	mi := &file_voltha_protos_ext_config_proto_msgTypes[5]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

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

func (*OnuItuPonAlarm_ValueThresholdConfig) ProtoMessage() {}

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

// Deprecated: Use OnuItuPonAlarm_ValueThresholdConfig.ProtoReflect.Descriptor instead.
func (*OnuItuPonAlarm_ValueThresholdConfig) Descriptor() ([]byte, []int) {
	return file_voltha_protos_ext_config_proto_rawDescGZIP(), []int{1, 3}
}

func (x *OnuItuPonAlarm_ValueThresholdConfig) GetThresholdLimit() uint64 {
	if x != nil {
		return x.ThresholdLimit
	}
	return 0
}

func (x *OnuItuPonAlarm_ValueThresholdConfig) GetSoakTime() *OnuItuPonAlarm_SoakTime {
	if x != nil {
		return x.SoakTime
	}
	return nil
}

var File_voltha_protos_ext_config_proto protoreflect.FileDescriptor

const file_voltha_protos_ext_config_proto_rawDesc = "" +
	"\n" +
	"\x1evoltha_protos/ext_config.proto\x12\x06config\"i\n" +
	"\vAlarmConfig\x12P\n" +
	"\x18onu_itu_pon_alarm_config\x18\x01 \x01(\v2\x16.config.OnuItuPonAlarmH\x00R\x14onuItuPonAlarmConfigB\b\n" +
	"\x06config\"\xbe\t\n" +
	"\x0eOnuItuPonAlarm\x12\x15\n" +
	"\x06pon_ni\x18\x01 \x01(\aR\x05ponNi\x12\x15\n" +
	"\x06onu_id\x18\x02 \x01(\aR\x05onuId\x129\n" +
	"\balarm_id\x18\x03 \x01(\x0e2\x1e.config.OnuItuPonAlarm.AlarmIDR\aalarmId\x12j\n" +
	"\x19alarm_reporting_condition\x18\x04 \x01(\x0e2..config.OnuItuPonAlarm.AlarmReportingConditionR\x17alarmReportingCondition\x12`\n" +
	"\x15rate_threshold_config\x18\x05 \x01(\v2*.config.OnuItuPonAlarm.RateThresholdConfigH\x00R\x13rateThresholdConfig\x12T\n" +
	"\x11rate_range_config\x18\x06 \x01(\v2&.config.OnuItuPonAlarm.RateRangeConfigH\x00R\x0frateRangeConfig\x12c\n" +
	"\x16value_threshold_config\x18\a \x01(\v2+.config.OnuItuPonAlarm.ValueThresholdConfigH\x00R\x14valueThresholdConfig\x1a\\\n" +
	"\bSoakTime\x12(\n" +
	"\x10active_soak_time\x18\x01 \x01(\aR\x0eactiveSoakTime\x12&\n" +
	"\x0fclear_soak_time\x18\x02 \x01(\aR\rclearSoakTime\x1a\xbd\x01\n" +
	"\x13RateThresholdConfig\x122\n" +
	"\x15rate_threshold_rising\x18\x01 \x01(\x06R\x13rateThresholdRising\x124\n" +
	"\x16rate_threshold_falling\x18\x02 \x01(\x06R\x14rateThresholdFalling\x12<\n" +
	"\tsoak_time\x18\x03 \x01(\v2\x1f.config.OnuItuPonAlarm.SoakTimeR\bsoakTime\x1a\xa3\x01\n" +
	"\x0fRateRangeConfig\x12(\n" +
	"\x10rate_range_lower\x18\x01 \x01(\x06R\x0erateRangeLower\x12(\n" +
	"\x10rate_range_upper\x18\x02 \x01(\x06R\x0erateRangeUpper\x12<\n" +
	"\tsoak_time\x18\x03 \x01(\v2\x1f.config.OnuItuPonAlarm.SoakTimeR\bsoakTime\x1a}\n" +
	"\x14ValueThresholdConfig\x12'\n" +
	"\x0fthreshold_limit\x18\x01 \x01(\x06R\x0ethresholdLimit\x12<\n" +
	"\tsoak_time\x18\x02 \x01(\v2\x1f.config.OnuItuPonAlarm.SoakTimeR\bsoakTime\"\x19\n" +
	"\aAlarmID\x12\x0e\n" +
	"\n" +
	"RDI_ERRORS\x10\x00\"R\n" +
	"\x17AlarmReportingCondition\x12\x12\n" +
	"\x0eRATE_THRESHOLD\x10\x00\x12\x0e\n" +
	"\n" +
	"RATE_RANGE\x10\x01\x12\x13\n" +
	"\x0fVALUE_THRESHOLD\x10\x02B\b\n" +
	"\x06configBI\n" +
	"\x13org.opencord.volthaZ2github.com/opencord/voltha-protos/v5/go/ext/configb\x06proto3"

var (
	file_voltha_protos_ext_config_proto_rawDescOnce sync.Once
	file_voltha_protos_ext_config_proto_rawDescData []byte
)

func file_voltha_protos_ext_config_proto_rawDescGZIP() []byte {
	file_voltha_protos_ext_config_proto_rawDescOnce.Do(func() {
		file_voltha_protos_ext_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_voltha_protos_ext_config_proto_rawDesc), len(file_voltha_protos_ext_config_proto_rawDesc)))
	})
	return file_voltha_protos_ext_config_proto_rawDescData
}

var file_voltha_protos_ext_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_voltha_protos_ext_config_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_voltha_protos_ext_config_proto_goTypes = []any{
	(OnuItuPonAlarm_AlarmID)(0),                 // 0: config.OnuItuPonAlarm.AlarmID
	(OnuItuPonAlarm_AlarmReportingCondition)(0), // 1: config.OnuItuPonAlarm.AlarmReportingCondition
	(*AlarmConfig)(nil),                         // 2: config.AlarmConfig
	(*OnuItuPonAlarm)(nil),                      // 3: config.OnuItuPonAlarm
	(*OnuItuPonAlarm_SoakTime)(nil),             // 4: config.OnuItuPonAlarm.SoakTime
	(*OnuItuPonAlarm_RateThresholdConfig)(nil),  // 5: config.OnuItuPonAlarm.RateThresholdConfig
	(*OnuItuPonAlarm_RateRangeConfig)(nil),      // 6: config.OnuItuPonAlarm.RateRangeConfig
	(*OnuItuPonAlarm_ValueThresholdConfig)(nil), // 7: config.OnuItuPonAlarm.ValueThresholdConfig
}
var file_voltha_protos_ext_config_proto_depIdxs = []int32{
	3, // 0: config.AlarmConfig.onu_itu_pon_alarm_config:type_name -> config.OnuItuPonAlarm
	0, // 1: config.OnuItuPonAlarm.alarm_id:type_name -> config.OnuItuPonAlarm.AlarmID
	1, // 2: config.OnuItuPonAlarm.alarm_reporting_condition:type_name -> config.OnuItuPonAlarm.AlarmReportingCondition
	5, // 3: config.OnuItuPonAlarm.rate_threshold_config:type_name -> config.OnuItuPonAlarm.RateThresholdConfig
	6, // 4: config.OnuItuPonAlarm.rate_range_config:type_name -> config.OnuItuPonAlarm.RateRangeConfig
	7, // 5: config.OnuItuPonAlarm.value_threshold_config:type_name -> config.OnuItuPonAlarm.ValueThresholdConfig
	4, // 6: config.OnuItuPonAlarm.RateThresholdConfig.soak_time:type_name -> config.OnuItuPonAlarm.SoakTime
	4, // 7: config.OnuItuPonAlarm.RateRangeConfig.soak_time:type_name -> config.OnuItuPonAlarm.SoakTime
	4, // 8: config.OnuItuPonAlarm.ValueThresholdConfig.soak_time:type_name -> config.OnuItuPonAlarm.SoakTime
	9, // [9:9] is the sub-list for method output_type
	9, // [9:9] is the sub-list for method input_type
	9, // [9:9] is the sub-list for extension type_name
	9, // [9:9] is the sub-list for extension extendee
	0, // [0:9] is the sub-list for field type_name
}

func init() { file_voltha_protos_ext_config_proto_init() }
func file_voltha_protos_ext_config_proto_init() {
	if File_voltha_protos_ext_config_proto != nil {
		return
	}
	file_voltha_protos_ext_config_proto_msgTypes[0].OneofWrappers = []any{
		(*AlarmConfig_OnuItuPonAlarmConfig)(nil),
	}
	file_voltha_protos_ext_config_proto_msgTypes[1].OneofWrappers = []any{
		(*OnuItuPonAlarm_RateThresholdConfig_)(nil),
		(*OnuItuPonAlarm_RateRangeConfig_)(nil),
		(*OnuItuPonAlarm_ValueThresholdConfig_)(nil),
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_voltha_protos_ext_config_proto_rawDesc), len(file_voltha_protos_ext_config_proto_rawDesc)),
			NumEnums:      2,
			NumMessages:   6,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_voltha_protos_ext_config_proto_goTypes,
		DependencyIndexes: file_voltha_protos_ext_config_proto_depIdxs,
		EnumInfos:         file_voltha_protos_ext_config_proto_enumTypes,
		MessageInfos:      file_voltha_protos_ext_config_proto_msgTypes,
	}.Build()
	File_voltha_protos_ext_config_proto = out.File
	file_voltha_protos_ext_config_proto_goTypes = nil
	file_voltha_protos_ext_config_proto_depIdxs = nil
}
