<commit_before>/*
 * Copyright 2015 <NAME> <<EMAIL>>
 * and other copyright owners as documented in the project's IP log.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.basinmc.faucet.plugin;

import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Consumer;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import javax.annotation.concurrent.ThreadSafe;

/**
 * Represents a semantic version.
 *
 * @author <NAME>
 */
@ThreadSafe
public final class PluginVersion {
    private final int major;
    private final int minor;
    private final int patch;

    private final String extra;
    private final String metadata;
    private final UnstableVersionType unstableVersionType;

    protected PluginVersion(@Nonnegative int major, @Nonnegative int minor, @Nonnegative int patch, @Nullable String extra, @Nullable String metadata, @Nullable UnstableVersionType unstableVersionType) {
        this.major = major;
        this.minor = minor;
        this.patch = patch;

        this.extra = extra;
        this.metadata = metadata;
        this.unstableVersionType = unstableVersionType;
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion.Builder} instance.
     *
     * @return the builder.
     */
    @Nonnull
    public static Builder builder() {
        return (new Builder());
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion.Builder} replicating the values
     * of {@code version}.
     *
     * @param version the version to replicate.
     * @return the builder.
     */
    @Nonnull
    public static Builder builder(@Nonnull PluginVersion version) {
        // @formatter:off
        return builder()
                .major(version.major())
                .minor(version.minor())
                .patch(version.patch())
                .extra(version.extra())
                .metadata(version.metadata());
        // @formatter:on
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion.Builder} based on values found
     * within a string.
     *
     * @param version the version string.
     * @return the builder.
     *
     * @throws java.lang.IllegalArgumentException when one or more bits are not within SemVer
     *                                            bounds.
     * @throws java.lang.NumberFormatException    when one or more numeric bits have invalid
     *                                            values.
     */
    @Nonnull
    public static Builder builder(@Nonnull String version) throws IllegalArgumentException, NumberFormatException {
        return builder().parse(version);
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion} based on values found within a
     * string.
     *
     * @param version the version string.
     * @return the version.
     *
     * @throws java.lang.IllegalArgumentException when one or more bits are not within SemVer
     *                                            bounds.
     * @throws java.lang.NumberFormatException    when one or more numeric bits have invalid
     *                                            values.
     */
    @Nonnull
    public static PluginVersion of(@Nonnull String version) throws IllegalArgumentException, NumberFormatException {
        // @formatter:off
        return builder(version)
                .build();
        // @formatter:on
    }

    /**
     * Creates a version range consisting of two {@link org.basinmc.faucet.plugin.PluginVersion}
     * instances.
     *
     * @param version1 the starting bound.
     * @param version2 the ending bound.
     * @return the range.
     */
    @Nonnull
    public static VersionRange range(@Nonnull PluginVersion version1, @Nonnull PluginVersion version2) {
        // @formatter:off
        return VersionRange.<PluginVersion>builder()
                .startBound(version1)
                .endBound(version2)
                .build();
        // @formatter:on
    }

    /**
     * Creates a version range consisting of two {@link org.basinmc.faucet.plugin.PluginVersion}
     * instances.
     *
     * @param version1 the starting bound.
     * @param version2 the ending bound.
     * @return the range.
     */
    @Nonnull
    public static VersionRange range(@Nonnull String version1, @Nonnull String version2) {
        return range(of(version1), of(version2));
    }

