diff --git a/common/typedef/BUILD b/common/typedef/BUILD new file mode 100644 index 000000000..be56c0383 --- /dev/null +++ b/common/typedef/BUILD @@ -0,0 +1,54 @@ +# Copyright 2026 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. + +load("@rules_cc//cc:cc_library.bzl", "cc_library") +load("@rules_cc//cc:cc_test.bzl", "cc_test") + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +cc_library( + name = "type_ref", + srcs = ["type_ref.cc"], + hdrs = ["type_ref.h"], + deps = [ + "//common:ast", + "//common:type", + "//common:type_kind", + "//internal:status_macros", + "@com_google_absl//absl/base:no_destructor", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings:string_view", + "@com_google_protobuf//:protobuf", + ], +) + +cc_test( + name = "type_ref_test", + srcs = ["type_ref_test.cc"], + deps = [ + ":type_ref", + "//common:type", + "//common:type_proto", + "//common/ast:metadata", + "//internal:proto_matchers", + "//internal:testing", + "//internal:testing_descriptor_pool", + "@com_google_absl//absl/status", + "@com_google_protobuf//:protobuf", + ], +) diff --git a/env/type_info.cc b/common/typedef/type_ref.cc similarity index 69% rename from env/type_info.cc rename to common/typedef/type_ref.cc index f49fab9f4..32c2403b2 100644 --- a/env/type_info.cc +++ b/common/typedef/type_ref.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "env/type_info.h" +#include "common/typedef/type_ref.h" #include #include @@ -27,7 +27,6 @@ #include "common/ast.h" #include "common/type.h" #include "common/type_kind.h" -#include "env/config.h" #include "internal/status_macros.h" #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" @@ -85,31 +84,31 @@ std::optional TypeNameToTypeKind(absl::string_view type_name) { } } // namespace -absl::StatusOr TypeInfoToType( - const Config::TypeInfo& type_info, - const google::protobuf::DescriptorPool* descriptor_pool, google::protobuf::Arena* arena) { - if (type_info.is_type_param) { - return TypeParamType(type_info.name); +absl::StatusOr TypeRefToType( + const TypeRef& type_ref, const google::protobuf::DescriptorPool* descriptor_pool, + google::protobuf::Arena* arena) { + if (type_ref.is_type_param) { + return TypeParamType(type_ref.name); } - std::optional type_kind = TypeNameToTypeKind(type_info.name); + std::optional type_kind = TypeNameToTypeKind(type_ref.name); if (!type_kind.has_value()) { - if (type_info.params.empty() && descriptor_pool != nullptr) { + if (type_ref.params.empty() && descriptor_pool != nullptr) { const google::protobuf::Descriptor* type = - descriptor_pool->FindMessageTypeByName(type_info.name); + descriptor_pool->FindMessageTypeByName(type_ref.name); if (type != nullptr) { return Type::Message(type); } } // TODO(uncreated-issue/88): use a TypeIntrospector to validate opaque types std::vector parameter_types; - for (const Config::TypeInfo& param : type_info.params) { + for (const TypeRef& param : type_ref.params) { CEL_ASSIGN_OR_RETURN(Type parameter_type, - TypeInfoToType(param, descriptor_pool, arena)); + TypeRefToType(param, descriptor_pool, arena)); parameter_types.push_back(parameter_type); } - return OpaqueType(arena, type_info.name, parameter_types); + return OpaqueType(arena, type_ref.name, parameter_types); } switch (*type_kind) { @@ -133,10 +132,10 @@ absl::StatusOr TypeInfoToType( return TimestampType(); case TypeKind::kList: { Type element_type; - if (!type_info.params.empty()) { + if (!type_ref.params.empty()) { CEL_ASSIGN_OR_RETURN( element_type, - TypeInfoToType(type_info.params[0], descriptor_pool, arena)); + TypeRefToType(type_ref.params[0], descriptor_pool, arena)); } else { element_type = DynType(); } @@ -145,14 +144,13 @@ absl::StatusOr TypeInfoToType( case TypeKind::kMap: { Type key_type = DynType(); Type value_type = DynType(); - if (!type_info.params.empty()) { - CEL_ASSIGN_OR_RETURN(key_type, TypeInfoToType(type_info.params[0], - descriptor_pool, arena)); + if (!type_ref.params.empty()) { + CEL_ASSIGN_OR_RETURN(key_type, TypeRefToType(type_ref.params[0], + descriptor_pool, arena)); } - if (type_info.params.size() > 1) { - CEL_ASSIGN_OR_RETURN( - value_type, - TypeInfoToType(type_info.params[1], descriptor_pool, arena)); + if (type_ref.params.size() > 1) { + CEL_ASSIGN_OR_RETURN(value_type, TypeRefToType(type_ref.params[1], + descriptor_pool, arena)); } return MapType(arena, key_type, value_type); } @@ -173,34 +171,35 @@ absl::StatusOr TypeInfoToType( case TypeKind::kBytesWrapper: return BytesWrapperType(); case TypeKind::kType: { - if (type_info.params.empty()) { + if (type_ref.params.empty()) { return TypeType(arena, DynType()); } - CEL_ASSIGN_OR_RETURN(Type type, TypeInfoToType(type_info.params[0], - descriptor_pool, arena)); + CEL_ASSIGN_OR_RETURN( + Type type, TypeRefToType(type_ref.params[0], descriptor_pool, arena)); return TypeType(arena, type); } default: return DynType(); } } -absl::StatusOr TypeInfoToTypeSpec(const Config::TypeInfo& type_info) { - if (type_info.is_type_param) { - return TypeSpec(ParamTypeSpec(type_info.name)); + +absl::StatusOr TypeRefToTypeSpec(const TypeRef& type_ref) { + if (type_ref.is_type_param) { + return TypeSpec(ParamTypeSpec(type_ref.name)); } - std::optional type_kind = TypeNameToTypeKind(type_info.name); + std::optional type_kind = TypeNameToTypeKind(type_ref.name); if (!type_kind.has_value()) { - if (type_info.params.empty()) { - return TypeSpec(MessageTypeSpec(type_info.name)); + if (type_ref.params.empty()) { + return TypeSpec(MessageTypeSpec(type_ref.name)); } else { std::vector param_specs; - param_specs.reserve(type_info.params.size()); - for (const Config::TypeInfo& param : type_info.params) { - CEL_ASSIGN_OR_RETURN(TypeSpec param_spec, TypeInfoToTypeSpec(param)); + param_specs.reserve(type_ref.params.size()); + for (const TypeRef& param : type_ref.params) { + CEL_ASSIGN_OR_RETURN(TypeSpec param_spec, TypeRefToTypeSpec(param)); param_specs.push_back(std::move(param_spec)); } - return TypeSpec(AbstractType(type_info.name, std::move(param_specs))); + return TypeSpec(AbstractType(type_ref.name, std::move(param_specs))); } } @@ -224,9 +223,9 @@ absl::StatusOr TypeInfoToTypeSpec(const Config::TypeInfo& type_info) { case TypeKind::kDuration: return TypeSpec(WellKnownTypeSpec::kDuration); case TypeKind::kList: { - if (!type_info.params.empty()) { + if (!type_ref.params.empty()) { CEL_ASSIGN_OR_RETURN(TypeSpec elem_type, - TypeInfoToTypeSpec(type_info.params[0])); + TypeRefToTypeSpec(type_ref.params[0])); return TypeSpec( ListTypeSpec(std::make_unique(std::move(elem_type)))); } else { @@ -234,14 +233,14 @@ absl::StatusOr TypeInfoToTypeSpec(const Config::TypeInfo& type_info) { } } case TypeKind::kMap: { - if (type_info.params.empty()) { + if (type_ref.params.empty()) { return TypeSpec(MapTypeSpec()); } CEL_ASSIGN_OR_RETURN(TypeSpec key_type, - TypeInfoToTypeSpec(type_info.params[0])); - if (type_info.params.size() > 1) { + TypeRefToTypeSpec(type_ref.params[0])); + if (type_ref.params.size() > 1) { CEL_ASSIGN_OR_RETURN(TypeSpec value_type, - TypeInfoToTypeSpec(type_info.params[1])); + TypeRefToTypeSpec(type_ref.params[1])); return TypeSpec( MapTypeSpec(std::make_unique(std::move(key_type)), std::make_unique(std::move(value_type)))); @@ -266,11 +265,11 @@ absl::StatusOr TypeInfoToTypeSpec(const Config::TypeInfo& type_info) { case TypeKind::kBytesWrapper: return TypeSpec(PrimitiveTypeWrapper(PrimitiveType::kBytes)); case TypeKind::kType: { - if (type_info.params.empty()) { + if (type_ref.params.empty()) { return TypeSpec(std::make_unique(DynTypeSpec())); } CEL_ASSIGN_OR_RETURN(TypeSpec type_param, - TypeInfoToTypeSpec(type_info.params[0])); + TypeRefToTypeSpec(type_ref.params[0])); return TypeSpec(std::make_unique(std::move(type_param))); } default: @@ -278,32 +277,32 @@ absl::StatusOr TypeInfoToTypeSpec(const Config::TypeInfo& type_info) { } } -absl::StatusOr TypeSpecToTypeInfo(const TypeSpec& type_spec) { - Config::TypeInfo type_info; +absl::StatusOr TypeSpecToTypeRef(const TypeSpec& type_spec) { + TypeRef type_ref; if (type_spec.has_dyn()) { - type_info.name = "dyn"; + type_ref.name = "dyn"; } else if (type_spec.has_null()) { - type_info.name = "null"; + type_ref.name = "null"; } else if (type_spec.has_primitive()) { switch (type_spec.primitive()) { case PrimitiveType::kBool: - type_info.name = "bool"; + type_ref.name = "bool"; break; case PrimitiveType::kInt64: - type_info.name = "int"; + type_ref.name = "int"; break; case PrimitiveType::kUint64: - type_info.name = "uint"; + type_ref.name = "uint"; break; case PrimitiveType::kDouble: - type_info.name = "double"; + type_ref.name = "double"; break; case PrimitiveType::kString: - type_info.name = "string"; + type_ref.name = "string"; break; case PrimitiveType::kBytes: - type_info.name = "bytes"; + type_ref.name = "bytes"; break; default: return absl::InvalidArgumentError("Unspecified primitive type"); @@ -311,22 +310,22 @@ absl::StatusOr TypeSpecToTypeInfo(const TypeSpec& type_spec) { } else if (type_spec.has_wrapper()) { switch (type_spec.wrapper()) { case PrimitiveType::kBool: - type_info.name = "bool_wrapper"; + type_ref.name = "bool_wrapper"; break; case PrimitiveType::kInt64: - type_info.name = "int_wrapper"; + type_ref.name = "int_wrapper"; break; case PrimitiveType::kUint64: - type_info.name = "uint_wrapper"; + type_ref.name = "uint_wrapper"; break; case PrimitiveType::kDouble: - type_info.name = "double_wrapper"; + type_ref.name = "double_wrapper"; break; case PrimitiveType::kString: - type_info.name = "string_wrapper"; + type_ref.name = "string_wrapper"; break; case PrimitiveType::kBytes: - type_info.name = "bytes_wrapper"; + type_ref.name = "bytes_wrapper"; break; default: return absl::InvalidArgumentError("Unspecified wrapper type"); @@ -334,27 +333,27 @@ absl::StatusOr TypeSpecToTypeInfo(const TypeSpec& type_spec) { } else if (type_spec.has_well_known()) { switch (type_spec.well_known()) { case WellKnownTypeSpec::kAny: - type_info.name = "any"; + type_ref.name = "any"; break; case WellKnownTypeSpec::kTimestamp: - type_info.name = "timestamp"; + type_ref.name = "timestamp"; break; case WellKnownTypeSpec::kDuration: - type_info.name = "duration"; + type_ref.name = "duration"; break; default: return absl::InvalidArgumentError("Unspecified well known type"); } } else if (type_spec.has_list_type()) { - type_info.name = "list"; + type_ref.name = "list"; const ListTypeSpec& list_type = type_spec.list_type(); if (list_type.has_elem_type() && list_type.elem_type().is_specified()) { - CEL_ASSIGN_OR_RETURN(Config::TypeInfo param, - TypeSpecToTypeInfo(list_type.elem_type())); - type_info.params.push_back(std::move(param)); + CEL_ASSIGN_OR_RETURN(TypeRef param, + TypeSpecToTypeRef(list_type.elem_type())); + type_ref.params.push_back(std::move(param)); } } else if (type_spec.has_map_type()) { - type_info.name = "map"; + type_ref.name = "map"; const MapTypeSpec& map_type = type_spec.map_type(); bool has_key = map_type.has_key_type() && map_type.key_type().is_specified(); @@ -362,49 +361,47 @@ absl::StatusOr TypeSpecToTypeInfo(const TypeSpec& type_spec) { map_type.has_value_type() && map_type.value_type().is_specified(); if (has_key || has_value) { if (has_key) { - CEL_ASSIGN_OR_RETURN(Config::TypeInfo param, - TypeSpecToTypeInfo(map_type.key_type())); - type_info.params.push_back(std::move(param)); + CEL_ASSIGN_OR_RETURN(TypeRef param, + TypeSpecToTypeRef(map_type.key_type())); + type_ref.params.push_back(std::move(param)); } else { - type_info.params.push_back(Config::TypeInfo{.name = "dyn"}); + type_ref.params.push_back(TypeRef{.name = "dyn"}); } if (has_value) { - CEL_ASSIGN_OR_RETURN(Config::TypeInfo param_value, - TypeSpecToTypeInfo(map_type.value_type())); - type_info.params.push_back(std::move(param_value)); + CEL_ASSIGN_OR_RETURN(TypeRef param_value, + TypeSpecToTypeRef(map_type.value_type())); + type_ref.params.push_back(std::move(param_value)); } else { - type_info.params.push_back(Config::TypeInfo{.name = "dyn"}); + type_ref.params.push_back(TypeRef{.name = "dyn"}); } } } else if (type_spec.has_message_type()) { - type_info.name = type_spec.message_type().type(); + type_ref.name = type_spec.message_type().type(); } else if (type_spec.has_type_param()) { - type_info.name = type_spec.type_param().type(); - type_info.is_type_param = true; + type_ref.name = type_spec.type_param().type(); + type_ref.is_type_param = true; } else if (type_spec.has_type()) { - type_info.name = "type"; - CEL_ASSIGN_OR_RETURN(Config::TypeInfo param, - TypeSpecToTypeInfo(type_spec.type())); - type_info.params.push_back(std::move(param)); + type_ref.name = "type"; + CEL_ASSIGN_OR_RETURN(TypeRef param, TypeSpecToTypeRef(type_spec.type())); + type_ref.params.push_back(std::move(param)); } else if (type_spec.has_abstract_type()) { - type_info.name = type_spec.abstract_type().name(); + type_ref.name = type_spec.abstract_type().name(); for (const TypeSpec& param_spec : type_spec.abstract_type().parameter_types()) { - CEL_ASSIGN_OR_RETURN(Config::TypeInfo param, - TypeSpecToTypeInfo(param_spec)); - type_info.params.push_back(std::move(param)); + CEL_ASSIGN_OR_RETURN(TypeRef param, TypeSpecToTypeRef(param_spec)); + type_ref.params.push_back(std::move(param)); } } else if (type_spec.has_error()) { return absl::InvalidArgumentError( - "ErrorType cannot be converted to TypeInfo"); + "ErrorType cannot be converted to TypeRef"); } else if (type_spec.has_function()) { return absl::InvalidArgumentError( - "FunctionType cannot be converted to TypeInfo"); + "FunctionType cannot be converted to TypeRef"); } else { return absl::InvalidArgumentError("Unknown TypeSpec kind"); } - return type_info; + return type_ref; } } // namespace cel diff --git a/common/typedef/type_ref.h b/common/typedef/type_ref.h new file mode 100644 index 000000000..8d87ae926 --- /dev/null +++ b/common/typedef/type_ref.h @@ -0,0 +1,57 @@ +// Copyright 2026 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. + +#ifndef THIRD_PARTY_CEL_CPP_COMMON_TYPEDEF_TYPE_REF_H_ +#define THIRD_PARTY_CEL_CPP_COMMON_TYPEDEF_TYPE_REF_H_ + +#include +#include + +#include "absl/status/statusor.h" +#include "common/ast.h" +#include "common/type.h" +#include "google/protobuf/arena.h" +#include "google/protobuf/descriptor.h" + +namespace cel { + +struct TypeRef { + std::string name; + std::vector params; + bool is_type_param = false; + + bool operator==(const TypeRef& other) const { + return name == other.name && params == other.params && + is_type_param == other.is_type_param; + } + + bool operator!=(const TypeRef& other) const { return !(*this == other); } +}; + +// Converts a TypeRef to a cel::Type. Returns an error if the type_ref +// cannot be converted to a known cel::Type, a list configured with more than +// one parameter. +absl::StatusOr TypeRefToType( + const TypeRef& type_ref, const google::protobuf::DescriptorPool* descriptor_pool, + google::protobuf::Arena* arena); + +// Converts a TypeRef to a cel::TypeSpec. +absl::StatusOr TypeRefToTypeSpec(const TypeRef& type_ref); + +// Converts a cel::TypeSpec to a TypeRef. +absl::StatusOr TypeSpecToTypeRef(const TypeSpec& type_spec); + +} // namespace cel + +#endif // THIRD_PARTY_CEL_CPP_COMMON_TYPEDEF_TYPE_REF_H_ diff --git a/env/type_info_test.cc b/common/typedef/type_ref_test.cc similarity index 57% rename from env/type_info_test.cc rename to common/typedef/type_ref_test.cc index f9d46f9a9..b5fd6be8f 100644 --- a/env/type_info_test.cc +++ b/common/typedef/type_ref_test.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "env/type_info.h" +#include "common/typedef/type_ref.h" #include #include @@ -24,7 +24,6 @@ #include "common/ast/metadata.h" #include "common/type.h" #include "common/type_proto.h" -#include "env/config.h" #include "internal/proto_matchers.h" #include "internal/testing.h" #include "internal/testing_descriptor_pool.h" @@ -34,16 +33,16 @@ namespace cel { -std::ostream& operator<<(std::ostream& os, const Config::TypeInfo& type_info) { - if (type_info.is_type_param) { +std::ostream& operator<<(std::ostream& os, const TypeRef& type_ref) { + if (type_ref.is_type_param) { os << "?"; } - os << type_info.name; - if (!type_info.params.empty()) { + os << type_ref.name; + if (!type_ref.params.empty()) { os << "<"; - for (size_t i = 0; i < type_info.params.size(); ++i) { + for (size_t i = 0; i < type_ref.params.size(); ++i) { if (i > 0) os << ", "; - os << type_info.params[i]; + os << type_ref.params[i]; } os << ">"; } @@ -57,13 +56,13 @@ using absl_testing::StatusIs; using testing::ValuesIn; struct TestCase { - Config::TypeInfo type_info; + TypeRef type_ref; std::string expected_type_pb; }; -using TypeInfoTest = testing::TestWithParam; +using TypeRefTest = testing::TestWithParam; -TEST_P(TypeInfoTest, TypeInfo) { +TEST_P(TypeRefTest, TypeRef) { const TestCase& param = GetParam(); cel::expr::Type expected_type_pb; ASSERT_TRUE(google::protobuf::TextFormat::ParseFromString(param.expected_type_pb, @@ -74,7 +73,7 @@ TEST_P(TypeInfoTest, TypeInfo) { cel::internal::GetTestingDescriptorPool(); ASSERT_OK_AND_ASSIGN( cel::Type actual_type, - cel::TypeInfoToType(param.type_info, descriptor_pool, &arena)); + cel::TypeRefToType(param.type_ref, descriptor_pool, &arena)); cel::expr::Type actual_type_pb; ASSERT_THAT(cel::TypeToProto(actual_type, &actual_type_pb), IsOk()); @@ -85,62 +84,59 @@ TEST_P(TypeInfoTest, TypeInfo) { std::vector GetTestCases() { return { TestCase{ - .type_info = {.name = "int"}, + .type_ref = {.name = "int"}, .expected_type_pb = "primitive: INT64", }, TestCase{ - .type_info = {.name = "list", - .params = {Config::TypeInfo{.name = "int"}}}, + .type_ref = {.name = "list", .params = {TypeRef{.name = "int"}}}, .expected_type_pb = "list_type { elem_type { primitive: INT64 } }", }, TestCase{ - .type_info = {.name = "list"}, + .type_ref = {.name = "list"}, .expected_type_pb = "list_type { elem_type { dyn {} }}", }, TestCase{ - .type_info = {.name = "map", - .params = {Config::TypeInfo{.name = "string"}, - Config::TypeInfo{.name = "int"}}}, + .type_ref = {.name = "map", + .params = {TypeRef{.name = "string"}, + TypeRef{.name = "int"}}}, .expected_type_pb = "map_type { key_type { primitive: STRING } " "value_type { primitive: INT64 }}", }, TestCase{ - .type_info = {.name = "cel.expr.conformance.proto2.TestAllTypes"}, + .type_ref = {.name = "cel.expr.conformance.proto2.TestAllTypes"}, .expected_type_pb = "message_type: 'cel.expr.conformance.proto2.TestAllTypes'", }, TestCase{ - .type_info = {.name = "A", - .params = {Config::TypeInfo{.name = "B", - .is_type_param = true}}}, + .type_ref = {.name = "A", + .params = {TypeRef{.name = "B", .is_type_param = true}}}, .expected_type_pb = "abstract_type { name: 'A' parameter_types { type_param: 'B' } }", }, TestCase{ - .type_info = {.name = "any"}, + .type_ref = {.name = "any"}, .expected_type_pb = "well_known: ANY", }, TestCase{ - .type_info = {.name = "timestamp"}, + .type_ref = {.name = "timestamp"}, .expected_type_pb = "well_known: TIMESTAMP", }, TestCase{ - .type_info = {.name = "google.protobuf.DoubleValue"}, + .type_ref = {.name = "google.protobuf.DoubleValue"}, .expected_type_pb = "wrapper: DOUBLE", }, TestCase{ - .type_info = {.name = "double_wrapper"}, + .type_ref = {.name = "double_wrapper"}, .expected_type_pb = "wrapper: DOUBLE", }, TestCase{ - .type_info = {.name = "type", - .params = {Config::TypeInfo{.name = "duration"}}}, + .type_ref = {.name = "type", .params = {TypeRef{.name = "duration"}}}, .expected_type_pb = "type: { well_known: DURATION }", }, TestCase{ - .type_info = {.name = "parameterized", - .params = {{.name = "A", .is_type_param = true}, - {.name = "double"}}}, + .type_ref = {.name = "parameterized", + .params = {{.name = "A", .is_type_param = true}, + {.name = "double"}}}, .expected_type_pb = "abstract_type { name: 'parameterized' " "parameter_types { type_param: 'A' } " "parameter_types { primitive: DOUBLE } }", @@ -148,151 +144,149 @@ std::vector GetTestCases() { }; } -INSTANTIATE_TEST_SUITE_P(TypeInfoTest, TypeInfoTest, ValuesIn(GetTestCases())); +INSTANTIATE_TEST_SUITE_P(TypeRefTest, TypeRefTest, ValuesIn(GetTestCases())); -bool TypeInfoEqImpl(const Config::TypeInfo& actual, - const Config::TypeInfo& expected) { +bool TypeRefEqImpl(const TypeRef& actual, const TypeRef& expected) { if (actual.name != expected.name) return false; if (actual.is_type_param != expected.is_type_param) return false; if (actual.params.size() != expected.params.size()) return false; for (size_t i = 0; i < actual.params.size(); ++i) { - if (!TypeInfoEqImpl(actual.params[i], expected.params[i])) return false; + if (!TypeRefEqImpl(actual.params[i], expected.params[i])) return false; } return true; } -MATCHER_P(TypeInfoEq, expected, "") { return TypeInfoEqImpl(arg, expected); } +MATCHER_P(TypeRefEq, expected, "") { return TypeRefEqImpl(arg, expected); } struct TypeSpecTestCase { TypeSpec type_spec; - Config::TypeInfo expected_type_info; + TypeRef expected_type_ref; }; -using TypeSpecToTypeInfoTest = testing::TestWithParam; +using TypeSpecToTypeRefTest = testing::TestWithParam; -TEST_P(TypeSpecToTypeInfoTest, Convert) { +TEST_P(TypeSpecToTypeRefTest, Convert) { const TypeSpecTestCase& param = GetParam(); - ASSERT_OK_AND_ASSIGN(Config::TypeInfo actual_type_info, - TypeSpecToTypeInfo(param.type_spec)); - EXPECT_THAT(actual_type_info, TypeInfoEq(param.expected_type_info)); + ASSERT_OK_AND_ASSIGN(TypeRef actual_type_ref, + TypeSpecToTypeRef(param.type_spec)); + EXPECT_THAT(actual_type_ref, TypeRefEq(param.expected_type_ref)); } std::vector GetTypeSpecTestCases() { return { TypeSpecTestCase{ .type_spec = TypeSpec(PrimitiveType::kInt64), - .expected_type_info = {.name = "int"}, + .expected_type_ref = {.name = "int"}, }, TypeSpecTestCase{ .type_spec = TypeSpec( ListTypeSpec(std::make_unique(PrimitiveType::kInt64))), - .expected_type_info = {.name = "list", - .params = {Config::TypeInfo{.name = "int"}}}, + .expected_type_ref = {.name = "list", + .params = {TypeRef{.name = "int"}}}, }, TypeSpecTestCase{ .type_spec = TypeSpec(ListTypeSpec()), - .expected_type_info = {.name = "list"}, + .expected_type_ref = {.name = "list"}, }, TypeSpecTestCase{ .type_spec = TypeSpec( MapTypeSpec(std::make_unique(PrimitiveType::kString), std::make_unique(PrimitiveType::kInt64))), - .expected_type_info = {.name = "map", - .params = {Config::TypeInfo{.name = "string"}, - Config::TypeInfo{.name = "int"}}}, + .expected_type_ref = {.name = "map", + .params = {TypeRef{.name = "string"}, + TypeRef{.name = "int"}}}, }, TypeSpecTestCase{ .type_spec = TypeSpec(MapTypeSpec()), - .expected_type_info = {.name = "map"}, + .expected_type_ref = {.name = "map"}, }, TypeSpecTestCase{ .type_spec = TypeSpec( MessageTypeSpec("cel.expr.conformance.proto2.TestAllTypes")), - .expected_type_info = - {.name = "cel.expr.conformance.proto2.TestAllTypes"}, + .expected_type_ref = {.name = + "cel.expr.conformance.proto2.TestAllTypes"}, }, TypeSpecTestCase{ .type_spec = TypeSpec(AbstractType("A", {TypeSpec(ParamTypeSpec("B"))})), - .expected_type_info = {.name = "A", - .params = {Config::TypeInfo{ - .name = "B", .is_type_param = true}}}, + .expected_type_ref = {.name = "A", + .params = {TypeRef{.name = "B", + .is_type_param = true}}}, }, TypeSpecTestCase{ .type_spec = TypeSpec(WellKnownTypeSpec::kAny), - .expected_type_info = {.name = "any"}, + .expected_type_ref = {.name = "any"}, }, TypeSpecTestCase{ .type_spec = TypeSpec(WellKnownTypeSpec::kTimestamp), - .expected_type_info = {.name = "timestamp"}, + .expected_type_ref = {.name = "timestamp"}, }, TypeSpecTestCase{ .type_spec = TypeSpec(PrimitiveTypeWrapper(PrimitiveType::kDouble)), - .expected_type_info = {.name = "double_wrapper"}, + .expected_type_ref = {.name = "double_wrapper"}, }, TypeSpecTestCase{ .type_spec = TypeSpec( std::make_unique(WellKnownTypeSpec::kDuration)), - .expected_type_info = {.name = "type", - .params = {Config::TypeInfo{.name = - "duration"}}}, + .expected_type_ref = {.name = "type", + .params = {TypeRef{.name = "duration"}}}, }, TypeSpecTestCase{ .type_spec = TypeSpec(std::make_unique(DynTypeSpec())), - .expected_type_info = {.name = "type", - .params = {Config::TypeInfo{.name = "dyn"}}}, + .expected_type_ref = {.name = "type", + .params = {TypeRef{.name = "dyn"}}}, }, TypeSpecTestCase{ .type_spec = TypeSpec(DynTypeSpec{}), - .expected_type_info = {.name = "dyn"}, + .expected_type_ref = {.name = "dyn"}, }, TypeSpecTestCase{ .type_spec = TypeSpec(NullTypeSpec{}), - .expected_type_info = {.name = "null"}, + .expected_type_ref = {.name = "null"}, }, TypeSpecTestCase{ .type_spec = TypeSpec( MapTypeSpec(std::make_unique(PrimitiveType::kString), std::make_unique(DynTypeSpec()))), - .expected_type_info = {.name = "map", - .params = {Config::TypeInfo{.name = "string"}, - Config::TypeInfo{.name = "dyn"}}}, + .expected_type_ref = {.name = "map", + .params = {TypeRef{.name = "string"}, + TypeRef{.name = "dyn"}}}, }, TypeSpecTestCase{ .type_spec = TypeSpec( MapTypeSpec(std::make_unique(DynTypeSpec()), std::make_unique(PrimitiveType::kInt64))), - .expected_type_info = {.name = "map", - .params = {Config::TypeInfo{.name = "dyn"}, - Config::TypeInfo{.name = "int"}}}, + .expected_type_ref = {.name = "map", + .params = {TypeRef{.name = "dyn"}, + TypeRef{.name = "int"}}}, }, }; } -INSTANTIATE_TEST_SUITE_P(TypeSpecToTypeInfoTest, TypeSpecToTypeInfoTest, +INSTANTIATE_TEST_SUITE_P(TypeSpecToTypeRefTest, TypeSpecToTypeRefTest, ValuesIn(GetTypeSpecTestCases())); -using TypeInfoToTypeSpecTest = testing::TestWithParam; +using TypeRefToTypeSpecTest = testing::TestWithParam; -TEST_P(TypeInfoToTypeSpecTest, Convert) { +TEST_P(TypeRefToTypeSpecTest, Convert) { const TypeSpecTestCase& param = GetParam(); ASSERT_OK_AND_ASSIGN(TypeSpec actual_type_spec, - TypeInfoToTypeSpec(param.expected_type_info)); + TypeRefToTypeSpec(param.expected_type_ref)); EXPECT_EQ(actual_type_spec, param.type_spec); } -INSTANTIATE_TEST_SUITE_P(TypeInfoToTypeSpecTest, TypeInfoToTypeSpecTest, +INSTANTIATE_TEST_SUITE_P(TypeRefToTypeSpecTest, TypeRefToTypeSpecTest, ValuesIn(GetTypeSpecTestCases())); -TEST(TypeSpecToTypeInfoTest, ErrorConversions) { - EXPECT_THAT(TypeSpecToTypeInfo(TypeSpec(ErrorTypeSpec::kValue)), +TEST(TypeSpecToTypeRefTest, ErrorConversions) { + EXPECT_THAT(TypeSpecToTypeRef(TypeSpec(ErrorTypeSpec::kValue)), StatusIs(absl::StatusCode::kInvalidArgument, - "ErrorType cannot be converted to TypeInfo")); - EXPECT_THAT(TypeSpecToTypeInfo(TypeSpec(FunctionTypeSpec())), + "ErrorType cannot be converted to TypeRef")); + EXPECT_THAT(TypeSpecToTypeRef(TypeSpec(FunctionTypeSpec())), StatusIs(absl::StatusCode::kInvalidArgument, - "FunctionType cannot be converted to TypeInfo")); + "FunctionType cannot be converted to TypeRef")); EXPECT_THAT( - TypeSpecToTypeInfo(TypeSpec(UnsetTypeSpec())), + TypeSpecToTypeRef(TypeSpec(UnsetTypeSpec())), StatusIs(absl::StatusCode::kInvalidArgument, "Unknown TypeSpec kind")); } diff --git a/env/BUILD b/env/BUILD index 0c17d6305..ba0a541f4 100644 --- a/env/BUILD +++ b/env/BUILD @@ -21,7 +21,6 @@ cc_library( name = "config", srcs = [ "config.cc", - "type_info.cc", ], hdrs = [ "config.h", @@ -31,10 +30,8 @@ cc_library( "//common:ast", "//common:constant", "//common:type", - "//common:type_kind", + "//common/typedef:type_ref", "//internal:status_macros", - "@com_google_absl//absl/base:no_destructor", - "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/functional:overload", "@com_google_absl//absl/status", @@ -57,6 +54,7 @@ cc_library( "//common:decl", "//common:signature", "//common:type", + "//common/typedef:type_ref", "//compiler", "//compiler:compiler_factory", "//compiler:standard_library", @@ -125,6 +123,7 @@ cc_library( "//common:ast", "//common:constant", "//common:signature", + "//common/typedef:type_ref", "//internal:status_macros", "//internal:strings", "@com_google_absl//absl/algorithm:container", @@ -176,22 +175,6 @@ cc_test( ], ) -cc_test( - name = "type_info_test", - srcs = ["type_info_test.cc"], - deps = [ - ":config", - "//common:type", - "//common:type_proto", - "//common/ast:metadata", - "//internal:proto_matchers", - "//internal:testing", - "//internal:testing_descriptor_pool", - "@com_google_absl//absl/status", - "@com_google_protobuf//:protobuf", - ], -) - cc_test( name = "env_test", srcs = ["env_test.cc"], @@ -280,6 +263,7 @@ cc_test( ":config", ":env_yaml", "//common:constant", + "//common/typedef:type_ref", "//internal:status_macros", "//internal:testing", "@com_google_absl//absl/status", diff --git a/env/config.h b/env/config.h index 68e4a1dd9..98e9b48b9 100644 --- a/env/config.h +++ b/env/config.h @@ -24,6 +24,7 @@ #include "absl/container/flat_hash_set.h" #include "absl/status/status.h" #include "common/constant.h" +#include "common/typedef/type_ref.h" // IWYU pragma: export namespace cel { @@ -108,16 +109,12 @@ class Config { return standard_library_config_; } - struct TypeInfo { - std::string name; - std::vector params; - bool is_type_param = false; - }; + using TypeInfo = cel::TypeRef; struct VariableConfig { std::string name; std::string description; - TypeInfo type_info; + TypeRef type_info; Constant value; }; @@ -137,8 +134,8 @@ class Config { std::string overload_id; std::vector examples; bool is_member_function = false; - std::vector parameters; - TypeInfo return_type; + std::vector parameters; + TypeRef return_type; }; struct FunctionConfig { diff --git a/env/config_test.cc b/env/config_test.cc index 8cfc3cf7f..f73899986 100644 --- a/env/config_test.cc +++ b/env/config_test.cc @@ -248,14 +248,12 @@ TEST(FunctionConfigTest, FunctionConfig) { EXPECT_THAT(overload_config.examples, ElementsAre("oracle.isTheOne('Neo', RED)")); EXPECT_TRUE(overload_config.is_member_function); - EXPECT_THAT( - overload_config.parameters, - ElementsAre(AllOf(Field(&Config::TypeInfo::name, "string"), - Field(&Config::TypeInfo::is_type_param, false)), - AllOf(Field(&Config::TypeInfo::name, "Choice"), - Field(&Config::TypeInfo::is_type_param, false)))); - EXPECT_THAT(overload_config.return_type, - Field(&Config::TypeInfo::name, "bool")); + EXPECT_THAT(overload_config.parameters, + ElementsAre(AllOf(Field(&TypeRef::name, "string"), + Field(&TypeRef::is_type_param, false)), + AllOf(Field(&TypeRef::name, "Choice"), + Field(&TypeRef::is_type_param, false)))); + EXPECT_THAT(overload_config.return_type, Field(&TypeRef::name, "bool")); } TEST(FunctionConfigTest, FunctionConfigInvalidMember) { diff --git a/env/env.cc b/env/env.cc index dd71323d5..6172e41b5 100644 --- a/env/env.cc +++ b/env/env.cc @@ -28,11 +28,11 @@ #include "common/decl.h" #include "common/signature.h" #include "common/type.h" +#include "common/typedef/type_ref.h" #include "compiler/compiler.h" #include "compiler/compiler_factory.h" #include "compiler/standard_library.h" #include "env/config.h" -#include "env/type_info.h" #include "internal/status_macros.h" #include "parser/macro.h" #include "google/protobuf/arena.h" @@ -128,14 +128,14 @@ absl::StatusOr FunctionConfigToFunctionDecl( OverloadDecl overload_decl; overload_decl.set_id(overload_config.overload_id); overload_decl.set_member(overload_config.is_member_function); - for (const Config::TypeInfo& parameter : overload_config.parameters) { + for (const TypeRef& parameter : overload_config.parameters) { CEL_ASSIGN_OR_RETURN(Type parameter_type, - TypeInfoToType(parameter, descriptor_pool, arena)); + TypeRefToType(parameter, descriptor_pool, arena)); overload_decl.mutable_args().push_back(parameter_type); } CEL_ASSIGN_OR_RETURN( Type return_type, - TypeInfoToType(overload_config.return_type, descriptor_pool, arena)); + TypeRefToType(overload_config.return_type, descriptor_pool, arena)); overload_decl.set_result(return_type); CEL_RETURN_IF_ERROR(function_decl.AddOverload(overload_decl)); } @@ -195,8 +195,8 @@ absl::StatusOr> Env::NewCompilerBuilder() VariableDecl variable_decl; variable_decl.set_name(variable_config.name); CEL_ASSIGN_OR_RETURN(Type type, - TypeInfoToType(variable_config.type_info, - descriptor_pool_.get(), arena)); + TypeRefToType(variable_config.type_info, + descriptor_pool_.get(), arena)); variable_decl.set_type(type); if (variable_config.value.has_value()) { variable_decl.set_value(variable_config.value); diff --git a/env/env_yaml.cc b/env/env_yaml.cc index 281cf3ff1..54cc4af0f 100644 --- a/env/env_yaml.cc +++ b/env/env_yaml.cc @@ -39,8 +39,8 @@ #include "common/ast.h" #include "common/constant.h" #include "common/signature.h" +#include "common/typedef/type_ref.h" #include "env/config.h" -#include "env/type_info.h" #include "internal/status_macros.h" #include "internal/strings.h" #include "yaml-cpp/emitter.h" @@ -420,9 +420,9 @@ absl::Status ParseStandardLibraryConfig(Config& config, absl::string_view yaml, return config.SetStandardLibraryConfig(standard_library_config); } -absl::StatusOr ParseTypeInfo(const YAML::Node& node, - absl::string_view yaml) { - Config::TypeInfo type_config; +absl::StatusOr ParseTypeRef(const YAML::Node& node, + absl::string_view yaml) { + TypeRef type_ref; const YAML::Node type = node["type"]; const YAML::Node type_name = node["type_name"]; if (type.IsDefined() && type_name.IsDefined()) { @@ -435,17 +435,17 @@ absl::StatusOr ParseTypeInfo(const YAML::Node& node, return YamlError(yaml, type, "Node 'type' is not a string"); } CEL_ASSIGN_OR_RETURN(auto type_spec, ParseTypeSpec(GetString(yaml, type))); - CEL_ASSIGN_OR_RETURN(auto type_config, TypeSpecToTypeInfo(type_spec)); - return type_config; + CEL_ASSIGN_OR_RETURN(TypeRef type_ref, TypeSpecToTypeRef(type_spec)); + return type_ref; } if (!type_name.IsDefined()) { - return type_config; + return type_ref; } if (!type_name || !type_name.IsScalar()) { return YamlError(yaml, type_name, "Node 'type_name' is not a string"); } - type_config.name = GetString(yaml, type_name); + type_ref.name = GetString(yaml, type_name); const YAML::Node is_type_param = node["is_type_param"]; if (is_type_param.IsDefined()) { @@ -453,27 +453,26 @@ absl::StatusOr ParseTypeInfo(const YAML::Node& node, return YamlError(yaml, is_type_param, "Node 'is_type_param' is not a boolean"); } - CEL_ASSIGN_OR_RETURN(type_config.is_type_param, + CEL_ASSIGN_OR_RETURN(type_ref.is_type_param, GetBool(yaml, "is_type_param", is_type_param)); } const YAML::Node params = node["params"]; if (!params.IsDefined()) { - return type_config; + return type_ref; } if (!params.IsSequence()) { return YamlError(yaml, params, "Node 'params' is not a sequence"); } for (const YAML::Node& param : params) { - CEL_ASSIGN_OR_RETURN(Config::TypeInfo param_config, - ParseTypeInfo(param, yaml)); - type_config.params.push_back(param_config); + CEL_ASSIGN_OR_RETURN(TypeRef param_ref, ParseTypeRef(param, yaml)); + type_ref.params.push_back(param_ref); } - return type_config; + return type_ref; } -bool CompareTypeInfo(const Config::TypeInfo& a, const Config::TypeInfo& b) { +bool CompareTypeRef(const TypeRef& a, const TypeRef& b) { if (a.name != b.name) { return a.name < b.name; } @@ -481,10 +480,10 @@ bool CompareTypeInfo(const Config::TypeInfo& a, const Config::TypeInfo& b) { return a.params.size() < b.params.size(); } for (size_t i = 0; i < a.params.size(); ++i) { - if (CompareTypeInfo(a.params[i], b.params[i])) { + if (CompareTypeRef(a.params[i], b.params[i])) { return true; } - if (CompareTypeInfo(b.params[i], a.params[i])) { + if (CompareTypeRef(b.params[i], a.params[i])) { return false; } } @@ -621,20 +620,20 @@ absl::Status ParseVariableConfigs(Config& config, absl::string_view yaml, variable_config.description = GetString(yaml, description); } const YAML::Node type = variable["type"]; - Config::TypeInfo type_info; + TypeRef type_ref; if (type.IsDefined() && !type.IsScalar()) { // Old format, type spec is in 'type' instead of directly embedded. - CEL_ASSIGN_OR_RETURN(type_info, ParseTypeInfo(variable["type"], yaml)); + CEL_ASSIGN_OR_RETURN(type_ref, ParseTypeRef(variable["type"], yaml)); } else { - CEL_ASSIGN_OR_RETURN(type_info, ParseTypeInfo(variable, yaml)); + CEL_ASSIGN_OR_RETURN(type_ref, ParseTypeRef(variable, yaml)); } - ConstantKindCase constant_kind_case = GetConstantKindCase(type_info.name); + ConstantKindCase constant_kind_case = GetConstantKindCase(type_ref.name); std::string value_str; YAML::Node value = variable["value"]; if (value.IsDefined()) { if (constant_kind_case == ConstantKindCase::kUnspecified) { return YamlError(yaml, value, - absl::StrCat("Constant type '", type_info.name, + absl::StrCat("Constant type '", type_ref.name, "' is not supported")); } if (!value.IsScalar()) { @@ -647,7 +646,7 @@ absl::Status ParseVariableConfigs(Config& config, absl::string_view yaml, } } - variable_config.type_info = type_info; + variable_config.type_info = type_ref; if (constant_kind_case != ConstantKindCase::kUnspecified && !value_str.empty()) { @@ -733,18 +732,17 @@ absl::StatusOr ParseFunctionOverloadConfig( const FunctionTypeSpec& function_type_spec = parsed_signature.signature_type.function(); for (const auto& arg : function_type_spec.arg_types()) { - CEL_ASSIGN_OR_RETURN(auto type_info, TypeSpecToTypeInfo(arg)); - overload_config.parameters.push_back(std::move(type_info)); + CEL_ASSIGN_OR_RETURN(TypeRef type_ref, TypeSpecToTypeRef(arg)); + overload_config.parameters.push_back(std::move(type_ref)); } } else { if (target.IsDefined()) { if (!target.IsMap()) { return YamlError(yaml, target, "Function overload target is not a map"); } - CEL_ASSIGN_OR_RETURN(Config::TypeInfo type_info, - ParseTypeInfo(target, yaml)); + CEL_ASSIGN_OR_RETURN(TypeRef type_ref, ParseTypeRef(target, yaml)); overload_config.is_member_function = true; - overload_config.parameters.push_back(type_info); + overload_config.parameters.push_back(type_ref); } if (args.IsDefined()) { @@ -756,9 +754,8 @@ absl::StatusOr ParseFunctionOverloadConfig( if (!arg.IsMap()) { return YamlError(yaml, arg, "Function overload arg is not a map"); } - CEL_ASSIGN_OR_RETURN(Config::TypeInfo type_info, - ParseTypeInfo(arg, yaml)); - overload_config.parameters.push_back(type_info); + CEL_ASSIGN_OR_RETURN(TypeRef type_ref, ParseTypeRef(arg, yaml)); + overload_config.parameters.push_back(type_ref); } } } @@ -768,10 +765,10 @@ absl::StatusOr ParseFunctionOverloadConfig( CEL_ASSIGN_OR_RETURN(auto type_spec, ParseTypeSpec(GetString(yaml, return_type))); CEL_ASSIGN_OR_RETURN(overload_config.return_type, - TypeSpecToTypeInfo(type_spec)); + TypeSpecToTypeRef(type_spec)); } else if (return_type.IsMap()) { CEL_ASSIGN_OR_RETURN(overload_config.return_type, - ParseTypeInfo(return_type, yaml)); + ParseTypeRef(return_type, yaml)); } else { return YamlError( yaml, return_type, @@ -983,13 +980,13 @@ void EmitStandardLibraryConfig(const Config& env_config, YAML::Emitter& out) { out << YAML::EndMap; } -void EmitTypeInfo(const Config::TypeInfo& type_info, YAML::Emitter& out, - const EnvConfigToYamlOptions& options) { +void EmitTypeRef(const TypeRef& type_ref, YAML::Emitter& out, + const EnvConfigToYamlOptions& options) { // Note: the map is already started when this is called, so we don't emit // BeginMap here or EndMap at the end. bool signature_generated = false; if (options.use_type_signatures) { - absl::StatusOr type_spec = TypeInfoToTypeSpec(type_info); + absl::StatusOr type_spec = TypeRefToTypeSpec(type_ref); if (type_spec.ok()) { absl::StatusOr signature = MakeTypeSpecSignature(*type_spec); if (signature.ok()) { @@ -1001,15 +998,15 @@ void EmitTypeInfo(const Config::TypeInfo& type_info, YAML::Emitter& out, } if (!signature_generated) { out << YAML::Key << "type_name"; - out << YAML::Value << YAML::DoubleQuoted << type_info.name; - if (type_info.is_type_param) { + out << YAML::Value << YAML::DoubleQuoted << type_ref.name; + if (type_ref.is_type_param) { out << YAML::Key << "is_type_param" << YAML::Value << true; } - if (!type_info.params.empty()) { + if (!type_ref.params.empty()) { out << YAML::Key << "params" << YAML::Value << YAML::BeginSeq; - for (const Config::TypeInfo& param : type_info.params) { + for (const TypeRef& param : type_ref.params) { out << YAML::BeginMap; - EmitTypeInfo(param, out, options); + EmitTypeRef(param, out, options); out << YAML::EndMap; } out << YAML::EndSeq; @@ -1042,7 +1039,7 @@ void EmitVariableConfigs(const Config& env_config, YAML::Emitter& out, out << YAML::Key << "description"; out << YAML::Value << YAML::DoubleQuoted << variable_config.description; } - EmitTypeInfo(variable_config.type_info, out, options); + EmitTypeRef(variable_config.type_info, out, options); if (variable_config.value.has_value()) { const Constant& constant = variable_config.value; switch (constant.kind_case()) { @@ -1108,7 +1105,7 @@ void EmitFunctionOverloadConfig( std::vector params; params.reserve(overload_config.parameters.size()); for (const auto& parameter : overload_config.parameters) { - absl::StatusOr type_spec = TypeInfoToTypeSpec(parameter); + absl::StatusOr type_spec = TypeRefToTypeSpec(parameter); if (!type_spec.ok()) { param_type_spec_generated = false; break; @@ -1140,9 +1137,9 @@ void EmitFunctionOverloadConfig( out << YAML::BeginMap; if (overload_config.parameters.empty()) { // This should never happen, but if it does, emit a dynamic type. - EmitTypeInfo({.name = "dyn"}, out, options); + EmitTypeRef({.name = "dyn"}, out, options); } else { - EmitTypeInfo(overload_config.parameters[0], out, options); + EmitTypeRef(overload_config.parameters[0], out, options); } out << YAML::EndMap; if (overload_config.parameters.size() > 1) { @@ -1150,7 +1147,7 @@ void EmitFunctionOverloadConfig( out << YAML::Value << YAML::BeginSeq; for (size_t i = 1; i < overload_config.parameters.size(); ++i) { out << YAML::BeginMap; - EmitTypeInfo(overload_config.parameters[i], out, options); + EmitTypeRef(overload_config.parameters[i], out, options); out << YAML::EndMap; } out << YAML::EndSeq; @@ -1159,9 +1156,9 @@ void EmitFunctionOverloadConfig( if (!overload_config.parameters.empty()) { out << YAML::Key << "args"; out << YAML::Value << YAML::BeginSeq; - for (const Config::TypeInfo& parameter : overload_config.parameters) { + for (const TypeRef& parameter : overload_config.parameters) { out << YAML::BeginMap; - EmitTypeInfo(parameter, out, options); + EmitTypeRef(parameter, out, options); out << YAML::EndMap; } out << YAML::EndSeq; @@ -1171,7 +1168,7 @@ void EmitFunctionOverloadConfig( bool return_type_signature_generated = false; if (options.use_type_signatures) { absl::StatusOr type_spec = - TypeInfoToTypeSpec(overload_config.return_type); + TypeRefToTypeSpec(overload_config.return_type); if (type_spec.ok()) { absl::StatusOr signature = MakeTypeSpecSignature(*type_spec); if (signature.ok()) { @@ -1184,7 +1181,7 @@ void EmitFunctionOverloadConfig( if (!return_type_signature_generated) { out << YAML::Key << "return"; out << YAML::Value << YAML::BeginMap; - EmitTypeInfo(overload_config.return_type, out, options); + EmitTypeRef(overload_config.return_type, out, options); out << YAML::EndMap; } out << YAML::EndMap; @@ -1228,10 +1225,10 @@ void EmitFunctionConfigs(const Config& env_config, YAML::Emitter& out, if (i >= b.parameters.size()) { return false; } - if (CompareTypeInfo(a.parameters[i], b.parameters[i])) { + if (CompareTypeRef(a.parameters[i], b.parameters[i])) { return true; } - if (CompareTypeInfo(b.parameters[i], a.parameters[i])) { + if (CompareTypeRef(b.parameters[i], a.parameters[i])) { return false; } } diff --git a/env/env_yaml_test.cc b/env/env_yaml_test.cc index c5bd1b787..a211e4188 100644 --- a/env/env_yaml_test.cc +++ b/env/env_yaml_test.cc @@ -30,6 +30,7 @@ #include "absl/strings/string_view.h" #include "absl/time/time.h" #include "common/constant.h" +#include "common/typedef/type_ref.h" #include "env/config.h" #include "internal/status_macros.h" #include "internal/testing.h" @@ -185,10 +186,10 @@ TEST(EnvYamlTest, ParseVariableConfigs) { const Config::VariableConfig& variable_config = config.GetVariableConfigs()[0]; EXPECT_EQ(variable_config.name, "msg"); - const auto& type_info = variable_config.type_info; - EXPECT_EQ(type_info.name, "google.expr.proto3.test.TestAllTypes"); - EXPECT_FALSE(type_info.is_type_param); - EXPECT_THAT(type_info.params, IsEmpty()); + const TypeRef& type_ref = variable_config.type_info; + EXPECT_EQ(type_ref.name, "google.expr.proto3.test.TestAllTypes"); + EXPECT_FALSE(type_ref.is_type_param); + EXPECT_THAT(type_ref.params, IsEmpty()); EXPECT_EQ(variable_config.description, "msg represents all possible type permutation which CEL " "understands from a proto perspective"); @@ -204,16 +205,16 @@ TEST(EnvYamlTest, ParseVariableConfigWithTypeParams) { const Config::VariableConfig& variable_config = config.GetVariableConfigs()[0]; EXPECT_EQ(variable_config.name, "dict"); - const auto& type_info = variable_config.type_info; - EXPECT_EQ(type_info.name, "map"); - EXPECT_FALSE(type_info.is_type_param); - EXPECT_THAT(type_info.params, SizeIs(2)); - EXPECT_EQ(type_info.params[0].name, "string"); - EXPECT_FALSE(type_info.params[0].is_type_param); - EXPECT_THAT(type_info.params[0].params, IsEmpty()); - EXPECT_EQ(type_info.params[1].name, "A"); - EXPECT_TRUE(type_info.params[1].is_type_param); - EXPECT_THAT(type_info.params[1].params, IsEmpty()); + const TypeRef& type_ref = variable_config.type_info; + EXPECT_EQ(type_ref.name, "map"); + EXPECT_FALSE(type_ref.is_type_param); + EXPECT_THAT(type_ref.params, SizeIs(2)); + EXPECT_EQ(type_ref.params[0].name, "string"); + EXPECT_FALSE(type_ref.params[0].is_type_param); + EXPECT_THAT(type_ref.params[0].params, IsEmpty()); + EXPECT_EQ(type_ref.params[1].name, "A"); + EXPECT_TRUE(type_ref.params[1].is_type_param); + EXPECT_THAT(type_ref.params[1].params, IsEmpty()); } TEST(EnvYamlTest, ParseContextVariableConfig) { @@ -271,16 +272,16 @@ TEST(EnvYamlTest, ParseVariableConfigWithTypeParamsLegacySyntax) { const Config::VariableConfig& variable_config = config.GetVariableConfigs()[0]; EXPECT_EQ(variable_config.name, "dict"); - const auto& type_info = variable_config.type_info; - EXPECT_EQ(type_info.name, "map"); - EXPECT_FALSE(type_info.is_type_param); - EXPECT_THAT(type_info.params, SizeIs(2)); - EXPECT_EQ(type_info.params[0].name, "string"); - EXPECT_FALSE(type_info.params[0].is_type_param); - EXPECT_THAT(type_info.params[0].params, IsEmpty()); - EXPECT_EQ(type_info.params[1].name, "A"); - EXPECT_TRUE(type_info.params[1].is_type_param); - EXPECT_THAT(type_info.params[1].params, IsEmpty()); + const TypeRef& type_ref = variable_config.type_info; + EXPECT_EQ(type_ref.name, "map"); + EXPECT_FALSE(type_ref.is_type_param); + EXPECT_THAT(type_ref.params, SizeIs(2)); + EXPECT_EQ(type_ref.params[0].name, "string"); + EXPECT_FALSE(type_ref.params[0].is_type_param); + EXPECT_THAT(type_ref.params[0].params, IsEmpty()); + EXPECT_EQ(type_ref.params[1].name, "A"); + EXPECT_TRUE(type_ref.params[1].is_type_param); + EXPECT_THAT(type_ref.params[1].params, IsEmpty()); } TEST(EnvYamlTest, ParseVariableConfigWithNestedRuleOldFormat) { @@ -295,10 +296,10 @@ TEST(EnvYamlTest, ParseVariableConfigWithNestedRuleOldFormat) { const Config::VariableConfig& variable_config = config.GetVariableConfigs()[0]; EXPECT_EQ(variable_config.name, "x"); - const auto& type_info = variable_config.type_info; - EXPECT_EQ(type_info.name, "int"); - EXPECT_FALSE(type_info.is_type_param); - EXPECT_THAT(type_info.params, IsEmpty()); + const TypeRef& type_ref = variable_config.type_info; + EXPECT_EQ(type_ref.name, "int"); + EXPECT_FALSE(type_ref.is_type_param); + EXPECT_THAT(type_ref.params, IsEmpty()); } struct ParseConstantTestCase { @@ -470,13 +471,12 @@ struct ParseFunctionTestCase { class EnvYamlParseFunctionTest : public testing::TestWithParam {}; -void ExpectTypeInfoEqual(const Config::TypeInfo& actual, - const Config::TypeInfo& expected) { +void ExpectTypeRefEqual(const TypeRef& actual, const TypeRef& expected) { EXPECT_EQ(actual.name, expected.name); EXPECT_EQ(actual.is_type_param, expected.is_type_param); ASSERT_THAT(actual.params, SizeIs(expected.params.size())); for (size_t i = 0; i < expected.params.size(); ++i) { - ExpectTypeInfoEqual(actual.params[i], expected.params[i]); + ExpectTypeRefEqual(actual.params[i], expected.params[i]); } } @@ -508,12 +508,12 @@ TEST_P(EnvYamlParseFunctionTest, EnvYamlParseFunction) { ASSERT_THAT(actual_overload.parameters, SizeIs(expected_overload.parameters.size())); for (size_t j = 0; j < expected_overload.parameters.size(); ++j) { - ExpectTypeInfoEqual(actual_overload.parameters[j], - expected_overload.parameters[j]); + ExpectTypeRefEqual(actual_overload.parameters[j], + expected_overload.parameters[j]); } - ExpectTypeInfoEqual(actual_overload.return_type, - expected_overload.return_type); + ExpectTypeRefEqual(actual_overload.return_type, + expected_overload.return_type); } } diff --git a/env/type_info.h b/env/type_info.h index 3f802ce1a..2707c5716 100644 --- a/env/type_info.h +++ b/env/type_info.h @@ -18,24 +18,22 @@ #include "absl/status/statusor.h" #include "common/ast.h" #include "common/type.h" -#include "env/config.h" +#include "common/typedef/type_ref.h" // IWYU pragma: export #include "google/protobuf/arena.h" #include "google/protobuf/descriptor.h" namespace cel { -// Converts a Config::TypeInfo to a cel::Type. Returns an error if the type_info -// cannot be converted to a known cel::Type, a list configured with more than -// one parameter. -absl::StatusOr TypeInfoToType( - const Config::TypeInfo& type_info, - const google::protobuf::DescriptorPool* descriptor_pool, google::protobuf::Arena* arena); +// Backwards-compatible aliases for existing third_party/cel/python callers. +inline absl::StatusOr TypeInfoToType( + const TypeRef& type_ref, const google::protobuf::DescriptorPool* descriptor_pool, + google::protobuf::Arena* arena) { + return TypeRefToType(type_ref, descriptor_pool, arena); +} -// Converts a Config::TypeInfo to a cel::TypeSpec. -absl::StatusOr TypeInfoToTypeSpec(const Config::TypeInfo& type_info); - -// Converts a cel::TypeSpec to a Config::TypeInfo. -absl::StatusOr TypeSpecToTypeInfo(const TypeSpec& type_spec); +inline absl::StatusOr TypeSpecToTypeInfo(const TypeSpec& type_spec) { + return TypeSpecToTypeRef(type_spec); +} } // namespace cel