Skip to content

Commit

Permalink
Enable math conformance tests
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 625034746
  • Loading branch information
jcking authored and copybara-github committed Apr 15, 2024
1 parent f81870e commit 1abb1ab
Show file tree
Hide file tree
Showing 9 changed files with 466 additions and 133 deletions.
33 changes: 33 additions & 0 deletions conformance/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ ALL_TESTS = [
"@com_google_cel_spec//tests/simple:testdata/lists.textproto",
"@com_google_cel_spec//tests/simple:testdata/logic.textproto",
"@com_google_cel_spec//tests/simple:testdata/macros.textproto",
"@com_google_cel_spec//tests/simple:testdata/math_ext.textproto",
"@com_google_cel_spec//tests/simple:testdata/namespace.textproto",
"@com_google_cel_spec//tests/simple:testdata/optionals.textproto",
"@com_google_cel_spec//tests/simple:testdata/parse.textproto",
"@com_google_cel_spec//tests/simple:testdata/plumbing.textproto",
"@com_google_cel_spec//tests/simple:testdata/proto2.textproto",
"@com_google_cel_spec//tests/simple:testdata/proto3.textproto",
"@com_google_cel_spec//tests/simple:testdata/string.textproto",
"@com_google_cel_spec//tests/simple:testdata/string_ext.textproto",
"@com_google_cel_spec//tests/simple:testdata/timestamps.textproto",
"@com_google_cel_spec//tests/simple:testdata/unknowns.textproto",
"@com_google_cel_spec//tests/simple:testdata/wrappers.textproto",
Expand Down Expand Up @@ -65,6 +67,9 @@ cc_binary(
"//eval/public:transform_utility",
"//extensions:bindings_ext",
"//extensions:encoders",
"//extensions:math_ext",
"//extensions:math_ext_macros",
"//extensions:strings",
"//extensions/protobuf:enum_adapter",
"//extensions/protobuf:memory_manager",
"//extensions/protobuf:runtime_adapter",
Expand Down Expand Up @@ -139,6 +144,20 @@ cc_binary(

# Legacy value does not support optional_type.
"--skip_test=optionals/optionals",

# Not yet implemented.
"--skip_test=string_ext/char_at",
"--skip_test=string_ext/index_of",
"--skip_test=string_ext/last_index_of",
"--skip_test=string_ext/ascii_casing/upperascii",
"--skip_test=string_ext/ascii_casing/upperascii_unicode",
"--skip_test=string_ext/ascii_casing/upperascii_unicode_with_space",
"--skip_test=string_ext/replace",
"--skip_test=string_ext/substring",
"--skip_test=string_ext/trim",
"--skip_test=string_ext/quote",
"--skip_test=string_ext/value_errors",
"--skip_test=string_ext/type_errors",
] + ["$(location " + test + ")" for test in ALL_TESTS],
data = [
":server",
Expand Down Expand Up @@ -187,6 +206,20 @@ cc_binary(
# TODO(issues/119): Strong typing support for enums, specified but not implemented.
"--skip_test=enums/strong_proto2",
"--skip_test=enums/strong_proto3",

# Not yet implemented.
"--skip_test=string_ext/char_at",
"--skip_test=string_ext/index_of",
"--skip_test=string_ext/last_index_of",
"--skip_test=string_ext/ascii_casing/upperascii",
"--skip_test=string_ext/ascii_casing/upperascii_unicode",
"--skip_test=string_ext/ascii_casing/upperascii_unicode_with_space",
"--skip_test=string_ext/replace",
"--skip_test=string_ext/substring",
"--skip_test=string_ext/trim",
"--skip_test=string_ext/quote",
"--skip_test=string_ext/value_errors",
"--skip_test=string_ext/type_errors",
] + ["$(location " + test + ")" for test in ALL_TESTS],
data = [
":server",
Expand Down
12 changes: 12 additions & 0 deletions conformance/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@
#include "eval/public/transform_utility.h"
#include "extensions/bindings_ext.h"
#include "extensions/encoders.h"
#include "extensions/math_ext.h"
#include "extensions/math_ext_macros.h"
#include "extensions/protobuf/enum_adapter.h"
#include "extensions/protobuf/memory_manager.h"
#include "extensions/protobuf/runtime_adapter.h"
#include "extensions/protobuf/type_reflector.h"
#include "extensions/strings.h"
#include "internal/status_macros.h"
#include "parser/macro_registry.h"
#include "parser/options.h"
Expand Down Expand Up @@ -123,6 +126,7 @@ absl::Status LegacyParse(const conformance::v1alpha1::ParseRequest& request,
cel::MacroRegistry macros;
CEL_RETURN_IF_ERROR(cel::RegisterStandardMacros(macros, options));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterBindingsMacros(macros, options));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterMathMacros(macros, options));
CEL_ASSIGN_OR_RETURN(auto source, cel::NewSource(request.cel_source(),
request.source_location()));
CEL_ASSIGN_OR_RETURN(auto parsed_expr,
Expand Down Expand Up @@ -174,6 +178,10 @@ class LegacyConformanceServiceImpl : public ConformanceServiceInterface {
RegisterBuiltinFunctions(builder->GetRegistry(), options));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterEncodersFunctions(
builder->GetRegistry(), options));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterStringsFunctions(
builder->GetRegistry(), options));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterMathExtensionFunctions(
builder->GetRegistry(), options));

return absl::WrapUnique(
new LegacyConformanceServiceImpl(std::move(builder)));
Expand Down Expand Up @@ -314,6 +322,10 @@ class ModernConformanceServiceImpl : public ConformanceServiceInterface {
CEL_RETURN_IF_ERROR(cel::extensions::EnableOptionalTypes(builder));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterEncodersFunctions(
builder.function_registry(), options));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterStringsFunctions(
builder.function_registry(), options));
CEL_RETURN_IF_ERROR(cel::extensions::RegisterMathExtensionFunctions(
builder.function_registry(), options));

