use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.
the class ContainerTest method ToQualifiedName.
@Test
void ToQualifiedName() {
Expr ident = Expr.newBuilder().setId(0).setIdentExpr(Ident.newBuilder().setName("var")).build();
String idName = toQualifiedName(ident);
assertThat(idName).isEqualTo("var");
Expr sel = Expr.newBuilder().setId(0).setSelectExpr(Select.newBuilder().setOperand(ident).setField("qualifier")).build();
String qualName = toQualifiedName(sel);
assertThat(qualName).isEqualTo("var.qualifier");
sel = Expr.newBuilder().setId(0).setSelectExpr(Select.newBuilder().setOperand(ident).setField("qualifier").setTestOnly(true)).build();
assertThat(toQualifiedName(sel)).isNull();
Expr unary = Expr.newBuilder().setId(0).setCallExpr(Call.newBuilder().setFunction("!_").addArgs(ident)).build();
sel = Expr.newBuilder().setId(0).setSelectExpr(Select.newBuilder().setOperand(unary).setField("qualifier")).build();
assertThat(toQualifiedName(sel)).isNull();
}
use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.
the class Checker method checkSelect.
void checkSelect(Expr.Builder e) {
Select.Builder sel = e.getSelectExprBuilder();
// Before traversing down the tree, try to interpret as qualified name.
String qname = Container.toQualifiedName(e.build());
if (qname != null) {
Decl ident = env.lookupIdent(qname);
if (ident != null) {
if (sel.getTestOnly()) {
errors.expressionDoesNotSelectField(location(e));
setType(e, Decls.Bool);
return;
}
// Rewrite the node to be a variable reference to the resolved fully-qualified
// variable name.
setType(e, ident.getIdent().getType());
setReference(e, newIdentReference(ident.getName(), ident.getIdent().getValue()));
String identName = ident.getName();
e.getIdentExprBuilder().setName(identName);
return;
}
}
// Interpret as field selection, first traversing down the operand.
check(sel.getOperandBuilder());
Type targetType = getType(sel.getOperandBuilder());
// Assume error type by default as most types do not support field selection.
Type resultType = Decls.Error;
switch(kindOf(targetType)) {
case kindMap:
// Maps yield their value type as the selection result type.
MapType mapType = targetType.getMapType();
resultType = mapType.getValueType();
break;
case kindObject:
// Objects yield their field type declaration as the selection result type, but only if
// the field is defined.
FieldType fieldType = lookupFieldType(location(e), targetType.getMessageType(), sel.getField());
if (fieldType != null) {
resultType = fieldType.type;
}
break;
case kindTypeParam:
// Set the operand type to DYN to prevent assignment to a potentionally incorrect type
// at a later point in type-checking. The isAssignable call will update the type
// substitutions for the type param under the covers.
isAssignable(Decls.Dyn, targetType);
// Also, set the result type to DYN.
resultType = Decls.Dyn;
break;
default:
// in order to allow forward progress on the check.
if (isDynOrError(targetType)) {
resultType = Decls.Dyn;
} else {
errors.typeDoesNotSupportFieldSelection(location(e), targetType);
}
break;
}
if (sel.getTestOnly()) {
resultType = Decls.Bool;
}
setType(e, resultType);
}
use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.
the class CheckerEnv method lookupIdent.
/**
* LookupIdent returns a Decl proto for typeName as an identifier in the Env. Returns nil if no
* such identifier is found in the Env.
*/
public Decl lookupIdent(String name) {
for (String candidate : container.resolveCandidateNames(name)) {
Decl ident = declarations.findIdent(candidate);
if (ident != null) {
return ident;
}
// Next try to import the name as a reference to a message type. If found,
// the declaration is added to the outest (global) scope of the
// environment, so next time we can access it faster.
Type t = provider.findType(candidate);
if (t != null) {
Decl decl = Decls.newVar(candidate, t);
declarations.addIdent(decl);
return decl;
}
// Next try to import this as an enum value by splitting the name in a type prefix and
// the enum inside.
Val enumValue = provider.enumValue(candidate);
if (enumValue.type() != ErrType) {
Decl decl = Decls.newIdent(candidate, Decls.Int, Constant.newBuilder().setInt64Value(enumValue.intValue()).build());
declarations.addIdent(decl);
return decl;
}
}
return null;
}
use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.
the class Checker method checkCreateMessage.
void checkCreateMessage(Expr.Builder e) {
CreateStruct.Builder msgVal = e.getStructExprBuilder();
// Determine the type of the message.
Type messageType = Decls.Error;
Decl decl = env.lookupIdent(msgVal.getMessageName());
if (decl == null) {
errors.undeclaredReference(location(e), env.container.name(), msgVal.getMessageName());
return;
}
// Ensure the type name is fully qualified in the AST.
msgVal.setMessageName(decl.getName());
setReference(e, newIdentReference(decl.getName(), null));
IdentDecl ident = decl.getIdent();
Types.Kind identKind = kindOf(ident.getType());
if (identKind != Kind.kindError) {
if (identKind != Kind.kindType) {
errors.notAType(location(e), ident.getType());
} else {
messageType = ident.getType().getType();
if (kindOf(messageType) != Kind.kindObject) {
errors.notAMessageType(location(e), messageType);
messageType = Decls.Error;
}
}
}
if (isObjectWellKnownType(messageType)) {
setType(e, getObjectWellKnownType(messageType));
} else {
setType(e, messageType);
}
// Check the field initializers.
for (Entry.Builder ent : msgVal.getEntriesBuilderList()) {
String field = ent.getFieldKey();
Expr.Builder value = ent.getValueBuilder();
check(value);
Type fieldType = Decls.Error;
FieldType t = lookupFieldType(locationByID(ent.getId()), messageType.getMessageType(), field);
if (t != null) {
fieldType = t.type;
}
if (!isAssignable(fieldType, getType(value))) {
errors.fieldTypeMismatch(locationByID(ent.getId()), field, fieldType, getType(value));
}
}
}
use of com.google.api.expr.v1alpha1.Expr.Ident in project cel-java by projectnessie.
the class Checker method checkIdent.
void checkIdent(Expr.Builder e) {
Ident.Builder identExpr = e.getIdentExprBuilder();
// Check to see if the identifier is declared.
Decl ident = env.lookupIdent(identExpr.getName());
if (ident != null) {
setType(e, ident.getIdent().getType());
setReference(e, newIdentReference(ident.getName(), ident.getIdent().getValue()));
// Overwrite the identifier with its fully qualified name.
identExpr.setName(ident.getName());
return;
}
setType(e, Decls.Error);
errors.undeclaredReference(location(e), env.container.name(), identExpr.getName());
}
Aggregations