google / cel-go

Fast, portable, non-Turing complete expression evaluation with gradual typing (Go)
https://cel.dev
Apache License 2.0
2.26k stars 220 forks source link

Question: How should callers check for unpopulated root variables #970

Closed jacobmikesell closed 1 month ago

jacobmikesell commented 4 months ago

Feature request checklist

Change Summary of the proposed change and some details about what problem it helps solve.

I'm curious if there is a better way to test precense/defaultness of a protobuf message when its not a "field" but at the root of the cel AST

Example


message TestMessage {
  string name = 1;
  int64 age = 2;
  bool adult = 3;
  google.type.Decimal height = 4;
  repeated string string_list = 5;
  map<string, int32> string_int_map = 6;
  google.type.Date birthday = 7;
 }
msg := &testproto.TestProto{}   
env, _ := cel.NewEnv(cel.ProtoContext(msg))

//Doesnt work`msg`
env.Compile("birthday == null")

//Doesnt work with `msg`
env.Compile("has(birthday)")

//works with `msg` but is a hassle to explain/requires people to know the namespace of message, error prone
env.Compile("birthday == google.type.Date{}")
TristonianJones commented 4 months ago

Hi @jacobmikesell, you'll want to use optional values; however, this likely requires an update to the ProtoContext method to support generation of optional bindings for all fields such that set field are optional.of(value) and unset fields are optional.none()

jacobmikesell commented 3 months ago

@TristonianJones would this require optional to be used in the proto definition file? or do you mean that we could say (for only root message fields of type message) that they are optional in the cel context?

TristonianJones commented 3 months ago

@jacobmikesell I was referring to the cel-go notion of cel.OptionalTypes() to be enabled. When enabled, you could generation CEL-optional bindings for fields whose type are optional_type(<field_type>) and when unpopulated, the value would be optional.none()