Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Refactor value deserialization to be handle agnostic #474

Merged
merged 1 commit into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions base/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ cc_library(
"//common:memory",
"//common:native_type",
"//internal:casts",
"//internal:deserialize",
"//internal:no_destructor",
"//internal:number",
"//internal:overloaded",
Expand Down
26 changes: 4 additions & 22 deletions base/types/duration_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@
#include "absl/time/time.h"
#include "base/value_factory.h"
#include "base/values/duration_value.h"
#include "internal/proto_wire.h"
#include "internal/deserialize.h"
#include "internal/status_macros.h"

namespace cel {

namespace {

using internal::MakeProtoWireTag;
using internal::ProtoWireDecoder;
using internal::ProtoWireType;
using internal::DeserializeDuration;

} // namespace

Expand All @@ -36,24 +34,8 @@ CEL_INTERNAL_TYPE_IMPL(DurationType);
absl::StatusOr<Handle<DurationValue>> DurationType::NewValueFromAny(
ValueFactory& value_factory, const absl::Cord& value) const {
// google.protobuf.Duration.
int64_t seconds = 0;
int32_t nanos = 0;
ProtoWireDecoder decoder("google.protobuf.Duration", value);
while (decoder.HasNext()) {
CEL_ASSIGN_OR_RETURN(auto tag, decoder.ReadTag());
if (tag == MakeProtoWireTag(1, ProtoWireType::kVarint)) {
CEL_ASSIGN_OR_RETURN(seconds, decoder.ReadVarint<int64_t>());
continue;
}
if (tag == MakeProtoWireTag(2, ProtoWireType::kVarint)) {
CEL_ASSIGN_OR_RETURN(nanos, decoder.ReadVarint<int32_t>());
continue;
}
CEL_RETURN_IF_ERROR(decoder.SkipLengthValue());
}
decoder.EnsureFullyDecoded();
return value_factory.CreateDurationValue(absl::Seconds(seconds) +
absl::Nanoseconds(nanos));
CEL_ASSIGN_OR_RETURN(auto deserialized_value, DeserializeDuration(value));
return value_factory.CreateDurationValue(deserialized_value);
}

} // namespace cel
56 changes: 6 additions & 50 deletions base/types/dyn_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@

#include "base/types/dyn_type.h"

#include <utility>

#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "base/value_factory.h"
#include "internal/proto_wire.h"
#include "internal/deserialize.h"
#include "internal/status_macros.h"

namespace cel {

namespace {

using internal::MakeProtoWireTag;
using internal::ProtoWireDecoder;
using internal::ProtoWireType;
using internal::DeserializeValue;

} // namespace

Expand All @@ -36,52 +36,8 @@ CEL_INTERNAL_TYPE_IMPL(DynType);
absl::StatusOr<Handle<Value>> DynType::NewValueFromAny(
ValueFactory& value_factory, const absl::Cord& value) const {
// google.protobuf.Value.
Handle<Value> primitive = value_factory.GetNullValue();
ProtoWireDecoder decoder("google.protobuf.Value", value);
while (decoder.HasNext()) {
CEL_ASSIGN_OR_RETURN(auto tag, decoder.ReadTag());
if (tag == MakeProtoWireTag(1, ProtoWireType::kVarint)) {
CEL_ASSIGN_OR_RETURN(auto unused, decoder.ReadVarint<bool>());
static_cast<void>(unused);
primitive = value_factory.GetNullValue();
continue;
}
if (tag == MakeProtoWireTag(2, ProtoWireType::kFixed64)) {
CEL_ASSIGN_OR_RETURN(auto number_value, decoder.ReadFixed64<double>());
primitive = value_factory.CreateDoubleValue(number_value);
continue;
}
if (tag == MakeProtoWireTag(3, ProtoWireType::kLengthDelimited)) {
CEL_ASSIGN_OR_RETURN(auto string_value, decoder.ReadLengthDelimited());
CEL_ASSIGN_OR_RETURN(primitive,
value_factory.CreateStringValue(string_value));
continue;
}
if (tag == MakeProtoWireTag(4, ProtoWireType::kVarint)) {
CEL_ASSIGN_OR_RETURN(auto bool_value, decoder.ReadVarint<bool>());
primitive = value_factory.CreateBoolValue(bool_value);
continue;
}
if (tag == MakeProtoWireTag(5, ProtoWireType::kLengthDelimited)) {
CEL_ASSIGN_OR_RETURN(auto struct_value, decoder.ReadLengthDelimited());
CEL_ASSIGN_OR_RETURN(
primitive,
value_factory.type_factory().GetJsonMapType()->NewValueFromAny(
value_factory, struct_value));
continue;
}
if (tag == MakeProtoWireTag(6, ProtoWireType::kLengthDelimited)) {
CEL_ASSIGN_OR_RETURN(auto list_value, decoder.ReadLengthDelimited());
CEL_ASSIGN_OR_RETURN(
primitive,
value_factory.type_factory().GetJsonListType()->NewValueFromAny(
value_factory, list_value));
continue;
}
CEL_RETURN_IF_ERROR(decoder.SkipLengthValue());
}
decoder.EnsureFullyDecoded();
return primitive;
CEL_ASSIGN_OR_RETURN(auto deserialized_value, DeserializeValue(value));
return value_factory.CreateValueFromJson(std::move(deserialized_value));
}

absl::Span<const absl::string_view> DynType::aliases() const {
Expand Down
52 changes: 4 additions & 48 deletions base/types/map_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,14 @@
#include "base/values/map_value.h"
#include "base/values/map_value_builder.h"
#include "base/values/string_value.h"
#include "internal/proto_wire.h"
#include "internal/deserialize.h"
#include "internal/status_macros.h"

namespace cel {

namespace {

using internal::MakeProtoWireTag;
using internal::ProtoWireDecoder;
using internal::ProtoWireType;
using internal::DeserializeStruct;

} // namespace

Expand Down Expand Up @@ -77,50 +75,8 @@ absl::StatusOr<Handle<MapValue>> MapType::NewValueFromAny(
absl::StrCat("google.protobuf.Any cannot be deserialized as ", name()));
}
// google.protobuf.Struct.
CEL_ASSIGN_OR_RETURN(auto builder, NewValueBuilder(value_factory));
ProtoWireDecoder decoder("google.protobuf.Struct", value);
while (decoder.HasNext()) {
CEL_ASSIGN_OR_RETURN(auto tag, decoder.ReadTag());
if (tag == MakeProtoWireTag(1, ProtoWireType::kLengthDelimited)) {
// fields
CEL_ASSIGN_OR_RETURN(auto fields_value, decoder.ReadLengthDelimited());
Handle<StringValue> field_name = value_factory.GetStringValue();
Handle<Value> field_value = value_factory.GetNullValue();
ProtoWireDecoder fields_decoder("google.protobuf.Struct.FieldsEntry",
fields_value);
while (fields_decoder.HasNext()) {
CEL_ASSIGN_OR_RETURN(auto fields_tag, fields_decoder.ReadTag());
if (fields_tag ==
MakeProtoWireTag(1, ProtoWireType::kLengthDelimited)) {
// key
CEL_ASSIGN_OR_RETURN(auto field_name_value,
fields_decoder.ReadLengthDelimited());
CEL_ASSIGN_OR_RETURN(field_name, value_factory.CreateStringValue(
std::move(field_name_value)));
continue;
}
if (fields_tag ==
MakeProtoWireTag(2, ProtoWireType::kLengthDelimited)) {
// value
CEL_ASSIGN_OR_RETURN(auto field_value_value,
fields_decoder.ReadLengthDelimited());
CEL_ASSIGN_OR_RETURN(
field_value,
value_factory.type_factory().GetJsonValueType()->NewValueFromAny(
value_factory, field_value_value));
continue;
}
CEL_RETURN_IF_ERROR(fields_decoder.SkipLengthValue());
}
fields_decoder.EnsureFullyDecoded();
CEL_RETURN_IF_ERROR(
builder->Put(std::move(field_name), std::move(field_value)));
continue;
}
CEL_RETURN_IF_ERROR(decoder.SkipLengthValue());
}
decoder.EnsureFullyDecoded();
return std::move(*builder).Build();
CEL_ASSIGN_OR_RETURN(auto deserialized_value, DeserializeStruct(value));
return value_factory.CreateMapValueFromJson(std::move(deserialized_value));
}

absl::Span<const absl::string_view> MapType::aliases() const {
Expand Down
26 changes: 4 additions & 22 deletions base/types/timestamp_type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@
#include "absl/time/time.h"
#include "base/value_factory.h"
#include "base/values/timestamp_value.h"
#include "internal/proto_wire.h"
#include "internal/deserialize.h"
#include "internal/status_macros.h"

namespace cel {

namespace {

using internal::MakeProtoWireTag;
using internal::ProtoWireDecoder;
using internal::ProtoWireType;
using internal::DeserializeTimestamp;

} // namespace

Expand All @@ -36,24 +34,8 @@ CEL_INTERNAL_TYPE_IMPL(TimestampType);
absl::StatusOr<Handle<TimestampValue>> TimestampType::NewValueFromAny(
ValueFactory& value_factory, const absl::Cord& value) const {
// google.protobuf.Timestamp.
int64_t seconds = 0;
int32_t nanos = 0;
ProtoWireDecoder decoder("google.protobuf.Timestamp", value);
while (decoder.HasNext()) {
CEL_ASSIGN_OR_RETURN(auto tag, decoder.ReadTag());
if (tag == MakeProtoWireTag(1, ProtoWireType::kVarint)) {
CEL_ASSIGN_OR_RETURN(seconds, decoder.ReadVarint<int64_t>());
continue;
}
if (tag == MakeProtoWireTag(2, ProtoWireType::kVarint)) {
CEL_ASSIGN_OR_RETURN(nanos, decoder.ReadVarint<int32_t>());
continue;
}
CEL_RETURN_IF_ERROR(decoder.SkipLengthValue());
}
decoder.EnsureFullyDecoded();
return value_factory.CreateTimestampValue(
absl::UnixEpoch() + absl::Seconds(seconds) + absl::Nanoseconds(nanos));
CEL_ASSIGN_OR_RETURN(auto deserialized_value, DeserializeTimestamp(value));
return value_factory.CreateTimestampValue(deserialized_value);
}

} // namespace cel
Loading