<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: google/protobuf/descriptor.proto

namespace Google\Protobuf\Internal;

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

use Google\Protobuf\Internal\GPBUtil;

/**
 * <pre>
 * A message representing a option the parser does not recognize. This only
 * appears in options protos created by the compiler::Parser class.
 * DescriptorPool resolves these when building Descriptor objects. Therefore,
 * options protos in descriptor objects (e.g. returned by Descriptor::options(),
 * or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
 * in them.
 * </pre>
 *
 * Protobuf type <code>google.protobuf.UninterpretedOption</code>
 */
class UninterpretedOption extends \Google\Protobuf\Internal\Message
{
    /**
     * <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
     */
    private $name;
    private $has_name = false;
    /**
     * <pre>
     * The value of the uninterpreted option, in whatever type the tokenizer
     * identified it as during parsing. Exactly one of these should be set.
     * </pre>
     *
     * <code>optional string identifier_value = 3;</code>
     */
    private $identifier_value = '';
    private $has_identifier_value = false;
    /**
     * <code>optional uint64 positive_int_value = 4;</code>
     */
    private $positive_int_value = 0;
    private $has_positive_int_value = false;
    /**
     * <code>optional int64 negative_int_value = 5;</code>
     */
    private $negative_int_value = 0;
    private $has_negative_int_value = false;
    /**
     * <code>optional double double_value = 6;</code>
     */
    private $double_value = 0.0;
    private $has_double_value = false;
    /**
     * <code>optional bytes string_value = 7;</code>
     */
    private $string_value = '';
    private $has_string_value = false;
    /**
     * <code>optional string aggregate_value = 8;</code>
     */
    private $aggregate_value = '';
    private $has_aggregate_value = false;

    public function __construct() {
        \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
        parent::__construct();
    }

    /**
     * <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
     */
    public function setName(&$var)
    {
        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption_NamePart::class);
        $this->name = $var;
        $this->has_name = true;
    }

    public function hasName()
    {
        return $this->has_name;
    }

    /**
     * <pre>
     * The value of the uninterpreted option, in whatever type the tokenizer
     * identified it as during parsing. Exactly one of these should be set.
     * </pre>
     *
     * <code>optional string identifier_value = 3;</code>
     */
    public function getIdentifierValue()
    {
        return $this->identifier_value;
    }

    /**
     * <pre>
     * The value of the uninterpreted option, in whatever type the tokenizer
     * identified it as during parsing. Exactly one of these should be set.
     * </pre>
     *
     * <code>optional string identifier_value = 3;</code>
     */
    public function setIdentifierValue($var)
    {
        GPBUtil::checkString($var, True);
        $this->identifier_value = $var;
        $this->has_identifier_value = true;
    }

    public function hasIdentifierValue()
    {
        return $this->has_identifier_value;
    }

    /**
     * <code>optional uint64 positive_int_value = 4;</code>
     */
    public function getPositiveIntValue()
    {
        return $this->positive_int_value;
    }

    /**
     * <code>optional uint64 positive_int_value = 4;</code>
     */
    public function setPositiveIntValue($var)
    {
        GPBUtil::checkUint64($var);
        $this->positive_int_value = $var;
        $this->has_positive_int_value = true;
    }

    public function hasPositiveIntValue()
    {
        return $this->has_positive_int_value;
    }

    /**
     * <code>optional int64 negative_int_value = 5;</code>
     */
    public function getNegativeIntValue()
    {
        return $this->negative_int_value;
    }

    /**
     * <code>optional int64 negative_int_value = 5;</code>
     */
    public function setNegativeIntValue($var)
    {
        GPBUtil::checkInt64($var);
        $this->negative_int_value = $var;
        $this->has_negative_int_value = true;
    }

    public function hasNegativeIntValue()
    {
        return $this->has_negative_int_value;
    }

    /**
     * <code>optional double double_value = 6;</code>
     */
    public function getDoubleValue()
    {
        return $this->double_value;
    }

    /**
     * <code>optional double double_value = 6;</code>
     */
    public function setDoubleValue($var)
    {
        GPBUtil::checkDouble($var);
        $this->double_value = $var;
        $this->has_double_value = true;
    }

    public function hasDoubleValue()
    {
        return $this->has_double_value;
    }

    /**
     * <code>optional bytes string_value = 7;</code>
     */
    public function getStringValue()
    {
        return $this->string_value;
    }

    /**
     * <code>optional bytes string_value = 7;</code>
     */
    public function setStringValue($var)
    {
        GPBUtil::checkString($var, False);
        $this->string_value = $var;
        $this->has_string_value = true;
    }

    public function hasStringValue()
    {
        return $this->has_string_value;
    }

    /**
     * <code>optional string aggregate_value = 8;</code>
     */
    public function getAggregateValue()
    {
        return $this->aggregate_value;
    }

    /**
     * <code>optional string aggregate_value = 8;</code>
     */
    public function setAggregateValue($var)
    {
        GPBUtil::checkString($var, True);
        $this->aggregate_value = $var;
        $this->has_aggregate_value = true;
    }

    public function hasAggregateValue()
    {
        return $this->has_aggregate_value;
    }

}

