<commit_before>package co.phoenixlab.common.localization;

import co.phoenixlab.common.lang.ReverseListIterator;

import java.util.*;

import static co.phoenixlab.common.localization.Localizer.internalIsFlagBitSet;
import static co.phoenixlab.common.localization.Localizer.stripFlags;

public class LocalizerImpl implements Localizer {

    private static final String NULL_KEY = "nullkey";
    private static final int MAX_REPEAT_COUNT = Integer.getInteger("co.phoenixlab.localizer.fmt.limits.repeat", 8);
    private static final int MAX_DEPTH = Integer.getInteger("co.phoenixlab.localizer.fmt.limits.depth", 8);

    private final Locale locale;
    private final List<LocaleStringProvider> providers;
    private final Collection<LocaleStringProvider> providersUnmodifiable;

    public LocalizerImpl(Locale locale) {
        Objects.requireNonNull(locale, "Locale cannot be null");
        this.locale = locale;
        this.providers = new ArrayList<>();
        this.providersUnmodifiable = Collections.unmodifiableCollection(providers);
    }

    @Override
    public Locale getLocale() {
        return locale;
    }

    @Override
    public void addLocaleStringProvider(LocaleStringProvider provider) {
        Objects.requireNonNull(provider, "Provider cannot be null");
        provider.setActiveLocale(locale);
        providers.add(provider);
    }

    @Override
    public void removeLocaleStringProvider(LocaleStringProvider provider) {
        Objects.requireNonNull(provider, "Provider cannot be null");
        providers.remove(provider);
    }

    @Override
    public Collection<LocaleStringProvider> getLocaleStringProviders() {
        return providersUnmodifiable;
    }

    @Override
    public void removeAllLocaleStringProviders() {
        providers.clear();
    }

    @Override
    public boolean containsKey(String key) {
        return providers.stream().
                anyMatch(p -> p.contains(key));
    }

    @Override
    public String localize(String key) {
        if (key == null) {
            return NULL_KEY;
        }

        return null;
    }

    @Override
    public String localize(String key, Object arg0) {
        if (key == null) {
            return NULL_KEY;
        }

        return null;
    }

    @Override
    public String localize(String key, Object arg0, Object arg1) {
        if (key == null) {
            return NULL_KEY;
        }

        return null;
    }

    @Override
    public String localize(String key, Object... args) {
        if (key == null) {
            return NULL_KEY;
        }
        String cleanKey = stripFlags(key);
        String ret = cleanKey;
        if (!internalIsFlagBitSet(key, PREFIX_FLAG_DO_NOT_LOCALIZE_BIT)) {
            //  Localize
            ret = lookup(cleanKey);
            if (ret == null) {
                return LOCALE_STRING_NOT_FOUND;
            }
        }
        if (!internalIsFlagBitSet(key, PREFIX_FLAG_DO_NOT_FORMAT_BIT)) {
            //  Format
            ret = format(cleanKey, ret, args);
        }
        return ret;
    }

    /**
     * Finds the value of the given key from the providers. This method iterates through the providers in a stack-like
     * fashion; that is, the last provider added is checked first, second last provider checked second, and so on.
     * This allows for proper overriding/priority of providers.
     *
     * @param key The key to look up
     * @return The value associated with the given key, or null if no provider could provide the requested value
     */
    private String lookup(String key) {
        ReverseListIterator<LocaleStringProvider> iterator = new ReverseListIterator<>(providers.listIterator());
        for (LocaleStringProvider provider : iterator) {
            String val = provider.get(key);
            if (val != null) {
                return val;
            }
        }
        return null;
    }

