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

namespace Gtfs;

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

/**
 * Generated from protobuf message <code>gtfs.FareAttribute</code>
 */
class FareAttribute extends \Google\Protobuf\Internal\Message
{
    /**
     * Generated from protobuf field <code>string fare_id = 1;</code>
     */
    protected $fare_id = '';
    /**
     * Generated from protobuf field <code>float price = 2;</code>
     */
    protected $price = 0.0;
    /**
     * Generated from protobuf field <code>string currency_type = 3;</code>
     */
    protected $currency_type = '';
    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute.PaymentMethod payment_method = 4;</code>
     */
    protected $payment_method = 0;
    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute.Transfers transfers = 5;</code>
     */
    protected $transfers = 0;
    /**
     * Generated from protobuf field <code>int32 transfer_duration = 6;</code>
     */
    protected $transfer_duration = 0;
    /**
     * The extensions namespace allows 3rd-party developers to extend the
     * GTFS specification in order to add and evaluate new features and
     * modifications to the spec.
     *
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     */
    protected $extension = null;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type string $fare_id
     *     @type float $price
     *     @type string $currency_type
     *     @type int $payment_method
     *     @type int $transfers
     *     @type int $transfer_duration
     *     @type \Google\Protobuf\Any $extension
     *           The extensions namespace allows 3rd-party developers to extend the
     *           GTFS specification in order to add and evaluate new features and
     *           modifications to the spec.
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\Proto\Gtfs::initOnce();
        parent::__construct($data);
    }

    /**
     * Generated from protobuf field <code>string fare_id = 1;</code>
     * @return string
     */
    public function getFareId()
    {
        return $this->fare_id;
    }

    /**
     * Generated from protobuf field <code>string fare_id = 1;</code>
     * @param string $var
     * @return $this
     */
    public function setFareId($var)
    {
        GPBUtil::checkString($var, True);
        $this->fare_id = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>float price = 2;</code>
     * @return float
     */
    public function getPrice()
    {
        return $this->price;
    }

    /**
     * Generated from protobuf field <code>float price = 2;</code>
     * @param float $var
     * @return $this
     */
    public function setPrice($var)
    {
        GPBUtil::checkFloat($var);
        $this->price = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>string currency_type = 3;</code>
     * @return string
     */
    public function getCurrencyType()
    {
        return $this->currency_type;
    }

    /**
     * Generated from protobuf field <code>string currency_type = 3;</code>
     * @param string $var
     * @return $this
     */
    public function setCurrencyType($var)
    {
        GPBUtil::checkString($var, True);
        $this->currency_type = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute.PaymentMethod payment_method = 4;</code>
     * @return int
     */
    public function getPaymentMethod()
    {
        return $this->payment_method;
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute.PaymentMethod payment_method = 4;</code>
     * @param int $var
     * @return $this
     */
    public function setPaymentMethod($var)
    {
        GPBUtil::checkEnum($var, \Gtfs\FareAttribute_PaymentMethod::class);
        $this->payment_method = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute.Transfers transfers = 5;</code>
     * @return int
     */
    public function getTransfers()
    {
        return $this->transfers;
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute.Transfers transfers = 5;</code>
     * @param int $var
     * @return $this
     */
    public function setTransfers($var)
    {
        GPBUtil::checkEnum($var, \Gtfs\FareAttribute_Transfers::class);
        $this->transfers = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>int32 transfer_duration = 6;</code>
     * @return int
     */
    public function getTransferDuration()
    {
        return $this->transfer_duration;
    }

    /**
     * Generated from protobuf field <code>int32 transfer_duration = 6;</code>
     * @param int $var
     * @return $this
     */
    public function setTransferDuration($var)
    {
        GPBUtil::checkInt32($var);
        $this->transfer_duration = $var;

        return $this;
    }

    /**
     * The extensions namespace allows 3rd-party developers to extend the
     * GTFS specification in order to add and evaluate new features and
     * modifications to the spec.
     *
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     * @return \Google\Protobuf\Any
     */
    public function getExtension()
    {
        return $this->extension;
    }

    /**
     * The extensions namespace allows 3rd-party developers to extend the
     * GTFS specification in order to add and evaluate new features and
     * modifications to the spec.
     *
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     * @param \Google\Protobuf\Any $var
     * @return $this
     */
    public function setExtension($var)
    {
        GPBUtil::checkMessage($var, \Google\Protobuf\Any::class);
        $this->extension = $var;

        return $this;
    }

}

