<?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;

/**
 * Generated from protobuf message <code>google.protobuf.MethodOptions</code>
 */
class MethodOptions extends \Google\Protobuf\Internal\Message
{
    /**
     * Is this method deprecated?
     * Depending on the target platform, this can emit Deprecated annotations
     * for the method, or it will be completely ignored; in the very least,
     * this is a formalization for deprecating methods.
     *
     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
     */
    protected $deprecated = null;
    /**
     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
     */
    protected $idempotency_level = null;
    /**
     * Any features defined in the specific edition.
     * WARNING: This field should only be used by protobuf plugins or special
     * cases like the proto compiler. Other uses are discouraged and
     * developers should rely on the protoreflect APIs for their client language.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FeatureSet features = 35;</code>
     */
    protected $features = null;
    /**
     * The parser stores options it doesn't recognize here. See above.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
     */
    private $uninterpreted_option;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type bool $deprecated
     *           Is this method deprecated?
     *           Depending on the target platform, this can emit Deprecated annotations
     *           for the method, or it will be completely ignored; in the very least,
     *           this is a formalization for deprecating methods.
     *     @type int $idempotency_level
     *     @type \Google\Protobuf\Internal\FeatureSet $features
     *           Any features defined in the specific edition.
     *           WARNING: This field should only be used by protobuf plugins or special
     *           cases like the proto compiler. Other uses are discouraged and
     *           developers should rely on the protoreflect APIs for their client language.
     *     @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option
     *           The parser stores options it doesn't recognize here. See above.
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
        parent::__construct($data);
    }

    /**
     * Is this method deprecated?
     * Depending on the target platform, this can emit Deprecated annotations
     * for the method, or it will be completely ignored; in the very least,
     * this is a formalization for deprecating methods.
     *
     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
     * @return bool
     */
    public function getDeprecated()
    {
        return isset($this->deprecated) ? $this->deprecated : false;
    }

    public function hasDeprecated()
    {
        return isset($this->deprecated);
    }

    public function clearDeprecated()
    {
        unset($this->deprecated);
    }

    /**
     * Is this method deprecated?
     * Depending on the target platform, this can emit Deprecated annotations
     * for the method, or it will be completely ignored; in the very least,
     * this is a formalization for deprecating methods.
     *
     * Generated from protobuf field <code>optional bool deprecated = 33 [default = false];</code>
     * @param bool $var
     * @return $this
     */
    public function setDeprecated(bool $var)
    {
        $this->deprecated = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
     * @return int one of the values in {@see \Google\Protobuf\Internal\MethodOptions\IdempotencyLevel}
     */
    public function getIdempotencyLevel()
    {
        return isset($this->idempotency_level) ? $this->idempotency_level : 0;
    }

    public function hasIdempotencyLevel()
    {
        return isset($this->idempotency_level);
    }

    public function clearIdempotencyLevel()
    {
        unset($this->idempotency_level);
    }

    /**
     * Generated from protobuf field <code>optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN];</code>
     * @param int $var one of the values in {@see \Google\Protobuf\Internal\MethodOptions\IdempotencyLevel}
     * @return $this
     */
    public function setIdempotencyLevel(int $var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Internal\MethodOptions\IdempotencyLevel::class);
        $this->idempotency_level = $var;

        return $this;
    }

    /**
     * Any features defined in the specific edition.
     * WARNING: This field should only be used by protobuf plugins or special
     * cases like the proto compiler. Other uses are discouraged and
     * developers should rely on the protoreflect APIs for their client language.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FeatureSet features = 35;</code>
     * @return \Google\Protobuf\Internal\FeatureSet|null
     */
    public function getFeatures()
    {
        return $this->features;
    }

    public function hasFeatures()
    {
        return isset($this->features);
    }

    public function clearFeatures()
    {
        unset($this->features);
    }

    /**
     * Any features defined in the specific edition.
     * WARNING: This field should only be used by protobuf plugins or special
     * cases like the proto compiler. Other uses are discouraged and
     * developers should rely on the protoreflect APIs for their client language.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FeatureSet features = 35;</code>
     * @param \Google\Protobuf\Internal\FeatureSet $var
     * @return $this
     */
    public function setFeatures(\Google\Protobuf\Internal\FeatureSet|null $var)
    {
        $this->features = $var;

        return $this;
    }

    /**
     * The parser stores options it doesn't recognize here. See above.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
     * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption>
     */
    public function getUninterpretedOption()
    {
        return $this->uninterpreted_option;
    }

    /**
     * The parser stores options it doesn't recognize here. See above.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
     * @param \Google\Protobuf\Internal\UninterpretedOption[] $var
     * @return $this
     */
    public function setUninterpretedOption(array|RepeatedField $var)
    {
        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
        $this->uninterpreted_option = $arr;

        return $this;
    }

}

