aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/schema/parser/ParsedField.java
blob: a4df2ac6dc23c71c55457cc5a683bdcdc69e6c69 (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.schema.parser;

import com.yahoo.schema.document.Stemming;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * This class holds the extracted information after parsing a "field"
 * block, using simple data structures as far as possible.  Do not put
 * advanced logic here!
 * @author arnej27959
 **/
class ParsedField extends ParsedBlock {

    private ParsedType type;
    private boolean hasBolding = false;
    private boolean isFilter = false;
    private int overrideId = 0;
    private boolean isLiteral = false;
    private boolean isNormal = false;
    private Integer weight;
    private String normalizing = null;
    private final ParsedMatchSettings matchInfo = new ParsedMatchSettings();
    private Stemming stemming = null;
    private ParsedIndexingOp indexingOp = null;
    private ParsedSorting sortSettings = null;
    private final Map<String, ParsedAttribute> attributes = new LinkedHashMap<>();
    private final Map<String, ParsedIndex> fieldIndexes = new LinkedHashMap<>();
    private final Map<String, String> aliases = new LinkedHashMap<>();
    private final Map<String, String> rankTypes = new LinkedHashMap<>();
    private final Map<String, ParsedField> structFields = new LinkedHashMap<>();
    private final Map<String, ParsedSummaryField> summaryFields = new LinkedHashMap<>();
    private final List<DictionaryOption> dictionaryOptions = new ArrayList<>();
    private final List<String> queryCommands = new ArrayList<>();

    ParsedField(String name, ParsedType type) {
        super(name, "field");
        this.type = type;
    }

    ParsedType getType() { return this.type; }
    boolean hasBolding() { return this.hasBolding; }
    boolean hasFilter() { return this.isFilter; }
    boolean hasLiteral() { return this.isLiteral; }
    boolean hasNormal() { return this.isNormal; }
    boolean hasIdOverride() { return overrideId != 0; }
    int idOverride() { return overrideId; }
    List<DictionaryOption> getDictionaryOptions() { return List.copyOf(dictionaryOptions); }
    List<ParsedAttribute> getAttributes() { return List.copyOf(attributes.values()); }
    List<ParsedIndex> getIndexes() { return List.copyOf(fieldIndexes.values()); }
    List<ParsedSummaryField> getSummaryFields() { return List.copyOf(summaryFields.values()); }
    List<ParsedField> getStructFields() { return List.copyOf(structFields.values()); }
    List<String> getAliases() { return List.copyOf(aliases.keySet()); }
    List<String> getQueryCommands() { return List.copyOf(queryCommands); }
    String lookupAliasedFrom(String alias) { return aliases.get(alias); }
    ParsedMatchSettings matchSettings() { return this.matchInfo; }
    Optional<Integer> getWeight() { return Optional.ofNullable(weight); }
    Optional<Stemming> getStemming() { return Optional.ofNullable(stemming); }
    Optional<String> getNormalizing() { return Optional.ofNullable(normalizing); }
    Optional<ParsedIndexingOp> getIndexing() { return Optional.ofNullable(indexingOp); }
    Optional<ParsedSorting> getSorting() { return Optional.ofNullable(sortSettings); }
    Map<String, String> getRankTypes() { return Collections.unmodifiableMap(rankTypes); }

    /** get an existing summary field for modification, or create it */
    ParsedSummaryField summaryFieldFor(String name) {
        if (summaryFields.containsKey(name)) {
            return summaryFields.get(name);
        }
        var sf = new ParsedSummaryField(name, getType());
        summaryFields.put(name, sf);
        return sf;
    }

    /** get an existing summary field for modification, or create it */
    ParsedSummaryField summaryFieldFor(String name, ParsedType type) {
        if (summaryFields.containsKey(name)) {
            var sf = summaryFields.get(name);
            if (sf.getType() == null) {
                sf.setType(type);
            } else {
                // TODO check that types are properly equal here
                String oldName = sf.getType().name();
                String newName = type.name();
                verifyThat(newName.equals(oldName), "type mismatch for summary field", name, ":", oldName, "/", newName);
            }
            return sf;
        }
        var sf = new ParsedSummaryField(name, type);
        summaryFields.put(name, sf);
        return sf;
    }

    void addAlias(String from, String to) {
        verifyThat(! aliases.containsKey(to), "already has alias", to);
        aliases.put(to, from);
    }

    void addIndex(ParsedIndex index) {
        String idxName = index.name();
        verifyThat(! fieldIndexes.containsKey(idxName), "already has index", idxName);
        fieldIndexes.put(idxName, index);
    }

    void addRankType(String index, String rankType) {
        rankTypes.put(index, rankType);
    }

    void dictionary(DictionaryOption option) {
        dictionaryOptions.add(option);
    }

    void setBolding(boolean value) { this.hasBolding = value; }
    void setFilter(boolean value) { this.isFilter = value; }
    void setId(int id) { this.overrideId = id; }
    void setLiteral(boolean value) { this.isLiteral = value; }
    void setNormal(boolean value) { this.isNormal = value; }
    void setNormalizing(String value) { this.normalizing = value; }
    void setStemming(Stemming stemming) { this.stemming = stemming; }
    void setWeight(int weight) { this.weight = weight; }

    ParsedAttribute attributeFor(String attrName) {
        return attributes.computeIfAbsent(attrName, n -> new ParsedAttribute(n));
    }

    void setIndexingOperation(ParsedIndexingOp idxOp) {
        verifyThat(indexingOp == null, "already has indexing");
        indexingOp = idxOp;
    }

    ParsedSorting sortInfo() {
        if (sortSettings == null) sortSettings = new ParsedSorting(name(), "field.sorting");
        return this.sortSettings;
    }

    void addQueryCommand(String command) {
        queryCommands.add(command);
    }

    void addStructField(ParsedField structField) {
        String fieldName = structField.name();
        verifyThat(! structFields.containsKey(fieldName), "already has struct-field", fieldName);
        structFields.put(fieldName, structField);
    }

    void addSummaryField(ParsedSummaryField summaryField) {
        String fieldName = summaryField.name();
        verifyThat(! summaryFields.containsKey(fieldName), "already has summary field", fieldName);
        if (summaryField.getType() == null) {
            summaryField.setType(getType());
        }
        summaryFields.put(fieldName, summaryField);
    }
}