diff --git a/compiler/BUILD b/compiler/BUILD index d4a0ab4ac..2e3f7a2ba 100644 --- a/compiler/BUILD +++ b/compiler/BUILD @@ -25,6 +25,7 @@ cc_library( "//checker:type_checker", "//checker:type_checker_builder", "//checker:validation_result", + "//common:source", "//parser:options", "//parser:parser_interface", "//validator", diff --git a/compiler/compiler.h b/compiler/compiler.h index 27237df60..174912f71 100644 --- a/compiler/compiler.h +++ b/compiler/compiler.h @@ -27,6 +27,7 @@ #include "checker/type_checker.h" #include "checker/type_checker_builder.h" #include "checker/validation_result.h" +#include "common/source.h" #include "parser/options.h" #include "parser/parser_interface.h" #include "validator/validator.h" @@ -129,9 +130,18 @@ class Compiler { public: virtual ~Compiler() = default; - virtual absl::StatusOr Compile( + absl::StatusOr Compile( + const Source& source, google::protobuf::Arena* absl_nullable arena) const { + return CompileImpl(source, arena); + } + + absl::StatusOr Compile(const Source& source) const { + return CompileImpl(source, nullptr); + } + + absl::StatusOr Compile( absl::string_view source, absl::string_view description, - google::protobuf::Arena* absl_nullable arena) const = 0; + google::protobuf::Arena* absl_nullable arena) const; absl::StatusOr Compile(absl::string_view source) const { return Compile(source, "", nullptr); @@ -159,8 +169,27 @@ class Compiler { // The returned builder does not share state with the compiler and may be // modified independently. virtual std::unique_ptr ToBuilder() const = 0; + + protected: + virtual absl::StatusOr CompileImpl( + const Source& source, google::protobuf::Arena* absl_nullable arena) const = 0; }; +inline absl::StatusOr Compiler::Compile( + absl::string_view source, absl::string_view description, + google::protobuf::Arena* absl_nullable arena) const { + absl::StatusOr source_obj = + NewSource(source, std::string(description)); + if (!source_obj.ok()) { + return source_obj.status(); + } + absl::StatusOr result = CompileImpl(**source_obj, arena); + if (result.ok()) { + result->SetSource(std::move(*source_obj)); + } + return result; +} + } // namespace cel #endif // THIRD_PARTY_CEL_CPP_COMPILER_COMPILER_INTERFACE_H_ diff --git a/compiler/compiler_factory.cc b/compiler/compiler_factory.cc index ed22c5630..a8a44461c 100644 --- a/compiler/compiler_factory.cc +++ b/compiler/compiler_factory.cc @@ -54,14 +54,18 @@ class CompilerImpl : public Compiler { validator_(std::move(validator)), options_(options) {} - absl::StatusOr Compile( - absl::string_view expression, absl::string_view description, - google::protobuf::Arena* arena) const override { - CEL_ASSIGN_OR_RETURN(auto source, - cel::NewSource(expression, std::string(description))); + std::unique_ptr ToBuilder() const override; + + const TypeChecker& GetTypeChecker() const override { return *type_checker_; } + const Parser& GetParser() const override { return *parser_; } + const Validator& GetValidator() const override { return validator_; } + + protected: + absl::StatusOr CompileImpl( + const Source& source, google::protobuf::Arena* arena) const override { std::vector parse_issues; absl::StatusOr> ast = - parser_->Parse(*source, &parse_issues); + parser_->Parse(source, &parse_issues); if (!ast.ok()) { if (!options_.adapt_parser_errors || ast.status().code() != absl::StatusCode::kInvalidArgument || @@ -74,26 +78,17 @@ class CompilerImpl : public Compiler { check_issues.push_back(TypeCheckIssue::CreateError( issue.location(), std::string(issue.message()))); } - ValidationResult result(std::move(check_issues)); - result.SetSource(std::move(source)); - return result; + return ValidationResult(std::move(check_issues)); } CEL_ASSIGN_OR_RETURN(ValidationResult result, type_checker_->Check(*std::move(ast), arena)); - result.SetSource(std::move(source)); if (!validator_.validations().empty()) { validator_.UpdateValidationResult(result); } return result; } - std::unique_ptr ToBuilder() const override; - - const TypeChecker& GetTypeChecker() const override { return *type_checker_; } - const Parser& GetParser() const override { return *parser_; } - const Validator& GetValidator() const override { return validator_; } - private: std::unique_ptr type_checker_; std::unique_ptr parser_; diff --git a/compiler/compiler_factory_test.cc b/compiler/compiler_factory_test.cc index 035fd8aa6..3f83f5bf2 100644 --- a/compiler/compiler_factory_test.cc +++ b/compiler/compiler_factory_test.cc @@ -427,5 +427,19 @@ TEST(CompilerFactoryTest, ReturnsIssuesFromParser) { EXPECT_THAT(result.GetIssues(), testing::Not(testing::IsEmpty())); } +TEST(CompilerFactoryTest, CompileSourceOverload) { + ASSERT_OK_AND_ASSIGN( + auto builder, + NewCompilerBuilder(cel::internal::GetSharedTestingDescriptorPool())); + + ASSERT_THAT(builder->AddLibrary(StandardCompilerLibrary()), IsOk()); + ASSERT_OK_AND_ASSIGN(auto compiler, builder->Build()); + + ASSERT_OK_AND_ASSIGN(auto source, cel::NewSource("1 + 2")); + ASSERT_OK_AND_ASSIGN(ValidationResult result, compiler->Compile(*source)); + + EXPECT_TRUE(result.IsValid()); +} + } // namespace } // namespace cel