aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/searchdefinition/parser/ParsedType.java
blob: 9f02c5247eff38534041978ba7b0f2bf1639fcce (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
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.searchdefinition.parser;

import com.yahoo.tensor.TensorType;

/**
 * This class holds the extracted information after parsing a type
 * declaration (typically for a field).  Since types can be complex,
 * struct names (known or unknown), or even document names, this class
 * is somewhat complicated.
 * @author arnej27959
 **/
class ParsedType {
    public enum Variant {
        NONE,
        BOOL, BYTE, INT, LONG,
        STRING,
        FLOAT, DOUBLE,
        URI, PREDICATE, TENSOR,
        ARRAY, WSET, MAP,
        DOC_REFERENCE,
        ANN_REFERENCE,
        STRUCT,
        DOCUMENT,
        UNKNOWN
    }

    private final String name;
    private final ParsedType keyType;
    private final ParsedType valType;
    private final TensorType tensorType;
    private Variant variant;
    private boolean createIfNonExistent = false;
    private boolean removeIfZero = false;

    private static Variant guessVariant(String name) {
        switch (name) {
        case "bool":      return Variant.BOOL;
        case "byte":      return Variant.BYTE;
        case "int":       return Variant.INT;
        case "long":      return Variant.LONG;
        case "string":    return Variant.STRING;
        case "float":     return Variant.FLOAT;
        case "double":    return Variant.DOUBLE;
        case "uri":       return Variant.URI;
        case "predicate": return Variant.PREDICATE;
        case "position":  return Variant.STRUCT;
        }
        return Variant.UNKNOWN;
    }

    public String name() { return name; }
    public Variant getVariant() { return variant; }
    public ParsedType mapKeyType() { assert(variant == Variant.MAP); return keyType; }
    public ParsedType mapValueType() { assert(variant == Variant.MAP); return valType; }
    public ParsedType nestedType() { assert(variant == Variant.ARRAY || variant == Variant.WSET); return valType; }
    public boolean getCreateIfNonExistent() { assert(variant == Variant.WSET); return this.createIfNonExistent; }
    public boolean getRemoveIfZero() { assert(variant == Variant.WSET); return this.removeIfZero; }
    public ParsedType getReferencedDocumentType() { assert(variant == Variant.DOC_REFERENCE); return valType; }
    public TensorType getTensorType() { assert(variant == Variant.TENSOR); return tensorType; }

    private ParsedType(String name, Variant variant) {
        this(name, variant, null, null, null);
    }
    private ParsedType(String name, Variant variant, ParsedType vt) {
        this(name, variant, vt, null, null);
    }
    private ParsedType(String name, Variant variant, ParsedType kt, ParsedType vt) {
        this(name, variant, vt, kt, null);
    }
    private ParsedType(String name, Variant variant, ParsedType kt, ParsedType vt, TensorType tType) {
        this.name = name;
        this.variant = variant;
        this.keyType = kt;
        this.valType = vt;
        this.tensorType = tType;
    }

    static ParsedType mapType(ParsedType kt, ParsedType vt) {
        String name = "map<" + kt.name() + "," + vt.name() + ">";
        return new ParsedType(name, Variant.MAP, kt, vt);
    }
    static ParsedType arrayOf(ParsedType vt) {
        return new ParsedType("array<" + vt.name() + ">", Variant.ARRAY, vt);
    }
    static ParsedType wsetOf(ParsedType vt) {
        return new ParsedType("weightedset<" + vt.name() + ">", Variant.WSET, vt);
    }
    static ParsedType documentRef(ParsedType docType) {
        return new ParsedType("reference<" + docType.name + ">", Variant.DOC_REFERENCE, docType);
    }
    static ParsedType annotationRef(String name) {
        return new ParsedType("annotationreference<" + name + ">", Variant.ANN_REFERENCE);
    }
    static ParsedType tensorType(TensorType tType) {
        return new ParsedType(tType.toString(), Variant.TENSOR, null, null, tType);
    }
    static ParsedType fromName(String name) {
        return new ParsedType(name, guessVariant(name));
    }
    static ParsedType documentType(String name) {
        return new ParsedType(name, Variant.DOCUMENT);
    }

    void setCreateIfNonExistent(boolean value) {
        if (variant != Variant.WSET) {
            throw new IllegalArgumentException("CreateIfNonExistent only valid for weightedset, not " + variant);
        }
        this.createIfNonExistent = value;
    }

    void setRemoveIfZero(boolean value) {
        if (variant != Variant.WSET) {
            throw new IllegalArgumentException("RemoveIfZero only valid for weightedset, not " + variant);
        }
        this.removeIfZero = value;
    }

    void setVariant(Variant value) {
        if (variant == value) return; // already OK
        if (variant != Variant.UNKNOWN) {
            throw new IllegalArgumentException("setVariant(" + value + ") only valid for UNKNOWN, not: " + variant);
        }
        // maybe even more checking would be useful
        this.variant = value;
    }
}