Skip to content

Commit 5e4c222

Browse files
l46kokcopybara-github
authored andcommitted
Optimize attribute qualification process and empty message creation
PiperOrigin-RevId: 892560916
1 parent cbe0104 commit 5e4c222

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

common/src/main/java/dev/cel/common/internal/DefaultMessageFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public Optional<Message.Builder> newBuilder(String messageName) {
5252
DefaultInstanceMessageFactory.getInstance().getPrototype(descriptor.get());
5353

5454
if (message.isPresent()) {
55-
return message.map(Message::toBuilder);
55+
return message.map(Message::newBuilderForType);
5656
}
5757

5858
return Optional.of(DynamicMessage.newBuilder(descriptor.get()));

runtime/src/main/java/dev/cel/runtime/CelAttribute.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.google.auto.value.AutoOneOf;
1818
import com.google.auto.value.AutoValue;
1919
import com.google.common.base.Preconditions;
20-
import com.google.common.base.Splitter;
2120
import com.google.common.collect.ImmutableList;
2221
import com.google.common.primitives.UnsignedLong;
2322
import com.google.errorprone.annotations.Immutable;
@@ -184,9 +183,13 @@ public static CelAttribute create(String rootIdentifier) {
184183
*/
185184
public static CelAttribute fromQualifiedIdentifier(String qualifiedIdentifier) {
186185
ImmutableList.Builder<Qualifier> qualifiers = ImmutableList.builder();
187-
Splitter.on(".")
188-
.split(qualifiedIdentifier)
189-
.forEach((element) -> qualifiers.add(Qualifier.ofString(element)));
186+
int start = 0;
187+
int next;
188+
while ((next = qualifiedIdentifier.indexOf('.', start)) != -1) {
189+
qualifiers.add(Qualifier.ofString(qualifiedIdentifier.substring(start, next)));
190+
start = next + 1;
191+
}
192+
qualifiers.add(Qualifier.ofString(qualifiedIdentifier.substring(start)));
190193
return new AutoValue_CelAttribute(qualifiers.build());
191194
}
192195

@@ -206,7 +209,7 @@ public CelAttribute qualify(Qualifier qualifier) {
206209
return EMPTY;
207210
}
208211
return new AutoValue_CelAttribute(
209-
ImmutableList.<Qualifier>builder().addAll(qualifiers()).add(qualifier).build());
212+
ImmutableList.<Qualifier>builderWithExpectedSize(qualifiers().size() + 1).addAll(qualifiers()).add(qualifier).build());
210213
}
211214

212215
@Override

runtime/src/main/java/dev/cel/runtime/CelAttributePattern.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import com.google.auto.value.AutoValue;
2020
import com.google.common.base.Preconditions;
21-
import com.google.common.base.Splitter;
2221
import com.google.common.collect.ImmutableList;
2322
import com.google.errorprone.annotations.Immutable;
2423

@@ -62,9 +61,13 @@ public static CelAttributePattern create(String rootIdentifier) {
6261
*/
6362
public static CelAttributePattern fromQualifiedIdentifier(String qualifiedIdentifier) {
6463
ImmutableList.Builder<CelAttribute.Qualifier> qualifiers = ImmutableList.builder();
65-
Splitter.on(".")
66-
.split(qualifiedIdentifier)
67-
.forEach((String element) -> qualifiers.add(CelAttribute.Qualifier.ofString(element)));
64+
int start = 0;
65+
int next;
66+
while ((next = qualifiedIdentifier.indexOf('.', start)) != -1) {
67+
qualifiers.add(CelAttribute.Qualifier.ofString(qualifiedIdentifier.substring(start, next)));
68+
start = next + 1;
69+
}
70+
qualifiers.add(CelAttribute.Qualifier.ofString(qualifiedIdentifier.substring(start)));
6871
return new AutoValue_CelAttributePattern(qualifiers.build());
6972
}
7073

@@ -74,7 +77,7 @@ public static CelAttributePattern fromQualifiedIdentifier(String qualifiedIdenti
7477
/** Create a new attribute pattern that specifies a subfield of this pattern. */
7578
public CelAttributePattern qualify(CelAttribute.Qualifier qualifier) {
7679
return new AutoValue_CelAttributePattern(
77-
ImmutableList.<CelAttribute.Qualifier>builder()
80+
ImmutableList.<CelAttribute.Qualifier>builderWithExpectedSize(qualifiers().size() + 1)
7881
.addAll(qualifiers())
7982
.add(qualifier)
8083
.build());

runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ private Optional<PlannedInterpretable> maybeInterceptOptionalCalls(
343343

344344
private PlannedInterpretable planCreateStruct(CelExpr celExpr, PlannerContext ctx) {
345345
CelStruct struct = celExpr.struct();
346-
CelType structType = resolveStructType(struct);
346+
CelType structType = resolveStructType(celExpr, ctx);
347347

348348
ImmutableList<Entry> entries = struct.entries();
349349
String[] keys = new String[entries.size()];
@@ -489,7 +489,17 @@ private ResolvedFunction resolveFunction(
489489
return ResolvedFunction.newBuilder().setFunctionName(functionName).setTarget(target).build();
490490
}
491491

492-
private CelType resolveStructType(CelStruct struct) {
492+
private CelType resolveStructType(CelExpr expr, PlannerContext ctx) {
493+
CelType checkedType = ctx.typeMap().get(expr.id());
494+
if (checkedType != null) {
495+
CelKind kind = checkedType.kind();
496+
// Type-checked ASTs do not need a type-provider lookup as long as it's of expected kind.
497+
if (isValidStructKind(kind)) {
498+
return checkedType;
499+
}
500+
}
501+
502+
CelStruct struct = expr.struct();
493503
String messageName = struct.messageName();
494504
for (String typeName : container.resolveCandidateNames(messageName)) {
495505
CelType structType = typeProvider.findType(typeName).orElse(null);
@@ -499,9 +509,7 @@ private CelType resolveStructType(CelStruct struct) {
499509

500510
CelKind kind = structType.kind();
501511

502-
if (!kind.equals(CelKind.STRUCT)
503-
&& !kind.equals(CelKind.TIMESTAMP)
504-
&& !kind.equals(CelKind.DURATION)) {
512+
if (!isValidStructKind(kind)) {
505513
throw new IllegalArgumentException(
506514
String.format(
507515
"Expected struct type for %s, got %s", structType.name(), structType.kind()));
@@ -513,6 +521,12 @@ private CelType resolveStructType(CelStruct struct) {
513521
throw new IllegalArgumentException("Undefined type name: " + messageName);
514522
}
515523

524+
private static boolean isValidStructKind(CelKind kind) {
525+
return kind.equals(CelKind.STRUCT)
526+
|| kind.equals(CelKind.TIMESTAMP)
527+
|| kind.equals(CelKind.DURATION);
528+
}
529+
516530
/** Converts a given expression into a qualified name, if possible. */
517531
private Optional<String> toQualifiedName(CelExpr operand) {
518532
switch (operand.getKind()) {

0 commit comments

Comments
 (0)