Skip to content
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
8 changes: 8 additions & 0 deletions checker/internal/type_checker_builder_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ absl::Status ValidateType(const Type& t, bool check_type_param_name,
return ValidateType(value_type, check_type_param_name, depth_limit,
remaining_depth);
}
case TypeKind::kStruct: {
auto message_type = t.AsMessage();
if (message_type.has_value() && !static_cast<bool>(*message_type)) {
return absl::InvalidArgumentError(
"an empty message type cannot be used in a type declaration");
}
return absl::OkStatus();
}
case TypeKind::kOpaque: {
for (Type type_param : t.AsOpaque()->GetParameters()) {
CEL_RETURN_IF_ERROR(ValidateType(type_param, check_type_param_name,
Expand Down
24 changes: 18 additions & 6 deletions checker/internal/type_checker_builder_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ TEST(ContextDeclsTest, ErrorOnOverlappingVariableDeclaration) {
"variable 'single_int64' declared multiple times"));
}

TEST(ContextDeclsTest, InvalidTypeParamNameVariableValidationDisabled) {
TEST(TypeCheckerBuilderImplTest,
InvalidTypeParamNameVariableValidationDisabled) {
CheckerOptions options;
options.enable_type_parameter_name_validation = false;
TypeCheckerBuilderImpl builder(internal::GetSharedTestingDescriptorPool(),
Expand All @@ -219,7 +220,18 @@ TEST(ContextDeclsTest, InvalidTypeParamNameVariableValidationDisabled) {
IsOk());
}

TEST(ContextDeclsTest, ErrorOnInvalidTypeParamNameVariable) {
TEST(TypeCheckerBuilderImplTest, ErrorOnUnspecifiedMessageType) {
CheckerOptions options;
options.enable_type_parameter_name_validation = true;
TypeCheckerBuilderImpl builder(internal::GetSharedTestingDescriptorPool(),
options);
ASSERT_THAT(
builder.AddVariable(MakeVariableDecl("x", MessageType())),
StatusIs(absl::StatusCode::kInvalidArgument,
"an empty message type cannot be used in a type declaration"));
}

TEST(TypeCheckerBuilderImplTest, ErrorOnInvalidTypeParamNameVariable) {
CheckerOptions options;
options.enable_type_parameter_name_validation = true;
TypeCheckerBuilderImpl builder(internal::GetSharedTestingDescriptorPool(),
Expand All @@ -234,7 +246,7 @@ TEST(ContextDeclsTest, ErrorOnInvalidTypeParamNameVariable) {
"type parameter name 'T% foo' is not a valid identifier"));
}

TEST(ContextDeclsTest, ErrorOnTooDeepTypeNestingVariable) {
TEST(TypeCheckerBuilderImplTest, ErrorOnTooDeepTypeNestingVariable) {
CheckerOptions options;
options.max_type_decl_nesting = 2;
google::protobuf::Arena arena;
Expand All @@ -251,7 +263,7 @@ TEST(ContextDeclsTest, ErrorOnTooDeepTypeNestingVariable) {
"type nesting limit of 2 exceeded"));
}

TEST(ContextDeclsTest, ErrorOnInvalidTypeParamNameFunction) {
TEST(TypeCheckerBuilderImplTest, ErrorOnInvalidTypeParamNameFunction) {
CheckerOptions options;
options.enable_type_parameter_name_validation = true;
TypeCheckerBuilderImpl builder(internal::GetSharedTestingDescriptorPool(),
Expand All @@ -269,7 +281,7 @@ TEST(ContextDeclsTest, ErrorOnInvalidTypeParamNameFunction) {
"type parameter name '' is not a valid identifier"));
}

TEST(ContextDeclsTest, ErrorOnTooDeepTypeNestingFunction) {
TEST(TypeCheckerBuilderImplTest, ErrorOnTooDeepTypeNestingFunction) {
CheckerOptions options;
options.max_type_decl_nesting = 2;
google::protobuf::Arena arena;
Expand All @@ -294,7 +306,7 @@ TEST(ContextDeclsTest, ErrorOnTooDeepTypeNestingFunction) {
"type nesting limit of 2 exceeded"));
}

TEST(ContextDeclsTest, ReplaceVariable) {
TEST(TypeCheckerBuilderImplTest, ReplaceVariable) {
TypeCheckerBuilderImpl builder(internal::GetSharedTestingDescriptorPool(),
{});
ASSERT_THAT(
Expand Down
4 changes: 4 additions & 0 deletions common/types/message_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class MessageType final {
<< descriptor->full_name();
}

// Constructs a `MessageType` in an empty state.
//
// Most operations on an empty `MessageType` result in undefined behavior. Use
// `operator bool` to test if a `MessageType` is empty.
MessageType() = default;
MessageType(const MessageType&) = default;
MessageType(MessageType&&) = default;
Expand Down