Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dev.cel.common.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import dev.cel.expr.ExprValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.Ints;
import com.google.common.primitives.UnsignedInts;
import com.google.common.primitives.UnsignedLong;
import com.google.errorprone.annotations.CheckReturnValue;
import com.google.errorprone.annotations.Immutable;
import com.google.protobuf.Any;
import com.google.protobuf.BoolValue;
import com.google.protobuf.ByteString;
import com.google.protobuf.BytesValue;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.DoubleValue;
import com.google.protobuf.Duration;
import com.google.protobuf.DynamicMessage;
import com.google.protobuf.FloatValue;
import com.google.protobuf.Int32Value;
import com.google.protobuf.Int64Value;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.ListValue;
import com.google.protobuf.MapEntry;
import com.google.protobuf.Message;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.NullValue;
import com.google.protobuf.StringValue;
import com.google.protobuf.Struct;
import com.google.protobuf.Timestamp;
import com.google.protobuf.UInt32Value;
import com.google.protobuf.UInt64Value;
import com.google.protobuf.Value;
import dev.cel.common.CelErrorCode;
import dev.cel.common.CelRuntimeException;
import dev.cel.common.annotations.Internal;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.jspecify.nullness.Nullable;
/**
* The {@code ProtoAdapter} utilities handle conversion between native Java objects which represent
* CEL values and well-known protobuf counterparts.
*
*
How a protobuf is adapted can depend on both the set of {@code Descriptor} values as well as
* on feature-flags. Whereas in the past such conversions were performed as static method calls,
* this class represents an evolving trend toward conditional conversion.
*
*
CEL Library Internals. Do Not Use.
*/
@Immutable
@CheckReturnValue
@Internal
public final class ProtoAdapter {
/**
* Int converter handles bidirectional conversions between int32 <-> int64 values.
*
*
Note: Unlike the {@code RuntimeHelpers#INT32_TO_INT64} and {@code
* RuntimeHelpers#INT64_TO_INT32} converter objects, the converter takes a {@code Number} as input
* and produces a {@code Number} as output in an effort to make the coverters more tolerant of
* Java native values which may enter the evaluation via {@code DYN} inputs.
*/
public static final BidiConverter INT_CONVERTER =
BidiConverter.of(Number::longValue, value -> intCheckedCast(value.longValue()));
/**
* Signed uint converter handles bidirectional conversions between uint32 <-> uint64 values.
*
*
Note: Unlike the {@code RuntimeHelpers#UINT32_TO_UINT64} and {@code
* RuntimeHelpers#UINT64_TO_UINT32} converter objects, the converter takes a {@code Number} as
* input and produces a {@code Number} as output in an effort to make the coverters more tolerant
* of Java native values which may enter the evaluation via {@code DYN} inputs.
*
*
If the long being converted to a uint exceeds 32 bits, an {@code IllegalArgumentException}
* will be thrown.
*/
public static final BidiConverter SIGNED_UINT32_CONVERTER =
BidiConverter.of(
value -> UnsignedInts.toLong(value.intValue()),
value -> unsignedIntCheckedCast(value.longValue()));
/**
* Unigned uint converter handles bidirectional conversions between uint32 <-> uint64 values.
*
*
Note: Unlike the {@code RuntimeHelpers#UINT32_TO_UINT64} and {@code
* RuntimeHelpers#UINT64_TO_UINT32} converter objects, the converter takes a {@code Number} as
* input and produces a {@code Number} as output in an effort to make the coverters more tolerant
* of Java native values which may enter the evaluation via {@code DYN} inputs.
*
*
If the long being converted to a uint exceeds 32 bits, an {@code IllegalArgumentException}
* will be thrown.
*/
public static final BidiConverter UNSIGNED_UINT32_CONVERTER =
BidiConverter.of(
value -> UnsignedLong.fromLongBits(Integer.toUnsignedLong(value.intValue())),
value -> unsignedIntCheckedCast(value.longValue()));
/**
* Unsigned uint64 converter which adapts from a {@code long} value on the wire to an {@code
* UnsignedLong}.
*/
public static final BidiConverter UNSIGNED_UINT64_CONVERTER =
BidiConverter.of(value -> UnsignedLong.fromLongBits(value.longValue()), Number::longValue);
/**
* Double converter handles bidirectional conversions between float32 <-> float64 values.
*
*
Note: Unlike the {@code RuntimeHelpers#FLOAT_TO_DOUBLE} and {@code
* RuntimeHelpers#DOUBLE_TO_FLOAT} converter objects, the converter takes a {@code Number} as
* input and produces a {@code Number} as output in an effort to make the coverters more tolerant
* of Java native values which may enter the evaluation via {@code DYN} inputs.
*/
public static final BidiConverter DOUBLE_CONVERTER =
BidiConverter.of(Number::doubleValue, Number::floatValue);
private final DynamicProto dynamicProto;
private final boolean enableUnsignedLongs;
public ProtoAdapter(DynamicProto dynamicProto, boolean enableUnsignedLongs) {
this.dynamicProto = checkNotNull(dynamicProto);
this.enableUnsignedLongs = enableUnsignedLongs;
}
/**
* Adapts a protobuf {@code MessageOrBuilder} into a Java object understood by CEL.
*
*
In some instances the input message is also the output value.
*/
public Object adaptProtoToValue(MessageOrBuilder proto) {
// Attempt to convert the proto from a dynamic message into a linked protobuf type if possible.
if (proto instanceof DynamicMessage) {
proto = dynamicProto.maybeAdaptDynamicMessage((DynamicMessage) proto);
}
// If the proto is not a well-known type, then the input Message is what's expected as the
// output return value.
WellKnownProto wellKnownProto =
WellKnownProto.getByDescriptorName(typeName(proto.getDescriptorForType()));
if (wellKnownProto == null) {
return proto;
}
// Exhaustive switch over the conversion and adaptation of well-known protobuf types to Java
// values.
switch (wellKnownProto) {
case ANY_VALUE:
return unpackAnyProto((Any) proto);
case JSON_VALUE:
return adaptJsonToValue((Value) proto);
case JSON_STRUCT_VALUE:
return adaptJsonStructToValue((Struct) proto);
case JSON_LIST_VALUE:
return adaptJsonListToValue((ListValue) proto);
case BOOL_VALUE:
return ((BoolValue) proto).getValue();
case BYTES_VALUE:
return ((BytesValue) proto).getValue();
case DOUBLE_VALUE:
return ((DoubleValue) proto).getValue();
case FLOAT_VALUE:
return (double) ((FloatValue) proto).getValue();
case INT32_VALUE:
return (long) ((Int32Value) proto).getValue();
case INT64_VALUE:
return ((Int64Value) proto).getValue();
case STRING_VALUE:
return ((StringValue) proto).getValue();
case UINT32_VALUE:
if (enableUnsignedLongs) {
return UnsignedLong.fromLongBits(
Integer.toUnsignedLong(((UInt32Value) proto).getValue()));
}
return (long) ((UInt32Value) proto).getValue();
case UINT64_VALUE:
if (enableUnsignedLongs) {
return UnsignedLong.fromLongBits(((UInt64Value) proto).getValue());
}
return ((UInt64Value) proto).getValue();
default:
return proto;
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
public Optional