Skip to content

Commit e421e78

Browse files
jnthntatumcopybara-github
authored andcommitted
Add interfaces and initial implementation for cel::Compiler.
PiperOrigin-RevId: 691975194
1 parent f15d8e6 commit e421e78

File tree

9 files changed

+610
-5
lines changed

9 files changed

+610
-5
lines changed

checker/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ cc_library(
4949
deps = [
5050
":type_check_issue",
5151
"//common:ast",
52+
"//common:source",
5253
"@com_google_absl//absl/base:nullability",
5354
"@com_google_absl//absl/status",
5455
"@com_google_absl//absl/status:statusor",

checker/type_checker_builder.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ absl::Status TypeCheckerBuilder::AddLibrary(CheckerLibrary library) {
117117
return absl::AlreadyExistsError(
118118
absl::StrCat("library '", library.id, "' already exists"));
119119
}
120-
absl::Status status = library.options(*this);
120+
if (!library.configure) {
121+
return absl::OkStatus();
122+
}
123+
absl::Status status = library.configure(*this);
121124

122125
libraries_.push_back(std::move(library));
123126
return status;

checker/type_checker_builder.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,16 @@ absl::StatusOr<TypeCheckerBuilder> CreateTypeCheckerBuilder(
6666
descriptor_pool,
6767
const CheckerOptions& options = {});
6868

69-
using ConfigureBuilderCallback =
70-
absl::AnyInvocable<absl::Status(TypeCheckerBuilder&)>;
69+
// Functional implementation to apply the library features to a
70+
// TypeCheckerBuilder.
71+
using TypeCheckerBuilderConfigurer =
72+
absl::AnyInvocable<absl::Status(TypeCheckerBuilder&) const>;
7173

7274
struct CheckerLibrary {
7375
// Optional identifier to avoid collisions re-adding the same declarations.
7476
// If id is empty, it is not considered.
7577
std::string id;
76-
// Functional implementation applying the library features to the builder.
77-
ConfigureBuilderCallback options;
78+
TypeCheckerBuilderConfigurer configure;
7879
};
7980

8081
// Builder for TypeChecker instances.

checker/validation_result.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "absl/types/span.h"
2626
#include "checker/type_check_issue.h"
2727
#include "common/ast.h"
28+
#include "common/source.h"
2829

2930
namespace cel {
3031

@@ -56,9 +57,21 @@ class ValidationResult {
5657

5758
absl::Span<const TypeCheckIssue> GetIssues() const { return issues_; }
5859

60+
// The source expression may optionally be set if it is available.
61+
absl::Nullable<const cel::Source*> GetSource() const { return source_.get(); }
62+
63+
void SetSource(std::unique_ptr<Source> source) {
64+
source_ = std::move(source);
65+
}
66+
67+
absl::Nullable<std::unique_ptr<cel::Source>> ReleaseSource() {
68+
return std::move(source_);
69+
}
70+
5971
private:
6072
absl::Nullable<std::unique_ptr<Ast>> ast_;
6173
std::vector<TypeCheckIssue> issues_;
74+
absl::Nullable<std::unique_ptr<Source>> source_;
6275
};
6376

6477
} // namespace cel

compiler/BUILD

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Copyright 2024 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
package(default_visibility = ["//visibility:public"])
16+
17+
cc_library(
18+
name = "compiler",
19+
hdrs = ["compiler.h"],
20+
deps = [
21+
"//checker:checker_options",
22+
"//checker:type_checker_builder",
23+
"//checker:validation_result",
24+
"//parser:options",
25+
"//parser:parser_interface",
26+
"@com_google_absl//absl/functional:any_invocable",
27+
"@com_google_absl//absl/status",
28+
"@com_google_absl//absl/status:statusor",
29+
"@com_google_absl//absl/strings:string_view",
30+
],
31+
)
32+
33+
cc_library(
34+
name = "compiler_factory",
35+
srcs = ["compiler_factory.cc"],
36+
hdrs = ["compiler_factory.h"],
37+
deps = [
38+
":compiler",
39+
"//checker:type_checker",
40+
"//checker:type_checker_builder",
41+
"//checker:validation_result",
42+
"//common:source",
43+
"//internal:noop_delete",
44+
"//internal:status_macros",
45+
"//parser",
46+
"//parser:parser_interface",
47+
"@com_google_absl//absl/base:nullability",
48+
"@com_google_absl//absl/container:flat_hash_set",
49+
"@com_google_absl//absl/status",
50+
"@com_google_absl//absl/status:statusor",
51+
"@com_google_absl//absl/strings",
52+
"@com_google_absl//absl/strings:string_view",
53+
"@com_google_protobuf//:protobuf",
54+
],
55+
)
56+
57+
cc_test(
58+
name = "compiler_factory_test",
59+
srcs = ["compiler_factory_test.cc"],
60+
deps = [
61+
":compiler",
62+
":compiler_factory",
63+
"//checker:optional",
64+
"//checker:standard_library",
65+
"//checker:type_check_issue",
66+
"//checker:validation_result",
67+
"//common:decl",
68+
"//common:type",
69+
"//internal:testing",
70+
"//internal:testing_descriptor_pool",
71+
"//parser:macro",
72+
"//parser:parser_interface",
73+
"//testutil:baseline_tests",
74+
"@com_google_absl//absl/status",
75+
"@com_google_absl//absl/status:status_matchers",
76+
"@com_google_protobuf//:protobuf",
77+
],
78+
)

compiler/compiler.h

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef THIRD_PARTY_CEL_CPP_COMPILER_COMPILER_INTERFACE_H_
16+
#define THIRD_PARTY_CEL_CPP_COMPILER_COMPILER_INTERFACE_H_
17+
18+
#include <memory>
19+
#include <string>
20+
#include <utility>
21+
22+
#include "absl/functional/any_invocable.h"
23+
#include "absl/status/status.h"
24+
#include "absl/status/statusor.h"
25+
#include "absl/strings/string_view.h"
26+
#include "checker/checker_options.h"
27+
#include "checker/type_checker_builder.h"
28+
#include "checker/validation_result.h"
29+
#include "parser/options.h"
30+
#include "parser/parser_interface.h"
31+
32+
namespace cel {
33+
34+
class Compiler;
35+
class CompilerBuilder;
36+
37+
// Callable for configuring a ParserBuilder.
38+
using ParserBuilderConfigurer =
39+
absl::AnyInvocable<absl::Status(ParserBuilder&) const>;
40+
41+
// A CompilerLibrary represents a package of CEL configuration that can be
42+
// added to a Compiler.
43+
//
44+
// It may contain either or both of a Parser configuration and a
45+
// TypeChecker configuration.
46+
struct CompilerLibrary {
47+
// Optional identifier to avoid collisions re-adding the same library.
48+
// If id is empty, it is not considered.
49+
std::string id;
50+
// Optional callback for configuring the parser.
51+
ParserBuilderConfigurer configure_parser;
52+
// Optional callback for configuring the type checker.
53+
TypeCheckerBuilderConfigurer configure_checker;
54+
55+
CompilerLibrary(std::string id, ParserBuilderConfigurer configure_parser,
56+
TypeCheckerBuilderConfigurer configure_checker = nullptr)
57+
: id(std::move(id)),
58+
configure_parser(std::move(configure_parser)),
59+
configure_checker(std::move(configure_checker)) {}
60+
61+
CompilerLibrary(std::string id,
62+
TypeCheckerBuilderConfigurer configure_checker)
63+
: id(std::move(id)),
64+
configure_parser(std::move(nullptr)),
65+
configure_checker(std::move(configure_checker)) {}
66+
67+
// Convenience conversion from the CheckerLibrary type.
68+
// NOLINTNEXTLINE(google-explicit-constructor)
69+
CompilerLibrary(CheckerLibrary checker_library)
70+
: id(std::move(checker_library.id)),
71+
configure_parser(nullptr),
72+
configure_checker(std::move(checker_library.configure)) {}
73+
};
74+
75+
// General options for configuring the underlying parser and checker.
76+
struct CompilerOptions {
77+
ParserOptions parser_options;
78+
CheckerOptions checker_options;
79+
};
80+
81+
// Interface for CEL CompilerBuilder objects.
82+
//
83+
// Builder implementations are thread hostile, but should create
84+
// thread-compatible Compiler instances.
85+
class CompilerBuilder {
86+
public:
87+
virtual ~CompilerBuilder() = default;
88+
89+
virtual absl::Status AddLibrary(cel::CompilerLibrary library) = 0;
90+
91+
virtual TypeCheckerBuilder& GetCheckerBuilder() = 0;
92+
virtual ParserBuilder& GetParserBuilder() = 0;
93+
94+
virtual absl::StatusOr<std::unique_ptr<Compiler>> Build() && = 0;
95+
};
96+
97+
// Interface for CEL Compiler objects.
98+
//
99+
// For CEL, compilation is the process of bundling the parse and type-check
100+
// passes.
101+
//
102+
// Compiler instances should be thread-compatible.
103+
class Compiler {
104+
public:
105+
virtual ~Compiler() = default;
106+
107+
virtual absl::StatusOr<ValidationResult> Compile(
108+
absl::string_view source, absl::string_view description) const = 0;
109+
110+
absl::StatusOr<ValidationResult> Compile(absl::string_view source) const {
111+
return Compile(source, "<input>");
112+
}
113+
};
114+
115+
} // namespace cel
116+
117+
#endif // THIRD_PARTY_CEL_CPP_COMPILER_COMPILER_INTERFACE_H_

0 commit comments

Comments
 (0)