return std::move(builder).Build();
}
Expand Down
8 changes: 1 addition & 7 deletions eval/public/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -1265,16 +1265,10 @@ cc_library(
srcs = ["string_extension_func_registrar.cc"],
hdrs = ["string_extension_func_registrar.h"],
deps = [
":cel_function",
":cel_function_adapter",
":cel_function_registry",
":cel_options",
":cel_value",
"//eval/public/containers:container_backed_list_impl",
"//internal:status_macros",
"//extensions:strings",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_protobuf//:protobuf",
],
)

Expand Down
126 changes: 3 additions & 123 deletions eval/public/string_extension_func_registrar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,136 +14,16 @@

#include "eval/public/string_extension_func_registrar.h"

#include <cstdint>
#include <string>
#include <string_view>
#include <vector>

#include "absl/status/status.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "eval/public/cel_function_adapter.h"
#include "eval/public/cel_function_registry.h"
#include "eval/public/cel_options.h"
#include "eval/public/cel_value.h"
#include "eval/public/containers/container_backed_list_impl.h"
#include "internal/status_macros.h"
#include "google/protobuf/arena.h"
#include "extensions/strings.h"

namespace google::api::expr::runtime {

using google::protobuf::Arena;

constexpr char kEmptySeparator[] = "";

CelValue SplitWithLimit(Arena* arena, const CelValue::StringHolder value,
const CelValue::StringHolder delimiter, int64_t limit) {
// As per specifications[1]. return empty list in case limit is set to 0.
// 1. https://pkg.go.dev/github.com/google/cel-go/ext#Strings
std::vector<std::string> string_split = {};
if (limit < 0) {
// perform regular split operation in case of limit < 0
string_split = absl::StrSplit(value.value(), delimiter.value());
} else if (limit > 0) {
// The absl::MaxSplits generate at max limit + 1 number of elements where as
// it is suppose to return limit nunmber of elements as per
// specifications[1].
// To resolve the inconsistency passing limit-1 as input to absl::MaxSplits
// 1. https://pkg.go.dev/github.com/google/cel-go/ext#Strings
string_split = absl::StrSplit(
value.value(), absl::MaxSplits(delimiter.value(), limit - 1));
}
std::vector<CelValue> cel_list;
cel_list.reserve(string_split.size());
for (const std::string& substring : string_split) {
cel_list.push_back(
CelValue::CreateString(Arena::Create<std::string>(arena, substring)));
}
auto result = CelValue::CreateList(
Arena::Create<ContainerBackedListImpl>(arena, cel_list));
return result;
}

CelValue Split(Arena* arena, CelValue::StringHolder value,
CelValue::StringHolder delimiter) {
return SplitWithLimit(arena, value, delimiter, -1);
}

CelValue::StringHolder JoinWithSeparator(Arena* arena, const CelValue& value,
absl::string_view separator) {
const CelList* cel_list = value.ListOrDie();
std::vector<std::string_view> string_list;
string_list.reserve(cel_list->size());
for (int i = 0; i < cel_list->size(); i++) {
string_list.push_back(cel_list->Get(arena, i).StringOrDie().value());
}
auto result =
Arena::Create<std::string>(arena, absl::StrJoin(string_list, separator));
return CelValue::StringHolder(result);
}

CelValue::StringHolder Join(Arena* arena, const CelValue& value) {
return JoinWithSeparator(arena, value, kEmptySeparator);
}

CelValue::StringHolder LowerAscii(Arena* arena,
const CelValue::StringHolder value) {
auto result =
Arena::Create<std::string>(arena, absl::AsciiStrToLower(value.value()));
return CelValue::StringHolder(result);
}

absl::Status RegisterStringExtensionFunctions(
CelFunctionRegistry* registry, const InterpreterOptions& options) {
if (options.enable_string_concat) {
CEL_RETURN_IF_ERROR(
(FunctionAdapter<CelValue::StringHolder, CelValue>::CreateAndRegister(
"join", true,
[](Arena* arena, CelValue value) -> CelValue::StringHolder {
return Join(arena, value);
},
registry)));
CEL_RETURN_IF_ERROR((
FunctionAdapter<CelValue::StringHolder, CelValue,
CelValue::StringHolder>::
CreateAndRegister(
"join", true,
[](Arena* arena, CelValue value,
CelValue::StringHolder separator) -> CelValue::StringHolder {
return JoinWithSeparator(arena, value, separator.value());
},
registry)));
}
CEL_RETURN_IF_ERROR(
(FunctionAdapter<CelValue, CelValue::StringHolder,
CelValue::StringHolder>::
CreateAndRegister(
"split", true,
[](Arena* arena, CelValue::StringHolder str,
CelValue::StringHolder delimiter) -> CelValue {
return Split(arena, str, delimiter);
},
registry)));

CEL_RETURN_IF_ERROR(
(FunctionAdapter<CelValue, CelValue::StringHolder, CelValue::StringHolder,
int64_t>::
CreateAndRegister(
"split", true,
[](Arena* arena, CelValue::StringHolder str,
CelValue::StringHolder delimiter, int64_t limit) -> CelValue {
return SplitWithLimit(arena, str, delimiter, limit);
},
registry)));
CEL_RETURN_IF_ERROR(
(FunctionAdapter<CelValue::StringHolder, CelValue::StringHolder>::
CreateAndRegister(
"lowerAscii", true,
[](Arena* arena, CelValue::StringHolder str)
-> CelValue::StringHolder { return LowerAscii(arena, str); },
registry)));
return absl::OkStatus();
return cel::extensions::RegisterStringsFunctions(registry, options);
}

} // namespace google::api::expr::runtime
5 changes: 2 additions & 3 deletions eval/public/string_extension_func_registrar.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@
#ifndef THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_STRING_EXTENSION_FUNC_REGISTRAR_H_
#define THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_STRING_EXTENSION_FUNC_REGISTRAR_H_

