<?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.FieldOptions</code>
 */
class FieldOptions extends \Google\Protobuf\Internal\Message
{
    /**
     * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead.
     * The ctype option instructs the C++ code generator to use a different
     * representation of the field than it normally would.  See the specific
     * options below.  This option is only implemented to support use of
     * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of
     * type "bytes" in the open source release.
     * TODO: make ctype actually deprecated.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
     */
    protected $ctype = null;
    /**
     * The packed option can be enabled for repeated primitive fields to enable
     * a more efficient representation on the wire. Rather than repeatedly
     * writing the tag and type for each element, the entire array is encoded as
     * a single length-delimited blob. In proto3, only explicit setting it to
     * false will avoid using packed encoding.  This option is prohibited in
     * Editions, but the `repeated_field_encoding` feature can be used to control
     * the behavior.
     *
     * Generated from protobuf field <code>optional bool packed = 2;</code>
     */
    protected $packed = null;
    /**
     * The jstype option determines the JavaScript type used for values of the
     * field.  The option is permitted only for 64 bit integral and fixed types
     * (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
     * is represented as JavaScript string, which avoids loss of precision that
     * can happen when a large value is converted to a floating point JavaScript.
     * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
     * use the JavaScript "number" type.  The behavior of the default option
     * JS_NORMAL is implementation dependent.
     * This option is an enum to permit additional types to be added, e.g.
     * goog.math.Integer.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
     */
    protected $jstype = null;
    /**
     * Should this field be parsed lazily?  Lazy applies only to message-type
     * fields.  It means that when the outer message is initially parsed, the
     * inner message's contents will not be parsed but instead stored in encoded
     * form.  The inner message will actually be parsed when it is first accessed.
     * This is only a hint.  Implementations are free to choose whether to use
     * eager or lazy parsing regardless of the value of this option.  However,
     * setting this option true suggests that the protocol author believes that
     * using lazy parsing on this field is worth the additional bookkeeping
     * overhead typically needed to implement it.
     * This option does not affect the public interface of any generated code;
     * all method signatures remain the same.  Furthermore, thread-safety of the
     * interface is not affected by this option; const methods remain safe to
     * call from multiple threads concurrently, while non-const methods continue
     * to require exclusive access.
     * Note that lazy message fields are still eagerly verified to check
     * ill-formed wireformat or missing required fields. Calling IsInitialized()
     * on the outer message would fail if the inner message has missing required
     * fields. Failed verification would result in parsing failure (except when
     * uninitialized messages are acceptable).
     *
     * Generated from protobuf field <code>optional bool lazy = 5 [default = false];</code>
     */
    protected $lazy = null;
    /**
     * unverified_lazy does no correctness checks on the byte stream. This should
     * only be used where lazy with verification is prohibitive for performance
     * reasons.
     *
     * Generated from protobuf field <code>optional bool unverified_lazy = 15 [default = false];</code>
     */
    protected $unverified_lazy = null;
    /**
     * Is this field deprecated?
     * Depending on the target platform, this can emit Deprecated annotations
     * for accessors, or it will be completely ignored; in the very least, this
     * is a formalization for deprecating fields.
     *
     * Generated from protobuf field <code>optional bool deprecated = 3 [default = false];</code>
     */
    protected $deprecated = null;
    /**
     * DEPRECATED. DO NOT USE!
     * For Google-internal migration only. Do not use.
     *
     * Generated from protobuf field <code>optional bool weak = 10 [default = false, deprecated = true];</code>
     * @deprecated
     */
    protected $weak = null;
    /**
     * Indicate that the field value should not be printed out when using debug
     * formats, e.g. when the field contains sensitive credentials.
     *
     * Generated from protobuf field <code>optional bool debug_redact = 16 [default = false];</code>
     */
    protected $debug_redact = null;
    /**
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.OptionRetention retention = 17;</code>
     */
    protected $retention = null;
    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19;</code>
     */
    private $targets;
    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20;</code>
     */
    private $edition_defaults;
    /**
     * 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 = 21;</code>
     */
    protected $features = null;
    /**
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22;</code>
     */
    protected $feature_support = 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 int $ctype
     *           NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead.
     *           The ctype option instructs the C++ code generator to use a different
     *           representation of the field than it normally would.  See the specific
     *           options below.  This option is only implemented to support use of
     *           [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of
     *           type "bytes" in the open source release.
     *           TODO: make ctype actually deprecated.
     *     @type bool $packed
     *           The packed option can be enabled for repeated primitive fields to enable
     *           a more efficient representation on the wire. Rather than repeatedly
     *           writing the tag and type for each element, the entire array is encoded as
     *           a single length-delimited blob. In proto3, only explicit setting it to
     *           false will avoid using packed encoding.  This option is prohibited in
     *           Editions, but the `repeated_field_encoding` feature can be used to control
     *           the behavior.
     *     @type int $jstype
     *           The jstype option determines the JavaScript type used for values of the
     *           field.  The option is permitted only for 64 bit integral and fixed types
     *           (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
     *           is represented as JavaScript string, which avoids loss of precision that
     *           can happen when a large value is converted to a floating point JavaScript.
     *           Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
     *           use the JavaScript "number" type.  The behavior of the default option
     *           JS_NORMAL is implementation dependent.
     *           This option is an enum to permit additional types to be added, e.g.
     *           goog.math.Integer.
     *     @type bool $lazy
     *           Should this field be parsed lazily?  Lazy applies only to message-type
     *           fields.  It means that when the outer message is initially parsed, the
     *           inner message's contents will not be parsed but instead stored in encoded
     *           form.  The inner message will actually be parsed when it is first accessed.
     *           This is only a hint.  Implementations are free to choose whether to use
     *           eager or lazy parsing regardless of the value of this option.  However,
     *           setting this option true suggests that the protocol author believes that
     *           using lazy parsing on this field is worth the additional bookkeeping
     *           overhead typically needed to implement it.
     *           This option does not affect the public interface of any generated code;
     *           all method signatures remain the same.  Furthermore, thread-safety of the
     *           interface is not affected by this option; const methods remain safe to
     *           call from multiple threads concurrently, while non-const methods continue
     *           to require exclusive access.
     *           Note that lazy message fields are still eagerly verified to check
     *           ill-formed wireformat or missing required fields. Calling IsInitialized()
     *           on the outer message would fail if the inner message has missing required
     *           fields. Failed verification would result in parsing failure (except when
     *           uninitialized messages are acceptable).
     *     @type bool $unverified_lazy
     *           unverified_lazy does no correctness checks on the byte stream. This should
     *           only be used where lazy with verification is prohibitive for performance
     *           reasons.
     *     @type bool $deprecated
     *           Is this field deprecated?
     *           Depending on the target platform, this can emit Deprecated annotations
     *           for accessors, or it will be completely ignored; in the very least, this
     *           is a formalization for deprecating fields.
     *     @type bool $weak
     *           DEPRECATED. DO NOT USE!
     *           For Google-internal migration only. Do not use.
     *     @type bool $debug_redact
     *           Indicate that the field value should not be printed out when using debug
     *           formats, e.g. when the field contains sensitive credentials.
     *     @type int $retention
     *     @type int[] $targets
     *     @type \Google\Protobuf\Internal\FieldOptions\EditionDefault[] $edition_defaults
     *     @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\FieldOptions\FeatureSupport $feature_support
     *     @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);
    }

    /**
     * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead.
     * The ctype option instructs the C++ code generator to use a different
     * representation of the field than it normally would.  See the specific
     * options below.  This option is only implemented to support use of
     * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of
     * type "bytes" in the open source release.
     * TODO: make ctype actually deprecated.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
     * @return int one of the values in {@see \Google\Protobuf\Internal\FieldOptions\CType}
     */
    public function getCtype()
    {
        return isset($this->ctype) ? $this->ctype : 0;
    }

    public function hasCtype()
    {
        return isset($this->ctype);
    }

    public function clearCtype()
    {
        unset($this->ctype);
    }

    /**
     * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead.
     * The ctype option instructs the C++ code generator to use a different
     * representation of the field than it normally would.  See the specific
     * options below.  This option is only implemented to support use of
     * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of
     * type "bytes" in the open source release.
     * TODO: make ctype actually deprecated.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];</code>
     * @param int $var one of the values in {@see \Google\Protobuf\Internal\FieldOptions\CType}
     * @return $this
     */
    public function setCtype(int $var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\CType::class);
        $this->ctype = $var;

        return $this;
    }

    /**
     * The packed option can be enabled for repeated primitive fields to enable
     * a more efficient representation on the wire. Rather than repeatedly
     * writing the tag and type for each element, the entire array is encoded as
     * a single length-delimited blob. In proto3, only explicit setting it to
     * false will avoid using packed encoding.  This option is prohibited in
     * Editions, but the `repeated_field_encoding` feature can be used to control
     * the behavior.
     *
     * Generated from protobuf field <code>optional bool packed = 2;</code>
     * @return bool
     */
    public function getPacked()
    {
        return isset($this->packed) ? $this->packed : false;
    }

    public function hasPacked()
    {
        return isset($this->packed);
    }

    public function clearPacked()
    {
        unset($this->packed);
    }

    /**
     * The packed option can be enabled for repeated primitive fields to enable
     * a more efficient representation on the wire. Rather than repeatedly
     * writing the tag and type for each element, the entire array is encoded as
     * a single length-delimited blob. In proto3, only explicit setting it to
     * false will avoid using packed encoding.  This option is prohibited in
     * Editions, but the `repeated_field_encoding` feature can be used to control
     * the behavior.
     *
     * Generated from protobuf field <code>optional bool packed = 2;</code>
     * @param bool $var
     * @return $this
     */
    public function setPacked(bool $var)
    {
        $this->packed = $var;

        return $this;
    }

    /**
     * The jstype option determines the JavaScript type used for values of the
     * field.  The option is permitted only for 64 bit integral and fixed types
     * (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
     * is represented as JavaScript string, which avoids loss of precision that
     * can happen when a large value is converted to a floating point JavaScript.
     * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
     * use the JavaScript "number" type.  The behavior of the default option
     * JS_NORMAL is implementation dependent.
     * This option is an enum to permit additional types to be added, e.g.
     * goog.math.Integer.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
     * @return int one of the values in {@see \Google\Protobuf\Internal\FieldOptions\JSType}
     */
    public function getJstype()
    {
        return isset($this->jstype) ? $this->jstype : 0;
    }

    public function hasJstype()
    {
        return isset($this->jstype);
    }

    public function clearJstype()
    {
        unset($this->jstype);
    }

    /**
     * The jstype option determines the JavaScript type used for values of the
     * field.  The option is permitted only for 64 bit integral and fixed types
     * (int64, uint64, sint64, fixed64, sfixed64).  A field with jstype JS_STRING
     * is represented as JavaScript string, which avoids loss of precision that
     * can happen when a large value is converted to a floating point JavaScript.
     * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to
     * use the JavaScript "number" type.  The behavior of the default option
     * JS_NORMAL is implementation dependent.
     * This option is an enum to permit additional types to be added, e.g.
     * goog.math.Integer.
     *
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL];</code>
     * @param int $var one of the values in {@see \Google\Protobuf\Internal\FieldOptions\JSType}
     * @return $this
     */
    public function setJstype(int $var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\JSType::class);
        $this->jstype = $var;

        return $this;
    }

    /**
     * Should this field be parsed lazily?  Lazy applies only to message-type
     * fields.  It means that when the outer message is initially parsed, the
     * inner message's contents will not be parsed but instead stored in encoded
     * form.  The inner message will actually be parsed when it is first accessed.
     * This is only a hint.  Implementations are free to choose whether to use
     * eager or lazy parsing regardless of the value of this option.  However,
     * setting this option true suggests that the protocol author believes that
     * using lazy parsing on this field is worth the additional bookkeeping
     * overhead typically needed to implement it.
     * This option does not affect the public interface of any generated code;
     * all method signatures remain the same.  Furthermore, thread-safety of the
     * interface is not affected by this option; const methods remain safe to
     * call from multiple threads concurrently, while non-const methods continue
     * to require exclusive access.
     * Note that lazy message fields are still eagerly verified to check
     * ill-formed wireformat or missing required fields. Calling IsInitialized()
     * on the outer message would fail if the inner message has missing required
     * fields. Failed verification would result in parsing failure (except when
     * uninitialized messages are acceptable).
     *
     * Generated from protobuf field <code>optional bool lazy = 5 [default = false];</code>
     * @return bool
     */
    public function getLazy()
    {
        return isset($this->lazy) ? $this->lazy : false;
    }

    public function hasLazy()
    {
        return isset($this->lazy);
    }

    public function clearLazy()
    {
        unset($this->lazy);
    }

    /**
     * Should this field be parsed lazily?  Lazy applies only to message-type
     * fields.  It means that when the outer message is initially parsed, the
     * inner message's contents will not be parsed but instead stored in encoded
     * form.  The inner message will actually be parsed when it is first accessed.
     * This is only a hint.  Implementations are free to choose whether to use
     * eager or lazy parsing regardless of the value of this option.  However,
     * setting this option true suggests that the protocol author believes that
     * using lazy parsing on this field is worth the additional bookkeeping
     * overhead typically needed to implement it.
     * This option does not affect the public interface of any generated code;
     * all method signatures remain the same.  Furthermore, thread-safety of the
     * interface is not affected by this option; const methods remain safe to
     * call from multiple threads concurrently, while non-const methods continue
     * to require exclusive access.
     * Note that lazy message fields are still eagerly verified to check
     * ill-formed wireformat or missing required fields. Calling IsInitialized()
     * on the outer message would fail if the inner message has missing required
     * fields. Failed verification would result in parsing failure (except when
     * uninitialized messages are acceptable).
     *
     * Generated from protobuf field <code>optional bool lazy = 5 [default = false];</code>
     * @param bool $var
     * @return $this
     */
    public function setLazy(bool $var)
    {
        $this->lazy = $var;

        return $this;
    }

    /**
     * unverified_lazy does no correctness checks on the byte stream. This should
     * only be used where lazy with verification is prohibitive for performance
     * reasons.
     *
     * Generated from protobuf field <code>optional bool unverified_lazy = 15 [default = false];</code>
     * @return bool
     */
    public function getUnverifiedLazy()
    {
        return isset($this->unverified_lazy) ? $this->unverified_lazy : false;
    }

    public function hasUnverifiedLazy()
    {
        return isset($this->unverified_lazy);
    }

    public function clearUnverifiedLazy()
    {
        unset($this->unverified_lazy);
    }

    /**
     * unverified_lazy does no correctness checks on the byte stream. This should
     * only be used where lazy with verification is prohibitive for performance
     * reasons.
     *
     * Generated from protobuf field <code>optional bool unverified_lazy = 15 [default = false];</code>
     * @param bool $var
     * @return $this
     */
    public function setUnverifiedLazy(bool $var)
    {
        $this->unverified_lazy = $var;

        return $this;
    }

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

        return $this;
    }

    /**
     * DEPRECATED. DO NOT USE!
     * For Google-internal migration only. Do not use.
     *
     * Generated from protobuf field <code>optional bool weak = 10 [default = false, deprecated = true];</code>
     * @return bool
     * @deprecated
     */
    public function getWeak()
    {
        if (isset($this->weak)) {
            @trigger_error('weak is deprecated.', E_USER_DEPRECATED);
        }
        return isset($this->weak) ? $this->weak : false;
    }

    public function hasWeak()
    {
        if (isset($this->weak)) {
            @trigger_error('weak is deprecated.', E_USER_DEPRECATED);
        }
        return isset($this->weak);
    }

    public function clearWeak()
    {
        @trigger_error('weak is deprecated.', E_USER_DEPRECATED);
        unset($this->weak);
    }

    /**
     * DEPRECATED. DO NOT USE!
     * For Google-internal migration only. Do not use.
     *
     * Generated from protobuf field <code>optional bool weak = 10 [default = false, deprecated = true];</code>
     * @param bool $var
     * @return $this
     * @deprecated
     */
    public function setWeak(bool $var)
    {
        @trigger_error('weak is deprecated.', E_USER_DEPRECATED);
        $this->weak = $var;

        return $this;
    }

    /**
     * Indicate that the field value should not be printed out when using debug
     * formats, e.g. when the field contains sensitive credentials.
     *
     * Generated from protobuf field <code>optional bool debug_redact = 16 [default = false];</code>
     * @return bool
     */
    public function getDebugRedact()
    {
        return isset($this->debug_redact) ? $this->debug_redact : false;
    }

    public function hasDebugRedact()
    {
        return isset($this->debug_redact);
    }

    public function clearDebugRedact()
    {
        unset($this->debug_redact);
    }

    /**
     * Indicate that the field value should not be printed out when using debug
     * formats, e.g. when the field contains sensitive credentials.
     *
     * Generated from protobuf field <code>optional bool debug_redact = 16 [default = false];</code>
     * @param bool $var
     * @return $this
     */
    public function setDebugRedact(bool $var)
    {
        $this->debug_redact = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.OptionRetention retention = 17;</code>
     * @return int one of the values in {@see \Google\Protobuf\Internal\FieldOptions\OptionRetention}
     */
    public function getRetention()
    {
        return isset($this->retention) ? $this->retention : 0;
    }

    public function hasRetention()
    {
        return isset($this->retention);
    }

    public function clearRetention()
    {
        unset($this->retention);
    }

    /**
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.OptionRetention retention = 17;</code>
     * @param int $var one of the values in {@see \Google\Protobuf\Internal\FieldOptions\OptionRetention}
     * @return $this
     */
    public function setRetention(int $var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\OptionRetention::class);
        $this->retention = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19;</code>
     * @return RepeatedField<int> one of the values in {@see \Google\Protobuf\Internal\FieldOptions\OptionTargetType}
     */
    public function getTargets()
    {
        return $this->targets;
    }

    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19;</code>
     * @param int[] $var one of the values in {@see \Google\Protobuf\Internal\FieldOptions\OptionTargetType}
     * @return $this
     */
    public function setTargets(array|RepeatedField $var)
    {
        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::ENUM, \Google\Protobuf\Internal\FieldOptions\OptionTargetType::class);
        $this->targets = $arr;

        return $this;
    }

    /**
     * Generated from protobuf field <code>repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20;</code>
     * @return RepeatedField<\Google\Protobuf\Internal\FieldOptions\EditionDefault>
     */
    public function getEditionDefaults()
    {
        return $this->edition_defaults;
    }

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

        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 = 21;</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 = 21;</code>
     * @param \Google\Protobuf\Internal\FeatureSet $var
     * @return $this
     */
    public function setFeatures(\Google\Protobuf\Internal\FeatureSet|null $var)
    {
        $this->features = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22;</code>
     * @return \Google\Protobuf\Internal\FieldOptions\FeatureSupport|null
     */
    public function getFeatureSupport()
    {
        return $this->feature_support;
    }

    public function hasFeatureSupport()
    {
        return isset($this->feature_support);
    }

    public function clearFeatureSupport()
    {
        unset($this->feature_support);
    }

    /**
     * Generated from protobuf field <code>optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22;</code>
     * @param \Google\Protobuf\Internal\FieldOptions\FeatureSupport $var
     * @return $this
     */
    public function setFeatureSupport(\Google\Protobuf\Internal\FieldOptions\FeatureSupport|null $var)
    {
        $this->feature_support = $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;
    }

}

