<commit_before>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.document;

import com.yahoo.collections.Pair;
import com.yahoo.concurrent.CopyOnWriteHashMap;
import com.yahoo.document.datatypes.ByteFieldValue;
import com.yahoo.document.datatypes.DoubleFieldValue;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.FloatFieldValue;
import com.yahoo.document.datatypes.IntegerFieldValue;
import com.yahoo.document.datatypes.LongFieldValue;
import com.yahoo.document.datatypes.PredicateFieldValue;
import com.yahoo.document.datatypes.Raw;
import com.yahoo.document.datatypes.StringFieldValue;
import com.yahoo.document.datatypes.TensorFieldValue;
import com.yahoo.document.datatypes.UriFieldValue;
import com.yahoo.tensor.TensorType;
import com.yahoo.vespa.objects.Identifiable;
import com.yahoo.vespa.objects.Ids;
import com.yahoo.vespa.objects.ObjectVisitor;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;

/**
 * Enumeration of the possible types of fields. Since arrays and weighted sets may be defined for any types, including
 * themselves, this enumeration is open ended.
 *
 * @author bratseth
 */
public abstract class DataType extends Identifiable implements Serializable, Comparable<DataType> {

    // The global class identifier shared with C++.
    public static int classId = registerClass(Ids.document + 50, DataType.class);

    // NOTE: These types are also defined in
    // document/src/vespa/document/datatype/datatype.h
    // Changes here must also be done there

    public final static NumericDataType NONE = new NumericDataType("none", -1, IntegerFieldValue.class, IntegerFieldValue.getFactory());
    public final static NumericDataType INT = new NumericDataType("int", 0, IntegerFieldValue.class, IntegerFieldValue.getFactory());
    public final static NumericDataType FLOAT = new NumericDataType("float", 1, FloatFieldValue.class, FloatFieldValue.getFactory());
    public final static PrimitiveDataType STRING = new PrimitiveDataType("string", 2, StringFieldValue.class, StringFieldValue.getFactory());
    public final static PrimitiveDataType RAW = new PrimitiveDataType("raw", 3, Raw.class, Raw.getFactory());
    public final static NumericDataType LONG = new NumericDataType("long", 4, LongFieldValue.class, LongFieldValue.getFactory());
    public final static NumericDataType DOUBLE = new NumericDataType("double", 5, DoubleFieldValue.class, DoubleFieldValue.getFactory());
    public final static DocumentType DOCUMENT = new DocumentType("document");
    public final static PrimitiveDataType URI = new PrimitiveDataType("uri", 10, UriFieldValue.class, new UriFieldValue.Factory());
    public final static NumericDataType BYTE = new NumericDataType("byte", 16, ByteFieldValue.class, ByteFieldValue.getFactory());
    public final static PrimitiveDataType PREDICATE = new PrimitiveDataType("predicate", 20, PredicateFieldValue.class, PredicateFieldValue.getFactory());
    public final static int tensorDataTypeCode = 21; // All TensorDataType instances have id=21 but carries additional type information serialized separately
    // ADDITIONAL parametrized types added at runtime: map, struct, array, weighted set, annotation reference, tensor

    // Tags are converted to weightedset<string> when reading the search definition TODO: Remove it
    public final static WeightedSetDataType TAG = new WeightedSetDataType(DataType.STRING, true, true);

    public static int lastPredefinedDataTypeId() {
        return 21;
    }

    /** Set to true when this type is registered in a type manager. From that time we should refuse changes. */
    private boolean registered = false;

    private String name;

    /** The id of this type */
    private int dataTypeId;

    static final private CopyOnWriteHashMap<Pair, Constructor> constructorCache = new CopyOnWriteHashMap<>();

    /**
     * Creates a datatype
     *
     * @param name       the name of the type
     * @param dataTypeId the id of the type
     */
    protected DataType(java.lang.String name, int dataTypeId) {
        this.name = name;
        this.dataTypeId = dataTypeId;
    }

    @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException")
    public DataType clone() {
        return (DataType)super.clone();
    }

    void setRegistered() {
        registered = true;
    }
    public boolean isRegistered() {
        return registered;
    }

    /** Creates a new, empty FieldValue of this type */
    public abstract FieldValue createFieldValue();

    /**
     * Creates a field value by reflection
     *
     * @param arg the value of the newly created field value
     * @return a fully constructed value
     */
    protected FieldValue createByReflection(Object arg) {
        Class<?> valClass = getValueClass();
        if (valClass != null) {
            Pair<Class<?>, Class<?>> key = new Pair<>(valClass, arg.getClass());
            Constructor<?> cstr = constructorCache.get(key);
            try {
                if (cstr == null) {
                    cstr = valClass.getConstructor(key.getSecond());
                    constructorCache.put(key, cstr);
                }
                return (FieldValue)cstr.newInstance(arg);
            } catch (ReflectiveOperationException e) {
                // Only rethrow exceptions coming from the underlying FieldValue constructor.
                if (e instanceof InvocationTargetException) {
                    throw new IllegalArgumentException(e.getCause().getMessage(), e.getCause());
                }
            }
        }
        return null;
    }<commit_msg>Rember that you did not have any constructor for this class and this parameter set. This will enable fail fast next time instead of having an exception thrown every time.<commit_after>// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.document;

import com.yahoo.collections.Pair;
import com.yahoo.concurrent.CopyOnWriteHashMap;
import com.yahoo.document.datatypes.ByteFieldValue;
import com.yahoo.document.datatypes.DoubleFieldValue;
import com.yahoo.document.datatypes.FieldValue;
import com.yahoo.document.datatypes.FloatFieldValue;
import com.yahoo.document.datatypes.IntegerFieldValue;
import com.yahoo.document.datatypes.LongFieldValue;
import com.yahoo.document.datatypes.PredicateFieldValue;
import com.yahoo.document.datatypes.Raw;
import com.yahoo.document.datatypes.StringFieldValue;
import com.yahoo.document.datatypes.TensorFieldValue;
import com.yahoo.document.datatypes.UriFieldValue;
import com.yahoo.tensor.TensorType;
import com.yahoo.vespa.objects.Identifiable;
import com.yahoo.vespa.objects.Ids;
import com.yahoo.vespa.objects.ObjectVisitor;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;

/**
 * Enumeration of the possible types of fields. Since arrays and weighted sets may be defined for any types, including
 * themselves, this enumeration is open ended.
 *
 * @author bratseth
 */
public abstract class DataType extends Identifiable implements Serializable, Comparable<DataType> {

