<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: google/protobuf/descriptor.proto

namespace Google\Protobuf\Internal;

use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\GPBWire;
use Google\Protobuf\Internal\InputStream;
use Google\Protobuf\Internal\GPBUtil;
use Google\Protobuf\RepeatedField;

/**
 * A compiled specification for the defaults of a set of features.  These
 * messages are generated from FeatureSet extensions and can be used to seed
 * feature resolution. The resolution with this object becomes a simple search
 * for the closest matching edition, followed by proto merges.
 *
 * Generated from protobuf message <code>google.protobuf.FeatureSetDefaults</code>
 */
class FeatureSetDefaults extends \Google\Protobuf\Internal\Message
{
    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1;</code>
     */
    private $defaults;
    /**
     * The minimum supported edition (inclusive) when this was constructed.
     * Editions before this will not have defaults.
     *
     * Generated from protobuf field <code>optional .google.protobuf.Edition minimum_edition = 4;</code>
     */
    protected $minimum_edition = null;
    /**
     * The maximum known edition (inclusive) when this was constructed. Editions
     * after this will not have reliable defaults.
     *
     * Generated from protobuf field <code>optional .google.protobuf.Edition maximum_edition = 5;</code>
     */
    protected $maximum_edition = null;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type \Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault[] $defaults
     *     @type int $minimum_edition
     *           The minimum supported edition (inclusive) when this was constructed.
     *           Editions before this will not have defaults.
     *     @type int $maximum_edition
     *           The maximum known edition (inclusive) when this was constructed. Editions
     *           after this will not have reliable defaults.
     * }
     */
    public function __construct($data = null)
    {
        \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
        parent::__construct($data);
    }

    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1;</code>
     * @return RepeatedField<\Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault>
     */
    public function getDefaults()
    {
        return $this->defaults;
    }

    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1;</code>
     * @param \Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault[] $var
     * @return $this
     */
    public function setDefaults(array|RepeatedField $var)
    {
        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault::class);
        $this->defaults = $arr;

        return $this;
    }

    /**
     * The minimum supported edition (inclusive) when this was constructed.
     * Editions before this will not have defaults.
     *
     * Generated from protobuf field <code>optional .google.protobuf.Edition minimum_edition = 4;</code>
     * @return int one of the values in {@see \Google\Protobuf\Internal\Edition}
     */
    public function getMinimumEdition()
    {
        return isset($this->minimum_edition) ? $this->minimum_edition : 0;
    }

    public function hasMinimumEdition()
    {
        return isset($this->minimum_edition);
    }

    public function clearMinimumEdition()
    {
        unset($this->minimum_edition);
    }

    /**
     * The minimum supported edition (inclusive) when this was constructed.
     * Editions before this will not have defaults.
     *
     * Generated from protobuf field <code>optional .google.protobuf.Edition minimum_edition = 4;</code>
     * @param int $var one of the values in {@see \Google\Protobuf\Internal\Edition}
     * @return $this
     */
    public function setMinimumEdition(int $var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class);
        $this->minimum_edition = $var;

        return $this;
    }

    /**
     * The maximum known edition (inclusive) when this was constructed. Editions
     * after this will not have reliable defaults.
     *
     * Generated from protobuf field <code>optional .google.protobuf.Edition maximum_edition = 5;</code>
     * @return int one of the values in {@see \Google\Protobuf\Internal\Edition}
     */
    public function getMaximumEdition()
    {
        return isset($this->maximum_edition) ? $this->maximum_edition : 0;
    }

    public function hasMaximumEdition()
    {
        return isset($this->maximum_edition);
    }

    public function clearMaximumEdition()
    {
        unset($this->maximum_edition);
    }

    /**
     * The maximum known edition (inclusive) when this was constructed. Editions
     * after this will not have reliable defaults.
     *
     * Generated from protobuf field <code>optional .google.protobuf.Edition maximum_edition = 5;</code>
     * @param int $var one of the values in {@see \Google\Protobuf\Internal\Edition}
     * @return $this
     */
    public function setMaximumEdition(int $var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class);
        $this->maximum_edition = $var;

        return $this;
    }

}

