<?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.Agency</code>
 */
class Agency extends \Google\Protobuf\Internal\Message
{
    /**
     * The agency_id field is an ID that uniquely identifies a transit agency.
     *
     * Generated from protobuf field <code>string agency_id = 1;</code>
     */
    protected $agency_id = '';
    /**
     * The agency_name field contains the full name of the transit agency.
     *
     * Generated from protobuf field <code>string agency_name = 2;</code>
     */
    protected $agency_name = '';
    /**
     * The agency_url field contains the URL of the transit agency.
     *
     * Generated from protobuf field <code>string agency_url = 3;</code>
     */
    protected $agency_url = '';
    /**
     * The agency_timezone field contains the timezone where the transit agency is located.
     *
     * Generated from protobuf field <code>string agency_timezone = 4;</code>
     */
    protected $agency_timezone = '';
    /**
     * The agency_lang field contains a two-letter ISO 639-1 code for the primary language used by this transit agency.
     *
     * Generated from protobuf field <code>string agency_lang = 5;</code>
     */
    protected $agency_lang = '';
    /**
     * The agency_phone field contains a single voice telephone number for the specified agency.
     *
     * Generated from protobuf field <code>string agency_phone = 6;</code>
     */
    protected $agency_phone = '';
    /**
     * The agency_fare_url specifies the URL of a web page that allows a rider to purchase tickets or other fare instruments for that agency online.
     *
     * Generated from protobuf field <code>string agency_fare_url = 7;</code>
     */
    protected $agency_fare_url = '';
    /**
     * 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 $agency_id
     *           The agency_id field is an ID that uniquely identifies a transit agency.
     *     @type string $agency_name
     *           The agency_name field contains the full name of the transit agency.
     *     @type string $agency_url
     *           The agency_url field contains the URL of the transit agency.
     *     @type string $agency_timezone
     *           The agency_timezone field contains the timezone where the transit agency is located.
     *     @type string $agency_lang
     *           The agency_lang field contains a two-letter ISO 639-1 code for the primary language used by this transit agency.
     *     @type string $agency_phone
     *           The agency_phone field contains a single voice telephone number for the specified agency.
     *     @type string $agency_fare_url
     *           The agency_fare_url specifies the URL of a web page that allows a rider to purchase tickets or other fare instruments for that agency online.
     *     @type \Google\Protobuf\Any $extension
     *           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);
    }

    /**
     * The agency_id field is an ID that uniquely identifies a transit agency.
     *
     * Generated from protobuf field <code>string agency_id = 1;</code>
     * @return string
     */
    public function getAgencyId()
    {
        return $this->agency_id;
    }

    /**
     * The agency_id field is an ID that uniquely identifies a transit agency.
     *
     * Generated from protobuf field <code>string agency_id = 1;</code>
     * @param string $var
     * @return $this
     */
    public function setAgencyId($var)
    {
        GPBUtil::checkString($var, True);
        $this->agency_id = $var;

        return $this;
    }

    /**
     * The agency_name field contains the full name of the transit agency.
     *
     * Generated from protobuf field <code>string agency_name = 2;</code>
     * @return string
     */
    public function getAgencyName()
    {
        return $this->agency_name;
    }

    /**
     * The agency_name field contains the full name of the transit agency.
     *
     * Generated from protobuf field <code>string agency_name = 2;</code>
     * @param string $var
     * @return $this
     */
    public function setAgencyName($var)
    {
        GPBUtil::checkString($var, True);
        $this->agency_name = $var;

        return $this;
    }

    /**
     * The agency_url field contains the URL of the transit agency.
     *
     * Generated from protobuf field <code>string agency_url = 3;</code>
     * @return string
     */
    public function getAgencyUrl()
    {
        return $this->agency_url;
    }

    /**
     * The agency_url field contains the URL of the transit agency.
     *
     * Generated from protobuf field <code>string agency_url = 3;</code>
     * @param string $var
     * @return $this
     */
    public function setAgencyUrl($var)
    {
        GPBUtil::checkString($var, True);
        $this->agency_url = $var;

        return $this;
    }

    /**
     * The agency_timezone field contains the timezone where the transit agency is located.
     *
     * Generated from protobuf field <code>string agency_timezone = 4;</code>
     * @return string
     */
    public function getAgencyTimezone()
    {
        return $this->agency_timezone;
    }

    /**
     * The agency_timezone field contains the timezone where the transit agency is located.
     *
     * Generated from protobuf field <code>string agency_timezone = 4;</code>
     * @param string $var
     * @return $this
     */
    public function setAgencyTimezone($var)
    {
        GPBUtil::checkString($var, True);
        $this->agency_timezone = $var;

        return $this;
    }

    /**
     * The agency_lang field contains a two-letter ISO 639-1 code for the primary language used by this transit agency.
     *
     * Generated from protobuf field <code>string agency_lang = 5;</code>
     * @return string
     */
    public function getAgencyLang()
    {
        return $this->agency_lang;
    }

    /**
     * The agency_lang field contains a two-letter ISO 639-1 code for the primary language used by this transit agency.
     *
     * Generated from protobuf field <code>string agency_lang = 5;</code>
     * @param string $var
     * @return $this
     */
    public function setAgencyLang($var)
    {
        GPBUtil::checkString($var, True);
        $this->agency_lang = $var;

        return $this;
    }

    /**
     * The agency_phone field contains a single voice telephone number for the specified agency.
     *
     * Generated from protobuf field <code>string agency_phone = 6;</code>
     * @return string
     */
    public function getAgencyPhone()
    {
        return $this->agency_phone;
    }

    /**
     * The agency_phone field contains a single voice telephone number for the specified agency.
     *
     * Generated from protobuf field <code>string agency_phone = 6;</code>
     * @param string $var
     * @return $this
     */
    public function setAgencyPhone($var)
    {
        GPBUtil::checkString($var, True);
        $this->agency_phone = $var;

        return $this;
    }

    /**
     * The agency_fare_url specifies the URL of a web page that allows a rider to purchase tickets or other fare instruments for that agency online.
     *
     * Generated from protobuf field <code>string agency_fare_url = 7;</code>
     * @return string
     */
    public function getAgencyFareUrl()
    {
        return $this->agency_fare_url;
    }

    /**
     * The agency_fare_url specifies the URL of a web page that allows a rider to purchase tickets or other fare instruments for that agency online.
     *
     * Generated from protobuf field <code>string agency_fare_url = 7;</code>
     * @param string $var
     * @return $this
     */
    public function setAgencyFareUrl($var)
    {
        GPBUtil::checkString($var, True);
        $this->agency_fare_url = $var;

        return $this;
    }

    /**
     * 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;
    }

    /**
     * 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;
    }

}

