Skip to content

Commit 8f53ec3

Browse files
CEL Dev Teamcopybara-github
authored andcommitted
Internal change
PiperOrigin-RevId: 825366361
1 parent dd4f368 commit 8f53ec3

8 files changed

Lines changed: 375 additions & 6 deletions

checker/internal/BUILD

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ cc_library(
6666
hdrs = ["type_check_env.h"],
6767
deps = [
6868
":descriptor_pool_type_introspector",
69+
":proto_type_mask",
70+
":proto_type_mask_registry",
6971
"//common:constant",
7072
"//common:container",
7173
"//common:decl",
@@ -76,6 +78,7 @@ cc_library(
7678
"@com_google_absl//absl/container:flat_hash_map",
7779
"@com_google_absl//absl/log:absl_check",
7880
"@com_google_absl//absl/memory",
81+
"@com_google_absl//absl/status",
7982
"@com_google_absl//absl/status:statusor",
8083
"@com_google_absl//absl/strings",
8184
"@com_google_absl//absl/strings:string_view",
@@ -129,6 +132,7 @@ cc_library(
129132
deps = [
130133
":format_type_name",
131134
":namespace_generator",
135+
":proto_type_mask",
132136
":type_check_env",
133137
":type_inference_context",
134138
"//checker:checker_options",
@@ -153,6 +157,7 @@ cc_library(
153157
"@com_google_absl//absl/base:no_destructor",
154158
"@com_google_absl//absl/base:nullability",
155159
"@com_google_absl//absl/cleanup",
160+
"@com_google_absl//absl/container:btree",
156161
"@com_google_absl//absl/container:flat_hash_map",
157162
"@com_google_absl//absl/container:flat_hash_set",
158163
"@com_google_absl//absl/log:absl_check",
@@ -225,6 +230,7 @@ cc_test(
225230
"@com_google_absl//absl/status",
226231
"@com_google_absl//absl/status:status_matchers",
227232
"@com_google_absl//absl/status:statusor",
233+
"@com_google_absl//absl/strings",
228234
"@com_google_absl//absl/strings:string_view",
229235
"@com_google_absl//absl/types:optional",
230236
"@com_google_protobuf//:protobuf",

checker/internal/type_check_env.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <cstddef>
1818
#include <cstdint>
19+
#include <optional>
1920

2021
#include "absl/base/nullability.h"
2122
#include "absl/status/statusor.h"
@@ -96,6 +97,10 @@ absl::StatusOr<std::optional<VariableDecl>> TypeCheckEnv::LookupTypeConstant(
9697

9798
absl::StatusOr<std::optional<StructTypeField>> TypeCheckEnv::LookupStructField(
9899
absl::string_view type_name, absl::string_view field_name) const {
100+
if (proto_type_mask_registry_ != nullptr &&
101+
!proto_type_mask_registry_->FieldIsVisible(type_name, field_name)) {
102+
return absl::nullopt;
103+
}
99104
// Check the type providers in registration order.
100105
// Note: this doesn't allow for shadowing a type with a subset type of the
101106
// same name -- the later type provider will still be considered when

checker/internal/type_check_env.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@
2525
#include "absl/container/flat_hash_map.h"
2626
#include "absl/log/absl_check.h"
2727
#include "absl/memory/memory.h"
28+
#include "absl/status/status.h"
2829
#include "absl/status/statusor.h"
2930
#include "absl/strings/string_view.h"
3031
#include "absl/types/optional.h"
3132
#include "absl/types/span.h"
3233
#include "checker/internal/descriptor_pool_type_introspector.h"
34+
#include "checker/internal/proto_type_mask.h"
35+
#include "checker/internal/proto_type_mask_registry.h"
3336
#include "common/constant.h"
3437
#include "common/container.h"
3538
#include "common/decl.h"
3639
#include "common/type.h"
3740
#include "common/type_introspector.h"
41+
#include "internal/status_macros.h"
3842
#include "google/protobuf/arena.h"
3943
#include "google/protobuf/descriptor.h"
4044

@@ -154,6 +158,14 @@ class TypeCheckEnv {
154158
variables_[decl.name()] = std::move(decl);
155159
}
156160

161+
absl::Status CreateProtoTypeMaskRegistry(
162+
const std::vector<ProtoTypeMask>& proto_type_masks) {
163+
CEL_ASSIGN_OR_RETURN(proto_type_mask_registry_,
164+
ProtoTypeMaskRegistry::Create(descriptor_pool_.get(),
165+
proto_type_masks));
166+
return absl::OkStatus();
167+
}
168+
157169
const absl::flat_hash_map<std::string, FunctionDecl>& functions() const {
158170
return functions_;
159171
}
@@ -224,6 +236,8 @@ class TypeCheckEnv {
224236
absl::flat_hash_map<std::string, VariableDecl> variables_;
225237
absl::flat_hash_map<std::string, FunctionDecl> functions_;
226238

239+
std::shared_ptr<ProtoTypeMaskRegistry> proto_type_mask_registry_;
240+
227241
// Type providers for custom types.
228242
std::vector<std::shared_ptr<const TypeIntrospector>> type_providers_;
229243

checker/internal/type_checker_builder_impl.cc

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,24 @@
1616

1717
#include <cstddef>
1818
#include <memory>
19+
#include <optional>
1920
#include <string>
2021
#include <utility>
2122
#include <vector>
2223

2324
#include "absl/base/no_destructor.h"
2425
#include "absl/base/nullability.h"
2526
#include "absl/cleanup/cleanup.h"
27+
#include "absl/container/btree_set.h"
2628
#include "absl/container/flat_hash_map.h"
29+
#include "absl/container/flat_hash_set.h"
2730
#include "absl/log/absl_log.h"
2831
#include "absl/status/status.h"
2932
#include "absl/status/statusor.h"
3033
#include "absl/strings/str_cat.h"
3134
#include "absl/strings/string_view.h"
3235
#include "absl/types/optional.h"
36+
#include "checker/internal/proto_type_mask.h"
3337
#include "checker/internal/type_check_env.h"
3438
#include "checker/internal/type_checker_impl.h"
3539
#include "checker/type_checker.h"
@@ -86,10 +90,19 @@ absl::Status CheckStdMacroOverlap(const FunctionDecl& decl) {
8690
}
8791

8892
absl::Status AddWellKnownContextDeclarationVariables(
89-
const google::protobuf::Descriptor* absl_nonnull descriptor, TypeCheckEnv& env,
90-
bool use_json_name) {
93+
const google::protobuf::Descriptor* absl_nonnull descriptor,
94+
const absl::flat_hash_map<absl::string_view,
95+
absl::btree_set<absl::string_view>>&
96+
context_type_fields,
97+
TypeCheckEnv& env, bool use_json_name) {
9198
for (int i = 0; i < descriptor->field_count(); ++i) {
9299
const google::protobuf::FieldDescriptor* field = descriptor->field(i);
100+
// Skip fields that are hidden because of a proto type mask.
101+
auto map_iterator = context_type_fields.find(descriptor->full_name());
102+
if (map_iterator != context_type_fields.end() &&
103+
!map_iterator->second.contains(field->name())) {
104+
continue;
105+
}
93106
Type type = MessageTypeField(field).GetType();
94107
if (type.IsEnum()) {
95108
type = IntType();
@@ -109,11 +122,15 @@ absl::Status AddWellKnownContextDeclarationVariables(
109122
}
110123

111124
absl::Status AddContextDeclarationVariables(
112-
const google::protobuf::Descriptor* absl_nonnull descriptor, TypeCheckEnv& env) {
125+
const google::protobuf::Descriptor* absl_nonnull descriptor,
126+
const absl::flat_hash_map<absl::string_view,
127+
absl::btree_set<absl::string_view>>&
128+
context_type_fields,
129+
TypeCheckEnv& env) {
113130
const bool use_json_name = env.proto_type_introspector().use_json_name();
114131
if (IsWellKnownMessageType(descriptor)) {
115-
return AddWellKnownContextDeclarationVariables(descriptor, env,
116-
use_json_name);
132+
return AddWellKnownContextDeclarationVariables(
133+
descriptor, context_type_fields, env, use_json_name);
117134
}
118135
CEL_ASSIGN_OR_RETURN(auto fields,
119136
env.proto_type_introspector().ListFieldsForStructType(
@@ -131,6 +148,13 @@ absl::Status AddContextDeclarationVariables(
131148

132149
absl::string_view name = field_entry.name;
133150

151+
// Skip fields that are hidden because of a proto type mask.
152+
auto map_iterator = context_type_fields.find(descriptor->full_name());
153+
if (map_iterator != context_type_fields.end() &&
154+
!map_iterator->second.contains(name)) {
155+
continue;
156+
}
157+
134158
if (!env.InsertVariableIfAbsent(MakeVariableDecl(name, type))) {
135159
return absl::AlreadyExistsError(
136160
absl::StrCat("variable '", name,
@@ -317,7 +341,8 @@ absl::Status TypeCheckerBuilderImpl::ApplyConfig(
317341
}
318342

319343
for (const google::protobuf::Descriptor* context_type : config.context_types) {
320-
CEL_RETURN_IF_ERROR(AddContextDeclarationVariables(context_type, env));
344+
CEL_RETURN_IF_ERROR(AddContextDeclarationVariables(
345+
context_type, config.context_type_fields, env));
321346
}
322347

323348
for (VariableDeclRecord& var : config.variables) {
@@ -339,6 +364,8 @@ absl::Status TypeCheckerBuilderImpl::ApplyConfig(
339364
}
340365
}
341366

367+
CEL_RETURN_IF_ERROR(env.CreateProtoTypeMaskRegistry(config.proto_type_masks));
368+
342369
return absl::OkStatus();
343370
}
344371

@@ -462,6 +489,23 @@ absl::Status TypeCheckerBuilderImpl::AddContextDeclaration(
462489
return absl::OkStatus();
463490
}
464491

492+
absl::Status TypeCheckerBuilderImpl::AddContextDeclarationWithProtoTypeMask(
493+
absl::string_view type, std::vector<std::string> field_paths) {
494+
if (field_paths.empty()) {
495+
return absl::InvalidArgumentError("field paths cannot be the empty set");
496+
}
497+
498+
ProtoTypeMask proto_type_mask(std::string(type), field_paths);
499+
target_config_->proto_type_masks.push_back(proto_type_mask);
500+
501+
CEL_RETURN_IF_ERROR(AddContextDeclaration(type));
502+
CEL_ASSIGN_OR_RETURN(
503+
absl::btree_set<absl::string_view> field_names,
504+
proto_type_mask.GetFieldNames(template_env_.descriptor_pool()));
505+
target_config_->context_type_fields.insert({type, std::move(field_names)});
506+
return absl::OkStatus();
507+
}
508+
465509
absl::Status TypeCheckerBuilderImpl::AddFunction(const FunctionDecl& decl) {
466510
CEL_RETURN_IF_ERROR(
467511
ValidateFunctionDecl(decl, options_.enable_type_parameter_name_validation,

checker/internal/type_checker_builder_impl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
#include <vector>
2222

2323
#include "absl/base/nullability.h"
24+
#include "absl/container/btree_set.h"
2425
#include "absl/container/flat_hash_map.h"
2526
#include "absl/container/flat_hash_set.h"
2627
#include "absl/status/status.h"
2728
#include "absl/status/statusor.h"
2829
#include "absl/strings/string_view.h"
2930
#include "absl/types/optional.h"
3031
#include "checker/checker_options.h"
32+
#include "checker/internal/proto_type_mask.h"
3133
#include "checker/internal/type_check_env.h"
3234
#include "checker/type_checker.h"
3335
#include "checker/type_checker_builder.h"
@@ -76,6 +78,8 @@ class TypeCheckerBuilderImpl : public TypeCheckerBuilder {
7678
absl::Status AddVariable(const VariableDecl& decl) override;
7779
absl::Status AddOrReplaceVariable(const VariableDecl& decl) override;
7880
absl::Status AddContextDeclaration(absl::string_view type) override;
81+
absl::Status AddContextDeclarationWithProtoTypeMask(
82+
absl::string_view type, std::vector<std::string> field_paths) override;
7983

8084
absl::Status AddFunction(const FunctionDecl& decl) override;
8185
absl::Status MergeFunction(const FunctionDecl& decl) override;
@@ -130,6 +134,11 @@ class TypeCheckerBuilderImpl : public TypeCheckerBuilder {
130134
std::vector<FunctionDeclRecord> functions;
131135
std::vector<std::shared_ptr<const TypeIntrospector>> type_providers;
132136
std::vector<const google::protobuf::Descriptor*> context_types;
137+
// Maps context type names to fields names to add as variables.
138+
// Only includes context types that are defined with proto type masks.
139+
absl::flat_hash_map<absl::string_view, absl::btree_set<absl::string_view>>
140+
context_type_fields;
141+
std::vector<ProtoTypeMask> proto_type_masks;
133142
};
134143

135144
absl::Status BuildLibraryConfig(const CheckerLibrary& library,

0 commit comments

Comments
 (0)