Skip to content

Commit bb67412

Browse files
jckingcopybara-github
authored andcommitted
Add TypeKind and ValueKind
PiperOrigin-RevId: 534130090
1 parent f86575b commit bb67412

4 files changed

Lines changed: 216 additions & 1 deletion

File tree

base/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ cc_library(
6565
srcs = ["kind.cc"],
6666
hdrs = ["kind.h"],
6767
deps = [
68+
"@com_google_absl//absl/base",
6869
"@com_google_absl//absl/base:core_headers",
70+
"@com_google_absl//absl/log:absl_check",
6971
"@com_google_absl//absl/strings",
7072
],
7173
)

base/kind.cc

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

1717
namespace cel {
1818

19+
bool KindIsTypeKind(Kind kind) {
20+
// Currently all Kind are valid TypeKind.
21+
return true;
22+
}
23+
24+
bool KindIsValueKind(Kind kind) {
25+
return kind != Kind::kWrapper && kind != Kind::kDyn && kind != Kind::kAny;
26+
}
27+
1928
absl::string_view KindToString(Kind kind) {
2029
switch (kind) {
2130
case Kind::kNullType:

base/kind.h

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@
1515
#ifndef THIRD_PARTY_CEL_CPP_BASE_KIND_H_
1616
#define THIRD_PARTY_CEL_CPP_BASE_KIND_H_
1717

18+
#include <type_traits>
19+
1820
#include "absl/base/attributes.h"
21+
#include "absl/base/casts.h"
22+
#include "absl/log/absl_check.h"
1923
#include "absl/strings/string_view.h"
2024

2125
namespace cel {
2226

2327
enum class Kind /* : uint8_t */ {
2428
// Must match legacy CelValue::Type.
25-
kNullType = 0,
29+
kNull = 0,
2630
kBool,
2731
kInt,
2832
kUint,
@@ -46,6 +50,7 @@ enum class Kind /* : uint8_t */ {
4650
kOpaque,
4751

4852
// Legacy aliases, deprecated do not use.
53+
kNullType = kNull,
4954
kInt64 = kInt,
5055
kUint64 = kUint,
5156
kMessage = kStruct,
@@ -59,6 +64,155 @@ enum class Kind /* : uint8_t */ {
5964

6065
ABSL_ATTRIBUTE_PURE_FUNCTION absl::string_view KindToString(Kind kind);
6166

67+
// `TypeKind` is a subset of `Kind`, representing all valid `Kind` for `Type`.
68+
// All `TypeKind` are valid `Kind`, but it is not guaranteed that all `Kind` are
69+
// valid `TypeKind`.
70+
enum class TypeKind : std::underlying_type_t<Kind> {
71+
kNull = static_cast<int>(Kind::kNull),
72+
kBool = static_cast<int>(Kind::kBool),
73+
kInt = static_cast<int>(Kind::kInt),
74+
kUint = static_cast<int>(Kind::kUint),
75+
kDouble = static_cast<int>(Kind::kDouble),
76+
kString = static_cast<int>(Kind::kString),
77+
kBytes = static_cast<int>(Kind::kBytes),
78+
kStruct = static_cast<int>(Kind::kStruct),
79+
kDuration = static_cast<int>(Kind::kDuration),
80+
kTimestamp = static_cast<int>(Kind::kTimestamp),
81+
kList = static_cast<int>(Kind::kList),
82+
kMap = static_cast<int>(Kind::kMap),
83+
kUnknown = static_cast<int>(Kind::kUnknown),
84+
kType = static_cast<int>(Kind::kType),
85+
kError = static_cast<int>(Kind::kError),
86+
kAny = static_cast<int>(Kind::kAny),
87+
kEnum = static_cast<int>(Kind::kEnum),
88+
kDyn = static_cast<int>(Kind::kDyn),
89+
kWrapper = static_cast<int>(Kind::kWrapper),
90+
kOpaque = static_cast<int>(Kind::kOpaque),
91+
92+
// Legacy aliases, deprecated do not use.
93+
kNullType = kNull,
94+
kInt64 = kInt,
95+
kUint64 = kUint,
96+
kMessage = kStruct,
97+
kUnknownSet = kUnknown,
98+
kCelType = kType,
99+
100+
// INTERNAL: Do not exceed 63. Implementation details rely on the fact that
101+
// we can store `Kind` using 6 bits.
102+
kNotForUseWithExhaustiveSwitchStatements =
103+
static_cast<int>(Kind::kNotForUseWithExhaustiveSwitchStatements),
104+
};
105+
106+
inline Kind TypeKindToKind(TypeKind kind) { return absl::bit_cast<Kind>(kind); }
107+
108+
ABSL_ATTRIBUTE_PURE_FUNCTION bool KindIsTypeKind(Kind kind);
109+
110+
inline bool operator==(Kind lhs, TypeKind rhs) {
111+
return lhs == TypeKindToKind(rhs);
112+
}
113+
114+
inline bool operator==(TypeKind lhs, Kind rhs) {
115+
return TypeKindToKind(lhs) == rhs;
116+
}
117+
118+
inline bool operator!=(Kind lhs, TypeKind rhs) { return !operator==(lhs, rhs); }
119+
120+
inline bool operator!=(TypeKind lhs, Kind rhs) { return !operator==(lhs, rhs); }
121+
122+
// `ValueKind` is a subset of `Kind`, representing all valid `Kind` for `Value`.
123+
// All `ValueKind` are valid `Kind`, but it is not guaranteed that all `Kind`
124+
// are valid `ValueKind`.
125+
enum class ValueKind : std::underlying_type_t<Kind> {
126+
kNull = static_cast<int>(Kind::kNull),
127+
kBool = static_cast<int>(Kind::kBool),
128+
kInt = static_cast<int>(Kind::kInt),
129+
kUint = static_cast<int>(Kind::kUint),
130+
kDouble = static_cast<int>(Kind::kDouble),
131+
kString = static_cast<int>(Kind::kString),
132+
kBytes = static_cast<int>(Kind::kBytes),
133+
kStruct = static_cast<int>(Kind::kStruct),
134+
kDuration = static_cast<int>(Kind::kDuration),
135+
kTimestamp = static_cast<int>(Kind::kTimestamp),
136+
kList = static_cast<int>(Kind::kList),
137+
kMap = static_cast<int>(Kind::kMap),
138+
kUnknown = static_cast<int>(Kind::kUnknown),
139+
kType = static_cast<int>(Kind::kType),
140+
kError = static_cast<int>(Kind::kError),
141+
kEnum = static_cast<int>(Kind::kEnum),
142+
kOpaque = static_cast<int>(Kind::kOpaque),
143+
144+
// Legacy aliases, deprecated do not use.
145+
kNullType = kNull,
146+
kInt64 = kInt,
147+
kUint64 = kUint,
148+
kMessage = kStruct,
149+
kUnknownSet = kUnknown,
150+
kCelType = kType,
151+
152+
// INTERNAL: Do not exceed 63. Implementation details rely on the fact that
153+
// we can store `Kind` using 6 bits.
154+
kNotForUseWithExhaustiveSwitchStatements =
155+
static_cast<int>(Kind::kNotForUseWithExhaustiveSwitchStatements),
156+
};
157+
158+
inline Kind ValueKindToKind(ValueKind kind) {
159+
return absl::bit_cast<Kind>(kind);
160+
}
161+
162+
ABSL_ATTRIBUTE_PURE_FUNCTION bool KindIsValueKind(Kind kind);
163+
164+
inline bool operator==(Kind lhs, ValueKind rhs) {
165+
return lhs == ValueKindToKind(rhs);
166+
}
167+
168+
inline bool operator==(ValueKind lhs, Kind rhs) {
169+
return ValueKindToKind(lhs) == rhs;
170+
}
171+
172+
inline bool operator==(TypeKind lhs, ValueKind rhs) {
173+
return TypeKindToKind(lhs) == ValueKindToKind(rhs);
174+
}
175+
176+
inline bool operator==(ValueKind lhs, TypeKind rhs) {
177+
return ValueKindToKind(lhs) == TypeKindToKind(rhs);
178+
}
179+
180+
inline bool operator!=(Kind lhs, ValueKind rhs) {
181+
return !operator==(lhs, rhs);
182+
}
183+
184+
inline bool operator!=(ValueKind lhs, Kind rhs) {
185+
return !operator==(lhs, rhs);
186+
}
187+
188+
inline bool operator!=(TypeKind lhs, ValueKind rhs) {
189+
return !operator==(lhs, rhs);
190+
}
191+
192+
inline bool operator!=(ValueKind lhs, TypeKind rhs) {
193+
return !operator==(lhs, rhs);
194+
}
195+
196+
inline absl::string_view TypeKindToString(TypeKind kind) {
197+
// All TypeKind are valid Kind.
198+
return KindToString(TypeKindToKind(kind));
199+
}
200+
201+
inline absl::string_view ValueKindToString(ValueKind kind) {
202+
// All ValueKind are valid Kind.
203+
return KindToString(ValueKindToKind(kind));
204+
}
205+
206+
inline TypeKind KindToTypeKind(Kind kind) {
207+
ABSL_DCHECK(KindIsTypeKind(kind)) << KindToString(kind);
208+
return absl::bit_cast<TypeKind>(kind);
209+
}
210+
211+
inline ValueKind KindToValueKind(Kind kind) {
212+
ABSL_DCHECK(KindIsValueKind(kind)) << KindToString(kind);
213+
return absl::bit_cast<ValueKind>(kind);
214+
}
215+
62216
} // namespace cel
63217

64218
#endif // THIRD_PARTY_CEL_CPP_BASE_KIND_H_

base/kind_test.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,55 @@ TEST(Kind, ToString) {
4646
"*error*");
4747
}
4848

49+
TEST(Kind, TypeKindRoundtrip) {
50+
EXPECT_EQ(TypeKindToKind(KindToTypeKind(Kind::kBool)), Kind::kBool);
51+
}
52+
53+
TEST(Kind, ValueKindRoundtrip) {
54+
EXPECT_EQ(ValueKindToKind(KindToValueKind(Kind::kBool)), Kind::kBool);
55+
}
56+
57+
TEST(Kind, IsTypeKind) {
58+
EXPECT_TRUE(KindIsTypeKind(Kind::kBool));
59+
EXPECT_TRUE(KindIsTypeKind(Kind::kAny));
60+
EXPECT_TRUE(KindIsTypeKind(Kind::kDyn));
61+
EXPECT_TRUE(KindIsTypeKind(Kind::kWrapper));
62+
}
63+
64+
TEST(Kind, IsValueKind) {
65+
EXPECT_TRUE(KindIsValueKind(Kind::kBool));
66+
EXPECT_FALSE(KindIsValueKind(Kind::kAny));
67+
EXPECT_FALSE(KindIsValueKind(Kind::kDyn));
68+
EXPECT_FALSE(KindIsValueKind(Kind::kWrapper));
69+
}
70+
71+
TEST(Kind, Equality) {
72+
EXPECT_EQ(Kind::kBool, TypeKind::kBool);
73+
EXPECT_EQ(TypeKind::kBool, Kind::kBool);
74+
75+
EXPECT_EQ(Kind::kBool, ValueKind::kBool);
76+
EXPECT_EQ(ValueKind::kBool, Kind::kBool);
77+
78+
EXPECT_EQ(TypeKind::kBool, ValueKind::kBool);
79+
EXPECT_EQ(ValueKind::kBool, TypeKind::kBool);
80+
81+
EXPECT_NE(Kind::kBool, TypeKind::kInt);
82+
EXPECT_NE(TypeKind::kInt, Kind::kBool);
83+
84+
EXPECT_NE(Kind::kBool, ValueKind::kInt);
85+
EXPECT_NE(ValueKind::kInt, Kind::kBool);
86+
87+
EXPECT_NE(TypeKind::kBool, ValueKind::kInt);
88+
EXPECT_NE(ValueKind::kInt, TypeKind::kBool);
89+
}
90+
91+
TEST(TypeKind, ToString) {
92+
EXPECT_EQ(TypeKindToString(TypeKind::kBool), KindToString(Kind::kBool));
93+
}
94+
95+
TEST(ValueKind, ToString) {
96+
EXPECT_EQ(ValueKindToString(ValueKind::kBool), KindToString(Kind::kBool));
97+
}
98+
4999
} // namespace
50100
} // namespace cel

0 commit comments

Comments
 (0)