// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.36.10
// 	protoc        v5.27.1
// source: cel/expr/value.proto

package expr

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	anypb "google.golang.org/protobuf/types/known/anypb"
	structpb "google.golang.org/protobuf/types/known/structpb"
	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 Value struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// Types that are valid to be assigned to Kind:
	//
	//	*Value_NullValue
	//	*Value_BoolValue
	//	*Value_Int64Value
	//	*Value_Uint64Value
	//	*Value_DoubleValue
	//	*Value_StringValue
	//	*Value_BytesValue
	//	*Value_EnumValue
	//	*Value_ObjectValue
	//	*Value_MapValue
	//	*Value_ListValue
	//	*Value_TypeValue
	Kind          isValue_Kind `protobuf_oneof:"kind"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*Value) ProtoMessage() {}

func (x *Value) ProtoReflect() protoreflect.Message {
	mi := &file_cel_expr_value_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 Value.ProtoReflect.Descriptor instead.
func (*Value) Descriptor() ([]byte, []int) {
	return file_cel_expr_value_proto_rawDescGZIP(), []int{0}
}

func (x *Value) GetKind() isValue_Kind {
	if x != nil {
		return x.Kind
	}
	return nil
}

func (x *Value) GetNullValue() structpb.NullValue {
	if x != nil {
		if x, ok := x.Kind.(*Value_NullValue); ok {
			return x.NullValue
		}
	}
	return structpb.NullValue(0)
}

func (x *Value) GetBoolValue() bool {
	if x != nil {
		if x, ok := x.Kind.(*Value_BoolValue); ok {
			return x.BoolValue
		}
	}
	return false
}

func (x *Value) GetInt64Value() int64 {
	if x != nil {
		if x, ok := x.Kind.(*Value_Int64Value); ok {
			return x.Int64Value
		}
	}
	return 0
}

func (x *Value) GetUint64Value() uint64 {
	if x != nil {
		if x, ok := x.Kind.(*Value_Uint64Value); ok {
			return x.Uint64Value
		}
	}
	return 0
}

func (x *Value) GetDoubleValue() float64 {
	if x != nil {
		if x, ok := x.Kind.(*Value_DoubleValue); ok {
			return x.DoubleValue
		}
	}
	return 0
}

func (x *Value) GetStringValue() string {
	if x != nil {
		if x, ok := x.Kind.(*Value_StringValue); ok {
			return x.StringValue
		}
	}
	return ""
}

func (x *Value) GetBytesValue() []byte {
	if x != nil {
		if x, ok := x.Kind.(*Value_BytesValue); ok {
			return x.BytesValue
		}
	}
	return nil
}

func (x *Value) GetEnumValue() *EnumValue {
	if x != nil {
		if x, ok := x.Kind.(*Value_EnumValue); ok {
			return x.EnumValue
		}
	}
	return nil
}

func (x *Value) GetObjectValue() *anypb.Any {
	if x != nil {
		if x, ok := x.Kind.(*Value_ObjectValue); ok {
			return x.ObjectValue
		}
	}
	return nil
}

func (x *Value) GetMapValue() *MapValue {
	if x != nil {
		if x, ok := x.Kind.(*Value_MapValue); ok {
			return x.MapValue
		}
	}
	return nil
}

func (x *Value) GetListValue() *ListValue {
	if x != nil {
		if x, ok := x.Kind.(*Value_ListValue); ok {
			return x.ListValue
		}
	}
	return nil
}

func (x *Value) GetTypeValue() string {
	if x != nil {
		if x, ok := x.Kind.(*Value_TypeValue); ok {
			return x.TypeValue
		}
	}
	return ""
}

type isValue_Kind interface {
	isValue_Kind()
}

type Value_NullValue struct {
	NullValue structpb.NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"`
}

type Value_BoolValue struct {
	BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"`
}

type Value_Int64Value struct {
	Int64Value int64 `protobuf:"varint,3,opt,name=int64_value,json=int64Value,proto3,oneof"`
}

type Value_Uint64Value struct {
	Uint64Value uint64 `protobuf:"varint,4,opt,name=uint64_value,json=uint64Value,proto3,oneof"`
}

type Value_DoubleValue struct {
	DoubleValue float64 `protobuf:"fixed64,5,opt,name=double_value,json=doubleValue,proto3,oneof"`
}

type Value_StringValue struct {
	StringValue string `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"`
}

type Value_BytesValue struct {
	BytesValue []byte `protobuf:"bytes,7,opt,name=bytes_value,json=bytesValue,proto3,oneof"`
}

type Value_EnumValue struct {
	EnumValue *EnumValue `protobuf:"bytes,9,opt,name=enum_value,json=enumValue,proto3,oneof"`
}

type Value_ObjectValue struct {
	ObjectValue *anypb.Any `protobuf:"bytes,10,opt,name=object_value,json=objectValue,proto3,oneof"`
}

