use of com.google.template.soy.data.SoyProtoValue in project closure-templates by google.
the class EvalVisitor method visitNullSafeFieldAccessNode.
private SoyValue visitNullSafeFieldAccessNode(FieldAccessNode fieldAccess) {
SoyValue base = visitNullSafeNodeRecurse(fieldAccess.getBaseExprChild());
// attempting field access on non-SoyRecord
if (!(base instanceof SoyRecord) && !(base instanceof SoyProtoValue)) {
if (base == NullSafetySentinel.INSTANCE) {
// Bail out if base expression failed a null-safety check.
return NullSafetySentinel.INSTANCE;
}
if (fieldAccess.isNullSafe()) {
if (isNullOrUndefinedBase(base)) {
// Return the sentinel value that indicates that a null-safety check failed.
return NullSafetySentinel.INSTANCE;
} else {
throw RenderException.create(String.format("While evaluating \"%s\", encountered non-record just before accessing \"%s\".", fieldAccess.toSourceString(), fieldAccess.getSourceStringSuffix()));
}
}
// TODO: If feasible, find and fix existing instances, then throw RenderException here.
return UndefinedData.INSTANCE;
}
// the base type is possibly nullable, so remove null before testing for being a proto
if (SoyTypes.tryRemoveNull(fieldAccess.getBaseExprChild().getType()).getKind() == Kind.PROTO) {
return ((SoyProtoValue) base).getProtoField(fieldAccess.getFieldName());
}
maybeMarkBadProtoAccess(fieldAccess, base);
// base is a valid SoyRecord: get value
SoyValue value = ((SoyRecord) base).getField(fieldAccess.getFieldName());
// TODO(user): Consider cleaning up the null / NullData inconsistencies.
if (value != null && !TofuTypeChecks.isInstance(fieldAccess.getType(), value)) {
throw RenderException.create(String.format("Expected value of type '%s', but actual type was '%s'.", fieldAccess.getType(), value.getClass().getSimpleName()));
}
return (value != null) ? value : UndefinedData.INSTANCE;
}
Aggregations