2323#include < vector>
2424
2525#include " absl/base/attributes.h"
26+ #include " absl/base/optimization.h"
2627#include " absl/functional/function_ref.h"
2728#include " absl/log/absl_check.h"
2829#include " absl/status/status.h"
@@ -78,6 +79,32 @@ class AttributeMatcherNode {
7879 const AttributeMatcherNode& rhs) const {
7980 return lhs < rhs.key ();
8081 }
82+
83+ bool operator ()(absl::string_view lhs,
84+ const AttributeQualifierPattern& rhs) const {
85+ // Fast path for top-level variable matching, should only be called in
86+ // that context.
87+ ABSL_DCHECK (rhs.IsString ());
88+ return lhs < rhs.GetString ();
89+ }
90+
91+ bool operator ()(const AttributeQualifierPattern& lhs,
92+ absl::string_view rhs) const {
93+ // Fast path for top-level variable matching, should only be called in
94+ // that context.
95+ ABSL_DCHECK (lhs.IsString ());
96+ return lhs.GetString () < rhs;
97+ }
98+
99+ bool operator ()(absl::string_view lhs,
100+ const AttributeMatcherNode& rhs) const {
101+ return (*this )(lhs, rhs.key ());
102+ }
103+
104+ bool operator ()(const AttributeMatcherNode& lhs,
105+ absl::string_view rhs) const {
106+ return (*this )(lhs.key (), rhs);
107+ }
81108 };
82109
83110 AttributeMatcherNode (AttributeMatcherNode* parent,
@@ -113,7 +140,21 @@ class AttributeMatcherNode {
113140
114141 [[nodiscard]]
115142 const AttributeMatcherNode* MatchQualifier (
116- const cel::AttributeQualifierView& qualifier) const {
143+ const AttributeQualifierView& qualifier) const {
144+ if (children_ != nullptr ) {
145+ auto it = children_->find (qualifier);
146+ if (it != children_->end ()) {
147+ return &*it;
148+ }
149+ } else if (wildcard_ != nullptr ) {
150+ return wildcard_.get ();
151+ }
152+ return nullptr ;
153+ }
154+
155+ [[nodiscard]]
156+ const AttributeMatcherNode* MatchQualifier (
157+ const AttributeQualifier& qualifier) const {
117158 if (children_ != nullptr ) {
118159 auto it = children_->find (qualifier);
119160 if (it != children_->end ()) {
@@ -159,8 +200,7 @@ AttributeMatch MakeAttributeMatch(
159200 const common_internal::AttributeMatcherNode* node);
160201
161202[[nodiscard]]
162- const AttributeMatcherNode* GetAttributeMatcherNode (
163- const AttributeMatch& match);
203+ const AttributeMatcherNode* GetAttributeMatcherNode (AttributeMatch match);
164204
165205} // namespace common_internal
166206
@@ -199,17 +239,26 @@ class [[nodiscard]] AttributeMatch {
199239 // match should be handled.
200240 AttributeMatch MatchQualifier (const AttributeQualifierView& qualifier) const {
201241 ABSL_DCHECK (!IsFull ());
242+ ABSL_DCHECK (qualifier);
202243 if (IsNone ()) {
203244 return AttributeMatch ();
204245 }
205246 return AttributeMatch (node_->MatchQualifier (qualifier));
206247 }
207248
208249 private:
250+ friend class AttributeMatcher ;
209251 friend AttributeMatch common_internal::MakeAttributeMatch (
210252 const common_internal::AttributeMatcherNode* node);
211253 friend const common_internal::AttributeMatcherNode*
212- common_internal::GetAttributeMatcherNode (const AttributeMatch& match);
254+ common_internal::GetAttributeMatcherNode (AttributeMatch match);
255+
256+ AttributeMatch NotNoneMatchQualifier (
257+ const AttributeQualifierView& qualifier) const {
258+ ABSL_DCHECK (!IsNone ());
259+ ABSL_DCHECK (qualifier);
260+ return AttributeMatch (node_->MatchQualifier (qualifier));
261+ }
213262
214263 explicit AttributeMatch (const common_internal::AttributeMatcherNode* node)
215264 : node_ (node) {}
@@ -226,7 +275,7 @@ inline AttributeMatch MakeAttributeMatch(
226275
227276[[nodiscard]]
228277inline const AttributeMatcherNode* GetAttributeMatcherNode (
229- const AttributeMatch& match) {
278+ AttributeMatch match) {
230279 return match.node_ ;
231280}
232281
@@ -273,13 +322,52 @@ class AttributeMatcher {
273322
274323 AttributeMatch MatchVariable (absl::string_view variable) const
275324 ABSL_ATTRIBUTE_LIFETIME_BOUND {
276- auto it = children_.find (AttributeQualifierView::OfString (variable));
277- if (it != children_.end ()) {
278- return common_internal::MakeAttributeMatch (&*it);
325+ if (!variable.empty ()) {
326+ auto it = children_.find (variable);
327+ if (it != children_.end ()) {
328+ return common_internal::MakeAttributeMatch (&*it);
329+ }
279330 }
280331 return AttributeMatch ();
281332 }
282333
334+ AttributeMatch MatchAttribute (
335+ absl::string_view variable,
336+ absl::Span<const AttributeQualifierView> qualifiers) const {
337+ AttributeMatch match = MatchVariable (variable);
338+ for (const auto & qualifier : qualifiers) {
339+ if (ABSL_PREDICT_FALSE (!qualifier)) {
340+ return AttributeMatch ();
341+ }
342+ if (match.IsNone ()) {
343+ break ;
344+ }
345+ match = match.NotNoneMatchQualifier (qualifier);
346+ }
347+ return match;
348+ }
349+
350+ AttributeMatch MatchAttribute (
351+ absl::string_view variable,
352+ absl::Span<const AttributeQualifier> qualifiers) const {
353+ AttributeMatch match = MatchVariable (variable);
354+ for (const auto & qualifier : qualifiers) {
355+ if (ABSL_PREDICT_FALSE (!qualifier)) {
356+ return AttributeMatch ();
357+ }
358+ if (match.IsNone ()) {
359+ break ;
360+ }
361+ match = match.NotNoneMatchQualifier (qualifier);
362+ }
363+ return match;
364+ }
365+
366+ AttributeMatch MatchAttribute (const Attribute& attribute) const {
367+ return MatchAttribute (attribute.variable_name (),
368+ attribute.qualifier_path ());
369+ }
370+
283371 // Returns an array of attribute patterns corresponding to the
284372 // previously added attribute patterns. The order of the attribute
285373 // patterns in the array is not guaranteed.
0 commit comments