type Value_MapValue struct {
	MapValue *MapValue `protobuf:"bytes,11,opt,name=map_value,json=mapValue,proto3,oneof"`
}

type Value_ListValue struct {
	ListValue *ListValue `protobuf:"bytes,12,opt,name=list_value,json=listValue,proto3,oneof"`
}

type Value_TypeValue struct {
	TypeValue string `protobuf:"bytes,15,opt,name=type_value,json=typeValue,proto3,oneof"`
}

func (*Value_NullValue) isValue_Kind() {}

func (*Value_BoolValue) isValue_Kind() {}

func (*Value_Int64Value) isValue_Kind() {}

func (*Value_Uint64Value) isValue_Kind() {}

func (*Value_DoubleValue) isValue_Kind() {}

func (*Value_StringValue) isValue_Kind() {}

func (*Value_BytesValue) isValue_Kind() {}

func (*Value_EnumValue) isValue_Kind() {}

func (*Value_ObjectValue) isValue_Kind() {}

func (*Value_MapValue) isValue_Kind() {}

func (*Value_ListValue) isValue_Kind() {}

func (*Value_TypeValue) isValue_Kind() {}

type EnumValue struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Type          string                 `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
	Value         int32                  `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*EnumValue) ProtoMessage() {}

func (x *EnumValue) ProtoReflect() protoreflect.Message {
	mi := &file_cel_expr_value_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 EnumValue.ProtoReflect.Descriptor instead.
func (*EnumValue) Descriptor() ([]byte, []int) {
	return file_cel_expr_value_proto_rawDescGZIP(), []int{1}
}

func (x *EnumValue) GetType() string {
	if x != nil {
		return x.Type
	}
	return ""
}

func (x *EnumValue) GetValue() int32 {
	if x != nil {
		return x.Value
	}
	return 0
}

type ListValue struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Values        []*Value               `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*ListValue) ProtoMessage() {}

func (x *ListValue) ProtoReflect() protoreflect.Message {
	mi := &file_cel_expr_value_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 ListValue.ProtoReflect.Descriptor instead.
func (*ListValue) Descriptor() ([]byte, []int) {
	return file_cel_expr_value_proto_rawDescGZIP(), []int{2}
}

func (x *ListValue) GetValues() []*Value {
	if x != nil {
		return x.Values
	}
	return nil
}

type MapValue struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Entries       []*MapValue_Entry      `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*MapValue) ProtoMessage() {}

func (x *MapValue) ProtoReflect() protoreflect.Message {
	mi := &file_cel_expr_value_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 MapValue.ProtoReflect.Descriptor instead.
func (*MapValue) Descriptor() ([]byte, []int) {
	return file_cel_expr_value_proto_rawDescGZIP(), []int{3}
}

func (x *MapValue) GetEntries() []*MapValue_Entry {
	if x != nil {
		return x.Entries
	}
	return nil
}

type MapValue_Entry struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Key           *Value                 `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
	Value         *Value                 `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*MapValue_Entry) ProtoMessage() {}

