aboutsummaryrefslogtreecommitdiffstats
path: root/indexinglanguage/src/main/java/com/yahoo/vespa/indexinglanguage/expressions/ExecutionContext.java
blob: b0478f8001cb18035458951ea7529dda3b8dbddc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.indexinglanguage.expressions;

import com.yahoo.document.DataType;
import com.yahoo.document.FieldPath;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.language.Language;
import com.yahoo.language.Linguistics;
import com.yahoo.language.detect.Detection;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Simon Thoresen Hult
 */
public class ExecutionContext implements FieldTypeAdapter, FieldValueAdapter, Cloneable {

    private final Map<String, FieldValue> variables = new HashMap<>();
    private final FieldValueAdapter adapter;
    private FieldValue value;
    private Language language;

    public ExecutionContext() {
        this(null);
    }

    public ExecutionContext(FieldValueAdapter adapter) {
        this.adapter = adapter;
        this.language = Language.UNKNOWN;
    }

    public ExecutionContext execute(Expression expression) {
        if (expression != null)
            expression.execute(this);
        return this;
    }

    /**
     * Returns whether this is for a complete execution of all statements of a script,
     * or a partial execution of only the statements accessing the available data.
     */
    public boolean isComplete() { return adapter == null ? false : adapter.isComplete(); }

    @Override
    public DataType getInputType(Expression exp, String fieldName) {
        return adapter.getInputType(exp, fieldName);
    }

    @Override
    public FieldValue getInputValue(String fieldName) {
        if (adapter == null) {
            throw new IllegalStateException("Can not get field '" + fieldName + "' because adapter is null");
        }
        return adapter.getInputValue(fieldName);
    }

    @Override
    public FieldValue getInputValue(FieldPath fieldPath) {
        if (adapter == null) {
            throw new IllegalStateException("Can not get field '" + fieldPath + "' because adapter is null");
        }
        return adapter.getInputValue(fieldPath);
    }

    @Override
    public void tryOutputType(Expression exp, String fieldName, DataType valueType) {
        adapter.tryOutputType(exp, fieldName, valueType);
    }

    @Override
    public ExecutionContext setOutputValue(Expression exp, String fieldName, FieldValue fieldValue) {
        if (adapter == null)
            throw new IllegalStateException("Can not set field '" + fieldName + "' because adapter is null");
        adapter.setOutputValue(exp, fieldName, fieldValue);
        return this;
    }

    public FieldValueAdapter getAdapter() {
        return adapter;
    }

    public FieldValue getVariable(String name) {
        return variables.get(name);
    }

    public ExecutionContext setVariable(String name, FieldValue value) {
        variables.put(name, value);
        return this;
    }

    public Language getLanguage() {
        return language;
    }

    public ExecutionContext setLanguage(Language language) {
        language.getClass();
        this.language = language;
        return this;
    }

    public Language resolveLanguage(Linguistics linguistics) {
        if (language != null && language != Language.UNKNOWN) {
            return language;
        }
        if (linguistics == null) {
            return Language.ENGLISH;
        }
        Detection detection = linguistics.getDetector().detect(String.valueOf(value), null);
        if (detection == null) {
            return Language.ENGLISH;
        }
        Language detected = detection.getLanguage();
        if (detected == Language.UNKNOWN) {
            return Language.ENGLISH;
        }
        return detected;
    }

    public FieldValue getValue() {
        return value;
    }

    public ExecutionContext setValue(FieldValue value) {
        this.value = value;
        return this;
    }

    public ExecutionContext clear() {
        variables.clear();
        value = null;
        return this;
    }

    void fillVariableTypes(VerificationContext vctx) {
        for (var entry : variables.entrySet()) {
            vctx.setVariable(entry.getKey(), entry.getValue().getDataType());
        }
    }

}