    /**
     * Creates a version range consisting of two {@link org.basinmc.faucet.plugin.PluginVersion}
     * instances declared by a string utilizing the interval notation.
     *
     * @param range the range string.
     * @return the range.
     *
     * @throws java.lang.IllegalArgumentException when the range or one of the version strings is
     *                                            invalid.
     * @throws java.lang.NumberFormatException    when one or more bits are invalid.
     */
    @Nonnull
    public static VersionRange range(@Nonnull String range) throws IllegalArgumentException, NumberFormatException {
        VersionRange.Builder builder = VersionRange.<PluginVersion>builder();

        int offset = range.indexOf(',');
        if (offset == -1) {
            PluginVersion version = of(range);
            PluginVersion endVersion = (version.unstable() ? version : version.minor(version.major + 1));

            return builder
                    .startBound(version)
                    .endBound(endVersion)
                    .startInclusive(true)
                    .endInclusive(false)
                    .build();
        }

        String startBound = range.substring(0, offset);
        String endBound = range.substring((offset + 1));

        if (startBound.startsWith("[")) {<commit_msg>Increased bounds for compatible versions (only major versions will break compatibility in SemVer).<commit_after>/*
 * Copyright 2015 <NAME> <<EMAIL>>
 * and other copyright owners as documented in the project's IP log.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.basinmc.faucet.plugin;

import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Consumer;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import javax.annotation.concurrent.ThreadSafe;

/**
 * Represents a semantic version.
 *
 * @author <NAME>
 */
@ThreadSafe
public final class PluginVersion {
    private final int major;
    private final int minor;
    private final int patch;

    private final String extra;
    private final String metadata;
    private final UnstableVersionType unstableVersionType;

    protected PluginVersion(@Nonnegative int major, @Nonnegative int minor, @Nonnegative int patch, @Nullable String extra, @Nullable String metadata, @Nullable UnstableVersionType unstableVersionType) {
        this.major = major;
        this.minor = minor;
        this.patch = patch;

        this.extra = extra;
        this.metadata = metadata;
        this.unstableVersionType = unstableVersionType;
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion.Builder} instance.
     *
     * @return the builder.
     */
    @Nonnull
    public static Builder builder() {
        return (new Builder());
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion.Builder} replicating the values
     * of {@code version}.
     *
     * @param version the version to replicate.
     * @return the builder.
     */
    @Nonnull
    public static Builder builder(@Nonnull PluginVersion version) {
        // @formatter:off
        return builder()
                .major(version.major())
                .minor(version.minor())
                .patch(version.patch())
                .extra(version.extra())
                .metadata(version.metadata());
        // @formatter:on
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion.Builder} based on values found
     * within a string.
     *
     * @param version the version string.
     * @return the builder.
     *
     * @throws java.lang.IllegalArgumentException when one or more bits are not within SemVer
     *                                            bounds.
     * @throws java.lang.NumberFormatException    when one or more numeric bits have invalid
     *                                            values.
     */
    @Nonnull
    public static Builder builder(@Nonnull String version) throws IllegalArgumentException, NumberFormatException {
        return builder().parse(version);
    }

    /**
     * Creates a new {@link org.basinmc.faucet.plugin.PluginVersion} based on values found within a
     * string.
     *
     * @param version the version string.
     * @return the version.
     *
     * @throws java.lang.IllegalArgumentException when one or more bits are not within SemVer
     *                                            bounds.
     * @throws java.lang.NumberFormatException    when one or more numeric bits have invalid
     *                                            values.
     */
    @Nonnull
    public static PluginVersion of(@Nonnull String version) throws IllegalArgumentException, NumberFormatException {
        // @formatter:off
        return builder(version)
                .build();
        // @formatter:on
    }

    /**
     * Creates a version range consisting of two {@link org.basinmc.faucet.plugin.PluginVersion}
     * instances.
     *
     * @param version1 the starting bound.
     * @param version2 the ending bound.
     * @return the range.
     */
    @Nonnull
    public static VersionRange range(@Nonnull PluginVersion version1, @Nonnull PluginVersion version2) {
        // @formatter:off
        return VersionRange.<PluginVersion>builder()
                .startBound(version1)
                .endBound(version2)
                .build();
        // @formatter:on
    }

    /**
     * Creates a version range consisting of two {@link org.basinmc.faucet.plugin.PluginVersion}
     * instances.
     *
     * @param version1 the starting bound.
     * @param version2 the ending bound.
     * @return the range.
     */
    @Nonnull
    public static VersionRange range(@Nonnull String version1, @Nonnull String version2) {
        return range(of(version1), of(version2));
    }

    /**
     * Creates a version range consisting of two {@link org.basinmc.faucet.plugin.PluginVersion}
     * instances declared by a string utilizing the interval notation.
     *
     * @param range the range string.
     * @return the range.
     *
     * @throws java.lang.IllegalArgumentException when the range or one of the version strings is
     *                                            invalid.
     * @throws java.lang.NumberFormatException    when one or more bits are invalid.
     */
    @Nonnull
    public static VersionRange range(@Nonnull String range) throws IllegalArgumentException, NumberFormatException {
        VersionRange.Builder builder = VersionRange.<PluginVersion>builder();

        int offset = range.indexOf(',');
        if (offset == -1) {
            PluginVersion version = of(range);
            PluginVersion endVersion = (version.unstable() ? version : version.major(version.major + 1));

            return builder
                    .startBound(version)
                    .endBound(endVersion)
                    .startInclusive(true)
                    .endInclusive(false)
                    .build();
        }

        String startBound = range.substring(0, offset);
        String endBound = range.substring((offset + 1));

        if (startBound.startsWith("[")) {
{'fraction_non_alphanumeric': 0.08779309807587443, 'fraction_numerical': 0.0037391913998597805, 'mean_word_length': 2.2402826855123674, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '675434', 'n_tokens_mistral': 3271, 'n_tokens_neox': 3138, 'n_words': 1038}