func (x *MapValue_Entry) ProtoReflect() protoreflect.Message {
	mi := &file_cel_expr_value_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 MapValue_Entry.ProtoReflect.Descriptor instead.
func (*MapValue_Entry) Descriptor() ([]byte, []int) {
	return file_cel_expr_value_proto_rawDescGZIP(), []int{3, 0}
}

func (x *MapValue_Entry) GetKey() *Value {
	if x != nil {
		return x.Key
	}
	return nil
}

func (x *MapValue_Entry) GetValue() *Value {
	if x != nil {
		return x.Value
	}
	return nil
}

var File_cel_expr_value_proto protoreflect.FileDescriptor

const file_cel_expr_value_proto_rawDesc = "" +
	"\n" +
	"\x14cel/expr/value.proto\x12\bcel.expr\x1a\x19google/protobuf/any.proto\x1a\x1cgoogle/protobuf/struct.proto\"\x9d\x04\n" +
	"\x05Value\x12;\n" +
	"\n" +
	"null_value\x18\x01 \x01(\x0e2\x1a.google.protobuf.NullValueH\x00R\tnullValue\x12\x1f\n" +
	"\n" +
	"bool_value\x18\x02 \x01(\bH\x00R\tboolValue\x12!\n" +
	"\vint64_value\x18\x03 \x01(\x03H\x00R\n" +
	"int64Value\x12#\n" +
	"\fuint64_value\x18\x04 \x01(\x04H\x00R\vuint64Value\x12#\n" +
	"\fdouble_value\x18\x05 \x01(\x01H\x00R\vdoubleValue\x12#\n" +
	"\fstring_value\x18\x06 \x01(\tH\x00R\vstringValue\x12!\n" +
	"\vbytes_value\x18\a \x01(\fH\x00R\n" +
	"bytesValue\x124\n" +
	"\n" +
	"enum_value\x18\t \x01(\v2\x13.cel.expr.EnumValueH\x00R\tenumValue\x129\n" +
	"\fobject_value\x18\n" +
	" \x01(\v2\x14.google.protobuf.AnyH\x00R\vobjectValue\x121\n" +
	"\tmap_value\x18\v \x01(\v2\x12.cel.expr.MapValueH\x00R\bmapValue\x124\n" +
	"\n" +
	"list_value\x18\f \x01(\v2\x13.cel.expr.ListValueH\x00R\tlistValue\x12\x1f\n" +
	"\n" +
	"type_value\x18\x0f \x01(\tH\x00R\ttypeValueB\x06\n" +
	"\x04kind\"5\n" +
	"\tEnumValue\x12\x12\n" +
	"\x04type\x18\x01 \x01(\tR\x04type\x12\x14\n" +
	"\x05value\x18\x02 \x01(\x05R\x05value\"4\n" +
	"\tListValue\x12'\n" +
	"\x06values\x18\x01 \x03(\v2\x0f.cel.expr.ValueR\x06values\"\x91\x01\n" +
	"\bMapValue\x122\n" +
	"\aentries\x18\x01 \x03(\v2\x18.cel.expr.MapValue.EntryR\aentries\x1aQ\n" +
	"\x05Entry\x12!\n" +
	"\x03key\x18\x01 \x01(\v2\x0f.cel.expr.ValueR\x03key\x12%\n" +
	"\x05value\x18\x02 \x01(\v2\x0f.cel.expr.ValueR\x05valueB-\n" +
	"\fdev.cel.exprB\n" +
	"ValueProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3"

var (
	file_cel_expr_value_proto_rawDescOnce sync.Once
	file_cel_expr_value_proto_rawDescData []byte
)

func file_cel_expr_value_proto_rawDescGZIP() []byte {
	file_cel_expr_value_proto_rawDescOnce.Do(func() {
		file_cel_expr_value_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_value_proto_rawDesc), len(file_cel_expr_value_proto_rawDesc)))
	})
	return file_cel_expr_value_proto_rawDescData
}

var file_cel_expr_value_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_cel_expr_value_proto_goTypes = []any{
	(*Value)(nil),           // 0: cel.expr.Value
	(*EnumValue)(nil),       // 1: cel.expr.EnumValue
	(*ListValue)(nil),       // 2: cel.expr.ListValue
	(*MapValue)(nil),        // 3: cel.expr.MapValue
	(*MapValue_Entry)(nil),  // 4: cel.expr.MapValue.Entry
	(structpb.NullValue)(0), // 5: google.protobuf.NullValue
	(*anypb.Any)(nil),       // 6: google.protobuf.Any
}
var file_cel_expr_value_proto_depIdxs = []int32{
	5, // 0: cel.expr.Value.null_value:type_name -> google.protobuf.NullValue
	1, // 1: cel.expr.Value.enum_value:type_name -> cel.expr.EnumValue
	6, // 2: cel.expr.Value.object_value:type_name -> google.protobuf.Any
	3, // 3: cel.expr.Value.map_value:type_name -> cel.expr.MapValue
	2, // 4: cel.expr.Value.list_value:type_name -> cel.expr.ListValue
	0, // 5: cel.expr.ListValue.values:type_name -> cel.expr.Value
	4, // 6: cel.expr.MapValue.entries:type_name -> cel.expr.MapValue.Entry
	0, // 7: cel.expr.MapValue.Entry.key:type_name -> cel.expr.Value
	0, // 8: cel.expr.MapValue.Entry.value:type_name -> cel.expr.Value
	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_cel_expr_value_proto_init() }
func file_cel_expr_value_proto_init() {
	if File_cel_expr_value_proto != nil {
		return
	}
	file_cel_expr_value_proto_msgTypes[0].OneofWrappers = []any{
		(*Value_NullValue)(nil),
		(*Value_BoolValue)(nil),
		(*Value_Int64Value)(nil),
		(*Value_Uint64Value)(nil),
		(*Value_DoubleValue)(nil),
		(*Value_StringValue)(nil),
		(*Value_BytesValue)(nil),
		(*Value_EnumValue)(nil),
		(*Value_ObjectValue)(nil),
		(*Value_MapValue)(nil),
		(*Value_ListValue)(nil),
		(*Value_TypeValue)(nil),
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_value_proto_rawDesc), len(file_cel_expr_value_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   5,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_cel_expr_value_proto_goTypes,
		DependencyIndexes: file_cel_expr_value_proto_depIdxs,
		MessageInfos:      file_cel_expr_value_proto_msgTypes,
	}.Build()
	File_cel_expr_value_proto = out.File
	file_cel_expr_value_proto_goTypes = nil
	file_cel_expr_value_proto_depIdxs = nil
}