    /**
     * Performs the formatting step, as detailed in {@link #localize(String, Object...)}
     *
     * @param s    The string containing optional tags to be formatted
     * @param args The arguments for formatting
     * @return The formatted string
     */
    private String format(String key, String s, Object[] args) {
        //  Formatting is done by repeatedly resolving curly brace tokens and then square bracket tokens repeatedly
        //  until no more of either remain in the resultant string
        //  There is a maximum repeat limit and a resolution depth limit to prevent infinite loops or unbounded string
        //  growth, governed by the system properties co.phoenixlab.localizer.fmt.limits.xxx where xxx is "repeat" or
        //  "depth", respectively.

        //  Number of times we've passed over the entire string
        int repeatCount = 0;
        //  Our current working string
        String working = s;
        //  StringBuilder for building the resultant for each pass
        StringBuilder builder = new StringBuilder();
        //  StringBuilder for accumulating the contents of a token
        StringBuilder tokenBuilder = new StringBuilder();
        //  Whether or not any substitution was made
        boolean substitution = true;
        while (repeatCount < MAX_REPEAT_COUNT && substitution) {
            substitution = false;
            //  Resolve curly brace tokens first
            char[] chars = working.toCharArray();
            boolean isEscaped = false;
            boolean isInTag = false;
            //  Track how many layers deep we are for curly brace tags - each pass will strip away the outermost layer
            int curlyBraceDepth = 0;
            for (int pos = 0; pos < chars.length; pos++) {
                char c = chars[pos];
                if (isEscaped) {<commit_msg>Refactor maximums to be tied to instance<commit_after>package co.phoenixlab.common.localization;

import co.phoenixlab.common.lang.ReverseListIterator;

import java.util.*;

import static co.phoenixlab.common.localization.Localizer.internalIsFlagBitSet;
import static co.phoenixlab.common.localization.Localizer.stripFlags;

public class LocalizerImpl implements Localizer {

    private static final String NULL_KEY = "nullkey";

    private final int maxRepeatCount;
    private final int maxDepth;
    private final Locale locale;
    private final List<LocaleStringProvider> providers;
    private final Collection<LocaleStringProvider> providersUnmodifiable;

    public LocalizerImpl(Locale locale) {
        Objects.requireNonNull(locale, "Locale cannot be null");
        this.locale = locale;
        this.providers = new ArrayList<>();
        this.providersUnmodifiable = Collections.unmodifiableCollection(providers);
        maxRepeatCount = Integer.getInteger("co.phoenixlab.localizer.fmt.limits.repeat", 8);
        maxDepth = Integer.getInteger("co.phoenixlab.localizer.fmt.limits.depth", 8);
    }

    @Override
    public Locale getLocale() {
        return locale;
    }

    @Override
    public void addLocaleStringProvider(LocaleStringProvider provider) {
        Objects.requireNonNull(provider, "Provider cannot be null");
        provider.setActiveLocale(locale);
        providers.add(provider);
    }

    @Override
    public void removeLocaleStringProvider(LocaleStringProvider provider) {
        Objects.requireNonNull(provider, "Provider cannot be null");
        providers.remove(provider);
    }

    @Override
    public Collection<LocaleStringProvider> getLocaleStringProviders() {
        return providersUnmodifiable;
    }

    @Override
    public void removeAllLocaleStringProviders() {
        providers.clear();
    }

    @Override
    public boolean containsKey(String key) {
        return providers.stream().
                anyMatch(p -> p.contains(key));
    }

    @Override
    public String localize(String key) {
        if (key == null) {
            return NULL_KEY;
        }

        return null;
    }

    @Override
    public String localize(String key, Object arg0) {
        if (key == null) {
            return NULL_KEY;
        }

        return null;
    }

    @Override
    public String localize(String key, Object arg0, Object arg1) {
        if (key == null) {
            return NULL_KEY;
        }

        return null;
    }

    @Override
    public String localize(String key, Object... args) {
        if (key == null) {
            return NULL_KEY;
        }
        String cleanKey = stripFlags(key);
        String ret = cleanKey;
        if (!internalIsFlagBitSet(key, PREFIX_FLAG_DO_NOT_LOCALIZE_BIT)) {
            //  Localize
            ret = lookup(cleanKey);
            if (ret == null) {
                return LOCALE_STRING_NOT_FOUND;
            }
        }
        if (!internalIsFlagBitSet(key, PREFIX_FLAG_DO_NOT_FORMAT_BIT)) {
            //  Format
            ret = format(cleanKey, ret, args);
        }
        return ret;
    }

    /**
     * Finds the value of the given key from the providers. This method iterates through the providers in a stack-like
     * fashion; that is, the last provider added is checked first, second last provider checked second, and so on.
     * This allows for proper overriding/priority of providers.
     *
     * @param key The key to look up
     * @return The value associated with the given key, or null if no provider could provide the requested value
     */
    private String lookup(String key) {
        ReverseListIterator<LocaleStringProvider> iterator = new ReverseListIterator<>(providers.listIterator());
        for (LocaleStringProvider provider : iterator) {
            String val = provider.get(key);
            if (val != null) {
                return val;
            }
        }
        return null;
    }

    /**
     * Performs the formatting step, as detailed in {@link #localize(String, Object...)}
     *
     * @param s    The string containing optional tags to be formatted
     * @param args The arguments for formatting
     * @return The formatted string
     */
    private String format(String key, String s, Object[] args) {
        //  Formatting is done by repeatedly resolving curly brace tokens and then square bracket tokens repeatedly
        //  until no more of either remain in the resultant string
        //  There is a maximum repeat limit and a resolution depth limit to prevent infinite loops or unbounded string
        //  growth, governed by the system properties co.phoenixlab.localizer.fmt.limits.xxx where xxx is "repeat" or
        //  "depth", respectively.

        //  Number of times we've passed over the entire string
        int repeatCount = 0;
        //  Our current working string
        String working = s;
        //  StringBuilder for building the resultant for each pass
        StringBuilder builder = new StringBuilder();
        //  StringBuilder for accumulating the contents of a token
        StringBuilder tokenBuilder = new StringBuilder();
        //  Whether or not any substitution was made
        boolean substitution = true;
        while (repeatCount < maxRepeatCount && substitution) {
            substitution = false;
            //  Resolve curly brace tokens first
            char[] chars = working.toCharArray();
            boolean isEscaped = false;
            boolean isInTag = false;
            //  Track how many layers deep we are for curly brace tags - each pass will strip away the outermost layer
            int curlyBraceDepth = 0;
            for (int pos = 0; pos < chars.length; pos++) {
                char c = chars[pos];
                if (isEscaped) {
{'fraction_non_alphanumeric': 0.07765479072985126, 'fraction_numerical': 0.0013836042891732965, 'mean_word_length': 2.3492615117289315, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '16203', 'n_tokens_mistral': 2992, 'n_tokens_neox': 2896, 'n_words': 986}