2222import com .google .common .collect .ImmutableSet ;
2323import com .google .common .primitives .UnsignedLong ;
2424import com .google .common .truth .Expect ;
25+ import com .google .protobuf .Any ;
2526import com .google .protobuf .BoolValue ;
2627import com .google .protobuf .ByteString ;
2728import com .google .protobuf .BytesValue ;
3334import com .google .protobuf .FloatValue ;
3435import com .google .protobuf .Int32Value ;
3536import com .google .protobuf .Int64Value ;
37+ import com .google .protobuf .Message ;
3638import com .google .protobuf .MessageLite ;
3739import com .google .protobuf .StringValue ;
3840import com .google .protobuf .TextFormat ;
@@ -148,10 +150,10 @@ private enum WellKnownProtoTestCase {
148150 UINT64 (UInt64Value .of (1L ), UnsignedLong .valueOf (1L )),
149151 ;
150152
151- private final MessageLite msg ;
153+ private final Message msg ;
152154 private final Object value ;
153155
154- WellKnownProtoTestCase (MessageLite msg , Object value ) {
156+ WellKnownProtoTestCase (Message msg , Object value ) {
155157 this .msg = msg ;
156158 this .value = value ;
157159 }
@@ -176,6 +178,87 @@ public void fromProtoMessageToCelValue_fieldMask_returnsProtoMessageLiteValue()
176178 .isEqualTo (ImmutableList .of ("foo" , "bar" ));
177179 }
178180
181+ @ Test
182+ public void toRuntimeValue_anyWithWellKnownProto_unpacksToCelValue (
183+ @ TestParameter WellKnownProtoTestCase testCase ) {
184+ Object adaptedValue = PROTO_LITE_CEL_VALUE_CONVERTER .toRuntimeValue (Any .pack (testCase .msg ));
185+
186+ assertThat (adaptedValue ).isEqualTo (testCase .value );
187+ }
188+
189+ @ Test
190+ public void toRuntimeValue_anyWithRegisteredMessage_returnsProtoMessageLiteValue () {
191+ TestAllTypes msg = TestAllTypes .newBuilder ().setSingleInt64 (42L ).build ();
192+
193+ Object adaptedValue = PROTO_LITE_CEL_VALUE_CONVERTER .toRuntimeValue (Any .pack (msg ));
194+
195+ assertThat (adaptedValue ).isInstanceOf (ProtoMessageLiteValue .class );
196+ assertThat (((ProtoMessageLiteValue ) adaptedValue ).value ()).isEqualTo (msg );
197+ }
198+
199+ @ Test
200+ public void toRuntimeValue_anyWithUnregisteredMessage_returnsRawValueOfPackedType () {
201+ ProtoLiteCelValueConverter wellKnownOnlyConverter =
202+ ProtoLiteCelValueConverter .newInstance (DefaultLiteDescriptorPool .newInstance ());
203+ TestAllTypes msg = TestAllTypes .newBuilder ().setSingleInt64 (42L ).build ();
204+
205+ Object adaptedValue = wellKnownOnlyConverter .toRuntimeValue (Any .pack (msg ));
206+
207+ assertThat (adaptedValue ).isInstanceOf (RawProtoMessageLiteValue .class );
208+ RawProtoMessageLiteValue rawValue = (RawProtoMessageLiteValue ) adaptedValue ;
209+ assertThat (rawValue .protoTypeName ()).isEqualTo (PROTO3_TEST_ALL_TYPES );
210+ assertThat (rawValue .toByteString ()).isEqualTo (msg .toByteString ());
211+ }
212+
213+ @ Test
214+ public void toRuntimeValue_anyNestedToMaxDepth_unpacks () {
215+ Object adaptedValue = PROTO_LITE_CEL_VALUE_CONVERTER .toRuntimeValue (nestedAny (100 ));
216+
217+ assertThat (adaptedValue ).isEqualTo (42L );
218+ }
219+
220+ @ Test
221+ public void toRuntimeValue_anyNestedBeyondMaxDepth_throws () {
222+ Any any = nestedAny (101 );
223+
224+ IllegalArgumentException thrown =
225+ assertThrows (
226+ IllegalArgumentException .class ,
227+ () -> PROTO_LITE_CEL_VALUE_CONVERTER .toRuntimeValue (any ));
228+
229+ assertThat (thrown )
230+ .hasMessageThat ()
231+ .isEqualTo ("Unpacking failed for message: google.protobuf.Any (nesting exceeds 100)" );
232+ }
233+
234+ @ Test
235+ public void toRuntimeValue_anyWithMalformedTypeUrl_throws (
236+ @ TestParameter ({"" , "type.googleapis.com/" }) String typeUrl ) {
237+ Any any =
238+ Any .newBuilder ().setTypeUrl (typeUrl ).setValue (Int64Value .of (1L ).toByteString ()).build ();
239+
240+ IllegalArgumentException thrown =
241+ assertThrows (
242+ IllegalArgumentException .class ,
243+ () -> PROTO_LITE_CEL_VALUE_CONVERTER .toRuntimeValue (any ));
244+
245+ assertThat (thrown )
246+ .hasMessageThat ()
247+ .isEqualTo (
248+ "Unpacking failed for message: google.protobuf.Any (malformed type URL: '"
249+ + typeUrl
250+ + "')" );
251+ }
252+
253+ /** Returns {@code layers} Anys nested around an {@code Int64Value} of 42. */
254+ private static Any nestedAny (int layers ) {
255+ Any any = Any .pack (Int64Value .of (42L ));
256+ for (int i = 1 ; i < layers ; i ++) {
257+ any = Any .pack (any );
258+ }
259+ return any ;
260+ }
261+
179262 /** Test cases for repeated_int64: 1L,2L,3L */
180263 @ SuppressWarnings ("ImmutableEnumChecker" ) // Test only
181264 private enum RepeatedFieldBytesTestCase {
0 commit comments