<?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;

/**
 * A definition (or update) of an entity in the transit feed.
 *
 * Generated from protobuf message <code>gtfs.FeedEntity</code>
 */
class FeedEntity extends \Google\Protobuf\Internal\Message
{
    /**
     * The ids are used only to provide incrementality support. The id should be
     * unique within a FeedMessage. Consequent FeedMessages may contain
     * FeedEntities with the same id. In case of a DIFFERENTIAL update the new
     * FeedEntity with some id will replace the old FeedEntity with the same id
     * (or delete it - see is_deleted below).
     * The actual GTFS entities (e.g. stations, routes, trips) referenced by the
     * feed must be specified by explicit selectors (see EntitySelector below for
     * more info).
     *
     * Generated from protobuf field <code>string id = 1;</code>
     */
    protected $id = '';
    /**
     * Whether this entity is to be deleted. Relevant only for incremental
     * fetches.
     *
     * Generated from protobuf field <code>bool is_deleted = 2;</code>
     */
    protected $is_deleted = false;
    /**
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     */
    protected $extension = null;
    protected $element;

    /**
     * Constructor.
     *
     * @param array $data {
     *     Optional. Data for populating the Message object.
     *
     *     @type string $id
     *           The ids are used only to provide incrementality support. The id should be
     *           unique within a FeedMessage. Consequent FeedMessages may contain
     *           FeedEntities with the same id. In case of a DIFFERENTIAL update the new
     *           FeedEntity with some id will replace the old FeedEntity with the same id
     *           (or delete it - see is_deleted below).
     *           The actual GTFS entities (e.g. stations, routes, trips) referenced by the
     *           feed must be specified by explicit selectors (see EntitySelector below for
     *           more info).
     *     @type bool $is_deleted
     *           Whether this entity is to be deleted. Relevant only for incremental
     *           fetches.
     *     @type \Gtfs\Agency $agency
     *     @type \Gtfs\Stop $stop
     *     @type \Gtfs\Route $route
     *     @type \Gtfs\Trip $trip
     *     @type \Gtfs\StopTime $stop_time
     *     @type \Gtfs\Calendar $calendar
     *     @type \Gtfs\CalendarDate $calendar_date
     *     @type \Gtfs\FareAttribute $fare_attribute
     *     @type \Gtfs\FareRule $fare_rule
     *     @type \Gtfs\Shape $shape
     *     @type \Gtfs\Frequency $frequency
     *     @type \Gtfs\Transfer $transfer
     *     @type \Google\Protobuf\Any $extension
     * }
     */
    public function __construct($data = NULL) {
        \GPBMetadata\Proto\Gtfs::initOnce();
        parent::__construct($data);
    }

    /**
     * The ids are used only to provide incrementality support. The id should be
     * unique within a FeedMessage. Consequent FeedMessages may contain
     * FeedEntities with the same id. In case of a DIFFERENTIAL update the new
     * FeedEntity with some id will replace the old FeedEntity with the same id
     * (or delete it - see is_deleted below).
     * The actual GTFS entities (e.g. stations, routes, trips) referenced by the
     * feed must be specified by explicit selectors (see EntitySelector below for
     * more info).
     *
     * Generated from protobuf field <code>string id = 1;</code>
     * @return string
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * The ids are used only to provide incrementality support. The id should be
     * unique within a FeedMessage. Consequent FeedMessages may contain
     * FeedEntities with the same id. In case of a DIFFERENTIAL update the new
     * FeedEntity with some id will replace the old FeedEntity with the same id
     * (or delete it - see is_deleted below).
     * The actual GTFS entities (e.g. stations, routes, trips) referenced by the
     * feed must be specified by explicit selectors (see EntitySelector below for
     * more info).
     *
     * Generated from protobuf field <code>string id = 1;</code>
     * @param string $var
     * @return $this
     */
    public function setId($var)
    {
        GPBUtil::checkString($var, True);
        $this->id = $var;

        return $this;
    }

    /**
     * Whether this entity is to be deleted. Relevant only for incremental
     * fetches.
     *
     * Generated from protobuf field <code>bool is_deleted = 2;</code>
     * @return bool
     */
    public function getIsDeleted()
    {
        return $this->is_deleted;
    }

