Skip to content
Open
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
64 changes: 64 additions & 0 deletions parser/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,29 @@
# limitations under the License.

load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")
load("//bazel:antlr.bzl", "antlr_cc_library")

package(default_visibility = ["//visibility:public"])

licenses(["notice"])

cc_library(
name = "ast_factory_interface",
hdrs = ["ast_factory_interface.h"],
)

cc_library(
name = "ast_factory",
hdrs = ["ast_factory.h"],
deps = [
":ast_factory_interface",
"//common:constant",
"//common:expr",
"@com_google_absl//absl/strings:string_view",
],
)

cc_library(
name = "options",
hdrs = ["options.h"],
Expand All @@ -29,3 +46,50 @@ antlr_cc_library(
src = "Cel.g4",
package = "cel_parser_internal",
)

cc_library(
name = "lexer",
srcs = ["lexer.cc"],
hdrs = ["lexer.h"],
deps = [
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:no_destructor",
"@com_google_absl//absl/base:nullability",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:function_ref",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:string_view",
],
)

cc_test(
name = "ast_factory_test",
srcs = ["ast_factory_test.cc"],
deps = [
":ast_factory",
":ast_factory_interface",
"//common:expr",
"//internal:testing",
],
)

cc_test(
name = "lexer_test",
srcs = ["lexer_test.cc"],
deps = [
":lexer",
"//internal:testing",
],
)

cc_test(
name = "lexer_fuzzer",
size = "large",
srcs = ["lexer_fuzzer.cc"],
deps = [
":lexer",
"//internal:testing",
"//testing/fuzzing:fuzztest",
],
)
236 changes: 236 additions & 0 deletions parser/internal/ast_factory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
// 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_PARSER_INTERNAL_AST_FACTORY_H_
#define THIRD_PARTY_CEL_CPP_PARSER_INTERNAL_AST_FACTORY_H_

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

#include "common/constant.h"
#include "common/expr.h"
#include "parser/internal/ast_factory_interface.h"

namespace cel::parser_internal {

// Explicit specialization of `AstFactoryInterface` for `cel::Expr` AST nodes.
template <>
class AstFactoryInterface<cel::Expr> {
public:
AstFactoryInterface() = default;

AstFactoryInterface(const AstFactoryInterface&) = delete;
AstFactoryInterface(AstFactoryInterface&&) = delete;
AstFactoryInterface& operator=(const AstFactoryInterface&) = delete;
AstFactoryInterface& operator=(AstFactoryInterface&&) = delete;

~AstFactoryInterface() = default;

// Node inspection and encapsulation API
int64_t GetId(const cel::Expr& expr) const { return expr.id(); }

bool IsEmpty(const cel::Expr& expr) const { return expr.id() == 0; }

bool IsConst(const cel::Expr& expr) const { return expr.has_const_expr(); }

bool IsIdent(const cel::Expr& expr) const { return expr.has_ident_expr(); }

std::string_view GetIdentName(const cel::Expr& expr) const {
return expr.has_ident_expr() ? std::string_view(expr.ident_expr().name())
: std::string_view();
}

bool IsSelect(const cel::Expr& expr) const { return expr.has_select_expr(); }

bool IsPresenceTest(const cel::Expr& expr) const {
return expr.has_select_expr() && expr.select_expr().test_only();
}

const cel::Expr* GetSelectOperand(const cel::Expr& expr) const {
return expr.has_select_expr() ? &expr.select_expr().operand() : nullptr;
}

std::string_view GetSelectField(const cel::Expr& expr) const {
return expr.has_select_expr() ? std::string_view(expr.select_expr().field())
: std::string_view();
}

// Node creation API
cel::Expr NewUnspecified(int64_t id) {
cel::Expr expr;
expr.set_id(id);
return expr;
}

cel::Expr NewNullConst(int64_t id) {
cel::Constant constant;
constant.set_null_value();
return NewConst(id, std::move(constant));
}

cel::Expr NewBoolConst(int64_t id, bool value) {
cel::Constant constant;
constant.set_bool_value(value);
return NewConst(id, std::move(constant));
}

cel::Expr NewIntConst(int64_t id, int64_t value) {
cel::Constant constant;
constant.set_int_value(value);
return NewConst(id, std::move(constant));
}

cel::Expr NewUintConst(int64_t id, uint64_t value) {
cel::Constant constant;
constant.set_uint_value(value);
return NewConst(id, std::move(constant));
}

cel::Expr NewDoubleConst(int64_t id, double value) {
cel::Constant constant;
constant.set_double_value(value);
return NewConst(id, std::move(constant));
}

cel::Expr NewBytesConst(int64_t id, std::string value) {
cel::Constant constant;
constant.set_bytes_value(std::move(value));
return NewConst(id, std::move(constant));
}

cel::Expr NewStringConst(int64_t id, std::string value) {
cel::Constant constant;
constant.set_string_value(std::move(value));
return NewConst(id, std::move(constant));
}

cel::Expr NewIdent(int64_t id, std::string name) {
cel::Expr expr;
expr.set_id(id);
cel::IdentExpr& ident_expr = expr.mutable_ident_expr();
ident_expr.set_name(std::move(name));
return expr;
}

cel::Expr NewSelect(int64_t id, cel::Expr operand, std::string field) {
cel::Expr expr;
expr.set_id(id);
cel::SelectExpr& select_expr = expr.mutable_select_expr();
select_expr.set_operand(std::move(operand));
select_expr.set_field(std::move(field));
select_expr.set_test_only(false);
return expr;
}

cel::Expr NewPresenceTest(int64_t id, cel::Expr operand, std::string field) {
cel::Expr expr;
expr.set_id(id);
cel::SelectExpr& select_expr = expr.mutable_select_expr();
select_expr.set_operand(std::move(operand));
select_expr.set_field(std::move(field));
select_expr.set_test_only(true);
return expr;
}

cel::Expr NewCall(int64_t id, std::string function,
std::vector<cel::Expr> args) {
cel::Expr expr;
expr.set_id(id);
cel::CallExpr& call_expr = expr.mutable_call_expr();
call_expr.set_function(std::move(function));
call_expr.set_args(std::move(args));
return expr;
}

cel::Expr NewMemberCall(int64_t id, std::string function, cel::Expr target,
std::vector<cel::Expr> args) {
cel::Expr expr;
expr.set_id(id);
cel::CallExpr& call_expr = expr.mutable_call_expr();
call_expr.set_function(std::move(function));
call_expr.set_target(std::move(target));
call_expr.set_args(std::move(args));
return expr;
}

cel::Expr NewList(int64_t id) {
cel::Expr expr;
expr.set_id(id);
expr.mutable_list_expr();
return expr;
}

void AddListElement(cel::Expr& list_expr, cel::Expr element,
bool optional = false) {
cel::ListExpr& list_val = list_expr.mutable_list_expr();
cel::ListExprElement expr_element;
expr_element.set_expr(std::move(element));
expr_element.set_optional(optional);
list_val.mutable_elements().push_back(std::move(expr_element));
}

cel::Expr NewStruct(int64_t id, std::string name) {
cel::Expr expr;
expr.set_id(id);
cel::StructExpr& struct_expr = expr.mutable_struct_expr();
struct_expr.set_name(std::move(name));
return expr;
}

void AddStructField(cel::Expr& struct_expr, int64_t id, std::string name,
cel::Expr value, bool optional = false) {
cel::StructExpr& struct_val = struct_expr.mutable_struct_expr();
cel::StructExprField field;
field.set_id(id);
field.set_name(std::move(name));
field.set_value(std::move(value));
field.set_optional(optional);
struct_val.mutable_fields().push_back(std::move(field));
}

cel::Expr NewMap(int64_t id) {
cel::Expr expr;
expr.set_id(id);
expr.mutable_map_expr();
return expr;
}

void AddMapEntry(cel::Expr& map_expr, int64_t id, cel::Expr key,
cel::Expr value, bool optional = false) {
cel::MapExpr& map_val = map_expr.mutable_map_expr();
cel::MapExprEntry entry;
entry.set_id(id);
entry.set_key(std::move(key));
entry.set_value(std::move(value));
entry.set_optional(optional);
map_val.mutable_entries().push_back(std::move(entry));
}

private:
cel::Expr NewConst(int64_t id, cel::Constant value) {
cel::Expr expr;
expr.set_id(id);
expr.mutable_const_expr() = std::move(value);
return expr;
}
};

using AstFactory = AstFactoryInterface<cel::Expr>;

} // namespace cel::parser_internal

#endif // THIRD_PARTY_CEL_CPP_PARSER_INTERNAL_AST_FACTORY_H_
Loading
Loading