-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Support evaluating dynamic messages with dynamic descriptors #350
Comments
Hi, First it'd be helpful for me to understand the larger context of what you're trying to achieve here. From the test code, it seems like you're trying to deal with JSON data. The canonical way of achieving that is to leverage To answer the question -- the reason why you're running into this specific issue is because two semantically equal descriptors that differ in binary are present in the runtime: https://github.com/google/cel-java/blob/main/common/src/main/java/dev/cel/common/internal/DefaultInstanceMessageFactory.java#L78-L82. When constructing a default protobuf message, we rely on java reflection to lookup the descriptor to construct a default instance with but we try to ensure we're using the right descriptor for this work. The fix here is to not load the same file descriptor when you already have it available in memory (I realize you're probably doing this to reproduce the issue, but this work shouldn't be necessary). You should see your test case pass if you just pass in As an aside -- I noticed that you're enabling CelValue and optional syntax in CelOptions. Keep in mind that 1) CelValue is currently experimental, as noted in the option, so you may run into some rough edges (but it is something we want to make the default for the runtime in the future) and 2) the preferred way of enabling optionals is through adding the library to your environment. |
@l46kok At first, sorry for not explaining enough my situation.
In step 3, input value’s schema is defined by a Descriptor and so I parse the value and convert it to DynamicMessage with the Descriptor. In my use case, runtime process dynamically load Descriptors and does not include generated Messages, so can not load a Descriptor from a generated Message like In my use case conditions, DefaultInstanceMessageFactory will not be able to load defaultInstance and it will be null: https://github.com/google/cel-java/blob/v0.5.1/common/src/main/java/dev/cel/common/internal/DefaultInstanceMessageFactory.java#L231-L234, https://github.com/google/cel-java/blob/v0.5.1/common/src/main/java/dev/cel/common/internal/DefaultInstanceMessageFactory.java#L75-L77. Sorry if I’m wrong, but It looks that a map field in DynamicMessage constructed using preveious described steps is consists of list of DynamicMessage which contains key and value fields, so to cast it to map, it may be necessary to execute some kind of conversion process, for example to take a key and value from each element of the list and convert it to an MapEntry. Because of these reasons, I asked that if there is a way to execute the cel expression in my use case or if cel-java plan to support this situation. Thank you also for your advise about CelOptions. I tried several settings, and remaining enableOptionalSyntax option but it is not necessary. Regarding CelValue, if I set enableCelValue to false, result of cel expression is like this and looks same as when set it true. |
Oh I follow now, thanks for elaborating. CEL for the most part expects non-dynamic descriptors as constructing protobuf messages (structs) in expressions is baked into the specification (example: One other thought I had is you could technically override the manner of how to construct the messages via |
Thinking about this further -- what I've mentioned regarding CEL-Java expecting concrete descriptors has been traditionally true, but we might be able to extend the support to dynamic descriptors as well. In discussing with the team, support for fully dynamic messages and descriptors may already be there for golang and C++ stacks via protobuf reflection. The biggest challenge would be to ensure that the usual CEL semantics is fully supported in CEL-Java. We'll explore this further and see what can be done. |
Thanks for your explanation for the specification and suggesting ways to support my situation.
I may not fully understand or misunderstand the cel-spec. If it's alright, let me ask about this comment. Does this mean cel-spec define that to execute a cel expression against a message, a runtime should load generated messages and should be able to call getDefaultInstance method correspoinding to that message? With dynamically loaded Descriptors, I tried to run cel expressions which access to various types of fields, for example enum, repeated, and map, and those were success in case except map. Therefore it would be very appreciated if cel-java support to run the expression for a map in a DynamicMessage with Descriptors loaded at runtime. |
Ah I meant to say CEL-Java on that, my mistake. CEL-Spec only specifies that an expression I think your observations about dynamic message is correct -- I think it should behave the same except for map (and only for cases where JSON is parsed into dynamic message, because it converts the json map into a dynamic message to preserve ordering post-serialization). I just need to verify the behavior against few other things such as function dispatch before we can canonically support this case. |
…ptors Closes #350 PiperOrigin-RevId: 636755364
…ptors Closes #350 PiperOrigin-RevId: 636755364
…ptors Closes #350 PiperOrigin-RevId: 636755364
…ptors Closes #350 PiperOrigin-RevId: 636755364
…ptors Closes #350 PiperOrigin-RevId: 636755364
…ptors Closes #350 PiperOrigin-RevId: 636755364
Thank you for your response. I understood what you are saying about cel-java specification. |
…ptors Closes #350 PiperOrigin-RevId: 636755364
Hi,
First of all, I would like to apologize for that the issue #333 I posted was incorrect.
I have once again confirmed my program behavior, so let me ask a question again.
I tried to execute cel expression against a map in DynamicMessage built with a Descriptor which created from FileDescriptorSet at run time, and then that java process resulted into
dev.cel.runtime.CelEvaluationException
.The exception message is like bellow.
My question is that are there any way to execute a cel expression to map in DynamicMessage built with a Descriptor created at run time or are there any plan to support that case in cel-java.
Description
It seems that cel-java try to convert input DynamicMessage to a generated Message, probably a Message class generated from protobuf definition, with DynamicProto::maybeAdaptDynamicMessage but when build a Descriptor from FileDescriptorSet and use it to construct DynamicMessage to pass to eval method's argument, cel-java can not load a generated Message and so use DynamicMessage::Builder as maybeBuilder that is local variable in maybeAdaptDynamicMessge.
I'm not familiar with the DynamicMessage implementation, but from the behavior it appears that DynamicMessage::Builder treats the map field as a list of DynamicMessages, then the map field in Message returned by maybeAdaptDynamicMessage will also be the list of DynamicMessages and cause exception of class cast.
If use a generated Message's Builder to build Message or use generated Message's Descriptor to build DynamicMessage and pass it to eval method as argument, cel-java will be able to acquire a generated Message's Builder at DynamicProto::maybeAdaptDynamicMessage method and it treat map field as Map, so Exception will not happen.
To Reproduce
To reproduce, create descriptor and execute cel expression with following steps.
To do that, I write test code and put here.
The text was updated successfully, but these errors were encountered: