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

namespace Google\Protobuf;

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

/**
 * Enum type definition.
 * New usages of this message as an alternative to EnumDescriptorProto are
 * strongly discouraged. This message does not reliability preserve all
 * information necessary to model the schema and preserve semantics. Instead
 * make use of FileDescriptorSet which preserves the necessary information.
 *
 * Generated from protobuf message <code>google.protobuf.Enum</code>
 */
class Enum extends \Google\Protobuf\Internal\Message
{
    /**
     * Enum type name.
     *
     * Generated from protobuf field <code>string name = 1;</code>
     */
    protected $name = '';
    /**
     * Enum value definitions.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
     */
    private $enumvalue;
    /**
     * Protocol buffer options.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.Option options = 3;</code>
     */
    private $options;
    /**
     * The source context.
     *
     * Generated from protobuf field <code>.google.protobuf.SourceContext source_context = 4;</code>
     */
    protected $source_context = null;
    /**
     * The source syntax.
     *
     * Generated from protobuf field <code>.google.protobuf.Syntax syntax = 5;</code>
     */
    protected $syntax = 0;
    /**
     * The source edition string, only valid when syntax is SYNTAX_EDITIONS.
     *
     * Generated from protobuf field <code>string edition = 6;</code>
     */
    protected $edition = '';

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type string $name
     *           Enum type name.
     *     @type \Google\Protobuf\EnumValue[] $enumvalue
     *           Enum value definitions.
     *     @type \Google\Protobuf\Option[] $options
     *           Protocol buffer options.
     *     @type \Google\Protobuf\SourceContext $source_context
     *           The source context.
     *     @type int $syntax
     *           The source syntax.
     *     @type string $edition
     *           The source edition string, only valid when syntax is SYNTAX_EDITIONS.
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\Google\Protobuf\Type::initOnce();
        parent::__construct($data);
    }

    /**
     * Enum type name.
     *
     * Generated from protobuf field <code>string name = 1;</code>
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Enum type name.
     *
     * Generated from protobuf field <code>string name = 1;</code>
     * @param string $var
     * @return $this
     */
    public function setName(string $var)
    {
        GPBUtil::checkString($var, true);
        $this->name = $var;

        return $this;
    }

    /**
     * Enum value definitions.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
     * @return RepeatedField<\Google\Protobuf\EnumValue>
     */
    public function getEnumvalue()
    {
        return $this->enumvalue;
    }

    /**
     * Enum value definitions.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.EnumValue enumvalue = 2;</code>
     * @param \Google\Protobuf\EnumValue[] $var
     * @return $this
     */
    public function setEnumvalue(array|RepeatedField $var)
    {
        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\EnumValue::class);
        $this->enumvalue = $arr;

        return $this;
    }

    /**
     * Protocol buffer options.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.Option options = 3;</code>
     * @return RepeatedField<\Google\Protobuf\Option>
     */
    public function getOptions()
    {
        return $this->options;
    }

    /**
     * Protocol buffer options.
     *
     * Generated from protobuf field <code>repeated .google.protobuf.Option options = 3;</code>
     * @param \Google\Protobuf\Option[] $var
     * @return $this
     */
    public function setOptions(array|RepeatedField $var)
    {
        $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Option::class);
        $this->options = $arr;

        return $this;
    }

    /**
     * The source context.
     *
     * Generated from protobuf field <code>.google.protobuf.SourceContext source_context = 4;</code>
     * @return \Google\Protobuf\SourceContext|null
     */
    public function getSourceContext()
    {
        return $this->source_context;
    }

    public function hasSourceContext()
    {
        return isset($this->source_context);
    }

    public function clearSourceContext()
    {
        unset($this->source_context);
    }

    /**
     * The source context.
     *
     * Generated from protobuf field <code>.google.protobuf.SourceContext source_context = 4;</code>
     * @param \Google\Protobuf\SourceContext $var
     * @return $this
     */
    public function setSourceContext(\Google\Protobuf\SourceContext|null $var)
    {
        $this->source_context = $var;

        return $this;
    }

    /**
     * The source syntax.
     *
     * Generated from protobuf field <code>.google.protobuf.Syntax syntax = 5;</code>
     * @return int one of the values in {@see \Google\Protobuf\Syntax}
     */
    public function getSyntax()
    {
        return $this->syntax;
    }

    /**
     * The source syntax.
     *
     * Generated from protobuf field <code>.google.protobuf.Syntax syntax = 5;</code>
     * @param int $var one of the values in {@see \Google\Protobuf\Syntax}
     * @return $this
     */
    public function setSyntax(int $var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Syntax::class);
        $this->syntax = $var;

        return $this;
    }

    /**
     * The source edition string, only valid when syntax is SYNTAX_EDITIONS.
     *
     * Generated from protobuf field <code>string edition = 6;</code>
     * @return string
     */
    public function getEdition()
    {
        return $this->edition;
    }

    /**
     * The source edition string, only valid when syntax is SYNTAX_EDITIONS.
     *
     * Generated from protobuf field <code>string edition = 6;</code>
     * @param string $var
     * @return $this
     */
    public function setEdition(string $var)
    {
        GPBUtil::checkString($var, true);
        $this->edition = $var;

        return $this;
    }

}