    // The global class identifier shared with C++.
    public static int classId = registerClass(Ids.document + 50, DataType.class);

    // NOTE: These types are also defined in
    // document/src/vespa/document/datatype/datatype.h
    // Changes here must also be done there

    public final static NumericDataType NONE = new NumericDataType("none", -1, IntegerFieldValue.class, IntegerFieldValue.getFactory());
    public final static NumericDataType INT = new NumericDataType("int", 0, IntegerFieldValue.class, IntegerFieldValue.getFactory());
    public final static NumericDataType FLOAT = new NumericDataType("float", 1, FloatFieldValue.class, FloatFieldValue.getFactory());
    public final static PrimitiveDataType STRING = new PrimitiveDataType("string", 2, StringFieldValue.class, StringFieldValue.getFactory());
    public final static PrimitiveDataType RAW = new PrimitiveDataType("raw", 3, Raw.class, Raw.getFactory());
    public final static NumericDataType LONG = new NumericDataType("long", 4, LongFieldValue.class, LongFieldValue.getFactory());
    public final static NumericDataType DOUBLE = new NumericDataType("double", 5, DoubleFieldValue.class, DoubleFieldValue.getFactory());
    public final static DocumentType DOCUMENT = new DocumentType("document");
    public final static PrimitiveDataType URI = new PrimitiveDataType("uri", 10, UriFieldValue.class, new UriFieldValue.Factory());
    public final static NumericDataType BYTE = new NumericDataType("byte", 16, ByteFieldValue.class, ByteFieldValue.getFactory());
    public final static PrimitiveDataType PREDICATE = new PrimitiveDataType("predicate", 20, PredicateFieldValue.class, PredicateFieldValue.getFactory());
    public final static int tensorDataTypeCode = 21; // All TensorDataType instances have id=21 but carries additional type information serialized separately
    // ADDITIONAL parametrized types added at runtime: map, struct, array, weighted set, annotation reference, tensor

    // Tags are converted to weightedset<string> when reading the search definition TODO: Remove it
    public final static WeightedSetDataType TAG = new WeightedSetDataType(DataType.STRING, true, true);

    public static int lastPredefinedDataTypeId() {
        return 21;
    }

    /** Set to true when this type is registered in a type manager. From that time we should refuse changes. */
    private boolean registered = false;

    private String name;

    /** The id of this type */
    private int dataTypeId;

    static final private CopyOnWriteHashMap<Pair, Constructor> constructorCache = new CopyOnWriteHashMap<>();

    /**
     * Creates a datatype
     *
     * @param name       the name of the type
     * @param dataTypeId the id of the type
     */
    protected DataType(java.lang.String name, int dataTypeId) {
        this.name = name;
        this.dataTypeId = dataTypeId;
    }

    @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException")
    public DataType clone() {
        return (DataType)super.clone();
    }

    void setRegistered() {
        registered = true;
    }
    public boolean isRegistered() {
        return registered;
    }

    /** Creates a new, empty FieldValue of this type */
    public abstract FieldValue createFieldValue();

    /**
     * Creates a field value by reflection
     *
     * @param arg the value of the newly created field value
     * @return a fully constructed value
     */
    protected FieldValue createByReflection(Object arg) {
        Class<?> valClass = getValueClass();
        if (valClass != null) {
            Pair<Class<?>, Class<?>> key = new Pair<>(valClass, arg.getClass());
            Constructor<?> cstr = constructorCache.get(key);
            if (cstr == null) {
                if (!constructorCache.containsKey(key)) {
                    try {
                        cstr = valClass.getConstructor(key.getSecond());
                        constructorCache.put(key, cstr);
                    } catch (NoSuchMethodException e) {
                        constructorCache.put(key, null);
                    }
                }
            }
            try {
                return cstr != null ? (FieldValue)cstr.newInstance(arg) : null;
            } catch (ReflectiveOperationException e) {
                // Only rethrow exceptions coming from the underlying FieldValue constructor.
                if (e instanceof InvocationTargetException) {
                    throw new IllegalArgumentException(e.getCause().getMessage(), e.getCause());
                }
            }
        }
        return null;
    }
{'fraction_non_alphanumeric': 0.08739397971062697, 'fraction_numerical': 0.004490271079328123, 'mean_word_length': 3.4876865671641792, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6885235', 'n_tokens_mistral': 3170, 'n_tokens_neox': 3096, 'n_words': 972}