// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.36.10
// 	protoc        v5.27.1
// source: cel/expr/eval.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"
	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 EvalState struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Values        []*ExprValue           `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
	Results       []*EvalState_Result    `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*EvalState) ProtoMessage() {}

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

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

func (x *EvalState) GetResults() []*EvalState_Result {
	if x != nil {
		return x.Results
	}
	return nil
}

type ExprValue struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// Types that are valid to be assigned to Kind:
	//
	//	*ExprValue_Value
	//	*ExprValue_Error
	//	*ExprValue_Unknown
	Kind          isExprValue_Kind `protobuf_oneof:"kind"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*ExprValue) ProtoMessage() {}

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

func (x *ExprValue) GetKind() isExprValue_Kind {
	if x != nil {
		return x.Kind
	}
	return nil
}

func (x *ExprValue) GetValue() *Value {
	if x != nil {
		if x, ok := x.Kind.(*ExprValue_Value); ok {
			return x.Value
		}
	}
	return nil
}

func (x *ExprValue) GetError() *ErrorSet {
	if x != nil {
		if x, ok := x.Kind.(*ExprValue_Error); ok {
			return x.Error
		}
	}
	return nil
}

func (x *ExprValue) GetUnknown() *UnknownSet {
	if x != nil {
		if x, ok := x.Kind.(*ExprValue_Unknown); ok {
			return x.Unknown
		}
	}
	return nil
}

type isExprValue_Kind interface {
	isExprValue_Kind()
}

type ExprValue_Value struct {
	Value *Value `protobuf:"bytes,1,opt,name=value,proto3,oneof"`
}

type ExprValue_Error struct {
	Error *ErrorSet `protobuf:"bytes,2,opt,name=error,proto3,oneof"`
}

type ExprValue_Unknown struct {
	Unknown *UnknownSet `protobuf:"bytes,3,opt,name=unknown,proto3,oneof"`
}

func (*ExprValue_Value) isExprValue_Kind() {}

func (*ExprValue_Error) isExprValue_Kind() {}

func (*ExprValue_Unknown) isExprValue_Kind() {}

type ErrorSet struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Errors        []*Status              `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*ErrorSet) ProtoMessage() {}

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

func (x *ErrorSet) GetErrors() []*Status {
	if x != nil {
		return x.Errors
	}
	return nil
}

type Status struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Code          int32                  `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
	Message       string                 `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
	Details       []*anypb.Any           `protobuf:"bytes,3,rep,name=details,proto3" json:"details,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*Status) ProtoMessage() {}

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

func (x *Status) GetCode() int32 {
	if x != nil {
		return x.Code
	}
	return 0
}

func (x *Status) GetMessage() string {
	if x != nil {
		return x.Message
	}
	return ""
}

func (x *Status) GetDetails() []*anypb.Any {
	if x != nil {
		return x.Details
	}
	return nil
}

type UnknownSet struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Exprs         []int64                `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*UnknownSet) ProtoMessage() {}