    /**
     * Whether this entity is to be deleted. Relevant only for incremental
     * fetches.
     *
     * Generated from protobuf field <code>bool is_deleted = 2;</code>
     * @param bool $var
     * @return $this
     */
    public function setIsDeleted($var)
    {
        GPBUtil::checkBool($var);
        $this->is_deleted = $var;

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Agency agency = 3;</code>
     * @return \Gtfs\Agency
     */
    public function getAgency()
    {
        return $this->readOneof(3);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Agency agency = 3;</code>
     * @param \Gtfs\Agency $var
     * @return $this
     */
    public function setAgency($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Agency::class);
        $this->writeOneof(3, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Stop stop = 4;</code>
     * @return \Gtfs\Stop
     */
    public function getStop()
    {
        return $this->readOneof(4);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Stop stop = 4;</code>
     * @param \Gtfs\Stop $var
     * @return $this
     */
    public function setStop($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Stop::class);
        $this->writeOneof(4, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Route route = 5;</code>
     * @return \Gtfs\Route
     */
    public function getRoute()
    {
        return $this->readOneof(5);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Route route = 5;</code>
     * @param \Gtfs\Route $var
     * @return $this
     */
    public function setRoute($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Route::class);
        $this->writeOneof(5, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Trip trip = 6;</code>
     * @return \Gtfs\Trip
     */
    public function getTrip()
    {
        return $this->readOneof(6);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Trip trip = 6;</code>
     * @param \Gtfs\Trip $var
     * @return $this
     */
    public function setTrip($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Trip::class);
        $this->writeOneof(6, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.StopTime stop_time = 7;</code>
     * @return \Gtfs\StopTime
     */
    public function getStopTime()
    {
        return $this->readOneof(7);
    }

    /**
     * Generated from protobuf field <code>.gtfs.StopTime stop_time = 7;</code>
     * @param \Gtfs\StopTime $var
     * @return $this
     */
    public function setStopTime($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\StopTime::class);
        $this->writeOneof(7, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Calendar calendar = 8;</code>
     * @return \Gtfs\Calendar
     */
    public function getCalendar()
    {
        return $this->readOneof(8);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Calendar calendar = 8;</code>
     * @param \Gtfs\Calendar $var
     * @return $this
     */
    public function setCalendar($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Calendar::class);
        $this->writeOneof(8, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.CalendarDate calendar_date = 9;</code>
     * @return \Gtfs\CalendarDate
     */
    public function getCalendarDate()
    {
        return $this->readOneof(9);
    }

    /**
     * Generated from protobuf field <code>.gtfs.CalendarDate calendar_date = 9;</code>
     * @param \Gtfs\CalendarDate $var
     * @return $this
     */
    public function setCalendarDate($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\CalendarDate::class);
        $this->writeOneof(9, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute fare_attribute = 10;</code>
     * @return \Gtfs\FareAttribute
     */
    public function getFareAttribute()
    {
        return $this->readOneof(10);
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareAttribute fare_attribute = 10;</code>
     * @param \Gtfs\FareAttribute $var
     * @return $this
     */
    public function setFareAttribute($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\FareAttribute::class);
        $this->writeOneof(10, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareRule fare_rule = 11;</code>
     * @return \Gtfs\FareRule
     */
    public function getFareRule()
    {
        return $this->readOneof(11);
    }

    /**
     * Generated from protobuf field <code>.gtfs.FareRule fare_rule = 11;</code>
     * @param \Gtfs\FareRule $var
     * @return $this
     */
    public function setFareRule($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\FareRule::class);
        $this->writeOneof(11, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Shape shape = 12;</code>
     * @return \Gtfs\Shape
     */
    public function getShape()
    {
        return $this->readOneof(12);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Shape shape = 12;</code>
     * @param \Gtfs\Shape $var
     * @return $this
     */
    public function setShape($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Shape::class);
        $this->writeOneof(12, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Frequency frequency = 13;</code>
     * @return \Gtfs\Frequency
     */
    public function getFrequency()
    {
        return $this->readOneof(13);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Frequency frequency = 13;</code>
     * @param \Gtfs\Frequency $var
     * @return $this
     */
    public function setFrequency($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Frequency::class);
        $this->writeOneof(13, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.gtfs.Transfer transfer = 14;</code>
     * @return \Gtfs\Transfer
     */
    public function getTransfer()
    {
        return $this->readOneof(14);
    }

    /**
     * Generated from protobuf field <code>.gtfs.Transfer transfer = 14;</code>
     * @param \Gtfs\Transfer $var
     * @return $this
     */
    public function setTransfer($var)
    {
        GPBUtil::checkMessage($var, \Gtfs\Transfer::class);
        $this->writeOneof(14, $var);

        return $this;
    }

    /**
     * Generated from protobuf field <code>.google.protobuf.Any extension = 2000;</code>
     * @return \Google\Protobuf\Any
     */
    public function getExtension()
    {
        return $this->extension;
    }

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

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

}

