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

namespace Google\Protobuf;

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

/**
 * `Value` represents a dynamically typed value which can be either
 * null, a number, a string, a boolean, a recursive struct value, or a
 * list of values. A producer of value is expected to set one of these
 * variants. Absence of any variant indicates an error.
 * The JSON representation for `Value` is JSON value.
 *
 * Generated from protobuf message <code>google.protobuf.Value</code>
 */
class Value extends \Google\Protobuf\Internal\Message
{
    protected $kind;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type int $null_value
     *           Represents a null value.
     *     @type float $number_value
     *           Represents a double value.
     *     @type string $string_value
     *           Represents a string value.
     *     @type bool $bool_value
     *           Represents a boolean value.
     *     @type \Google\Protobuf\Struct $struct_value
     *           Represents a structured value.
     *     @type \Google\Protobuf\ListValue $list_value
     *           Represents a repeated `Value`.
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\Google\Protobuf\Struct::initOnce();
        parent::__construct($data);
    }

    /**
     * Represents a null value.
     *
     * Generated from protobuf field <code>.google.protobuf.NullValue null_value = 1;</code>
     * @return int
     */
    public function getNullValue()
    {
        return $this->readOneof(1);
    }

    public function hasNullValue()
    {
        return $this->hasOneof(1);
    }

    /**
     * Represents a null value.
     *
     * Generated from protobuf field <code>.google.protobuf.NullValue null_value = 1;</code>
     * @param int $var
     * @return $this
     */
    public function setNullValue($var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\NullValue::class);
        $this->writeOneof(1, $var);

        return $this;
    }

    /**
     * Represents a double value.
     *
     * Generated from protobuf field <code>double number_value = 2;</code>
     * @return float
     */
    public function getNumberValue()
    {
        return $this->readOneof(2);
    }

    public function hasNumberValue()
    {
        return $this->hasOneof(2);
    }

    /**
     * Represents a double value.
     *
     * Generated from protobuf field <code>double number_value = 2;</code>
     * @param float $var
     * @return $this
     */
    public function setNumberValue($var)
    {
        GPBUtil::checkDouble($var);
        $this->writeOneof(2, $var);

        return $this;
    }

    /**
     * Represents a string value.
     *
     * Generated from protobuf field <code>string string_value = 3;</code>
     * @return string
     */
    public function getStringValue()
    {
        return $this->readOneof(3);
    }

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

    /**
     * Represents a string value.
     *
     * Generated from protobuf field <code>string string_value = 3;</code>
     * @param string $var
     * @return $this
     */
    public function setStringValue($var)
    {
        GPBUtil::checkString($var, True);
        $this->writeOneof(3, $var);

        return $this;
    }

    /**
     * Represents a boolean value.
     *
     * Generated from protobuf field <code>bool bool_value = 4;</code>
     * @return bool
     */
    public function getBoolValue()
    {
        return $this->readOneof(4);
    }

    public function hasBoolValue()
    {
        return $this->hasOneof(4);
    }

    /**
     * Represents a boolean value.
     *
     * Generated from protobuf field <code>bool bool_value = 4;</code>
     * @param bool $var
     * @return $this
     */
    public function setBoolValue($var)
    {
        GPBUtil::checkBool($var);
        $this->writeOneof(4, $var);

        return $this;
    }

    /**
     * Represents a structured value.
     *
     * Generated from protobuf field <code>.google.protobuf.Struct struct_value = 5;</code>
     * @return \Google\Protobuf\Struct|null
     */
    public function getStructValue()
    {
        return $this->readOneof(5);
    }

    public function hasStructValue()
    {
        return $this->hasOneof(5);
    }

    /**
     * Represents a structured value.
     *
     * Generated from protobuf field <code>.google.protobuf.Struct struct_value = 5;</code>
     * @param \Google\Protobuf\Struct $var
     * @return $this
     */
    public function setStructValue($var)
    {
        GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
        $this->writeOneof(5, $var);

        return $this;
    }

    /**
     * Represents a repeated `Value`.
     *
     * Generated from protobuf field <code>.google.protobuf.ListValue list_value = 6;</code>
     * @return \Google\Protobuf\ListValue|null
     */
    public function getListValue()
    {
        return $this->readOneof(6);
    }

    public function hasListValue()
    {
        return $this->hasOneof(6);
    }

    /**
     * Represents a repeated `Value`.
     *
     * Generated from protobuf field <code>.google.protobuf.ListValue list_value = 6;</code>
     * @param \Google\Protobuf\ListValue $var
     * @return $this
     */
    public function setListValue($var)
    {
        GPBUtil::checkMessage($var, \Google\Protobuf\ListValue::class);
        $this->writeOneof(6, $var);

        return $this;
    }

    /**
     * @return string
     */
    public function getKind()
    {
        return $this->whichOneof("kind");
    }

}