func (x *UnknownSet) ProtoReflect() protoreflect.Message {
	mi := &file_cel_expr_eval_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 UnknownSet.ProtoReflect.Descriptor instead.
func (*UnknownSet) Descriptor() ([]byte, []int) {
	return file_cel_expr_eval_proto_rawDescGZIP(), []int{4}
}

func (x *UnknownSet) GetExprs() []int64 {
	if x != nil {
		return x.Exprs
	}
	return nil
}

type EvalState_Result struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Expr          int64                  `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"`
	Value         int64                  `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

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

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

func (*EvalState_Result) ProtoMessage() {}

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

func (x *EvalState_Result) GetExpr() int64 {
	if x != nil {
		return x.Expr
	}
	return 0
}

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

var File_cel_expr_eval_proto protoreflect.FileDescriptor

const file_cel_expr_eval_proto_rawDesc = "" +
	"\n" +
	"\x13cel/expr/eval.proto\x12\bcel.expr\x1a\x19google/protobuf/any.proto\x1a\x14cel/expr/value.proto\"\xa2\x01\n" +
	"\tEvalState\x12+\n" +
	"\x06values\x18\x01 \x03(\v2\x13.cel.expr.ExprValueR\x06values\x124\n" +
	"\aresults\x18\x03 \x03(\v2\x1a.cel.expr.EvalState.ResultR\aresults\x1a2\n" +
	"\x06Result\x12\x12\n" +
	"\x04expr\x18\x01 \x01(\x03R\x04expr\x12\x14\n" +
	"\x05value\x18\x02 \x01(\x03R\x05value\"\x9a\x01\n" +
	"\tExprValue\x12'\n" +
	"\x05value\x18\x01 \x01(\v2\x0f.cel.expr.ValueH\x00R\x05value\x12*\n" +
	"\x05error\x18\x02 \x01(\v2\x12.cel.expr.ErrorSetH\x00R\x05error\x120\n" +
	"\aunknown\x18\x03 \x01(\v2\x14.cel.expr.UnknownSetH\x00R\aunknownB\x06\n" +
	"\x04kind\"4\n" +
	"\bErrorSet\x12(\n" +
	"\x06errors\x18\x01 \x03(\v2\x10.cel.expr.StatusR\x06errors\"f\n" +
	"\x06Status\x12\x12\n" +
	"\x04code\x18\x01 \x01(\x05R\x04code\x12\x18\n" +
	"\amessage\x18\x02 \x01(\tR\amessage\x12.\n" +
	"\adetails\x18\x03 \x03(\v2\x14.google.protobuf.AnyR\adetails\"\"\n" +
	"\n" +
	"UnknownSet\x12\x14\n" +
	"\x05exprs\x18\x01 \x03(\x03R\x05exprsB,\n" +
	"\fdev.cel.exprB\tEvalProtoP\x01Z\fcel.dev/expr\xf8\x01\x01b\x06proto3"

var (
	file_cel_expr_eval_proto_rawDescOnce sync.Once
	file_cel_expr_eval_proto_rawDescData []byte
)

func file_cel_expr_eval_proto_rawDescGZIP() []byte {
	file_cel_expr_eval_proto_rawDescOnce.Do(func() {
		file_cel_expr_eval_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cel_expr_eval_proto_rawDesc), len(file_cel_expr_eval_proto_rawDesc)))
	})
	return file_cel_expr_eval_proto_rawDescData
}

var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_cel_expr_eval_proto_goTypes = []any{
	(*EvalState)(nil),        // 0: cel.expr.EvalState
	(*ExprValue)(nil),        // 1: cel.expr.ExprValue
	(*ErrorSet)(nil),         // 2: cel.expr.ErrorSet
	(*Status)(nil),           // 3: cel.expr.Status
	(*UnknownSet)(nil),       // 4: cel.expr.UnknownSet
	(*EvalState_Result)(nil), // 5: cel.expr.EvalState.Result
	(*Value)(nil),            // 6: cel.expr.Value
	(*anypb.Any)(nil),        // 7: google.protobuf.Any
}
var file_cel_expr_eval_proto_depIdxs = []int32{
	1, // 0: cel.expr.EvalState.values:type_name -> cel.expr.ExprValue
	5, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result
	6, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value
	2, // 3: cel.expr.ExprValue.error:type_name -> cel.expr.ErrorSet
	4, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet
	3, // 5: cel.expr.ErrorSet.errors:type_name -> cel.expr.Status
	7, // 6: cel.expr.Status.details:type_name -> google.protobuf.Any
	7, // [7:7] is the sub-list for method output_type
	7, // [7:7] is the sub-list for method input_type
	7, // [7:7] is the sub-list for extension type_name
	7, // [7:7] is the sub-list for extension extendee
	0, // [0:7] is the sub-list for field type_name
}

func init() { file_cel_expr_eval_proto_init() }
func file_cel_expr_eval_proto_init() {
	if File_cel_expr_eval_proto != nil {
		return
	}
	file_cel_expr_value_proto_init()
	file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []any{
		(*ExprValue_Value)(nil),
		(*ExprValue_Error)(nil),
		(*ExprValue_Unknown)(nil),
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: unsafe.Slice(unsafe.StringData(file_cel_expr_eval_proto_rawDesc), len(file_cel_expr_eval_proto_rawDesc)),
			NumEnums:      0,
			NumMessages:   6,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_cel_expr_eval_proto_goTypes,
		DependencyIndexes: file_cel_expr_eval_proto_depIdxs,
		MessageInfos:      file_cel_expr_eval_proto_msgTypes,
	}.Build()
	File_cel_expr_eval_proto = out.File
	file_cel_expr_eval_proto_goTypes = nil
	file_cel_expr_eval_proto_depIdxs = nil
}