#include "eval/public/cel_function.h"
#include "absl/status/status.h"
#include "eval/public/cel_function_registry.h"
#include "eval/public/cel_options.h"

namespace google::api::expr::runtime {

// Register string related widely used extension functions.
// TODO(uncreated-issue/22): Move String extension function to
// extensions
absl::Status RegisterStringExtensionFunctions(
CelFunctionRegistry* registry,
const InterpreterOptions& options = InterpreterOptions());
Expand Down
45 changes: 45 additions & 0 deletions extensions/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,48 @@ cc_test(
"@com_google_protobuf//:protobuf",
],
)

cc_library(
name = "strings",
srcs = ["strings.cc"],
hdrs = ["strings.h"],
deps = [
"//common:casting",
"//common:type",
"//common:value",
"//eval/public:cel_function_registry",
"//eval/public:cel_options",
"//internal:status_macros",
"//internal:utf8",
"//runtime:function_adapter",
"//runtime:function_registry",
"//runtime:runtime_options",
"//runtime/internal:errors",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:cord",
"@com_google_absl//absl/strings:string_view",
],
)

cc_test(
name = "strings_test",
srcs = ["strings_test.cc"],
deps = [
":strings",
"//common:memory",
"//common:value",
"//extensions/protobuf:runtime_adapter",
"//internal:testing",
"//parser",
"//parser:options",
"//runtime",
"//runtime:activation",
"//runtime:runtime_builder",
"//runtime:runtime_options",
"//runtime:standard_runtime_builder_factory",
"@com_google_absl//absl/strings:cord",
"@com_google_googleapis//google/api/expr/v1alpha1:syntax_cc_proto",
],
)
Loading

0 comments on commit 1abb1ab

Please sign in to comment.