Merge branch 'master' of https://github.com/maxious/ACTBus-ui
Merge branch 'master' of https://github.com/maxious/ACTBus-ui

Conflicts:
include/common.inc.php

file:a/about.php -> file:b/about.php
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
include_header("About", "about") include_header("About", "about")
?> ?>
<p> <p>
Busness Time - An ACT bus timetable webapp<br /> Busness Time - An ACT bus timetable webapp<br />
Based on the maxious-canberra-transit-feed (<a Based on the maxious-canberra-transit-feed (<a
href="http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip">download</a>, href="http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip">download</a>,
last updated <?php last updated <?php
echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br /> echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br />
Source code for the <a Source code for the <a
href="https://github.com/maxious/ACTBus-data">transit href="https://github.com/maxious/ACTBus-data">transit
feed</a> and <a href="https://github.com/maxious/ACTBus-ui">this feed</a> and <a href="https://github.com/maxious/ACTBus-ui">this
site</a> available from github.<br /> site</a> available from github.<br />
Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br /> Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br />
<br /> <br />
Feedback encouraged; contact maxious@lambdacomplex.org<br /> Feedback encouraged; contact maxious@lambdacomplex.org<br />
<br /> <br />
Some icons by Joseph Wain / glyphish.com<br /> Some icons by Joseph Wain / glyphish.com<br />
Native clients also available for iPhone(<a href="http://itunes.apple.com/au/app/cbrtimetable/id444287349?mt=8">cbrTimetable by Sandor Kolotenko</a> Native clients also available for iPhone(<a href="http://itunes.apple.com/au/app/cbrtimetable/id444287349?mt=8">cbrTimetable by Sandor Kolotenko</a>
, <a href="http://itunes.apple.com/au/app/act-buses/id376634797?mt=8">ACT Buses by David Sullivan</a>) , <a href="http://itunes.apple.com/au/app/act-buses/id376634797?mt=8">ACT Buses by David Sullivan</a>)
and Android (<a href="https://market.android.com/details?id=com.action">MyBus 2.0 by Imagine Team</a>) and Android (<a href="https://market.android.com/details?id=com.action">MyBus 2.0 by Imagine Team</a>)
<br /> <br />
  GTFS-realtime API;
  Alerts and Trip Updates (but only Cancelled or Stop Skipped)
  Default format binary but can get JSON by adding ?ascii=yes
  <br />
<br /> <br />
<small>Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. <small>Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip.
Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty,
express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided
"as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. "as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability.
All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend,
change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site
without prior notice. </small> without prior notice. </small>
<?php <?php
include_footer(); include_footer();
?> ?>
   
<?php <?php
// Copyright 2009 Google Inc. All Rights Reserved. // Copyright 2009 Google Inc. All Rights Reserved.
$GA_ACCOUNT = "MO-22173039-1"; $GA_ACCOUNT = "MO-22173039-1";
$GA_PIXEL = "/lib/ga.php"; $GA_PIXEL = "/lib/ga.php";
function googleAnalyticsGetImageUrl() function googleAnalyticsGetImageUrl()
{ {
global $GA_ACCOUNT, $GA_PIXEL; global $GA_ACCOUNT, $GA_PIXEL;
//if (stristr($_SERVER['HTTP_USER_AGENT'], 'Googlebot') return ""; //if (stristr($_SERVER['HTTP_USER_AGENT'], 'Googlebot') return "";
$url = ""; $url = "";
$url.= $GA_PIXEL . "?"; $url.= $GA_PIXEL . "?";
$url.= "utmac=" . $GA_ACCOUNT; $url.= "utmac=" . $GA_ACCOUNT;
$url.= "&utmn=" . rand(0, 0x7fffffff); $url.= "&utmn=" . rand(0, 0x7fffffff);
$referer = $_SERVER["HTTP_REFERER"]; $referer = $_SERVER["HTTP_REFERER"];
$query = $_SERVER["QUERY_STRING"]; $query = $_SERVER["QUERY_STRING"];
$path = $_SERVER["REQUEST_URI"]; $path = $_SERVER["REQUEST_URI"];
if (empty($referer)) { if (empty($referer)) {
$referer = "-"; $referer = "-";
} }
$url.= "&utmr=" . urlencode($referer); $url.= "&utmr=" . urlencode($referer);
if (!empty($path)) { if (!empty($path)) {
$url.= "&utmp=" . urlencode($path); $url.= "&utmp=" . urlencode($path);
} }
$url.= "&guid=ON"; $url.= "&guid=ON";
return str_replace("&", "&amp;", $url); return str_replace("&", "&amp;", $url);
} }
function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false) function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false)
{ {
global $labsPath,$serviceAlertsEnabled; global $labsPath,$serviceAlertsEnabled;
echo ' echo '
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>' . $pageTitle . '</title> <title>' . $pageTitle . ' - Canberra Bus Timetable</title>
<meta name="google-site-verification" content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" /> <meta name="google-site-verification" content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" />
<link rel="dns-prefetch" href="//code.jquery.com"> <link rel="dns-prefetch" href="//code.jquery.com">
<link rel="dns-prefetch" href="//ajax.googleapis.com"> <link rel="dns-prefetch" href="//ajax.googleapis.com">
<link rel="stylesheet" href="' . $labsPath . 'css/jquery-ui-1.8.12.custom.css" />'; <link rel="stylesheet" href="' . $labsPath . 'css/jquery-ui-1.8.12.custom.css" />';
if (isDebugServer()) { if (isDebugServer()) {
$jqmcss = $labsPath . 'css/jquery.mobile-1.0b2.css'; $jqmcss = $labsPath . 'css/jquery.mobile-1.0b2.css';
$jqjs = $labsPath . 'js/jquery-1.6.2.min.js'; $jqjs = $labsPath . 'js/jquery-1.6.2.min.js';
$jqmjs = $labsPath . 'js/jquery.mobile-1.0b2.js'; $jqmjs = $labsPath . 'js/jquery.mobile-1.0b2.js';
} }
else { else {
$jqmcss = "//code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css"; $jqmcss = "//code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css";
$jqjs = "//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"; $jqjs = "//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js";
$jqmjs = "//code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"; $jqmjs = "//code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js";
} }
echo '<link rel="stylesheet" href="' . $jqmcss . '" /> echo '<link rel="stylesheet" href="' . $jqmcss . '" />
<script src="'.$jqjs.'"></script> <script src="'.$jqjs.'"></script>
<script>$(document).bind("mobileinit", function(){ <script>$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false; $.mobile.ajaxEnabled = false;
}); });
</script> </script>
<script src="'.$jqmjs.'"></script> <script src="'.$jqmjs.'"></script>
   
<script src="' . $labsPath . 'js/jquery.ui.core.min.js"></script> <script src="' . $labsPath . 'js/jquery.ui.core.min.js"></script>
<script src="' . $labsPath . 'js/jquery.ui.position.min.js"></script> <script src="' . $labsPath . 'js/jquery.ui.position.min.js"></script>
<script src="' . $labsPath . 'js/jquery.ui.widget.min.js"></script> <script src="' . $labsPath . 'js/jquery.ui.widget.min.js"></script>
<script src="' . $labsPath . 'js/jquery.ui.autocomplete.min.js"></script> <script src="' . $labsPath . 'js/jquery.ui.autocomplete.min.js"></script>
<script> <script>
$(function() { $(function() {
$( "#geolocate" ).autocomplete({ $( "#geolocate" ).autocomplete({
source: "lib/autocomplete.php", source: "lib/autocomplete.php",
minLength: 2 minLength: 2
}); });
$( "#from" ).autocomplete({ $( "#from" ).autocomplete({
source: "lib/autocomplete.php", source: "lib/autocomplete.php",
minLength: 2 minLength: 2
}); });
$( "#to" ).autocomplete({ $( "#to" ).autocomplete({
source: "lib/autocomplete.php", source: "lib/autocomplete.php",
minLength: 2 minLength: 2
}); });
}); });
</script>'; </script>';
echo '<style type="text/css">'; echo '<style type="text/css">';
if (strstr($_SERVER['HTTP_USER_AGENT'], 'Android')) echo '.ui-shadow,.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a,.ui-body-b,.ui-btn-up-b,.ui-btn-hover-b, if (strstr($_SERVER['HTTP_USER_AGENT'], 'Android')) echo '.ui-shadow,.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a,.ui-body-b,.ui-btn-up-b,.ui-btn-hover-b,
.ui-btn-down-b,.ui-bar-c,.ui-body-c,.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c,.ui-bar-c,.ui-body-d, .ui-btn-down-b,.ui-bar-c,.ui-body-c,.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c,.ui-bar-c,.ui-body-d,
.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d,.ui-bar-d,.ui-body-e,.ui-btn-up-e,.ui-btn-hover-e, .ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d,.ui-bar-d,.ui-body-e,.ui-btn-up-e,.ui-btn-hover-e,
.ui-btn-down-e,.ui-bar-e,.ui-overlay-shadow,.ui-shadow,.ui-btn-active,.ui-body-a,.ui-bar-a { .ui-btn-down-e,.ui-bar-e,.ui-overlay-shadow,.ui-shadow,.ui-btn-active,.ui-body-a,.ui-bar-a {
text-shadow: none; text-shadow: none;
box-shadow: none; box-shadow: none;
-webkit-box-shadow: none; -webkit-box-shadow: none;
}'; }';
echo '</style>'; echo '</style>';
echo '<link rel="stylesheet" href="' . $labsPath . 'css/local.css.php" />'; echo '<link rel="stylesheet" href="' . $labsPath . 'css/local.css.php" />';
if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) { if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) {
echo '<meta name="apple-mobile-web-app-capable" content="yes" /> echo '<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="apple-touch-startup-image" href="startup.png" /> <link rel="apple-touch-startup-image" href="startup.png" />
<link rel="apple-touch-icon" href="apple-touch-icon.png" />'; <link rel="apple-touch-icon" href="apple-touch-icon.png" />';
} }
if ($geolocate) { if ($geolocate) {
echo "<script> echo "<script>
   
function success(position) { function success(position) {
$('#error').val('Location now detected. Please wait for data to load.'); $('#error').val('Location now detected. Please wait for data to load.');
$('#geolocate').val(position.coords.latitude+','+position.coords.longitude); $('#geolocate').val(position.coords.latitude+','+position.coords.longitude);
$.ajax({ async: false, $.ajax({ async: false,
success: function(){ success: function(){
location.reload(true); location.reload(true);
}, },
url: \"include/common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude }); url: \"include/common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude });
} }
function error(msg) { function error(msg) {
$('#error').val('Error: '+msg); $('#error').val('Error: '+msg);
} }
   
function geolocate() { function geolocate() {
if (navigator.geolocation) { if (navigator.geolocation) {
var options = { var options = {
enableHighAccuracy: true, enableHighAccuracy: true,
timeout: 60000, timeout: 60000,
maximumAge: 10000 maximumAge: 10000
} }
navigator.geolocation.getCurrentPosition(success, error, options); navigator.geolocation.getCurrentPosition(success, error, options);
} }
} }
$(document).ready(function() { $(document).ready(function() {
$('#here').click(function(event) { $('#geolocate').val(geolocate()); return false;}); $('#here').click(function(event) { $('#geolocate').val(geolocate()); return false;});
$('#here').show(); $('#here').show();
}); });
"; ";
if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();"; if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();";
echo "</script> "; echo "</script> ";
} }
if (isAnalyticsOn()) echo ' if (isAnalyticsOn()) echo '
<script type="text/javascript">' . " <script type="text/javascript">' . "
   
var _gaq = _gaq || []; var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-22173039-1']); _gaq.push(['_setAccount', 'UA-22173039-1']);
_gaq.push(['_trackPageview']); _gaq.push(['_trackPageview']);
_gaq.push(['_trackPageLoadTime']); _gaq.push(['_trackPageLoadTime']);
</script>"; </script>";
echo '</head> echo '</head>
<body> <body>
<div id="skip"> <div id="skip">
<a href="#maincontent">Skip to content</a> <a href="#maincontent">Skip to content</a>
</div> </div>
'; ';
if ($opendiv) { if ($opendiv) {
echo '<div data-role="page"> echo '<div data-role="page">
<div data-role="header" data-position="inline"> <div data-role="header" data-position="inline">
<a href="' . (isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "javascript:history.go(-1)") . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> <a href="' . (isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "javascript:history.go(-1)") . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a>
<h1>' . $pageTitle . '</h1> <h1>' . $pageTitle . '</h1>
<a href="' . $labsPath . '/index.php" data-icon="home" class="ui-btn-right">Home</a> <a href="' . $labsPath . '/index.php" data-icon="home" class="ui-btn-right">Home</a>
</div><!-- /header --> </div><!-- /header -->
<a name="maincontent" id="maincontent"></a> <a name="maincontent" id="maincontent"></a>
<div data-role="content"> '; <div data-role="content"> ';
$overrides = getServiceOverride(); $overrides = getServiceOverride();
if ($overrides['service_id']) { if ($overrides['service_id']) {
if ($overrides['service_id'] == "noservice") { if ($overrides['service_id'] == "noservice") {
echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a
href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
} }
else { else {
echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
} }
} }
if ($serviceAlertsEnabled) { if ($GTFSREnabled) {
$serviceAlerts = getServiceAlerts("network","network"); $serviceAlerts = getServiceAlertsAsArray("agency","0");
foreach ($serviceAlerts['entities'] as $entity) { foreach ($serviceAlerts['entity'] as $entity) {
echo "<div id='servicewarning'>".date("F j, g:i a",strtotime($entity['alert']['active_period']['start']))." to ". date("F j, g:i a", strtotime($entity['alert']['active_period']['end']))."<br>Warning: {$entity['alert']['description']['translation']} echo "<div id='servicewarning'>".date("F j, g:i a",strtotime($entity['alert']['active_period'][0]['start']))." to ". date("F j, g:i a", strtotime($entity['alert']['active_period'][0]['end']))."{$entity['alert']['header_text']['translation'][0]['text']}<br>Warning: {$entity['alert']['description_text']['translation'][0]['text']}
<br><a href='{$entity['alert']['url']['translation']}'>Source</a> </div>"; <br><a href='{$entity['alert']['url']['translation'][0]['text']}'>Source</a> </div>";
} }
} }
} }
} }
function include_footer() function include_footer()
{ {
global $labsPath; global $labsPath;
echo '<div id="footer"><a href="' . $labsPath . 'about.php">About/Contact Us</a>&nbsp;<a href="' . $labsPath . 'feedback.php">Feedback/Bug Report</a>&nbsp;<a href="' . $labsPath . 'privacy.php">Privacy Policy</a>'; echo '<div id="footer"><a href="' . $labsPath . 'about.php">About/Contact Us</a>&nbsp;<a href="' . $labsPath . 'feedback.php">Feedback/Bug Report</a>&nbsp;<a href="' . $labsPath . 'privacy.php">Privacy Policy</a>';
echo '</div>'; echo '</div>';
if (isAnalyticsOn()) { if (isAnalyticsOn()) {
echo "<script> (function() { echo "<script> (function() {
var ga = document.createElement('script'); ga.type = var ga = document.createElement('script'); ga.type =
'text/javascript'; ga.async = true; 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? ga.src = ('https:' == document.location.protocol ?
'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s); s.parentNode.insertBefore(ga, s);
})();</script>"; })();</script>";
$googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl();
echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>'; echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>';
} }
echo "\n</div></div></body></html>"; echo "\n</div></div></body></html>";
} }
function placeSettings() function placeSettings()
{ {
global $service_periods; global $service_periods;
$geoerror = false; $geoerror = false;
$geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "";
   
echo '<div id="error">'; echo '<div id="error">';
if ($geoerror) { if ($geoerror) {
echo 'Sorry, but your location could not currently be detected. echo 'Sorry, but your location could not currently be detected.
Please allow location permission, wait for your location to be detected, Please allow location permission, wait for your location to be detected,
or enter an address/co-ordinates in the box below.'; or enter an address/co-ordinates in the box below.';
} }
echo '</div>'; echo '</div>';
echo '<div id="settings" data-role="collapsible" data-collapsed="' . !$geoerror . '"> echo '<div id="settings" data-role="collapsible" data-collapsed="' . !$geoerror . '">
<h3>Change Location...</h3> <h3>Change Location...</h3>
<form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post"> <form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post">
<div class="ui-body"> <div class="ui-body">
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="geolocate"> Current Location: </label> <label for="geolocate"> Current Location: </label>
<input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here">Here?</a> <input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here">Here?</a>
</div> </div>
<input type="submit" value="Update"/> <input type="submit" value="Update"/>
</div></form> </div></form>
</div>'; </div>';
} }
function trackEvent($category, $action, $label = "", $value = - 1) function trackEvent($category, $action, $label = "", $value = - 1)
{ {
if (isAnalyticsOn()) { if (isAnalyticsOn()) {
echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'" . ($label != "" ? ", '$label'" : "") . ($value != - 1 ? ", $value" : "") . "]);</script>"; echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'" . ($label != "" ? ", '$label'" : "") . ($value != - 1 ? ", $value" : "") . "]);</script>";
} }
} }
?> ?>
   
<?php <?php
$service_periods = Array( $service_periods = Array(
'sunday', 'sunday',
'saturday', 'saturday',
'weekday' 'weekday'
); );
   
function service_period($date = "") function service_period($date = "")
{ {
if (isset($_SESSION['service_period'])) return $_SESSION['service_period']; if (isset($_SESSION['service_period'])) return $_SESSION['service_period'];
$override = getServiceOverride($date); $override = getServiceOverride($date);
if ($override['service_id']){ if ($override['service_id']){
return $override['service_id']; return $override['service_id'];
} }
   
switch (date('w',($date != "" ? $date : time()))) { switch (date('w',($date != "" ? $date : time()))) {
case 0: case 0:
return 'sunday'; return 'sunday';
case 6: case 6:
return 'saturday'; return 'saturday';
default: default:
return 'weekday'; return 'weekday';
} }
} }
function midnight_seconds($time = "") function midnight_seconds($time = "")
{ {
// from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html // from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html
if ($time != "") { if ($time != "") {
return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time);
} }
if (isset($_SESSION['time'])) { if (isset($_SESSION['time'])) {
$time = strtotime($_SESSION['time']); $time = strtotime($_SESSION['time']);
return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time);
} }
return (date("G") * 3600) + (date("i") * 60) + date("s"); return (date("G") * 3600) + (date("i") * 60) + date("s");
} }
function midnight_seconds_to_time($seconds) function midnight_seconds_to_time($seconds)
{ {
if ($seconds > 0) { if ($seconds > 0) {
$midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y")); $midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y"));
return date("h:ia", $midnight + $seconds); return date("h:ia", $midnight + $seconds);
} }
else { else {
return ""; return "";
} }
} }
function getServiceAlerts($filter_class, $filter_id) { if ($GTFSREnabled) {
  $serviceAlertCause = Array(
  "UNKNOWN_CAUSE" => "Unknown cause",
  "OTHER_CAUSE" => "Other cause",
  "TECHNICAL_PROBLEM" => "Technical problem",
  "STRIKE" => "Strike",
  "DEMONSTRATION" => "Demonstration",
  "ACCIDENT" => "Accident",
  "HOLIDAY" => "Holiday",
  "WEATHER" => "Weather",
  "MAINTENANCE" => "Maintenance",
  "CONSTRUCTION" => "Construction",
  "POLICE_ACTIVITY" => "Police activity",
  "MEDICAL_EMERGENCY" => "Medical emergency"
  );
  $serviceAlertEffect = Array(
  "NO_SERVICE" => "No service",
  "REDUCED_SERVICE" => "Reduced service",
  "SIGNIFICANT_DELAYS" => "Significant delays",
  "DETOUR" => "Detour",
  "ADDITIONAL_SERVICE" => "Additional service",
  "MODIFIED_SERVICE" => "Modified service",
  "OTHER_EFFECT" => "Other effect",
  "UNKNOWN_EFFECT" => "Unknown effect",
  "STOP_MOVED" => "Stop moved");
   
  set_include_path(get_include_path() . PATH_SEPARATOR . $labsPath."lib/Protobuf-PHP/library/DrSlump/");
   
  include_once("Protobuf.php");
  include_once("Protobuf/Message.php");
  include_once("Protobuf/Registry.php");
  include_once("Protobuf/Descriptor.php");
  include_once("Protobuf/Field.php");
   
  include_once($labsPath."lib/Protobuf-PHP/gtfs-realtime.php");
  include_once("Protobuf/CodecInterface.php");
  include_once("Protobuf/Codec/PhpArray.php");
  include_once("Protobuf/Codec/Binary.php");
  include_once("Protobuf/Codec/Binary/Writer.php");
  include_once("Protobuf/Codec/Json.php");
   
  function getServiceAlerts($filter_class = "", $filter_id = "") {
/* /*
   
also need last modified epoch of client gtfs also need last modified epoch of client gtfs
- add,remove,patch,inform (null) - add,remove,patch,inform (null)
- stop - stop
- trip - trip
- network - network
- classes (WHERE=) - classes (WHERE=)
- route (short_name or route_id) - route (short_name or route_id)
- street - street
- stop - stop
- trip - trip
Currently support: Currently support:
network inform network inform
trip patch: stop remove trip patch: stop remove
street inform: route inform, trip inform, stop inform street inform: route inform, trip inform, stop inform
route patch: trip remove route patch: trip remove
*/ */
$return = Array(); $fm = new transit_realtime\FeedMessage();
$return['header']['gtrtfs_version'] = "1"; $fh = new transit_realtime\FeedHeader();
$return['header']['timestamp'] = time(); $fh->setGtfsRealtimeVersion(1);
$return['entities'] = Array(); $fh->setTimestamp(time());
  $fm->setHeader($fh);
foreach(getCurrentAlerts() as $alert) { foreach(getCurrentAlerts() as $alert) {
$informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']); $fe = new transit_realtime\FeedEntity();
  $fe->setId($alert['id']);
  $fe->setIsDeleted(false);
  $alert = new transit_realtime\Alert();
  $tr = new transit_realtime\TimeRange();
  $tr->setStart($alert['start']);
  $tr->setEnd($alert['end']);
  $alert-> addActivePeriod($tr);
  $informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']);
if (sizeof($informedEntities) >0) { if (sizeof($informedEntities) >0) {
$entity = Array(); $informed = Array();
$entity['id'] = $alert['id']; $es = new transit_realtime\EntitySelector();
$entity['alert']['active_period']['start'] = $alert['start']; if ($informedEntity['informed_class'] == "agency") {
$entity['alert']['active_period']['end'] = $alert['end']; $es->setAgencyId($informedEntity['informed_id']);
$entity['alert']['url']['translation'] = $alert['url']; }
$entity['alert']['description']['translation'] = $alert['description']; if ($informedEntity['informed_class'] == "stop") {
  $es->setStopId($informedEntity['informed_id']);
foreach ($informedEntities as $informedEntity) { }
$informed = Array(); if ($informedEntity['informed_class'] == "route") {
$informed[$informedEntity['informed_class']."_id"] = $informedEntity['informed_id']; $es->setRouteId($informedEntity['informed_id']);
if ($informedEntity['informed_action'] != "") $informed["x-action"] = $informedEntity['informed_action']; }
$informed[$informedEntity['class']."_type"] = $informedEntity['type']; if ($informedEntity['informed_class'] == "trip") {
$entity['informed'][] = $informed; $td = new transit_realtime\TripDescriptor();
} $td->setTripId($informedEntity['informed_id']);
$return['entities'][] = $entity; $es->setTrip($td);
} }
} $alert-> addInformedEntity($es);
return $return; }
  $alert->setCause(constant("transit_realtime\Alert\Cause::".$alert['cause']));
  $alert->setEffect(constant("transit_realtime\Alert\Effect::".$alert['effect']));
  $tsUrl = new transit_realtime\TranslatedString();
  $tUrl = new transit_realtime\TranslatedString\Translation();
  $tUrl->setText($alert['url']);
  $tUrl->setLanguage("en");
  $tsUrl->addTranslation($tUrl);
  $alert->setUrl($tsUrl);
  $tsHeaderText= new transit_realtime\TranslatedString();
  $tHeaderText = new transit_realtime\TranslatedString\Translation();
  $tHeaderText->setText($alert['header']);
  $tHeaderText->setLanguage("en");
  $tsHeaderText->addTranslation($tHeaderText);
  $alert->setHeaderText($tsHeaderText);
  $tsDescriptionText= new transit_realtime\TranslatedString();
  $tDescriptionText = new transit_realtime\TranslatedString\Translation();
  $tDescriptionText->setText($alert['description']);
  $tDescriptionText->setLanguage("en");
  $tsDescriptionText->addTranslation($tDescriptionText);
  $alert->setDescriptionText($tsDescriptionText);
  $fe->setAlert($alert);
  $fm->addEntity($fe);
  }
  return $fm;
  }
  function getServiceAlertsAsArray($filter_class = "", $filter_id = "") {
  $codec = new DrSlump\Protobuf\Codec\PhpArray();
  return $codec->encode(getServiceAlerts($filter_class, $filter_id));
  }
   
  function getServiceAlertsAsBinary($filter_class = "", $filter_id = "") {
  $codec = new DrSlump\Protobuf\Codec\Binary();
  return $codec->encode(getServiceAlerts($filter_class, $filter_id));
  }
   
  function getServiceAlertsAsJSON($filter_class = "", $filter_id = "") {
  $codec = new DrSlump\Protobuf\Codec\Json();
  return $codec->encode(getServiceAlerts($filter_class, $filter_id));
} }
function getServiceAlertsByClass() { function getServiceAlertsByClass() {
$return = Array(); $return = Array();
$alerts = getServiceAlerts("",""); $alerts = getServiceAlertsAsArray("","");
foreach ($alerts['entities'] as $entity) { foreach ($alerts['entities'] as $entity) {
foreach ($entity['informed'] as $informed) { foreach ($entity['informed'] as $informed) {
foreach($informed as $key => $value){ foreach($informed as $key => $value){
if (strpos("_id",$key) > 0) { if (strpos("_id",$key) > 0) {
$parts = explode($key); $parts = explode($key);
$class = $parts[0]; $class = $parts[0];
$id = $value; $id = $value;
} }
} }
$return[$class][$id][]['entity'] = $entity; $return[$class][$id][] = $entity;
$return[$class][$id][]['action'] = $informed["x-action"]; }
} }
} }
   
  function getTripUpdates($filter_class = "", $filter_id = "") {
  $fm = new transit_realtime\FeedMessage();
  $fh = new transit_realtime\FeedHeader();
  $fh->setGtfsRealtimeVersion(1);
  $fh->setTimestamp(time());
  $fm->setHeader($fh);
  foreach(getCurrentAlerts() as $alert) {
  $informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']);
  $stops = Array();
  $routestrips = Array();
  if (sizeof($informedEntities) >0) {
  if ($informedEntity['informed_class'] == "stop" && $informed["x-action"] == "remove") {
  $stops[] = $informedEntity['informed_id'];
  }
  if (($informedEntity['informed_class'] == "route" || $informedEntity['informed_class'] == "trip") && $informed["x-action"] == "patch" ) {
  $routestrips[] = Array( "id" => $informedEntity['informed_id'],
  "type"=>$informedEntity['informed_class']);
  }
  }
  foreach ($routestrips as $routetrip) {
  $fe = new transit_realtime\FeedEntity();
  $fe->setId($alert['id'].$routetrip['id']);
  $fe->setIsDeleted(false);
  $tu = new transit_realtime\TripUpdate();
  $td = new transit_realtime\TripDescriptor();
  if ($routetrip['type'] == "route") {
  $td->setRouteId($routetrip['id']);
  } else if ($routetrip['type'] == "trip") {
  $td->setTripId($routetrip['id']);
  }
  $tu->setTrip($td);
  foreach ($stops as $stop) {
  $stu = new transit_realtime\TripUpdate\StopTimeUpdate();
  $stu->setStopId($stop);
  $stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED);
  $tu->addStopTimeUpdate($stu);
  }
  $fe->setTripUpdate($tu);
  $fm->addEntity($fe);
  }
   
  }
  return $fm;
   
  }
  function getTripUpdatesAsArray($filter_class = "", $filter_id = "") {
  $codec = new DrSlump\Protobuf\Codec\PhpArray();
  return $codec->encode(getTripUpdates($filter_class, $filter_id));
  }
   
  function getTripUpdatesAsBinary($filter_class = "", $filter_id = "") {
  $codec = new DrSlump\Protobuf\Codec\Binary();
  return $codec->encode(getTripUpdates($filter_class, $filter_id));
  }
   
  function getTripUpdatesAsJSON($filter_class = "", $filter_id = "") {
  $codec = new DrSlump\Protobuf\Codec\Json();
  return $codec->encode(getTripUpdates($filter_class, $filter_id));
  }
} }
?> ?>
   
<?php <?php
date_default_timezone_set('Australia/ACT'); date_default_timezone_set('Australia/ACT');
$debugOkay = Array( $debugOkay = Array(
"session", "session",
"json", "json",
"phperror", "phperror",
"awsotp", "awsotp",
//"squallotp", //"squallotp",
//"vanilleotp", //"vanilleotp",
"database", "database",
"other" "other"
); );
$serviceAlertsEnabled = true; $GTFSREnabled = true;
$cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6"; $cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6";
$googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q"; $googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q";
$otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/';
if (isDebug("awsotp") || php_uname('n') == "maxious.xen.prgmr.com") { if (isDebug("awsotp") || php_uname('n') == "maxious.xen.prgmr.com") {
$otpAPIurl = 'http://bus-main.lambdacomplex.org:8080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://bus-main.lambdacomplex.org:8080/opentripplanner-api-webapp/';
} }
if (isDebug("dotcloudotp") || php_uname('n') == "actbus-www") { if (isDebug("dotcloudotp") || php_uname('n') == "actbus-www") {
$otpAPIurl = 'http://otp.actbus.dotcloud.com/opentripplanner-api-webapp/'; $otpAPIurl = 'http://otp.actbus.dotcloud.com/opentripplanner-api-webapp/';
} }
if (isDebug("squallotp")) { if (isDebug("squallotp")) {
$otpAPIurl = 'http://10.0.1.108:5080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://10.0.1.108:5080/opentripplanner-api-webapp/';
} }
if (isDebug("vanilleotp")) { if (isDebug("vanilleotp")) {
$otpAPIurl = 'http://10.0.1.135:8080/opentripplanner-api-webapp/'; $otpAPIurl = 'http://10.0.1.135:8080/opentripplanner-api-webapp/';
} }
if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE); if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE);
$labsPath = ""; $labsPath = "";
if (strstr($_SERVER['PHP_SELF'],"labs")) $labsPath = "../"; if (strstr($_SERVER['PHP_SELF'],"labs")) $labsPath = "../";
   
function isDebugServer() function isDebugServer()
{ {
return php_sapi_name() == "cli" || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "vanille" || $_SERVER['SERVER_NAME'] == "10.1.0.4" || $_SERVER['SERVER_NAME'] == return php_sapi_name() == "cli" || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "azusa" || $_SERVER['SERVER_NAME'] == "vanille"
"localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1") ; || $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1") ;
} }
   
include_once ("common-geo.inc.php"); include_once ("common-geo.inc.php");
include_once ("common-net.inc.php"); include_once ("common-net.inc.php");
include_once ("common-transit.inc.php"); include_once ("common-transit.inc.php");
include_once ("common-db.inc.php"); include_once ("common-db.inc.php");
   
include_once ("common-request.inc.php"); include_once ("common-request.inc.php");
include_once ("common-session.inc.php"); include_once ("common-session.inc.php");
include_once ("common-auth.inc.php"); include_once ("common-auth.inc.php");
include_once ("common-template.inc.php"); include_once ("common-template.inc.php");
   
   
function isAnalyticsOn() function isAnalyticsOn()
{ {
return !isDebugServer(); $user_agent = $_SERVER['HTTP_USER_AGENT'];
  return !isDebugServer() && !preg_match('/cloudkick/i', $user_agent) && !preg_match('/googlebot/i', $user_agent) &&
  !preg_match('/baidu/i', $user_agent);
} }
function isDebug($debugReason = "other") function isDebug($debugReason = "other")
{ {
global $debugOkay; global $debugOkay;
return in_array($debugReason, $debugOkay, false) && isDebugServer(); return in_array($debugReason, $debugOkay, false) && isDebugServer();
} }
   
function debug($msg, $debugReason = "other") function debug($msg, $debugReason = "other")
{ {
if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n"; if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n";
} }
function isJQueryMobileDevice() function isJQueryMobileDevice()
{ {
// http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 // http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897
$user_agent = $_SERVER['HTTP_USER_AGENT']; $user_agent = $_SERVER['HTTP_USER_AGENT'];
return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5); return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5);
} }
function isFastDevice() function isFastDevice()
{ {
$ua = $_SERVER['HTTP_USER_AGENT']; $ua = $_SERVER['HTTP_USER_AGENT'];
$fastDevices = Array( $fastDevices = Array(
"Mozilla/5.0 (X11;", "Mozilla/5.0 (X11;",
"Mozilla/5.0 (Windows;", "Mozilla/5.0 (Windows;",
"Mozilla/5.0 (iP", "Mozilla/5.0 (iP",
"Mozilla/5.0 (Linux; U; Android", "Mozilla/5.0 (Linux; U; Android",
"Mozilla/4.0 (compatible; MSIE" "Mozilla/4.0 (compatible; MSIE"
); );
$slowDevices = Array( $slowDevices = Array(
"J2ME", "J2ME",
"MIDP", "MIDP",
"Opera/", "Opera/",
"Mozilla/2.0 (compatible;", "Mozilla/2.0 (compatible;",
"Mozilla/3.0 (compatible;" "Mozilla/3.0 (compatible;"
); );
return true; return true;
} }
function array_flatten($a, $f = array()) function array_flatten($a, $f = array())
{ {
if (!$a || !is_array($a)) return ''; if (!$a || !is_array($a)) return '';
foreach ($a as $k => $v) { foreach ($a as $k => $v) {
if (is_array($v)) $f = array_flatten($v, $f); if (is_array($v)) $f = array_flatten($v, $f);
else $f[$k] = $v; else $f[$k] = $v;
} }
return $f; return $f;
} }
function remove_spaces($string) function remove_spaces($string)
{ {
return str_replace(' ', '', $string); return str_replace(' ', '', $string);
} }
function object2array($object) function object2array($object)
{ {
if (is_object($object)) { if (is_object($object)) {
foreach ($object as $key => $value) { foreach ($object as $key => $value) {
$array[$key] = $value; $array[$key] = $value;
} }
} }
else { else {
$array = $object; $array = $object;
} }
return $array; return $array;
} }
function startsWith($haystack, $needle, $case = true) function startsWith($haystack, $needle, $case = true)
{ {
if ($case) { if ($case) {
return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0);
} }
return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0);
} }
   
function endsWith($haystack, $needle, $case = true) function endsWith($haystack, $needle, $case = true)
{ {
if ($case) { if ($case) {
return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0);
} }
return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0);
} }
function bracketsMeanNewLine($input) function bracketsMeanNewLine($input)
{ {
return str_replace(")", "</small>", str_replace("(", "<br><small>", $input)); return str_replace(")", "</small>", str_replace("(", "<br><small>", $input));
} }
function sksort(&$array, $subkey = "id", $sort_ascending = false) function sksort(&$array, $subkey = "id", $sort_ascending = false)
{ {
if (count($array)) $temp_array[key($array) ] = array_shift($array); if (count($array)) $temp_array[key($array) ] = array_shift($array);
foreach ($array as $key => $val) { foreach ($array as $key => $val) {
$offset = 0; $offset = 0;
$found = false; $found = false;
foreach ($temp_array as $tmp_key => $tmp_val) { foreach ($temp_array as $tmp_key => $tmp_val) {
if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) {
$temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array(
$key => $val $key => $val
) , array_slice($temp_array, $offset)); ) , array_slice($temp_array, $offset));
$found = true; $found = true;
} }
$offset++; $offset++;
} }
if (!$found) $temp_array = array_merge($temp_array, array( if (!$found) $temp_array = array_merge($temp_array, array(
$key => $val $key => $val
)); ));
} }
if ($sort_ascending) $array = array_reverse($temp_array); if ($sort_ascending) $array = array_reverse($temp_array);
else $array = $temp_array; else $array = $temp_array;
} }
function sktimesort(&$array, $subkey = "id", $sort_ascending = false) function sktimesort(&$array, $subkey = "id", $sort_ascending = false)
{ {
if (count($array)) $temp_array[key($array) ] = array_shift($array); if (count($array)) $temp_array[key($array) ] = array_shift($array);
foreach ($array as $key => $val) { foreach ($array as $key => $val) {
$offset = 0; $offset = 0;
$found = false; $found = false;
foreach ($temp_array as $tmp_key => $tmp_val) { foreach ($temp_array as $tmp_key => $tmp_val) {
if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) {
$temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( $temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array(
$key => $val $key => $val
) , array_slice($temp_array, $offset)); ) , array_slice($temp_array, $offset));
$found = true; $found = true;
} }
$offset++; $offset++;
} }
if (!$found) $temp_array = array_merge($temp_array, array( if (!$found) $temp_array = array_merge($temp_array, array(
$key => $val $key => $val
)); ));
} }
if ($sort_ascending && isset($temp_array)) $array = array_reverse($temp_array); if ($sort_ascending && isset($temp_array)) $array = array_reverse($temp_array);
else $array = $temp_array; else $array = $temp_array;
} }
function r_implode( $glue, $pieces ) function r_implode( $glue, $pieces )
{ {
foreach( $pieces as $r_pieces ) foreach( $pieces as $r_pieces )
{ {
if( is_array( $r_pieces ) ) if( is_array( $r_pieces ) )
{ {
$retVal[] = r_implode( $glue, $r_pieces ); $retVal[] = r_implode( $glue, $r_pieces );
} }
else else
{ {
$retVal[] = $r_pieces; $retVal[] = $r_pieces;
} }
} }
return implode( $glue, $retVal ); return implode( $glue, $retVal );
} }
   
?> ?>
   
<?php <?php
function getServiceOverride($date = "") function getServiceOverride($date = "")
{ {
global $conn; global $conn;
$query = "Select * from calendar_dates where date = :date and exception_type = '1' LIMIT 1"; $query = "Select * from calendar_dates where date = :date and exception_type = '1' LIMIT 1";
// debug($query,"database"); // debug($query,"database");
$query = $conn -> prepare($query); // Create a prepared statement $query = $conn -> prepare($query); // Create a prepared statement
$query -> bindParam(":date", date("Ymd", ($date != "" ? $date : time()))); $query -> bindParam(":date", date("Ymd", ($date != "" ? $date : time())));
$query -> execute(); $query -> execute();
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return $query -> fetch(PDO :: FETCH_ASSOC); return $query -> fetch(PDO :: FETCH_ASSOC);
} }
   
function getServiceAlert($alertID) function getServiceAlert($alertID)
{ {
global $conn; global $conn;
$query = 'SELECT * from servicealerts_alerts where id = :servicealert_id'; $query = "SELECT id,extract('epoch', start) as start, extract('epoch', end) as end,cause,effect,header,description,url from servicealerts_alerts where id = :servicealert_id";
debug($query, "database"); debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
$query -> bindParam(":servicealert_id", $alertID); $query -> bindParam(":servicealert_id", $alertID);
$query -> execute(); $query -> execute();
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return $query -> fetch(PDO :: FETCH_ASSOC); return $query -> fetch(PDO :: FETCH_ASSOC);
} }
   
   
function updateServiceAlert($alertID, $start, $end, $description, $url) function updateServiceAlert($alertID, $start, $end, $header, $description, $url)
{ {
global $conn; global $conn;
$query = 'update servicealerts_alerts set start=:start, "end"=:end, description=:description, url=:url where id = :servicealert_id'; $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url where id = :servicealert_id';
debug($query, "database"); debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
$query -> bindParam(":servicealert_id", $alertID); $query -> bindParam(":servicealert_id", $alertID);
$query -> bindParam(":start", $start); $query -> bindParam(":start", $start);
$query -> bindParam(":end", $end); $query -> bindParam(":end", $end);
  $query -> bindParam(":header", $header);
$query -> bindParam(":description", $description); $query -> bindParam(":description", $description);
$query -> bindParam(":url", $url); $query -> bindParam(":url", $url);
$query -> execute(); $query -> execute();
   
print_r($conn -> errorInfo()); print_r($conn -> errorInfo());
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return $query -> fetch(PDO :: FETCH_ASSOC); return $query -> fetch(PDO :: FETCH_ASSOC);
} }
   
function addServiceAlert($start, $end, $description, $url) function addServiceAlert($start, $end, $header, $description, $url)
{ {
global $conn; global $conn;
$query = 'INSERT INTO servicealerts_alerts (start, "end", description, url) VALUES (:start, :end, :description, :url) '; $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url) VALUES (:start, :end, :header, :description, :url) ';
debug($query, "database"); debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
$query -> bindParam(":start", $start); $query -> bindParam(":start", $start);
$query -> bindParam(":end", $end); $query -> bindParam(":end", $end);
  $query -> bindParam(":header", $header);
$query -> bindParam(":description", $description); $query -> bindParam(":description", $description);
$query -> bindParam(":url", $url); $query -> bindParam(":url", $url);
$query -> execute(); $query -> execute();
   
print_r($conn -> errorInfo()); print_r($conn -> errorInfo());
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return $query -> fetch(PDO :: FETCH_ASSOC); return $query -> fetch(PDO :: FETCH_ASSOC);
} }
   
function getCurrentAlerts() function getCurrentAlerts()
{ {
global $conn; global $conn;
$query = 'SELECT * from servicealerts_alerts where NOW() > start and NOW() < "end"'; $query = "SELECT id,extract('epoch', start) as start, extract('epoch', end) as end,cause,effect,header,description,url from servicealerts_alerts where NOW() > start and NOW() < \"end\"";
// debug($query, "database"); // debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
$query -> execute(); $query -> execute();
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return $query -> fetchAll(); return $query -> fetchAll();
} }
   
function getFutureAlerts() function getFutureAlerts()
{ {
global $conn; global $conn;
$query = 'SELECT * from servicealerts_alerts where NOW() > start or NOW() < "end"'; $query = "SELECT id,extract('epoch', start) as start, extract('epoch', end) as end,cause,effect,header,description,url from servicealerts_alerts where NOW() > start or NOW() < \"end\"";
// debug($query, "database"); // debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
$query -> execute(); $query -> execute();
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return $query -> fetchAll(); return $query -> fetchAll();
} }
function getInformedAlerts($id, $filter_class, $filter_id) function getInformedAlerts($id, $filter_class, $filter_id)
{ {
global $conn; global $conn;
$query = "SELECT * from servicealerts_informed where servicealert_id = :servicealert_id"; $query = "SELECT * from servicealerts_informed where servicealert_id = :servicealert_id";
if ($filter_class != "") { if ($filter_class != "") {
$query .= " AND informed_class = :informed_class "; $query .= " AND informed_class = :informed_class ";
} }
if ($filter_id != "") { if ($filter_id != "") {
$query .= " AND informed_id = :informed_id "; $query .= " AND informed_id = :informed_id ";
} }
// debug($query, "database"); // debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
if ($filter_class != "") { if ($filter_class != "") {
$query -> bindParam(":informed_class", $filter_class); $query -> bindParam(":informed_class", $filter_class);
} }
if ($filter_id != "") { if ($filter_id != "") {
$query -> bindParam(":informed_id", $filter_id); $query -> bindParam(":informed_id", $filter_id);
} }
$query -> bindParam(":servicealert_id", $id); $query -> bindParam(":servicealert_id", $id);
$query -> execute(); $query -> execute();
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return $query -> fetchAll(); return $query -> fetchAll();
} }
function deleteInformedAlert($serviceAlertID, $class, $id) function deleteInformedAlert($serviceAlertID, $class, $id)
{ {
global $conn; global $conn;
$query = 'DELETE from servicealerts_informed where servicealert_id = :servicealert_id and informed_class = :informed_class AND informed_id = :informed_id'; $query = 'DELETE from servicealerts_informed where servicealert_id = :servicealert_id and informed_class = :informed_class AND informed_id = :informed_id';
debug($query, "database"); debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
$query -> bindParam(":servicealert_id", $serviceAlertID); $query -> bindParam(":servicealert_id", $serviceAlertID);
$query -> bindParam(":informed_class", $class); $query -> bindParam(":informed_class", $class);
$query -> bindParam(":informed_id", $id); $query -> bindParam(":informed_id", $id);
$query -> execute(); $query -> execute();
print_r($conn -> errorInfo()); print_r($conn -> errorInfo());
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return null; return null;
} }
function addInformedAlert($serviceAlertID, $class, $id, $action) function addInformedAlert($serviceAlertID, $class, $id, $action)
{ {
global $conn; global $conn;
$query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id) VALUES(:servicealert_id ,:informed_class, :informed_id)'; $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id) VALUES(:servicealert_id ,:informed_class, :informed_id)';
debug($query, "database"); debug($query, "database");
$query = $conn -> prepare($query); $query = $conn -> prepare($query);
$query -> bindParam(":servicealert_id", $serviceAlertID); $query -> bindParam(":servicealert_id", $serviceAlertID);
$query -> bindParam(":informed_class", $class); $query -> bindParam(":informed_class", $class);
$query -> bindParam(":informed_id", $id); $query -> bindParam(":informed_id", $id);
$query -> execute(); $query -> execute();
   
print_r($conn -> errorInfo()); print_r($conn -> errorInfo());
if (!$query) { if (!$query) {
databaseError($conn -> errorInfo()); databaseError($conn -> errorInfo());
return Array(); return Array();
} }
return null; return null;
} }
?> ?>
<?php <?php
include ('../include/common.inc.php'); include ('../include/common.inc.php');
auth(); auth();
include_header("Service Alert Editor", "serviceAlertEditor"); include_header("Service Alert Editor", "serviceAlertEditor");
/** /**
* Currently support: * Currently support:
* network inform * network inform
* stop remove: trip patch, route inform * stop remove: route patch, stop remove
* - stop search * - stop search
* street inform: route inform, trip inform, stop inform * street inform: route inform, stop inform
* - street search * - street search
* trip remove: route patch, stop inform  
* - trip search by route  
*/ */
if (isset($_REQUEST['saveedit'])) { if (isset($_REQUEST['saveedit'])) {
if ($_REQUEST['saveedit'] != "") updateServiceAlert($_REQUEST['saveedit'], $_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']); if ($_REQUEST['saveedit'] != "") updateServiceAlert($_REQUEST['saveedit'], $_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['header'], $_REQUEST['description'], $_REQUEST['url']);
else addServiceAlert($_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']); else addServiceAlert($_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']);
echo "Saved " . $_REQUEST['saveedit']; echo "Saved " . $_REQUEST['saveedit'];
die(); die();
} }
if ($_REQUEST['delete']) { if ($_REQUEST['delete']) {
$deleteParts = explode(";", $_REQUEST['delete']); $deleteParts = explode(";", $_REQUEST['delete']);
deleteInformedAlert($deleteParts[0], $deleteParts[1], $deleteParts[2]); deleteInformedAlert($deleteParts[0], $deleteParts[1], $deleteParts[2]);
echo "Deleted network inform for {$deleteParts[0]} ({$deleteParts[1]},{$deleteParts[2]})<br>\n"; echo "Deleted network inform for {$deleteParts[0]} ({$deleteParts[1]},{$deleteParts[2]})<br>\n";
die(); die();
} }
if ($_REQUEST['networkinform']) { if ($_REQUEST['networkinform']) {
addInformedAlert($_REQUEST['networkinform'], "network", "network", "inform"); addInformedAlert($_REQUEST['networkinform'], "agency", "0", "inform");
echo "Added network inform for" . $_REQUEST['networkinform']; echo "Added network inform for" . $_REQUEST['networkinform'];
die(); die();
} }
if ($_REQUEST['stopsearch']) { if ($_REQUEST['stopsearch']) {
addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove"); addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove");
echo "Added stop remove for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n"; echo "Added stop remove for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n";
foreach ($service_periods as $sp) { foreach ($service_periods as $sp) {
echo "Patching $sp trips<br>\n"; echo "Remove from $sp routes<br>\n";
foreach (getStopTrips($_REQUEST['stopid'], $sp) as $trip) {  
addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch");  
echo "Added trip patch for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n";  
   
}  
echo "Informing $sp routes<br>\n";  
foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) { foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) {
addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform"); addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "patch");
echo "Added route inform for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n"; echo "Added route patch for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n";
} }
} }
die(); die();
} }
if ($_REQUEST['routesearch']) {  
echo "Informing route<br>\n";  
$stops = Array();  
echo "Informing trips<br>\n";  
foreach(getRouteTrips() as $trip) {  
addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch");  
echo "Added trip patch for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n";  
viaPoints($tripID, "", false);  
}  
   
echo "Informing stops<br>\n";  
foreach($stops as $stop) {  
addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove");  
echo "Added stop remove for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n";  
}  
die();  
}  
if ($_REQUEST['streetsearch']) { if ($_REQUEST['streetsearch']) {
echo "Informing stops<br>\n"; echo "Informing stops of street<br>\n";
foreach(getStopByName() as $stop) { foreach(getStopByName() as $stop) {
addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove"); addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "inform");
echo "Added stop inform for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n"; echo "Added stop inform for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n";
foreach ($service_periods as $sp) { foreach ($service_periods as $sp) {
echo "Patching $sp trips<br>\n";  
foreach (getStopTrips($_REQUEST['stopid'], $sp) as $trip) {  
addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch");  
echo "Added trip inform for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n";  
   
}  
echo "Informing $sp routes<br>\n"; echo "Informing $sp routes<br>\n";
foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) { foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) {
addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform"); addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform");
echo "Added route inform for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n"; echo "Added route inform for stop" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n";
   
   
} }
} }
die(); die();
} }
} }
?> ?>
Active and Future Alerts: Active and Future Alerts:
<table> <table>
<?php <?php
foreach(getFutureAlerts() as $alert) { foreach(getFutureAlerts() as $alert) {
echo "<tr><td>{$alert['start']}</td><td>{$alert['end']}</td><td>" . substr($alert['description'], 0, 999) . '</td><td><a href="?edit=' . $alert['id'] . '">edit</a></td></tr>'; echo "<tr><td>{$alert['start']}</td><td>{$alert['end']}</td><td>" . substr($alert['description'], 0, 999) . '</td><td><a href="?edit=' . $alert['id'] . '">edit</a></td></tr>';
} }
   
?> ?>
</table> </table>
<?php <?php
$alert = getServiceAlert($_REQUEST['edit']); $alert = getServiceAlert($_REQUEST['edit']);
   
?> ?>
<form action="<?php echo basename(__FILE__) ; <form action="<?php echo basename(__FILE__) ;
?>" method="get"> ?>" method="get">
   
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="startdate"> Start Date</label> <label for="startdate"> Start Date</label>
<input type="text" name="startdate" id="startdate" value="<?php <input type="text" name="startdate" id="startdate" value="<?php
if ($alert['start']) echo $alert['start']; if ($alert['start']) echo $alert['start'];
else echo date("c", strtotime("0:00")); else echo date("c", strtotime("0:00"));
?>" /> ?>" />
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="enddate"> End Date </label> <label for="enddate"> End Date </label>
<input type="text" name="enddate" id="enddate" value="<?php <input type="text" name="enddate" id="enddate" value="<?php
if ($alert['end']) echo $alert['end']; if ($alert['end']) echo $alert['end'];
else echo date("c", strtotime("23:59")); else echo date("c", strtotime("23:59"));
?>" /> ?>" />
</div> </div>
  <div data-role="fieldcontain">
  <label for="header">Header</label>
  <input type="text" name="header" id="header" value="<?php echo $alert['header'];
  ?>" />
  </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="description">Description</label> <label for="description">Description</label>
<textarea name="description"> <textarea name="description">
<?php echo $alert['description']; <?php echo $alert['description'];
?></textarea> ?></textarea>
</div> </div>
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="url">URL</label> <label for="url">URL</label>
<input type="text" name="url" id="url" value="<?php echo $alert['url']; <input type="text" name="url" id="url" value="<?php echo $alert['url'];
?>" /> ?>" />
</div> </div>
<input type="hidden" name="saveedit" value="<?php echo $_REQUEST['edit']; <input type="hidden" name="saveedit" value="<?php echo $_REQUEST['edit'];
?>"/> ?>"/>
<input type="submit" value="Save"/> <input type="submit" value="Save"/>
</div></form> </div></form>
   
<?php <?php
if ($_REQUEST['edit']) { if ($_REQUEST['edit']) {
echo "Informed Entities for ID {$_REQUEST['edit']}:"; echo "Informed Entities for ID {$_REQUEST['edit']}:";
echo '<table>'; echo '<table>';
foreach(getInformedAlerts($_REQUEST['edit'], "", "") as $informed) { foreach(getInformedAlerts($_REQUEST['edit'], "", "") as $informed) {
echo "<tr><td>{$informed['informed_class']}</td><td>{$informed['informed_id']}</td><td>{$informed['informed_action']}" . '</td><td><a href="?delete=' . $_REQUEST['edit'] . ';' . $informed['informed_class'] . ';' . $informed['informed_id'] . '">delete</a></td></tr>'; echo "<tr><td>{$informed['informed_class']}</td><td>{$informed['informed_id']}</td><td>{$informed['informed_action']}" . '</td><td><a href="?delete=' . $_REQUEST['edit'] . ';' . $informed['informed_class'] . ';' . $informed['informed_id'] . '">delete</a></td></tr>';
} }
echo '</table>'; echo '</table>';
?> ?>
<form action="<?php echo basename(__FILE__) ; <form action="<?php echo basename(__FILE__) ;
?>" method="get"> ?>" method="get">
<input type="hidden" name="networkinform" value="<?php echo $_REQUEST['edit']; <input type="hidden" name="networkinform" value="<?php echo $_REQUEST['edit'];
?>"/> ?>"/>
<input type="submit" value="Add Network Inform"/> <input type="submit" value="Add Network Inform"/>
</form> </form>
<form action="<?php echo basename(__FILE__) ; <form action="<?php echo basename(__FILE__) ;
?>" method="get"> ?>" method="get">
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="stopid">StopID</label> <label for="stopid">StopID to remove</label>
<input type="text" name="stopid" /> <input type="text" name="stopid" />
</div> </div>
<input type="hidden" name="stopsearch" value="<?php echo $_REQUEST['edit']; <input type="hidden" name="stopsearch" value="<?php echo $_REQUEST['edit'];
?>"/> ?>"/>
<input type="submit" value="Stop Search"/> <input type="submit" value="Stop Search"/>
</form> </form>
<form action="<?php echo basename(__FILE__) ; <form action="<?php echo basename(__FILE__) ;
?>" method="get"> ?>" method="get">
<div data-role="fieldcontain"> <div data-role="fieldcontain">
<label for="street">Street</label> <label for="street">Street to inform</label>
<input type="text" name="street" /> <input type="text" name="street" />
</div> </div>
<input type="hidden" name="streetsearch" value="<?php echo $_REQUEST['edit']; <input type="hidden" name="streetsearch" value="<?php echo $_REQUEST['edit'];
?>"/> ?>"/>
<input type="submit" value="Street Search"/> <input type="submit" value="Street Search"/>
</form> </form>
<form action="<?php echo basename(__FILE__) ; <?php
?>" method="get">  
<div data-role="fieldcontain">  
<label for="routeid">routeID</label>  
<input type="text" name="routeid" />  
</div>  
<input type="hidden" name="routesearch" value="<?php echo $_REQUEST['edit'];  
?>"/>  
<input type="submit" value="Route Search"/>  
</form>  
<?php  
} }
include_footer(); include_footer();
?> ?>
  InputStream modelIn = new FileInputStream("en-ner-person.bin");
 
  try {
  TokenNameFinder model = new TokenNameFinderModel(modelIn);
  }
  catch (IOException e) {
  e.printStackTrace();
  }
  finally {
  if (modelIn != null) {
  try {
  modelIn.close();
  }
  catch (IOException e) {
  }
  }
  }
 
  NameFinderME nameFinder = new NameFinderME(model);
 
  for (String document[][] : documents) {
 
  for (String[] sentence : document) {
  Span nameSpans[] = find(sentence);
  // do something with the names
  }
 
  nameFinder.clearAdaptiveData()
  }
 
 
  InputStream in = getClass()
  .getClassLoader()
  .getResourceAsStream(
  "opennlp/tools/namefind/AnnotatedSentences.txt");
 
  String encoding = "ISO-8859-1";
 
  ObjectStream<NameSample> sampleStream = new NameSampleDataStream(
  new PlainTextByLineStream(new InputStreamReader(in,
  encoding)));
 
  TokenNameFinderModel nameFinderModel = NameFinderME.train("en",
  "default", sampleStream, Collections
  .<String, Object> emptyMap(), 70, 1);
 
  TokenNameFinder nameFinder = new NameFinderME(nameFinderModel);
 
  // now test if it can detect the sample sentences
 
  String sentence[] = { "Alisa", "appreciated", "the", "hint",
  "and", "enjoyed", "a", "delicious", "traditional",
  "meal." };
 
  Span names[] = nameFinder.find(sentence);
 
  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.lambdacomplex.bus</groupId>
  <artifactId>servicealerts_twitter</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
  <dependency>
  <groupId>org.apache.opennlp</groupId>
  <artifactId>opennlp</artifactId>
  <version>1.5.1-incubating</version>
  </dependency>
  <dependency>
  <groupId>org.apache.opennlp</groupId>
  <artifactId>opennlp-tools</artifactId>
  <version>1.5.1-incubating</version>
  </dependency>
  </dependencies>
  </project>
 
  The MIT License
 
  Copyright (c) 2011 Iván -DrSlump- Montes
 
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:
 
  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.
 
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
  Protobuf for PHP
  ================
 
  Protobuf for PHP is an implementation of Google's Protocol Buffers for the PHP
  language, supporting its binary data serialization and including a `protoc`
  plugin to generate PHP classes from .proto files.
 
  Great effort has been put into generating PHP files that include all sort of type
  hints to aide IDE's with autocompletion. Therefore, it can not only be used to
  communicate with Protocol Buffers services but also as a generation tool for
  _data objects_ no matter what the final serialization is.
 
  For more information see the [included man pages](http://drslump.github.com/Protobuf-PHP/).
 
 
  ## Requirements
 
  - PHP 5.3
  - Pear's Console_CommandLine (for the protoc wrapper tool)
  - Google's `protoc` compiler version 2.3 or above
  - GMP or BC Math extensions ¹
 
  ¹ Only needed for negative values in `int32`, `int64` or `fixed64` types. See
  the _known issues_ section.
 
 
  ## Features
 
  ### Working
 
  - Standard types (numbers, string, enums, messages, etc)
  - Pluggable serialization backends (codecs)
  - Standard Binary
  - Standard TextFormat ¹
  - PhpArray
  - JSON
  - [ProtoJson](https://github.com/drslump/ProtoJson) (_TagMap_ and _Indexed_ variants)
  - XML
  - Protoc compiler plugin to generate the PHP classes
  - Extensions
  - Unknown fields
  - Packed fields
  - Reflection
  - Dynamic messages with annotations support
  - Generates service interfaces
  - Includes comments from .proto files in the generated files
  - Pear package for easy installation
 
  ¹ Only serialization is supported
 
  ### Future
 
  - Speed optimized code generation mode
  - Support numbers beyond PHP's native limits
 
 
 
  ## Example usage
 
  $person = new Tutorial\Person();
  $person->name = 'DrSlump';
  $person->setId(12);
 
  $book = new Tutorial\AddressBook();
  $book->addPerson($person);
 
  // Use default codec
  $data = $book->serialize();
 
  // Use custom codec
  $codec = new \DrSlump\Protobuf\Codec\Binary();
  $data = $codec->encode($book);
  // ... or ...
  $data = $book->serialize($codec);
 
 
  ## Installation
 
  Install with Pear
 
  pear channel-discover pear.pollinimini.net
  pear install drslump/Protobuf-beta
 
  You can also get the latest version by checking out a copy of the
  repository in your computer.
 
 
 
  ## Known issues
 
 
  ### Types
 
  PHP is very weak when dealing with numbers processing. Several work arounds have been applied
  to the standard binary codec to reduce incompatibilities between Protobuf types and PHP ones.
 
  - Protobuf stores floating point values using the [IEEE 754](http://en.wikipedia.org/wiki/IEEE_754) standard
  with 64bit words for the `double` and 32bit for the `float` types. PHP supports IEEE 754 natively although
  the precission is platform dependant, however it typically supports 64bit doubles. It means that
  if your PHP was compiled with 64bit sized doubles (or greater) you shouldn't have any problem encoding
  and decoded float and double typed values with Protobuf.
 
  - Integer values are also [platform dependant in PHP](http://www.php.net/manual/en/language.types.integer.php).
  The library has been developed and tested against PHP binaries compiled with 64bit integers. The encoding and
  decoding algorithm should in theory work no matter if PHP uses 32bit or 64bit integers internally, just take
  into account that with 32bit integers the numbers cannot exceed in any case the `PHP_INT_MAX` value (2147483647).
 
  While Protobuf supports unsigned integers PHP does not. In fact, numbers above the compiled PHP maximum
  integer (`PHP_INT_MAX`, 0x7FFFFFFFFFFFFFFF for 64bits) will be automatically casted to doubles, which
  typically will offer 53bits of decimal precission, allowing to safely work with numbers upto
  0x20000000000000 (2^53), even if they are represented in PHP as floats instead of integers. Higher numbers
  will loose precission or might even return an _infinity_ value, note that the library does not include
  any checking for these numbers and using them might provoke unexpected behaviour.
 
  Negative values when encoded as `int32`, `int64` or `fixed64` types require the big integer extensions
  [GMP](http://www.php.net/gmp) or [BC Math](http://www.php.net/bc) (the later only for 64bit architectures)
  to be available in your PHP environment. The reason is that when encoding these negative numbers without
  using _zigzag_ the binary representation uses the most significant bit for the sign, thus the numbers become
  above the maximum supported values in PHP. The library will check for these conditions and will automatically
  try to use GMP or BC to process the value.
 
 
  ### Strings
 
  The binary codec expects strings to be encoded using UTF-8. PHP does not natively support string encodings,
  PHP's string data type is basically a length delimited stream of bytes, so it's not trivial to include
  automatic encoding conversion into the library encoding and decoding routines. Instead of trying to guess
  or offer a configuration interface for the encoding, the binary codec will process the `string` type just as
  it would process `byte` one, delegating on your application the task of encoding or decoding in the desired
  character set.
 
  ### Memory usage
 
  Large messages might be troublesome since the way the library is modelled does not allow to parse or
  serialize messages as a streams, instead the whole operation is performed in memory, which allows for faster
  processing but could consume too much RAM if messages are too large.
 
 
  ### Unknown fields
 
  Since wire types are different across different codec's formats, it's not possible to transcode unkwnon
  fields consumed in one codec to another. This means, for example, that when consuming a message using the
  binary codec, if it contains unknown fields, they won't be included when serializing the message using the
  Json codec.
 
 
  ## Generating PHP classes
 
  The generation tool is designed to be run as a `protoc` plugin, thus it should
  work with any proto file supported by the official compiler.
 
  protoc --plugin=protoc-gen-php --php_out=./build tutorial.proto
 
  To make use of non-standard options in your proto files (like `php.namespace`) you'll
  have to import the `php.proto` file included with the library. It's location will
  depend on where you've installed this library.
 
  protoc -I=./Protobuf-PHP/library/DrSlump/Protobuf/Compiler/protos \
  --plugin=protoc-gen-php --php_out=./build tutorial.proto
 
  In order to make your life easier, the supplied protoc plugin offers an additional
  execution mode, where it acts as a wrapper for the `protoc` invocation. It will
  automatically include the `php.proto` path so that you don't need to worry about it.
 
  protoc-gen-php -o ./build tutorial.proto
 
 
  ## LICENSE:
 
  The MIT License
 
  Copyright (c) 2011 Iván -DrSlump- Montes
 
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  'Software'), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:
 
  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.
 
  THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 
 
 
 
 
  # encoding: utf-8
  namespace :pear do
 
  support_files = ['README.md', 'LICENSE', 'protoc-gen-php.php', 'protoc-gen-php.bat']
  tpl_file = 'package.pear'
  xml_file = 'library/package.xml'
 
  desc "Generate package.xml"
  task :xml => [:clean] do |t, args|
  unless ENV['version'] then
  puts 'Version number not given. Use "pear:xml version=1.0"'
  exit 1
  end
 
  # Get template contents
  text = File.read(tpl_file, :encoding => "UTF-8")
  # Replace the version, date and time
  text = text.gsub("{VERSION}", ENV['version'])
  text = text.gsub('{DATE}', Time.now.strftime('%Y-%m-%d'))
  text = text.gsub('{TIME}', Time.now.strftime('%H:%M:%S'))
 
  # Include source files
  dirs = []
  Dir.glob('library/**/*.*') do |file|
  file[0, 'library/'.length] = ''
  dirs << '<file name="' + file + '" role="php">'
  dirs << '<tasks:replace from="@package_version@" to="version" type="package-info" />'
  dirs << '</file>'
  end
 
  text = text.gsub('{DIRS}', dirs.join("\n"))
 
  # Generate a new pear package.xml
  xml = File.new(xml_file, 'w')
  xml.syswrite(text);
  xml.close();
  end
 
  desc "Build a release"
  task :package => ['doc:build', :xml] do
 
  # Copy supporting files to the package root
 
  support_files.each do |file|
  cp file, "library/#{file}"
  end
 
  begin
  sh "pear package -n #{xml_file}"
  rescue Exception => e
  puts "Rolling back..."
  Rake::Task['pear:clean'].execute
  raise
  end
 
  Rake::Task['pear:clean'].execute
  end
 
  desc "Clean up"
  task :clean do
  puts "Cleaning up..."
 
  # Remove package.xml
  rm_f xml_file
 
  # Remove supporting files
  support_files.each { |file| rm_f "library/#{file}" }
  end
 
  end
 
  namespace :doc do
 
  desc "Generate manual"
  task :build do
  version = ENV['version']
  ENV['RONN_MANUAL'] = "Protobuf-PHP #{version}"
  ENV['RONN_ORGANIZATION'] = "Ivan -DrSlump- Montes"
  sh "ronn -w -s toc -r5 --markdown man/*.ronn"
  end
 
  desc 'Publish to github pages'
  task :github => 'doc:build' do
  require 'git'
  require 'logger'
 
  remote = `git remote show origin`
  .split(%r{\n}) # Ruby 1.9 only has grep() on Array
  .grep(/Push.*URL/)
  .first[/git@.*/]
 
  files = [
  'protoc-gen-php.1.html',
  'protobuf-php.3.html',
  'protobuf-php.5.html',
  ]
 
  root = "/tmp/checkout-#{Time.now.to_i}"
  g = Git.clone(remote, root, :log => Logger.new(STDOUT))
 
  # Make sure this actually switches branches.
  g.checkout(g.branch('gh-pages'))
 
  files.each {|file|
  cp "man/#{file}", "#{root}/."
  g.add(file)
  }
 
  g.commit('Regenerating Github Pages.')
 
  # PUSH!
  g.push(g.remote('origin'), g.branch('gh-pages'))
 
  puts '--> GitHub Pages Commit and Push successful.'
  end
 
  end
 
 
 
  <?php
  // DO NOT EDIT! Generated by Protobuf-PHP protoc plugin @package_version@
  // cmd line php -f protoc-gen-php.php gtfs-realtime.proto -i ./
  // Source: gtfs-realtime.proto
  // Date: 2011-08-23 07:08:46
 
  // @@protoc_insertion_point(scope_file)
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class FeedMessage extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.FeedMessage');
 
  // required .transit_realtime.FeedHeader header = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "header";
  $f->type = 11;
  $f->rule = 2;
  $f->reference = '\transit_realtime\FeedHeader';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedMessage:header)
  $descriptor->addField($f);
 
  // repeated .transit_realtime.FeedEntity entity = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "entity";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\transit_realtime\FeedEntity';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedMessage:entity)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.FeedMessage)
 
  return $descriptor;
  }
 
  /** @var \transit_realtime\FeedHeader */
  public $header = null;
 
  /** @var \transit_realtime\FeedEntity[] */
  public $entity = array();
 
 
  /**
  * Check if <header> has a value
  *
  * @return boolean
  */
  public function hasHeader(){
  return $this->_has(1);
  }
 
  /**
  * Clear <header> value
  *
  * @return \transit_realtime\FeedMessage
  */
  public function clearHeader(){
  return $this->_clear(1);
  }
 
  /**
  * Get <header> value
  *
  * @return \transit_realtime\FeedHeader
  */
  public function getHeader(){
  return $this->_get(1);
  }
 
  /**
  * Set <header> value
  *
  * @param \transit_realtime\FeedHeader $value
  * @return \transit_realtime\FeedMessage
  */
  public function setHeader(\transit_realtime\FeedHeader $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <entity> has a value
  *
  * @return boolean
  */
  public function hasEntity(){
  return $this->_has(2);
  }
 
  /**
  * Clear <entity> value
  *
  * @return \transit_realtime\FeedMessage
  */
  public function clearEntity(){
  return $this->_clear(2);
  }
 
  /**
  * Get <entity> value
  *
  * @param int $idx
  * @return \transit_realtime\FeedEntity
  */
  public function getEntity($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <entity> value
  *
  * @param \transit_realtime\FeedEntity $value
  * @return \transit_realtime\FeedMessage
  */
  public function setEntity(\transit_realtime\FeedEntity $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <entity>
  *
  * @return \transit_realtime\FeedEntity[]
  */
  public function getEntityList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <entity>
  *
  * @param \transit_realtime\FeedEntity $value
  * @return \transit_realtime\FeedMessage
  */
  public function addEntity(\transit_realtime\FeedEntity $value){
  return $this->_add(2, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.FeedMessage)
  }
  }
 
  namespace transit_realtime\FeedHeader {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.FeedHeader)
 
  class Incrementality {
  const FULL_DATASET = 0;
  const DIFFERENTIAL = 1;
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.FeedHeader.Incrementality)
  }
  }
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class FeedHeader extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.FeedHeader');
 
  // required gtfs_realtime_version = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "gtfs_realtime_version";
  $f->type = 9;
  $f->rule = 2;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedHeader:gtfs_realtime_version)
  $descriptor->addField($f);
 
  // optional .transit_realtime.FeedHeader.Incrementality incrementality = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "incrementality";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\transit_realtime\FeedHeader\Incrementality';
  $f->default = \transit_realtime\FeedHeader\Incrementality::FULL_DATASET;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedHeader:incrementality)
  $descriptor->addField($f);
 
  // optional timestamp = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "timestamp";
  $f->type = 4;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedHeader:timestamp)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.FeedHeader)
 
  return $descriptor;
  }
 
  /** @var string */
  public $gtfs_realtime_version = null;
 
  /** @var int - \transit_realtime\FeedHeader\Incrementality */
  public $incrementality = \transit_realtime\FeedHeader\Incrementality::FULL_DATASET;
 
  /** @var int */
  public $timestamp = null;
 
 
  /**
  * Check if <gtfs_realtime_version> has a value
  *
  * @return boolean
  */
  public function hasGtfsRealtimeVersion(){
  return $this->_has(1);
  }
 
  /**
  * Clear <gtfs_realtime_version> value
  *
  * @return \transit_realtime\FeedHeader
  */
  public function clearGtfsRealtimeVersion(){
  return $this->_clear(1);
  }
 
  /**
  * Get <gtfs_realtime_version> value
  *
  * @return string
  */
  public function getGtfsRealtimeVersion(){
  return $this->_get(1);
  }
 
  /**
  * Set <gtfs_realtime_version> value
  *
  * @param string $value
  * @return \transit_realtime\FeedHeader
  */
  public function setGtfsRealtimeVersion( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <incrementality> has a value
  *
  * @return boolean
  */
  public function hasIncrementality(){
  return $this->_has(2);
  }
 
  /**
  * Clear <incrementality> value
  *
  * @return \transit_realtime\FeedHeader
  */
  public function clearIncrementality(){
  return $this->_clear(2);
  }
 
  /**
  * Get <incrementality> value
  *
  * @return int - \transit_realtime\FeedHeader\Incrementality
  */
  public function getIncrementality(){
  return $this->_get(2);
  }
 
  /**
  * Set <incrementality> value
  *
  * @param int - \transit_realtime\FeedHeader\Incrementality $value
  * @return \transit_realtime\FeedHeader
  */
  public function setIncrementality( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <timestamp> has a value
  *
  * @return boolean
  */
  public function hasTimestamp(){
  return $this->_has(3);
  }
 
  /**
  * Clear <timestamp> value
  *
  * @return \transit_realtime\FeedHeader
  */
  public function clearTimestamp(){
  return $this->_clear(3);
  }
 
  /**
  * Get <timestamp> value
  *
  * @return int
  */
  public function getTimestamp(){
  return $this->_get(3);
  }
 
  /**
  * Set <timestamp> value
  *
  * @param int $value
  * @return \transit_realtime\FeedHeader
  */
  public function setTimestamp( $value){
  return $this->_set(3, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.FeedHeader)
  }
  }
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class FeedEntity extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.FeedEntity');
 
  // required id = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "id";
  $f->type = 9;
  $f->rule = 2;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedEntity:id)
  $descriptor->addField($f);
 
  // optional is_deleted = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "is_deleted";
  $f->type = 8;
  $f->rule = 1;
  $f->default = false;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedEntity:is_deleted)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TripUpdate trip_update = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "trip_update";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TripUpdate';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedEntity:trip_update)
  $descriptor->addField($f);
 
  // optional .transit_realtime.VehiclePosition vehicle = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "vehicle";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\VehiclePosition';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedEntity:vehicle)
  $descriptor->addField($f);
 
  // optional .transit_realtime.Alert alert = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "alert";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\Alert';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.FeedEntity:alert)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.FeedEntity)
 
  return $descriptor;
  }
 
  /** @var string */
  public $id = null;
 
  /** @var boolean */
  public $is_deleted = true;
 
  /** @var \transit_realtime\TripUpdate */
  public $trip_update = null;
 
  /** @var \transit_realtime\VehiclePosition */
  public $vehicle = null;
 
  /** @var \transit_realtime\Alert */
  public $alert = null;
 
 
  /**
  * Check if <id> has a value
  *
  * @return boolean
  */
  public function hasId(){
  return $this->_has(1);
  }
 
  /**
  * Clear <id> value
  *
  * @return \transit_realtime\FeedEntity
  */
  public function clearId(){
  return $this->_clear(1);
  }
 
  /**
  * Get <id> value
  *
  * @return string
  */
  public function getId(){
  return $this->_get(1);
  }
 
  /**
  * Set <id> value
  *
  * @param string $value
  * @return \transit_realtime\FeedEntity
  */
  public function setId( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <is_deleted> has a value
  *
  * @return boolean
  */
  public function hasIsDeleted(){
  return $this->_has(2);
  }
 
  /**
  * Clear <is_deleted> value
  *
  * @return \transit_realtime\FeedEntity
  */
  public function clearIsDeleted(){
  return $this->_clear(2);
  }
 
  /**
  * Get <is_deleted> value
  *
  * @return boolean
  */
  public function getIsDeleted(){
  return $this->_get(2);
  }
 
  /**
  * Set <is_deleted> value
  *
  * @param boolean $value
  * @return \transit_realtime\FeedEntity
  */
  public function setIsDeleted( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <trip_update> has a value
  *
  * @return boolean
  */
  public function hasTripUpdate(){
  return $this->_has(3);
  }
 
  /**
  * Clear <trip_update> value
  *
  * @return \transit_realtime\FeedEntity
  */
  public function clearTripUpdate(){
  return $this->_clear(3);
  }
 
  /**
  * Get <trip_update> value
  *
  * @return \transit_realtime\TripUpdate
  */
  public function getTripUpdate(){
  return $this->_get(3);
  }
 
  /**
  * Set <trip_update> value
  *
  * @param \transit_realtime\TripUpdate $value
  * @return \transit_realtime\FeedEntity
  */
  public function setTripUpdate(\transit_realtime\TripUpdate $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <vehicle> has a value
  *
  * @return boolean
  */
  public function hasVehicle(){
  return $this->_has(4);
  }
 
  /**
  * Clear <vehicle> value
  *
  * @return \transit_realtime\FeedEntity
  */
  public function clearVehicle(){
  return $this->_clear(4);
  }
 
  /**
  * Get <vehicle> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function getVehicle(){
  return $this->_get(4);
  }
 
  /**
  * Set <vehicle> value
  *
  * @param \transit_realtime\VehiclePosition $value
  * @return \transit_realtime\FeedEntity
  */
  public function setVehicle(\transit_realtime\VehiclePosition $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <alert> has a value
  *
  * @return boolean
  */
  public function hasAlert(){
  return $this->_has(5);
  }
 
  /**
  * Clear <alert> value
  *
  * @return \transit_realtime\FeedEntity
  */
  public function clearAlert(){
  return $this->_clear(5);
  }
 
  /**
  * Get <alert> value
  *
  * @return \transit_realtime\Alert
  */
  public function getAlert(){
  return $this->_get(5);
  }
 
  /**
  * Set <alert> value
  *
  * @param \transit_realtime\Alert $value
  * @return \transit_realtime\FeedEntity
  */
  public function setAlert(\transit_realtime\Alert $value){
  return $this->_set(5, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.FeedEntity)
  }
  }
 
  namespace transit_realtime\TripUpdate {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.TripUpdate)
 
  class StopTimeEvent extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripUpdate.StopTimeEvent');
 
  // optional delay = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "delay";
  $f->type = 5;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeEvent:delay)
  $descriptor->addField($f);
 
  // optional time = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "time";
  $f->type = 3;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeEvent:time)
  $descriptor->addField($f);
 
  // optional uncertainty = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "uncertainty";
  $f->type = 5;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeEvent:uncertainty)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.TripUpdate.StopTimeEvent)
 
  return $descriptor;
  }
 
  /** @var int */
  public $delay = null;
 
  /** @var int */
  public $time = null;
 
  /** @var int */
  public $uncertainty = null;
 
 
  /**
  * Check if <delay> has a value
  *
  * @return boolean
  */
  public function hasDelay(){
  return $this->_has(1);
  }
 
  /**
  * Clear <delay> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function clearDelay(){
  return $this->_clear(1);
  }
 
  /**
  * Get <delay> value
  *
  * @return int
  */
  public function getDelay(){
  return $this->_get(1);
  }
 
  /**
  * Set <delay> value
  *
  * @param int $value
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function setDelay( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <time> has a value
  *
  * @return boolean
  */
  public function hasTime(){
  return $this->_has(2);
  }
 
  /**
  * Clear <time> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function clearTime(){
  return $this->_clear(2);
  }
 
  /**
  * Get <time> value
  *
  * @return int
  */
  public function getTime(){
  return $this->_get(2);
  }
 
  /**
  * Set <time> value
  *
  * @param int $value
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function setTime( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <uncertainty> has a value
  *
  * @return boolean
  */
  public function hasUncertainty(){
  return $this->_has(3);
  }
 
  /**
  * Clear <uncertainty> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function clearUncertainty(){
  return $this->_clear(3);
  }
 
  /**
  * Get <uncertainty> value
  *
  * @return int
  */
  public function getUncertainty(){
  return $this->_get(3);
  }
 
  /**
  * Set <uncertainty> value
  *
  * @param int $value
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function setUncertainty( $value){
  return $this->_set(3, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TripUpdate.StopTimeEvent)
  }
  }
 
  namespace transit_realtime\TripUpdate\StopTimeUpdate {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.TripUpdate.StopTimeUpdate)
 
  class ScheduleRelationship {
  const SCHEDULED = 0;
  const SKIPPED = 1;
  const NO_DATA = 2;
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TripUpdate.StopTimeUpdate.ScheduleRelationship)
  }
  }
  namespace transit_realtime\TripUpdate {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.TripUpdate)
 
  class StopTimeUpdate extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripUpdate.StopTimeUpdate');
 
  // optional stop_sequence = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "stop_sequence";
  $f->type = 13;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:stop_sequence)
  $descriptor->addField($f);
 
  // optional stop_id = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "stop_id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:stop_id)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TripUpdate.StopTimeEvent arrival = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "arrival";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TripUpdate\StopTimeEvent';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:arrival)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TripUpdate.StopTimeEvent departure = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "departure";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TripUpdate\StopTimeEvent';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:departure)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TripUpdate.StopTimeUpdate.ScheduleRelationship schedule_relationship = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "schedule_relationship";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship';
  $f->default = \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SCHEDULED;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:schedule_relationship)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.TripUpdate.StopTimeUpdate)
 
  return $descriptor;
  }
 
  /** @var int */
  public $stop_sequence = null;
 
  /** @var string */
  public $stop_id = null;
 
  /** @var \transit_realtime\TripUpdate\StopTimeEvent */
  public $arrival = null;
 
  /** @var \transit_realtime\TripUpdate\StopTimeEvent */
  public $departure = null;
 
  /** @var int - \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship */
  public $schedule_relationship = \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SCHEDULED;
 
 
  /**
  * Check if <stop_sequence> has a value
  *
  * @return boolean
  */
  public function hasStopSequence(){
  return $this->_has(1);
  }
 
  /**
  * Clear <stop_sequence> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function clearStopSequence(){
  return $this->_clear(1);
  }
 
  /**
  * Get <stop_sequence> value
  *
  * @return int
  */
  public function getStopSequence(){
  return $this->_get(1);
  }
 
  /**
  * Set <stop_sequence> value
  *
  * @param int $value
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function setStopSequence( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <stop_id> has a value
  *
  * @return boolean
  */
  public function hasStopId(){
  return $this->_has(4);
  }
 
  /**
  * Clear <stop_id> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function clearStopId(){
  return $this->_clear(4);
  }
 
  /**
  * Get <stop_id> value
  *
  * @return string
  */
  public function getStopId(){
  return $this->_get(4);
  }
 
  /**
  * Set <stop_id> value
  *
  * @param string $value
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function setStopId( $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <arrival> has a value
  *
  * @return boolean
  */
  public function hasArrival(){
  return $this->_has(2);
  }
 
  /**
  * Clear <arrival> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function clearArrival(){
  return $this->_clear(2);
  }
 
  /**
  * Get <arrival> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function getArrival(){
  return $this->_get(2);
  }
 
  /**
  * Set <arrival> value
  *
  * @param \transit_realtime\TripUpdate\StopTimeEvent $value
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function setArrival(\transit_realtime\TripUpdate\StopTimeEvent $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <departure> has a value
  *
  * @return boolean
  */
  public function hasDeparture(){
  return $this->_has(3);
  }
 
  /**
  * Clear <departure> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function clearDeparture(){
  return $this->_clear(3);
  }
 
  /**
  * Get <departure> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeEvent
  */
  public function getDeparture(){
  return $this->_get(3);
  }
 
  /**
  * Set <departure> value
  *
  * @param \transit_realtime\TripUpdate\StopTimeEvent $value
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function setDeparture(\transit_realtime\TripUpdate\StopTimeEvent $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <schedule_relationship> has a value
  *
  * @return boolean
  */
  public function hasScheduleRelationship(){
  return $this->_has(5);
  }
 
  /**
  * Clear <schedule_relationship> value
  *
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function clearScheduleRelationship(){
  return $this->_clear(5);
  }
 
  /**
  * Get <schedule_relationship> value
  *
  * @return int - \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship
  */
  public function getScheduleRelationship(){
  return $this->_get(5);
  }
 
  /**
  * Set <schedule_relationship> value
  *
  * @param int - \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship $value
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function setScheduleRelationship( $value){
  return $this->_set(5, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TripUpdate.StopTimeUpdate)
  }
  }
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class TripUpdate extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripUpdate');
 
  // required .transit_realtime.TripDescriptor trip = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "trip";
  $f->type = 11;
  $f->rule = 2;
  $f->reference = '\transit_realtime\TripDescriptor';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate:trip)
  $descriptor->addField($f);
 
  // optional .transit_realtime.VehicleDescriptor vehicle = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "vehicle";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\VehicleDescriptor';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate:vehicle)
  $descriptor->addField($f);
 
  // repeated .transit_realtime.TripUpdate.StopTimeUpdate stop_time_update = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "stop_time_update";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\transit_realtime\TripUpdate\StopTimeUpdate';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripUpdate:stop_time_update)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.TripUpdate)
 
  return $descriptor;
  }
 
  /** @var \transit_realtime\TripDescriptor */
  public $trip = null;
 
  /** @var \transit_realtime\VehicleDescriptor */
  public $vehicle = null;
 
  /** @var \transit_realtime\TripUpdate\StopTimeUpdate[] */
  public $stop_time_update = array();
 
 
  /**
  * Check if <trip> has a value
  *
  * @return boolean
  */
  public function hasTrip(){
  return $this->_has(1);
  }
 
  /**
  * Clear <trip> value
  *
  * @return \transit_realtime\TripUpdate
  */
  public function clearTrip(){
  return $this->_clear(1);
  }
 
  /**
  * Get <trip> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function getTrip(){
  return $this->_get(1);
  }
 
  /**
  * Set <trip> value
  *
  * @param \transit_realtime\TripDescriptor $value
  * @return \transit_realtime\TripUpdate
  */
  public function setTrip(\transit_realtime\TripDescriptor $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <vehicle> has a value
  *
  * @return boolean
  */
  public function hasVehicle(){
  return $this->_has(3);
  }
 
  /**
  * Clear <vehicle> value
  *
  * @return \transit_realtime\TripUpdate
  */
  public function clearVehicle(){
  return $this->_clear(3);
  }
 
  /**
  * Get <vehicle> value
  *
  * @return \transit_realtime\VehicleDescriptor
  */
  public function getVehicle(){
  return $this->_get(3);
  }
 
  /**
  * Set <vehicle> value
  *
  * @param \transit_realtime\VehicleDescriptor $value
  * @return \transit_realtime\TripUpdate
  */
  public function setVehicle(\transit_realtime\VehicleDescriptor $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <stop_time_update> has a value
  *
  * @return boolean
  */
  public function hasStopTimeUpdate(){
  return $this->_has(2);
  }
 
  /**
  * Clear <stop_time_update> value
  *
  * @return \transit_realtime\TripUpdate
  */
  public function clearStopTimeUpdate(){
  return $this->_clear(2);
  }
 
  /**
  * Get <stop_time_update> value
  *
  * @param int $idx
  * @return \transit_realtime\TripUpdate\StopTimeUpdate
  */
  public function getStopTimeUpdate($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <stop_time_update> value
  *
  * @param \transit_realtime\TripUpdate\StopTimeUpdate $value
  * @return \transit_realtime\TripUpdate
  */
  public function setStopTimeUpdate(\transit_realtime\TripUpdate\StopTimeUpdate $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <stop_time_update>
  *
  * @return \transit_realtime\TripUpdate\StopTimeUpdate[]
  */
  public function getStopTimeUpdateList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <stop_time_update>
  *
  * @param \transit_realtime\TripUpdate\StopTimeUpdate $value
  * @return \transit_realtime\TripUpdate
  */
  public function addStopTimeUpdate(\transit_realtime\TripUpdate\StopTimeUpdate $value){
  return $this->_add(2, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TripUpdate)
  }
  }
 
  namespace transit_realtime\VehiclePosition {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.VehiclePosition)
 
  class VehicleStopStatus {
  const INCOMING_AT = 0;
  const STOPPED_AT = 1;
  const IN_TRANSIT_TO = 2;
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.VehiclePosition.VehicleStopStatus)
  }
  }
  namespace transit_realtime\VehiclePosition {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.VehiclePosition)
 
  class CongestionLevel {
  const UNKNOWN_CONGESTION_LEVEL = 0;
  const RUNNING_SMOOTHLY = 1;
  const STOP_AND_GO = 2;
  const CONGESTION = 3;
  const SEVERE_CONGESTION = 4;
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.VehiclePosition.CongestionLevel)
  }
  }
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class VehiclePosition extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.VehiclePosition');
 
  // optional .transit_realtime.TripDescriptor trip = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "trip";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TripDescriptor';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:trip)
  $descriptor->addField($f);
 
  // optional .transit_realtime.VehicleDescriptor vehicle = 8
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 8;
  $f->name = "vehicle";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\VehicleDescriptor';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:vehicle)
  $descriptor->addField($f);
 
  // optional .transit_realtime.Position position = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "position";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\Position';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:position)
  $descriptor->addField($f);
 
  // optional current_stop_sequence = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "current_stop_sequence";
  $f->type = 13;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:current_stop_sequence)
  $descriptor->addField($f);
 
  // optional stop_id = 7
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 7;
  $f->name = "stop_id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:stop_id)
  $descriptor->addField($f);
 
  // optional .transit_realtime.VehiclePosition.VehicleStopStatus current_status = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "current_status";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\transit_realtime\VehiclePosition\VehicleStopStatus';
  $f->default = \transit_realtime\VehiclePosition\VehicleStopStatus::IN_TRANSIT_TO;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:current_status)
  $descriptor->addField($f);
 
  // optional timestamp = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "timestamp";
  $f->type = 4;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:timestamp)
  $descriptor->addField($f);
 
  // optional .transit_realtime.VehiclePosition.CongestionLevel congestion_level = 6
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 6;
  $f->name = "congestion_level";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\transit_realtime\VehiclePosition\CongestionLevel';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehiclePosition:congestion_level)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.VehiclePosition)
 
  return $descriptor;
  }
 
  /** @var \transit_realtime\TripDescriptor */
  public $trip = null;
 
  /** @var \transit_realtime\VehicleDescriptor */
  public $vehicle = null;
 
  /** @var \transit_realtime\Position */
  public $position = null;
 
  /** @var int */
  public $current_stop_sequence = null;
 
  /** @var string */
  public $stop_id = null;
 
  /** @var int - \transit_realtime\VehiclePosition\VehicleStopStatus */
  public $current_status = \transit_realtime\VehiclePosition\VehicleStopStatus::IN_TRANSIT_TO;
 
  /** @var int */
  public $timestamp = null;
 
  /** @var int - \transit_realtime\VehiclePosition\CongestionLevel */
  public $congestion_level = null;
 
 
  /**
  * Check if <trip> has a value
  *
  * @return boolean
  */
  public function hasTrip(){
  return $this->_has(1);
  }
 
  /**
  * Clear <trip> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearTrip(){
  return $this->_clear(1);
  }
 
  /**
  * Get <trip> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function getTrip(){
  return $this->_get(1);
  }
 
  /**
  * Set <trip> value
  *
  * @param \transit_realtime\TripDescriptor $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setTrip(\transit_realtime\TripDescriptor $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <vehicle> has a value
  *
  * @return boolean
  */
  public function hasVehicle(){
  return $this->_has(8);
  }
 
  /**
  * Clear <vehicle> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearVehicle(){
  return $this->_clear(8);
  }
 
  /**
  * Get <vehicle> value
  *
  * @return \transit_realtime\VehicleDescriptor
  */
  public function getVehicle(){
  return $this->_get(8);
  }
 
  /**
  * Set <vehicle> value
  *
  * @param \transit_realtime\VehicleDescriptor $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setVehicle(\transit_realtime\VehicleDescriptor $value){
  return $this->_set(8, $value);
  }
 
  /**
  * Check if <position> has a value
  *
  * @return boolean
  */
  public function hasPosition(){
  return $this->_has(2);
  }
 
  /**
  * Clear <position> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearPosition(){
  return $this->_clear(2);
  }
 
  /**
  * Get <position> value
  *
  * @return \transit_realtime\Position
  */
  public function getPosition(){
  return $this->_get(2);
  }
 
  /**
  * Set <position> value
  *
  * @param \transit_realtime\Position $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setPosition(\transit_realtime\Position $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <current_stop_sequence> has a value
  *
  * @return boolean
  */
  public function hasCurrentStopSequence(){
  return $this->_has(3);
  }
 
  /**
  * Clear <current_stop_sequence> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearCurrentStopSequence(){
  return $this->_clear(3);
  }
 
  /**
  * Get <current_stop_sequence> value
  *
  * @return int
  */
  public function getCurrentStopSequence(){
  return $this->_get(3);
  }
 
  /**
  * Set <current_stop_sequence> value
  *
  * @param int $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setCurrentStopSequence( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <stop_id> has a value
  *
  * @return boolean
  */
  public function hasStopId(){
  return $this->_has(7);
  }
 
  /**
  * Clear <stop_id> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearStopId(){
  return $this->_clear(7);
  }
 
  /**
  * Get <stop_id> value
  *
  * @return string
  */
  public function getStopId(){
  return $this->_get(7);
  }
 
  /**
  * Set <stop_id> value
  *
  * @param string $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setStopId( $value){
  return $this->_set(7, $value);
  }
 
  /**
  * Check if <current_status> has a value
  *
  * @return boolean
  */
  public function hasCurrentStatus(){
  return $this->_has(4);
  }
 
  /**
  * Clear <current_status> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearCurrentStatus(){
  return $this->_clear(4);
  }
 
  /**
  * Get <current_status> value
  *
  * @return int - \transit_realtime\VehiclePosition\VehicleStopStatus
  */
  public function getCurrentStatus(){
  return $this->_get(4);
  }
 
  /**
  * Set <current_status> value
  *
  * @param int - \transit_realtime\VehiclePosition\VehicleStopStatus $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setCurrentStatus( $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <timestamp> has a value
  *
  * @return boolean
  */
  public function hasTimestamp(){
  return $this->_has(5);
  }
 
  /**
  * Clear <timestamp> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearTimestamp(){
  return $this->_clear(5);
  }
 
  /**
  * Get <timestamp> value
  *
  * @return int
  */
  public function getTimestamp(){
  return $this->_get(5);
  }
 
  /**
  * Set <timestamp> value
  *
  * @param int $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setTimestamp( $value){
  return $this->_set(5, $value);
  }
 
  /**
  * Check if <congestion_level> has a value
  *
  * @return boolean
  */
  public function hasCongestionLevel(){
  return $this->_has(6);
  }
 
  /**
  * Clear <congestion_level> value
  *
  * @return \transit_realtime\VehiclePosition
  */
  public function clearCongestionLevel(){
  return $this->_clear(6);
  }
 
  /**
  * Get <congestion_level> value
  *
  * @return int - \transit_realtime\VehiclePosition\CongestionLevel
  */
  public function getCongestionLevel(){
  return $this->_get(6);
  }
 
  /**
  * Set <congestion_level> value
  *
  * @param int - \transit_realtime\VehiclePosition\CongestionLevel $value
  * @return \transit_realtime\VehiclePosition
  */
  public function setCongestionLevel( $value){
  return $this->_set(6, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.VehiclePosition)
  }
  }
 
  namespace transit_realtime\Alert {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.Alert)
 
  class Cause {
  const UNKNOWN_CAUSE = 1;
  const OTHER_CAUSE = 2;
  const TECHNICAL_PROBLEM = 3;
  const STRIKE = 4;
  const DEMONSTRATION = 5;
  const ACCIDENT = 6;
  const HOLIDAY = 7;
  const WEATHER = 8;
  const MAINTENANCE = 9;
  const CONSTRUCTION = 10;
  const POLICE_ACTIVITY = 11;
  const MEDICAL_EMERGENCY = 12;
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.Alert.Cause)
  }
  }
  namespace transit_realtime\Alert {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.Alert)
 
  class Effect {
  const NO_SERVICE = 1;
  const REDUCED_SERVICE = 2;
  const SIGNIFICANT_DELAYS = 3;
  const DETOUR = 4;
  const ADDITIONAL_SERVICE = 5;
  const MODIFIED_SERVICE = 6;
  const OTHER_EFFECT = 7;
  const UNKNOWN_EFFECT = 8;
  const STOP_MOVED = 9;
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.Alert.Effect)
  }
  }
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class Alert extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.Alert');
 
  // repeated .transit_realtime.TimeRange active_period = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "active_period";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\transit_realtime\TimeRange';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Alert:active_period)
  $descriptor->addField($f);
 
  // repeated .transit_realtime.EntitySelector informed_entity = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "informed_entity";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\transit_realtime\EntitySelector';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Alert:informed_entity)
  $descriptor->addField($f);
 
  // optional .transit_realtime.Alert.Cause cause = 6
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 6;
  $f->name = "cause";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\transit_realtime\Alert\Cause';
  $f->default = \transit_realtime\Alert\Cause::UNKNOWN_CAUSE;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Alert:cause)
  $descriptor->addField($f);
 
  // optional .transit_realtime.Alert.Effect effect = 7
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 7;
  $f->name = "effect";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\transit_realtime\Alert\Effect';
  $f->default = \transit_realtime\Alert\Effect::UNKNOWN_EFFECT;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Alert:effect)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TranslatedString url = 8
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 8;
  $f->name = "url";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TranslatedString';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Alert:url)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TranslatedString header_text = 10
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 10;
  $f->name = "header_text";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TranslatedString';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Alert:header_text)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TranslatedString description_text = 11
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 11;
  $f->name = "description_text";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TranslatedString';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Alert:description_text)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.Alert)
 
  return $descriptor;
  }
 
  /** @var \transit_realtime\TimeRange[] */
  public $active_period = array();
 
  /** @var \transit_realtime\EntitySelector[] */
  public $informed_entity = array();
 
  /** @var int - \transit_realtime\Alert\Cause */
  public $cause = \transit_realtime\Alert\Cause::UNKNOWN_CAUSE;
 
  /** @var int - \transit_realtime\Alert\Effect */
  public $effect = \transit_realtime\Alert\Effect::UNKNOWN_EFFECT;
 
  /** @var \transit_realtime\TranslatedString */
  public $url = null;
 
  /** @var \transit_realtime\TranslatedString */
  public $header_text = null;
 
  /** @var \transit_realtime\TranslatedString */
  public $description_text = null;
 
 
  /**
  * Check if <active_period> has a value
  *
  * @return boolean
  */
  public function hasActivePeriod(){
  return $this->_has(1);
  }
 
  /**
  * Clear <active_period> value
  *
  * @return \transit_realtime\Alert
  */
  public function clearActivePeriod(){
  return $this->_clear(1);
  }
 
  /**
  * Get <active_period> value
  *
  * @param int $idx
  * @return \transit_realtime\TimeRange
  */
  public function getActivePeriod($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <active_period> value
  *
  * @param \transit_realtime\TimeRange $value
  * @return \transit_realtime\Alert
  */
  public function setActivePeriod(\transit_realtime\TimeRange $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <active_period>
  *
  * @return \transit_realtime\TimeRange[]
  */
  public function getActivePeriodList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <active_period>
  *
  * @param \transit_realtime\TimeRange $value
  * @return \transit_realtime\Alert
  */
  public function addActivePeriod(\transit_realtime\TimeRange $value){
  return $this->_add(1, $value);
  }
 
  /**
  * Check if <informed_entity> has a value
  *
  * @return boolean
  */
  public function hasInformedEntity(){
  return $this->_has(5);
  }
 
  /**
  * Clear <informed_entity> value
  *
  * @return \transit_realtime\Alert
  */
  public function clearInformedEntity(){
  return $this->_clear(5);
  }
 
  /**
  * Get <informed_entity> value
  *
  * @param int $idx
  * @return \transit_realtime\EntitySelector
  */
  public function getInformedEntity($idx = NULL){
  return $this->_get(5, $idx);
  }
 
  /**
  * Set <informed_entity> value
  *
  * @param \transit_realtime\EntitySelector $value
  * @return \transit_realtime\Alert
  */
  public function setInformedEntity(\transit_realtime\EntitySelector $value, $idx = NULL){
  return $this->_set(5, $value, $idx);
  }
 
  /**
  * Get all elements of <informed_entity>
  *
  * @return \transit_realtime\EntitySelector[]
  */
  public function getInformedEntityList(){
  return $this->_get(5);
  }
 
  /**
  * Add a new element to <informed_entity>
  *
  * @param \transit_realtime\EntitySelector $value
  * @return \transit_realtime\Alert
  */
  public function addInformedEntity(\transit_realtime\EntitySelector $value){
  return $this->_add(5, $value);
  }
 
  /**
  * Check if <cause> has a value
  *
  * @return boolean
  */
  public function hasCause(){
  return $this->_has(6);
  }
 
  /**
  * Clear <cause> value
  *
  * @return \transit_realtime\Alert
  */
  public function clearCause(){
  return $this->_clear(6);
  }
 
  /**
  * Get <cause> value
  *
  * @return int - \transit_realtime\Alert\Cause
  */
  public function getCause(){
  return $this->_get(6);
  }
 
  /**
  * Set <cause> value
  *
  * @param int - \transit_realtime\Alert\Cause $value
  * @return \transit_realtime\Alert
  */
  public function setCause( $value){
  return $this->_set(6, $value);
  }
 
  /**
  * Check if <effect> has a value
  *
  * @return boolean
  */
  public function hasEffect(){
  return $this->_has(7);
  }
 
  /**
  * Clear <effect> value
  *
  * @return \transit_realtime\Alert
  */
  public function clearEffect(){
  return $this->_clear(7);
  }
 
  /**
  * Get <effect> value
  *
  * @return int - \transit_realtime\Alert\Effect
  */
  public function getEffect(){
  return $this->_get(7);
  }
 
  /**
  * Set <effect> value
  *
  * @param int - \transit_realtime\Alert\Effect $value
  * @return \transit_realtime\Alert
  */
  public function setEffect( $value){
  return $this->_set(7, $value);
  }
 
  /**
  * Check if <url> has a value
  *
  * @return boolean
  */
  public function hasUrl(){
  return $this->_has(8);
  }
 
  /**
  * Clear <url> value
  *
  * @return \transit_realtime\Alert
  */
  public function clearUrl(){
  return $this->_clear(8);
  }
 
  /**
  * Get <url> value
  *
  * @return \transit_realtime\TranslatedString
  */
  public function getUrl(){
  return $this->_get(8);
  }
 
  /**
  * Set <url> value
  *
  * @param \transit_realtime\TranslatedString $value
  * @return \transit_realtime\Alert
  */
  public function setUrl(\transit_realtime\TranslatedString $value){
  return $this->_set(8, $value);
  }
 
  /**
  * Check if <header_text> has a value
  *
  * @return boolean
  */
  public function hasHeaderText(){
  return $this->_has(10);
  }
 
  /**
  * Clear <header_text> value
  *
  * @return \transit_realtime\Alert
  */
  public function clearHeaderText(){
  return $this->_clear(10);
  }
 
  /**
  * Get <header_text> value
  *
  * @return \transit_realtime\TranslatedString
  */
  public function getHeaderText(){
  return $this->_get(10);
  }
 
  /**
  * Set <header_text> value
  *
  * @param \transit_realtime\TranslatedString $value
  * @return \transit_realtime\Alert
  */
  public function setHeaderText(\transit_realtime\TranslatedString $value){
  return $this->_set(10, $value);
  }
 
  /**
  * Check if <description_text> has a value
  *
  * @return boolean
  */
  public function hasDescriptionText(){
  return $this->_has(11);
  }
 
  /**
  * Clear <description_text> value
  *
  * @return \transit_realtime\Alert
  */
  public function clearDescriptionText(){
  return $this->_clear(11);
  }
 
  /**
  * Get <description_text> value
  *
  * @return \transit_realtime\TranslatedString
  */
  public function getDescriptionText(){
  return $this->_get(11);
  }
 
  /**
  * Set <description_text> value
  *
  * @param \transit_realtime\TranslatedString $value
  * @return \transit_realtime\Alert
  */
  public function setDescriptionText(\transit_realtime\TranslatedString $value){
  return $this->_set(11, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.Alert)
  }
  }
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class TimeRange extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TimeRange');
 
  // optional start = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "start";
  $f->type = 4;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TimeRange:start)
  $descriptor->addField($f);
 
  // optional end = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "end";
  $f->type = 4;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TimeRange:end)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.TimeRange)
 
  return $descriptor;
  }
 
  /** @var int */
  public $start = null;
 
  /** @var int */
  public $end = null;
 
 
  /**
  * Check if <start> has a value
  *
  * @return boolean
  */
  public function hasStart(){
  return $this->_has(1);
  }
 
  /**
  * Clear <start> value
  *
  * @return \transit_realtime\TimeRange
  */
  public function clearStart(){
  return $this->_clear(1);
  }
 
  /**
  * Get <start> value
  *
  * @return int
  */
  public function getStart(){
  return $this->_get(1);
  }
 
  /**
  * Set <start> value
  *
  * @param int $value
  * @return \transit_realtime\TimeRange
  */
  public function setStart( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <end> has a value
  *
  * @return boolean
  */
  public function hasEnd(){
  return $this->_has(2);
  }
 
  /**
  * Clear <end> value
  *
  * @return \transit_realtime\TimeRange
  */
  public function clearEnd(){
  return $this->_clear(2);
  }
 
  /**
  * Get <end> value
  *
  * @return int
  */
  public function getEnd(){
  return $this->_get(2);
  }
 
  /**
  * Set <end> value
  *
  * @param int $value
  * @return \transit_realtime\TimeRange
  */
  public function setEnd( $value){
  return $this->_set(2, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TimeRange)
  }
  }
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class Position extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.Position');
 
  // required latitude = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "latitude";
  $f->type = 2;
  $f->rule = 2;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Position:latitude)
  $descriptor->addField($f);
 
  // required longitude = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "longitude";
  $f->type = 2;
  $f->rule = 2;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Position:longitude)
  $descriptor->addField($f);
 
  // optional bearing = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "bearing";
  $f->type = 2;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Position:bearing)
  $descriptor->addField($f);
 
  // optional odometer = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "odometer";
  $f->type = 1;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Position:odometer)
  $descriptor->addField($f);
 
  // optional speed = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "speed";
  $f->type = 2;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.Position:speed)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.Position)
 
  return $descriptor;
  }
 
  /** @var float */
  public $latitude = null;
 
  /** @var float */
  public $longitude = null;
 
  /** @var float */
  public $bearing = null;
 
  /** @var float */
  public $odometer = null;
 
  /** @var float */
  public $speed = null;
 
 
  /**
  * Check if <latitude> has a value
  *
  * @return boolean
  */
  public function hasLatitude(){
  return $this->_has(1);
  }
 
  /**
  * Clear <latitude> value
  *
  * @return \transit_realtime\Position
  */
  public function clearLatitude(){
  return $this->_clear(1);
  }
 
  /**
  * Get <latitude> value
  *
  * @return float
  */
  public function getLatitude(){
  return $this->_get(1);
  }
 
  /**
  * Set <latitude> value
  *
  * @param float $value
  * @return \transit_realtime\Position
  */
  public function setLatitude( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <longitude> has a value
  *
  * @return boolean
  */
  public function hasLongitude(){
  return $this->_has(2);
  }
 
  /**
  * Clear <longitude> value
  *
  * @return \transit_realtime\Position
  */
  public function clearLongitude(){
  return $this->_clear(2);
  }
 
  /**
  * Get <longitude> value
  *
  * @return float
  */
  public function getLongitude(){
  return $this->_get(2);
  }
 
  /**
  * Set <longitude> value
  *
  * @param float $value
  * @return \transit_realtime\Position
  */
  public function setLongitude( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <bearing> has a value
  *
  * @return boolean
  */
  public function hasBearing(){
  return $this->_has(3);
  }
 
  /**
  * Clear <bearing> value
  *
  * @return \transit_realtime\Position
  */
  public function clearBearing(){
  return $this->_clear(3);
  }
 
  /**
  * Get <bearing> value
  *
  * @return float
  */
  public function getBearing(){
  return $this->_get(3);
  }
 
  /**
  * Set <bearing> value
  *
  * @param float $value
  * @return \transit_realtime\Position
  */
  public function setBearing( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <odometer> has a value
  *
  * @return boolean
  */
  public function hasOdometer(){
  return $this->_has(4);
  }
 
  /**
  * Clear <odometer> value
  *
  * @return \transit_realtime\Position
  */
  public function clearOdometer(){
  return $this->_clear(4);
  }
 
  /**
  * Get <odometer> value
  *
  * @return float
  */
  public function getOdometer(){
  return $this->_get(4);
  }
 
  /**
  * Set <odometer> value
  *
  * @param float $value
  * @return \transit_realtime\Position
  */
  public function setOdometer( $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <speed> has a value
  *
  * @return boolean
  */
  public function hasSpeed(){
  return $this->_has(5);
  }
 
  /**
  * Clear <speed> value
  *
  * @return \transit_realtime\Position
  */
  public function clearSpeed(){
  return $this->_clear(5);
  }
 
  /**
  * Get <speed> value
  *
  * @return float
  */
  public function getSpeed(){
  return $this->_get(5);
  }
 
  /**
  * Set <speed> value
  *
  * @param float $value
  * @return \transit_realtime\Position
  */
  public function setSpeed( $value){
  return $this->_set(5, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.Position)
  }
  }
 
  namespace transit_realtime\TripDescriptor {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.TripDescriptor)
 
  class ScheduleRelationship {
  const SCHEDULED = 0;
  const ADDED = 1;
  const UNSCHEDULED = 2;
  const CANCELED = 3;
  const REPLACEMENT = 5;
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TripDescriptor.ScheduleRelationship)
  }
  }
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class TripDescriptor extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripDescriptor');
 
  // optional trip_id = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "trip_id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripDescriptor:trip_id)
  $descriptor->addField($f);
 
  // optional route_id = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "route_id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripDescriptor:route_id)
  $descriptor->addField($f);
 
  // optional start_time = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "start_time";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripDescriptor:start_time)
  $descriptor->addField($f);
 
  // optional start_date = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "start_date";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripDescriptor:start_date)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TripDescriptor.ScheduleRelationship schedule_relationship = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "schedule_relationship";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TripDescriptor\ScheduleRelationship';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TripDescriptor:schedule_relationship)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.TripDescriptor)
 
  return $descriptor;
  }
 
  /** @var string */
  public $trip_id = null;
 
  /** @var string */
  public $route_id = null;
 
  /** @var string */
  public $start_time = null;
 
  /** @var string */
  public $start_date = null;
 
  /** @var int - \transit_realtime\TripDescriptor\ScheduleRelationship */
  public $schedule_relationship = null;
 
 
  /**
  * Check if <trip_id> has a value
  *
  * @return boolean
  */
  public function hasTripId(){
  return $this->_has(1);
  }
 
  /**
  * Clear <trip_id> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function clearTripId(){
  return $this->_clear(1);
  }
 
  /**
  * Get <trip_id> value
  *
  * @return string
  */
  public function getTripId(){
  return $this->_get(1);
  }
 
  /**
  * Set <trip_id> value
  *
  * @param string $value
  * @return \transit_realtime\TripDescriptor
  */
  public function setTripId( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <route_id> has a value
  *
  * @return boolean
  */
  public function hasRouteId(){
  return $this->_has(5);
  }
 
  /**
  * Clear <route_id> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function clearRouteId(){
  return $this->_clear(5);
  }
 
  /**
  * Get <route_id> value
  *
  * @return string
  */
  public function getRouteId(){
  return $this->_get(5);
  }
 
  /**
  * Set <route_id> value
  *
  * @param string $value
  * @return \transit_realtime\TripDescriptor
  */
  public function setRouteId( $value){
  return $this->_set(5, $value);
  }
 
  /**
  * Check if <start_time> has a value
  *
  * @return boolean
  */
  public function hasStartTime(){
  return $this->_has(2);
  }
 
  /**
  * Clear <start_time> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function clearStartTime(){
  return $this->_clear(2);
  }
 
  /**
  * Get <start_time> value
  *
  * @return string
  */
  public function getStartTime(){
  return $this->_get(2);
  }
 
  /**
  * Set <start_time> value
  *
  * @param string $value
  * @return \transit_realtime\TripDescriptor
  */
  public function setStartTime( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <start_date> has a value
  *
  * @return boolean
  */
  public function hasStartDate(){
  return $this->_has(3);
  }
 
  /**
  * Clear <start_date> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function clearStartDate(){
  return $this->_clear(3);
  }
 
  /**
  * Get <start_date> value
  *
  * @return string
  */
  public function getStartDate(){
  return $this->_get(3);
  }
 
  /**
  * Set <start_date> value
  *
  * @param string $value
  * @return \transit_realtime\TripDescriptor
  */
  public function setStartDate( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <schedule_relationship> has a value
  *
  * @return boolean
  */
  public function hasScheduleRelationship(){
  return $this->_has(4);
  }
 
  /**
  * Clear <schedule_relationship> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function clearScheduleRelationship(){
  return $this->_clear(4);
  }
 
  /**
  * Get <schedule_relationship> value
  *
  * @return int - \transit_realtime\TripDescriptor\ScheduleRelationship
  */
  public function getScheduleRelationship(){
  return $this->_get(4);
  }
 
  /**
  * Set <schedule_relationship> value
  *
  * @param int - \transit_realtime\TripDescriptor\ScheduleRelationship $value
  * @return \transit_realtime\TripDescriptor
  */
  public function setScheduleRelationship( $value){
  return $this->_set(4, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TripDescriptor)
  }
  }
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class VehicleDescriptor extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.VehicleDescriptor');
 
  // optional id = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehicleDescriptor:id)
  $descriptor->addField($f);
 
  // optional label = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "label";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehicleDescriptor:label)
  $descriptor->addField($f);
 
  // optional license_plate = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "license_plate";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.VehicleDescriptor:license_plate)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.VehicleDescriptor)
 
  return $descriptor;
  }
 
  /** @var string */
  public $id = null;
 
  /** @var string */
  public $label = null;
 
  /** @var string */
  public $license_plate = null;
 
 
  /**
  * Check if <id> has a value
  *
  * @return boolean
  */
  public function hasId(){
  return $this->_has(1);
  }
 
  /**
  * Clear <id> value
  *
  * @return \transit_realtime\VehicleDescriptor
  */
  public function clearId(){
  return $this->_clear(1);
  }
 
  /**
  * Get <id> value
  *
  * @return string
  */
  public function getId(){
  return $this->_get(1);
  }
 
  /**
  * Set <id> value
  *
  * @param string $value
  * @return \transit_realtime\VehicleDescriptor
  */
  public function setId( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <label> has a value
  *
  * @return boolean
  */
  public function hasLabel(){
  return $this->_has(2);
  }
 
  /**
  * Clear <label> value
  *
  * @return \transit_realtime\VehicleDescriptor
  */
  public function clearLabel(){
  return $this->_clear(2);
  }
 
  /**
  * Get <label> value
  *
  * @return string
  */
  public function getLabel(){
  return $this->_get(2);
  }
 
  /**
  * Set <label> value
  *
  * @param string $value
  * @return \transit_realtime\VehicleDescriptor
  */
  public function setLabel( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <license_plate> has a value
  *
  * @return boolean
  */
  public function hasLicensePlate(){
  return $this->_has(3);
  }
 
  /**
  * Clear <license_plate> value
  *
  * @return \transit_realtime\VehicleDescriptor
  */
  public function clearLicensePlate(){
  return $this->_clear(3);
  }
 
  /**
  * Get <license_plate> value
  *
  * @return string
  */
  public function getLicensePlate(){
  return $this->_get(3);
  }
 
  /**
  * Set <license_plate> value
  *
  * @param string $value
  * @return \transit_realtime\VehicleDescriptor
  */
  public function setLicensePlate( $value){
  return $this->_set(3, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.VehicleDescriptor)
  }
  }
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class EntitySelector extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.EntitySelector');
 
  // optional agency_id = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "agency_id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.EntitySelector:agency_id)
  $descriptor->addField($f);
 
  // optional route_id = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "route_id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.EntitySelector:route_id)
  $descriptor->addField($f);
 
  // optional route_type = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "route_type";
  $f->type = 5;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.EntitySelector:route_type)
  $descriptor->addField($f);
 
  // optional .transit_realtime.TripDescriptor trip = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "trip";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = '\transit_realtime\TripDescriptor';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.EntitySelector:trip)
  $descriptor->addField($f);
 
  // optional stop_id = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "stop_id";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.EntitySelector:stop_id)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.EntitySelector)
 
  return $descriptor;
  }
 
  /** @var string */
  public $agency_id = null;
 
  /** @var string */
  public $route_id = null;
 
  /** @var int */
  public $route_type = null;
 
  /** @var \transit_realtime\TripDescriptor */
  public $trip = null;
 
  /** @var string */
  public $stop_id = null;
 
 
  /**
  * Check if <agency_id> has a value
  *
  * @return boolean
  */
  public function hasAgencyId(){
  return $this->_has(1);
  }
 
  /**
  * Clear <agency_id> value
  *
  * @return \transit_realtime\EntitySelector
  */
  public function clearAgencyId(){
  return $this->_clear(1);
  }
 
  /**
  * Get <agency_id> value
  *
  * @return string
  */
  public function getAgencyId(){
  return $this->_get(1);
  }
 
  /**
  * Set <agency_id> value
  *
  * @param string $value
  * @return \transit_realtime\EntitySelector
  */
  public function setAgencyId( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <route_id> has a value
  *
  * @return boolean
  */
  public function hasRouteId(){
  return $this->_has(2);
  }
 
  /**
  * Clear <route_id> value
  *
  * @return \transit_realtime\EntitySelector
  */
  public function clearRouteId(){
  return $this->_clear(2);
  }
 
  /**
  * Get <route_id> value
  *
  * @return string
  */
  public function getRouteId(){
  return $this->_get(2);
  }
 
  /**
  * Set <route_id> value
  *
  * @param string $value
  * @return \transit_realtime\EntitySelector
  */
  public function setRouteId( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <route_type> has a value
  *
  * @return boolean
  */
  public function hasRouteType(){
  return $this->_has(3);
  }
 
  /**
  * Clear <route_type> value
  *
  * @return \transit_realtime\EntitySelector
  */
  public function clearRouteType(){
  return $this->_clear(3);
  }
 
  /**
  * Get <route_type> value
  *
  * @return int
  */
  public function getRouteType(){
  return $this->_get(3);
  }
 
  /**
  * Set <route_type> value
  *
  * @param int $value
  * @return \transit_realtime\EntitySelector
  */
  public function setRouteType( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <trip> has a value
  *
  * @return boolean
  */
  public function hasTrip(){
  return $this->_has(4);
  }
 
  /**
  * Clear <trip> value
  *
  * @return \transit_realtime\EntitySelector
  */
  public function clearTrip(){
  return $this->_clear(4);
  }
 
  /**
  * Get <trip> value
  *
  * @return \transit_realtime\TripDescriptor
  */
  public function getTrip(){
  return $this->_get(4);
  }
 
  /**
  * Set <trip> value
  *
  * @param \transit_realtime\TripDescriptor $value
  * @return \transit_realtime\EntitySelector
  */
  public function setTrip(\transit_realtime\TripDescriptor $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <stop_id> has a value
  *
  * @return boolean
  */
  public function hasStopId(){
  return $this->_has(5);
  }
 
  /**
  * Clear <stop_id> value
  *
  * @return \transit_realtime\EntitySelector
  */
  public function clearStopId(){
  return $this->_clear(5);
  }
 
  /**
  * Get <stop_id> value
  *
  * @return string
  */
  public function getStopId(){
  return $this->_get(5);
  }
 
  /**
  * Set <stop_id> value
  *
  * @param string $value
  * @return \transit_realtime\EntitySelector
  */
  public function setStopId( $value){
  return $this->_set(5, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.EntitySelector)
  }
  }
 
  namespace transit_realtime\TranslatedString {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime.TranslatedString)
 
  class Translation extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TranslatedString.Translation');
 
  // required text = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "text";
  $f->type = 9;
  $f->rule = 2;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TranslatedString.Translation:text)
  $descriptor->addField($f);
 
  // optional language = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "language";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TranslatedString.Translation:language)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.TranslatedString.Translation)
 
  return $descriptor;
  }
 
  /** @var string */
  public $text = null;
 
  /** @var string */
  public $language = null;
 
 
  /**
  * Check if <text> has a value
  *
  * @return boolean
  */
  public function hasText(){
  return $this->_has(1);
  }
 
  /**
  * Clear <text> value
  *
  * @return \transit_realtime\TranslatedString\Translation
  */
  public function clearText(){
  return $this->_clear(1);
  }
 
  /**
  * Get <text> value
  *
  * @return string
  */
  public function getText(){
  return $this->_get(1);
  }
 
  /**
  * Set <text> value
  *
  * @param string $value
  * @return \transit_realtime\TranslatedString\Translation
  */
  public function setText( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <language> has a value
  *
  * @return boolean
  */
  public function hasLanguage(){
  return $this->_has(2);
  }
 
  /**
  * Clear <language> value
  *
  * @return \transit_realtime\TranslatedString\Translation
  */
  public function clearLanguage(){
  return $this->_clear(2);
  }
 
  /**
  * Get <language> value
  *
  * @return string
  */
  public function getLanguage(){
  return $this->_get(2);
  }
 
  /**
  * Set <language> value
  *
  * @param string $value
  * @return \transit_realtime\TranslatedString\Translation
  */
  public function setLanguage( $value){
  return $this->_set(2, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TranslatedString.Translation)
  }
  }
 
  namespace transit_realtime {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_transit_realtime)
 
  class TranslatedString extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TranslatedString');
 
  // repeated .transit_realtime.TranslatedString.Translation translation = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "translation";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\transit_realtime\TranslatedString\Translation';
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_transit_realtime.TranslatedString:translation)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_transit_realtime.TranslatedString)
 
  return $descriptor;
  }
 
  /** @var \transit_realtime\TranslatedString\Translation[] */
  public $translation = array();
 
 
  /**
  * Check if <translation> has a value
  *
  * @return boolean
  */
  public function hasTranslation(){
  return $this->_has(1);
  }
 
  /**
  * Clear <translation> value
  *
  * @return \transit_realtime\TranslatedString
  */
  public function clearTranslation(){
  return $this->_clear(1);
  }
 
  /**
  * Get <translation> value
  *
  * @param int $idx
  * @return \transit_realtime\TranslatedString\Translation
  */
  public function getTranslation($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <translation> value
  *
  * @param \transit_realtime\TranslatedString\Translation $value
  * @return \transit_realtime\TranslatedString
  */
  public function setTranslation(\transit_realtime\TranslatedString\Translation $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <translation>
  *
  * @return \transit_realtime\TranslatedString\Translation[]
  */
  public function getTranslationList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <translation>
  *
  * @param \transit_realtime\TranslatedString\Translation $value
  * @return \transit_realtime\TranslatedString
  */
  public function addTranslation(\transit_realtime\TranslatedString\Translation $value){
  return $this->_add(1, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_transit_realtime.TranslatedString)
  }
  }
 
 
  // Copyright 2010 Google Inc
  //
  // The content of this file is licensed under the Creative Commons Attribution
  // 3.0 License.
  //
  // Protocol definition file for GTFS-realtime.
  //
  // GTFS-realtime lets transit agencies provide consumers with realtime
  // information about disruptions to their service (stations closed, lines not
  // operating, important delays etc), location of their vehicles and expected
  // arrival times.
  //
  // This protocol is published on http://code.google.com/transit/realtime/ .
 
  syntax = "proto2";
 
  option cc_api_version = 2;
  option py_api_version = 1;
 
  option java_package = "com.google.transit.realtime";
  package transit_realtime;
 
  // The contents of a feed message.
  // A feed is a continuous stream of feed messages. Each message in the stream is
  // obtained as a response to an appropriate HTTP GET request.
  // A realtime feed is always defined with relation to an existing GTFS feed.
  // All the entity ids are resolved with respect to the GTFS feed.
  //
  // A feed depends on some external configuration:
  // - The corresponding GTFS feed.
  // - Feed application (updates, positions or alerts). A feed should contain only
  // items of one specified application; all the other entities will be ignored.
  // - Polling frequency
  message FeedMessage {
  // Metadata about this feed and feed message.
  required FeedHeader header = 1;
 
  // Contents of the feed.
  repeated FeedEntity entity = 2;
  }
 
  // Metadata about a feed, included in feed messages.
  message FeedHeader {
  // Version of the feed specification.
  // The current version is 1.0.
  required string gtfs_realtime_version = 1;
 
  // Determines whether the current fetch is incremental.
  enum Incrementality {
  FULL_DATASET = 0;
  DIFFERENTIAL = 1;
  }
  optional Incrementality incrementality = 2 [default = FULL_DATASET];
 
  // This timestamp identifies the moment when the content of this feed has been
  // created (in server time). In POSIX time (i.e., number of seconds since
  // January 1st 1970 00:00:00 UTC).
  optional uint64 timestamp = 3;
  }
 
  // A definition (or update) of an entity in the transit feed.
  message FeedEntity {
  // 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).
  required string id = 1;
 
  // Whether this entity is to be deleted. Relevant only for incremental
  // fetches.
  optional bool is_deleted = 2 [default = false];
 
  // Data about the entity itself. Exactly one of the following fields must be
  // present (unless the entity is being deleted).
  optional TripUpdate trip_update = 3;
  optional VehiclePosition vehicle = 4;
  optional Alert alert = 5;
  }
 
  //
  // Entities used in the feed.
  //
 
  // Realtime update of the progress of a vehicle along a trip.
  // Depending on the value of ScheduleRelationship, a TripUpdate can specify:
  // - A trip that proceeds along the schedule.
  // - A trip that proceeds along a route but has no fixed schedule.
  // - A trip that have been added or removed with regard to schedule.
  //
  // The updates can be for future, predicted arrival/departure events, or for
  // past events that already occurred.
  // Normally, updates should get more precise and more certain (see
  // uncertainty below) as the events gets closer to current time.
  // Even if that is not possible, the information for past events should be
  // precise and certain. In particular, if an update points to time in the past
  // but its update's uncertainty is not 0, the client should conclude that the
  // update is a (wrong) prediction and that the trip has not completed yet.
  //
  // Note that the update can describe a trip that is already completed.
  // To this end, it is enough to provide an update for the last stop of the trip.
  // If the time of that is in the past, the client will conclude from that that
  // the whole trip is in the past (it is possible, although inconsequential, to
  // also provide updates for preceding stops).
  // This option is most relevant for a trip that has completed ahead of schedule,
  // but according to the schedule, the trip is still proceeding at the current
  // time. Removing the updates for this trip could make the client assume
  // that the trip is still proceeding.
  // Note that the feed provider is allowed, but not required, to purge past
  // updates - this is one case where this would be practically useful.
  message TripUpdate {
  // The Trip that this message applies to. There can be at most one
  // TripUpdate entity for each actual trip instance.
  // If there is none, that means there is no prediction information available.
  // It does *not* mean that the trip is progressing according to schedule.
  required TripDescriptor trip = 1;
 
  // Additional information on the vehicle that is serving this trip.
  optional VehicleDescriptor vehicle = 3;
 
  // Timing information for a single predicted event (either arrival or
  // departure).
  // Timing consists of delay and/or estimated time, and uncertainty.
  // - delay should be used when the prediction is given relative to some
  // existing schedule in GTFS.
  // - time should be given whether there is a predicted schedule or not. If
  // both time and delay are specified, time will take precedence
  // (although normally, time, if given for a scheduled trip, should be
  // equal to scheduled time in GTFS + delay).
  //
  // Uncertainty applies equally to both time and delay.
  // The uncertainty roughly specifies the expected error in true delay (but
  // note, we don't yet define its precise statistical meaning). It's possible
  // for the uncertainty to be 0, for example for trains that are driven under
  // computer timing control.
  message StopTimeEvent {
  // Delay (in seconds) can be positive (meaning that the vehicle is late) or
  // negative (meaning that the vehicle is ahead of schedule). Delay of 0
  // means that the vehicle is exactly on time.
  optional int32 delay = 1;
 
  // Event as absolute time.
  // In Unix time (i.e., number of seconds since January 1st 1970 00:00:00
  // UTC).
  optional int64 time = 2;
 
  // If uncertainty is omitted, it is interpreted as unknown.
  // If the prediction is unknown or too uncertain, the delay (or time) field
  // should be empty. In such case, the uncertainty field is ignored.
  // To specify a completely certain prediction, set its uncertainty to 0.
  optional int32 uncertainty = 3;
  }
 
  // Realtime update for arrival and/or departure events for a given stop on a
  // trip. Updates can be supplied for both past and future events.
  // The producer is allowed, although not required, to drop past events.
  message StopTimeUpdate {
  // The update is linked to a specific stop either through stop_sequence or
  // stop_id, so one of the fields below must necessarily be set.
  // See the documentation in TripDescriptor for more information.
 
  // Must be the same as in stop_times.txt in the corresponding GTFS feed.
  optional uint32 stop_sequence = 1;
  // Must be the same as in stops.txt in the corresponding GTFS feed.
  optional string stop_id = 4;
 
  optional StopTimeEvent arrival = 2;
  optional StopTimeEvent departure = 3;
 
  // The relation between this StopTime and the static schedule.
  enum ScheduleRelationship {
  // The vehicle is proceeding in accordance with its static schedule of
  // stops, although not necessarily according to the times of the schedule.
  // At least one of arrival and departure must be provided. If the schedule
  // for this stop contains both arrival and departure times then so must
  // this update. An update with only an arrival, say, where the schedule
  // has both, indicates that the trip is terminating early at this stop.
  SCHEDULED = 0;
 
  // The stop is skipped, i.e., the vehicle will not stop at this stop.
  // Arrival and departure are optional.
  SKIPPED = 1;
 
  // No data is given for this stop. The main intention for this value is to
  // give the predictions only for part of a trip, i.e., if the last update
  // for a trip has a NO_DATA specifier, then StopTimes for the rest of the
  // stops in the trip are considered to be unspecified as well.
  // Neither arrival nor departure should be supplied.
  NO_DATA = 2;
  }
  optional ScheduleRelationship schedule_relationship = 5
  [default = SCHEDULED];
  }
 
  // Updates to StopTimes for the trip (both future, i.e., predictions, and in
  // some cases, past ones, i.e., those that already happened).
  // The updates must be sorted by stop_sequence, and apply for all the
  // following stops of the trip up to the next specified one.
  //
  // Example 1:
  // For a trip with 20 stops, a StopTimeUpdate with arrival delay and departure
  // delay of 0 for stop_sequence of the current stop means that the trip is
  // exactly on time.
  //
  // Example 2:
  // For the same trip instance, 3 StopTimeUpdates are provided:
  // - delay of 5 min for stop_sequence 3
  // - delay of 1 min for stop_sequence 8
  // - delay of unspecified duration for stop_sequence 10
  // This will be interpreted as:
  // - stop_sequences 3,4,5,6,7 have delay of 5 min.
  // - stop_sequences 8,9 have delay of 1 min.
  // - stop_sequences 10,... have unknown delay.
  repeated StopTimeUpdate stop_time_update = 2;
  }
 
  // Realtime positioning information for a given vehicle.
  message VehiclePosition {
  // The Trip that this vehicle is serving.
  // Can be empty or partial if the vehicle can not be identified with a given
  // trip instance.
  optional TripDescriptor trip = 1;
 
  // Additional information on the vehicle that is serving this trip.
  optional VehicleDescriptor vehicle = 8;
 
  // Current position of this vehicle.
  optional Position position = 2;
 
  // The stop sequence index of the current stop. The meaning of
  // current_stop_sequence (i.e., the stop that it refers to) is determined by
  // current_status.
  // If current_status is missing IN_TRANSIT_TO is assumed.
  optional uint32 current_stop_sequence = 3;
  // Identifies the current stop. The value must be the same as in stops.txt in
  // the corresponding GTFS feed.
  optional string stop_id = 7;
 
  enum VehicleStopStatus {
  // The vehicle is just about to arrive at the stop (on a stop
  // display, the vehicle symbol typically flashes).
  INCOMING_AT = 0;
 
  // The vehicle is standing at the stop.
  STOPPED_AT = 1;
 
  // The vehicle has departed and is in transit to the next stop.
  IN_TRANSIT_TO = 2;
  }
  // The exact status of the vehicle with respect to the current stop.
  // Ignored if current_stop_sequence is missing.
  optional VehicleStopStatus current_status = 4 [default = IN_TRANSIT_TO];
 
  // Moment at which the vehicle's position was measured. In POSIX time
  // (i.e., number of seconds since January 1st 1970 00:00:00 UTC).
  optional uint64 timestamp = 5;
 
  // Congestion level that is affecting this vehicle.
  enum CongestionLevel {
  UNKNOWN_CONGESTION_LEVEL = 0;
  RUNNING_SMOOTHLY = 1;
  STOP_AND_GO = 2;
  CONGESTION = 3;
  SEVERE_CONGESTION = 4; // People leaving their cars.
  }
  optional CongestionLevel congestion_level = 6;
  }
 
  // An alert, indicating some sort of incident in the public transit network.
  message Alert {
  // Time when the alert should be shown to the user. If missing, the
  // alert will be shown as long as it appears in the feed.
  // If multiple ranges are given, the alert will be shown during all of them.
  repeated TimeRange active_period = 1;
 
  // Entities whose users we should notify of this alert.
  repeated EntitySelector informed_entity = 5;
 
  // Cause of this alert.
  enum Cause {
  UNKNOWN_CAUSE = 1;
  OTHER_CAUSE = 2; // Not machine-representable.
  TECHNICAL_PROBLEM = 3;
  STRIKE = 4; // Public transit agency employees stopped working.
  DEMONSTRATION = 5; // People are blocking the streets.
  ACCIDENT = 6;
  HOLIDAY = 7;
  WEATHER = 8;
  MAINTENANCE = 9;
  CONSTRUCTION = 10;
  POLICE_ACTIVITY = 11;
  MEDICAL_EMERGENCY = 12;
  }
  optional Cause cause = 6 [default = UNKNOWN_CAUSE];
 
  // What is the effect of this problem on the affected entity.
  enum Effect {
  NO_SERVICE = 1;
  REDUCED_SERVICE = 2;
 
  // We don't care about INsignificant delays: they are hard to detect, have
  // little impact on the user, and would clutter the results as they are too
  // frequent.
  SIGNIFICANT_DELAYS = 3;
 
  DETOUR = 4;
  ADDITIONAL_SERVICE = 5;
  MODIFIED_SERVICE = 6;
  OTHER_EFFECT = 7;
  UNKNOWN_EFFECT = 8;
  STOP_MOVED = 9;
  }
  optional Effect effect = 7 [default = UNKNOWN_EFFECT];
 
  // The URL which provides additional information about the alert.
  optional TranslatedString url = 8;
 
  // Alert header. Contains a short summary of the alert text.
  optional TranslatedString header_text = 10;
 
  // Full description for the alert. The information in the description
  // should add to the information of the header.
  optional TranslatedString description_text = 11;
  }
 
  //
  // Low level data structures used above.
  //
 
  // A time interval.
  message TimeRange {
  // Start time, in POSIX time (i.e., number of seconds since January 1st 1970
  // 00:00:00 UTC).
  // If missing, the interval starts at minus infinity.
  optional uint64 start = 1;
 
  // End time, in POSIX time (i.e., number of seconds since January 1st 1970
  // 00:00:00 UTC).
  // If missing, the interval ends at plus infinity.
  optional uint64 end = 2;
  }
 
  // A position.
  message Position {
  // Degrees North, in the WGS-84 coordinate system.
  required float latitude = 1;
 
  // Degrees East, in the WGS-84 coordinate system.
  required float longitude = 2;
 
  // Bearing, in degrees, clockwise from North, i.e., 0 is North and 90 is East.
  // This can be the compass bearing, or the direction towards the next stop
  // or intermediate location.
  // This should not be direction deduced from the sequence of previous
  // positions, which can be computed from previous data.
  optional float bearing = 3;
 
  // Odometer value, in meters.
  optional double odometer = 4;
  // Momentary speed measured by the vehicle, in meters per second.
  optional float speed = 5;
 
  }
 
  // A descriptor that identifies an instance of a GTFS trip, or all instances of
  // a trip along a route.
  // - To specify a single trip instance, the trip_id (and if necessary,
  // start_time) is set. If route_id is also set, then it should be same as one
  // that the given trip corresponds to.
  // - To specify all the trips along a given route, only the route_id should be
  // set. Note that if the trip_id is not known, then stop sequence ids in
  // TripUpdate are not sufficient, and stop_ids must be provided as well. In
  // addition, absolute arrival/departure times must be provided.
  message TripDescriptor {
  // The trip_id from the GTFS feed that this selector refers to.
  // For non frequency expanded trips, this field is enough to uniquely identify
  // the trip. For frequency expanded, start_time and start_date might also be
  // necessary.
  optional string trip_id = 1;
 
  // The route_id from the GTFS that this selector refers to.
  optional string route_id = 5;
 
  // The scheduled start time of this trip instance.
  // This field should be given only if the trip is frequency-expanded in the
  // GTFS feed. The value must precisely correspond to start_time specified for
  // the route in the GTFS feed plus some multiple of headway_secs.
  // Format of the field is same as that of GTFS/frequencies.txt/start_time,
  // e.g., 11:15:35 or 25:15:35.
  optional string start_time = 2;
 
  // The scheduled start date of this trip instance.
  // Must be provided to disambiguate trips that are so late as to collide with
  // a scheduled trip on a next day. For example, for a train that departs 8:00
  // and 20:00 every day, and is 12 hours late, there would be two distinct
  // trips on the same time.
  // This field can be provided but is not mandatory for schedules in which such
  // collisions are impossible - for example, a service running on hourly
  // schedule where a vehicle that is one hour late is not considered to be
  // related to schedule anymore.
  // In YYYYMMDD format.
  optional string start_date = 3;
 
  // The relation between this trip and the static schedule. If a trip is done
  // in accordance with temporary schedule, not reflected in GTFS, then it
  // shouldn't be marked as SCHEDULED, but likely as ADDED.
  enum ScheduleRelationship {
  // Trip that is running in accordance with its GTFS schedule, or is close
  // enough to the scheduled trip to be associated with it.
  SCHEDULED = 0;
 
  // An extra trip that was added in addition to a running schedule, for
  // example, to replace a broken vehicle or to respond to sudden passenger
  // load.
  ADDED = 1;
 
  // A trip that is running with no schedule associated to it, for example, if
  // there is no schedule at all.
  UNSCHEDULED = 2;
 
  // A trip that existed in the schedule but was removed.
  CANCELED = 3;
 
  // A trip that replaces a portion of static schedule.
  // If the trip selector identifies a certain trip instance, then only that
  // instance is replaced. If the selector identifies a route, then all the
  // trips along that route are replaced.
  //
  // The replacement applies only to the portion of the trip supplied. For
  // instance, consider a route that goes through stops A,B,C,D,E,F, and a
  // REPLACEMENT trip provides data for stops A,B,C. Then, the times for stops
  // D,E,F are still taken from the static schedule.
  //
  // A feed might supply several REPLACEMENT trips. In this case, the portion
  // of static schedule that is replaced is the union of what is defined by
  // all the feeds. Normally, all the REPLACEMENT trips should either
  // correspond to the same route or to individual trip instances.
  REPLACEMENT = 5;
  }
  optional ScheduleRelationship schedule_relationship = 4;
  }
 
  // Identification information for the vehicle performing the trip.
  message VehicleDescriptor {
  // Internal system identification of the vehicle. Should be unique per
  // vehicle, and can be used for tracking the vehicle as it proceeds through
  // the system.
  optional string id = 1;
 
  // User visible label, i.e., something that must be shown to the passenger to
  // help identify the correct vehicle.
  optional string label = 2;
 
  // The license plate of the vehicle.
  optional string license_plate = 3;
  }
 
  // A selector for an entity in a GTFS feed.
  message EntitySelector {
  // The values of the fields should correspond to the appropriate fields in the
  // GTFS feed.
  // At least one specifier must be given. If several are given, then the
  // matching has to apply to all the given specifiers.
  optional string agency_id = 1;
  optional string route_id = 2;
  // corresponds to route_type in GTFS.
  optional int32 route_type = 3;
  optional TripDescriptor trip = 4;
  optional string stop_id = 5;
  }
 
  // An internationalized message containing per-language versions of a snippet of
  // text or a URL.
  // One of the strings from a message will be picked up. The resolution proceeds
  // as follows:
  // 1. If the UI language matches the language code of a translation,
  // the first matching translation is picked.
  // 2. If a default UI language (e.g., English) matches the language code of a
  // translation, the first matching translation is picked.
  // 3. If some translation has an unspecified language code, that translation is
  // picked.
  message TranslatedString {
  message Translation {
  // A UTF-8 string containing the message.
  required string text = 1;
  // BCP-47 language code. Can be omitted if the language is unknown or if
  // no i18n is done at all for the feed. At most one translation is
  // allowed to have an unspecified language tag.
  optional string language = 2;
  }
  // At least one translation must be provided.
  repeated Translation translation = 1;
  }
 
 
  <?php
 
  namespace DrSlump;
 
  use DrSlump\Protobuf;
 
  class Protobuf
  {
  const VERSION = '@package_version@';
 
  const RULE_OPTIONAL = 1;
  const RULE_REQUIRED = 2;
  const RULE_REPEATED = 3;
  const RULE_UNKNOWN = -1;
 
  const TYPE_DOUBLE = 1;
  const TYPE_FLOAT = 2;
  const TYPE_INT64 = 3;
  const TYPE_UINT64 = 4;
  const TYPE_INT32 = 5;
  const TYPE_FIXED64 = 6;
  const TYPE_FIXED32 = 7;
  const TYPE_BOOL = 8;
  const TYPE_STRING = 9;
  const TYPE_GROUP = 10;
  const TYPE_MESSAGE = 11;
  const TYPE_BYTES = 12;
  const TYPE_UINT32 = 13;
  const TYPE_ENUM = 14;
  const TYPE_SFIXED32 = 15;
  const TYPE_SFIXED64 = 16;
  const TYPE_SINT32 = 17;
  const TYPE_SINT64 = 18;
  const TYPE_UNKNOWN = -1;
 
 
  static protected $codecs = array();
 
 
  /**
  * Setup SPL autoloader for Protobuf library classes
  *
  * @static
  * @return void
  */
  static public function autoload()
  {
  spl_autoload_register(function($class){
  $prefix = __CLASS__ . '\\';
  if (strpos($class, $prefix) === 0) {
  // Remove vendor from name
  $class = substr($class, strlen(__NAMESPACE__)+1);
  // Convert namespace separator to directory ones
  $class = str_replace('\\', DIRECTORY_SEPARATOR, $class);
  // Prefix with this file's directory
  $class = __DIR__ . DIRECTORY_SEPARATOR . $class;
 
  include($class . '.php');
  return true;
  }
 
  return false;
  });
  }
 
  /**
  * Obtain an instance of the descriptor's registry
  *
  * @static
  * @return Protobuf\Registry
  */
  static public function getRegistry()
  {
  static $registry = NULL;
 
  if (NULL === $registry) {
  $registry = new Protobuf\Registry();
  }
 
  return $registry;
  }
 
 
  static public function getCodec($codec = null)
  {
  if ($codec instanceof Protobuf\CodecInterface) {
  return $codec;
  }
 
  // Bootstrap the library's default codec if none is available
  if (!isset(self::$codecs['default'])) {
  $default = new Protobuf\Codec\Binary();
  self::registerCodec('default', $default);
  self::registerCodec('binary', $default);
  }
 
  if (is_string($codec)) {
  $codec = strtolower($codec);
  if (!isset(self::$codecs[$codec])) {
  throw new Protobuf\Exception('No codec found by name "' . $codec . '"');
  }
  return self::$codecs[$codec];
  }
 
  return self::getCodec('default');
  }
 
  static public function setDefaultCodec($codec)
  {
  if (is_string($codec)) {
  $codec = self::getCodec($codec);
  }
 
  if ($codec instanceof Protobuf\CodecInterface) {
  self::registerCodec('default', $codec);
  } else {
  throw new Protobuf\Exception('Codec must implement DrSlump\Protobuf\CodecInterface');
  }
  }
 
  static public function registerCodec($name, Protobuf\CodecInterface $codec)
  {
  $name = strtolower($name);
  self::$codecs[$name] = $codec;
  }
 
  static public function unregisterCodec($name)
  {
  $name = strtolower($name);
  if (isset(self::$codecs[$name])) {
  unset(self::$codecs[$name]);
  return true;
  }
  return false;
  }
 
  /**
  * Encodes a message using the default codec
  *
  * @static
  * @param \DrSlump\Protobuf\Message $message
  * @return string
  */
  static public function encode(Protobuf\Message $message)
  {
  $codec = self::getCodec();
  return $codec->encode($message);
  }
 
  /**
  * @static
  * @param String|Message $message
  * @param String $data
  * @return \DrSlump\Protobuf\Message
  */
  static public function decode($message, $data)
  {
  if (is_string($message)) {
  $message = '\\' . ltrim($message, '\\');
  $message = new $message;
  }
 
  $codec = self::getCodec();
  return $codec->decode($message, $data);
  }
  }
 
  <?php
 
  namespace DrSlump\Protobuf;
 
  use DrSlump\Protobuf;
 
  abstract class AnnotatedMessage extends Message
  {
  static public function descriptor()
  {
  $class = get_called_class();
 
  // Instantiate a new descriptor
  $descriptor = new Descriptor($class);
 
  $rflClass = new \ReflectionClass($class);
  $props = $rflClass->getProperties();
  foreach ($props as $prop) {
  $doc = $prop->getDocComment();
  if (empty($doc)) {
  continue;
  }
 
  // Format: @protobuf(tag=X, type=bool, required=true)
 
  // Extract annotation from the comment
  if (!preg_match('/@protobuf\s?\(([^\)]+)\)/', $doc, $m)) {
  continue;
  }
 
  // Parse params
  $params = explode(',', $m[1]);
  $params = array_filter(array_map('trim', $params));
 
  $options = array();
  foreach ($params as $param) {
  $parts = explode('=', $param);
  $parts = array_filter(array_map('trim', $parts));
  $options[$parts[0]] = count($parts) < 2
  ? true
  : $parts[1];
  }
 
  // Check if we have the minimum required options
  if (empty($options['tag'])) {
  throw new \InvalidArgumentException('The tag option is required for property ' . $prop->getName());
  }
  if (empty($options['type'])) {
  throw new \InvalidArgumentException('The type option is required for property ' . $prop->getName());
  }
 
  // Normalize boolean values
  foreach(array('required', 'optional', 'repeated', 'packed') as $opt) {
  if (isset($options[$opt])) {
  $options[$opt] = filter_var($options[$opt], FILTER_VALIDATE_BOOLEAN);
  }
  }
 
  // Build a field descriptor
  $f = new Protobuf\Field();
  $f->number = (int)$options['tag'];
  $f->name = $prop->getName();
 
  // Convert type name to its numeric constant
  switch (strtolower($options['type'])) {
  case 'double' : $f->type = Protobuf::TYPE_DOUBLE; break;
  case 'float' : $f->type = Protobuf::TYPE_FLOAT; break;
  case 'int64' : $f->type = Protobuf::TYPE_INT64; break;
  case 'uint64' : $f->type = Protobuf::TYPE_UINT64; break;
  case 'int32' : $f->type = Protobuf::TYPE_INT32; break;
  case 'fixed64' : $f->type = Protobuf::TYPE_FIXED64; break;
  case 'fixed32' : $f->type = Protobuf::TYPE_FIXED32; break;
  case 'bool' : $f->type = Protobuf::TYPE_BOOL; break;
  case 'string' : $f->type = Protobuf::TYPE_STRING; break;
  case 'message' : $f->type = Protobuf::TYPE_MESSAGE; break;
  case 'bytes' : $f->type = Protobuf::TYPE_BYTES; break;
  case 'uint32' : $f->type = Protobuf::TYPE_UINT32; break;
  case 'enum' : $f->type = Protobuf::TYPE_ENUM; break;
  case 'sfixed32': $f->type = Protobuf::TYPE_SFIXED32; break;
  case 'sfixed64': $f->type = Protobuf::TYPE_SFIXED64; break;
  case 'sint32' : $f->type = Protobuf::TYPE_SINT32; break;
  case 'sint64' : $f->type = Protobuf::TYPE_SINT64; break;
  default:
  throw new \InvalidArgumentException('Type ' . $options['type'] . ' is not recognized as valid for property ' . $prop->getName());
  }
 
  // Define the rule type
  $f->rule = Protobuf::RULE_OPTIONAL;
  if (!empty($options['required'])) $f->rule = Protobuf::RULE_REQUIRED;
  if (!empty($options['repeated'])) $f->rule = Protobuf::RULE_REPEATED;
 
  // Check if it's flagged as packed
  if (isset($options['packed'])) {
  $f->packed = $options['packed'];
  }
 
  // Get the reference
  if (isset($options['reference'])) {
  $f->reference = $options['reference'];
  } else if ($f->type === Protobuf::TYPE_MESSAGE || $f->type === Protobuf::TYPE_ENUM) {
  throw new \InvalidArgumentException('Property ' . $prop->getName() . ' requires the "reference" option');
  }
 
  if (isset($options['default'])) {
  $f->default = $options['default'];
  }
 
  // Add the field to the message descriptor
  $descriptor->addField($f);
  }
 
  return $descriptor;
  }
 
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec;
 
  use DrSlump\Protobuf;
 
  class Binary implements Protobuf\CodecInterface
  {
  const WIRE_VARINT = 0;
  const WIRE_FIXED64 = 1;
  const WIRE_LENGTH = 2;
  const WIRE_GROUP_START = 3;
  const WIRE_GROUP_END = 4;
  const WIRE_FIXED32 = 5;
  const WIRE_UNKNOWN = -1;
 
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @return string
  */
  public function encode(Protobuf\Message $message)
  {
  return $this->encodeMessage($message);
  }
 
  /**
  * @param String|Message $message
  * @param String $data
  * @return \DrSlump\Protobuf\Message
  */
  public function decode(Protobuf\Message $message, $data)
  {
  return $this->decodeMessage($message, $data);
  }
 
 
  protected function encodeMessage(Protobuf\Message $message)
  {
  $writer = new Binary\Writer();
 
  // Get message descriptor
  $descriptor = Protobuf::getRegistry()->getDescriptor($message);
 
  foreach ($descriptor->getFields() as $tag=>$field) {
 
  $empty = !$message->_has($tag);
  if ($field->isRequired() && $empty) {
  throw new \UnexpectedValueException(
  'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value'
  );
  }
 
  // Skip empty fields
  if ($empty) {
  continue;
  }
 
  $type = $field->getType();
  $wire = $field->isPacked() ? self::WIRE_LENGTH : $this->getWireType($type, null);
 
  // Compute key with tag number and wire type
  $key = $tag << 3 | $wire;
 
  $value = $message->_get($tag);
 
  if ($field->isRepeated()) {
 
  // Packed fields are encoded as a length-delimited stream containing
  // the concatenated encoding of each value.
  if ($field->isPacked() && !empty($value)) {
  $subwriter = new Binary\Writer();
  foreach($value as $val) {
  $this->encodeSimpleType($subwriter, $type, $val);
  }
  $data = $subwriter->getBytes();
  $writer->varint($key);
  $writer->varint(strlen($data));
  $writer->write($data);
  } else {
  foreach($value as $val) {
  if ($type !== Protobuf::TYPE_MESSAGE) {
  $writer->varint($key);
  $this->encodeSimpleType($writer, $type, $val);
  } else {
  $writer->varint($key);
  $data = $this->encodeMessage($val);
  $writer->varint(strlen($data));
  $writer->write($data);
  }
  }
  }
  } else {
  if ($type !== Protobuf::TYPE_MESSAGE) {
  $writer->varint($key);
  $this->encodeSimpleType($writer, $type, $value);
  } else {
  $writer->varint($key);
  $data = $this->encodeMessage($value);
  $writer->varint(strlen($data));
  $writer->write($data);
  }
  }
  }
 
  return $writer->getBytes();
  }
 
  protected function encodeSimpleType($writer, $type, $value)
  {
  switch ($type) {
  case Protobuf::TYPE_INT32:
  case Protobuf::TYPE_INT64:
  case Protobuf::TYPE_UINT64:
  case Protobuf::TYPE_UINT32:
  $writer->varint($value);
  break;
 
  case Protobuf::TYPE_SINT32: // ZigZag
  $writer->zigzag($value, 32);
  break;
 
  case Protobuf::TYPE_SINT64 : // ZigZag
  $writer->zigzag($value, 64);
  break;
 
  case Protobuf::TYPE_DOUBLE:
  $writer->double($value);
  break;
  case Protobuf::TYPE_FIXED64:
  $writer->fixed64($value);
  break;
  case Protobuf::TYPE_SFIXED64:
  $writer->sFixed64($value);
  break;
 
  case Protobuf::TYPE_FLOAT:
  $writer->float($value);
  break;
  case Protobuf::TYPE_FIXED32:
  $writer->fixed32($value);
  break;
  case Protobuf::TYPE_SFIXED32:
  $writer->sFixed32($value);
  break;
 
  case Protobuf::TYPE_BOOL:
  $writer->varint($value ? 1 : 0);
  break;
 
  case Protobuf::TYPE_STRING:
  case Protobuf::TYPE_BYTES:
  $writer->varint(strlen($value));
  $writer->write($value);
  break;
 
  case Protobuf::TYPE_MESSAGE:
  // Messages are not supported in this method
  return null;
 
  case Protobuf::TYPE_ENUM:
  $writer->varint($value);
  break;
 
  default:
  throw new \Exception('Unknown field type ' . $type);
  }
  }
 
 
  protected function decodeMessage(\DrSlump\Protobuf\Message $message, $data)
  {
  /** @var $message \DrSlump\Protobuf\Message */
  /** @var $descriptor \DrSlump\Protobuf\Descriptor */
 
  // Create a binary reader for the data
  $reader = new Protobuf\Codec\Binary\Reader($data);
 
  // Get message descriptor
  $descriptor = Protobuf::getRegistry()->getDescriptor($message);
 
  while (!$reader->eof()) {
 
  // Get initial varint with tag number and wire type
  $key = $reader->varint();
  if ($reader->eof()) break;
 
  $wire = $key & 0x7;
  $tag = $key >> 3;
 
  // Find the matching field for the tag number
  $field = $descriptor->getField($tag);
  if (!$field) {
  $data = $this->decodeUnknown($reader, $wire);
  $unknown = new Binary\Unknown($tag, $wire, $data);
  $message->addUnknown($unknown);
  continue;
  }
 
  $type = $field->getType();
 
  // Check if we are dealing with a packed stream, we cannot rely on the packed
  // flag of the message since we cannot be certain if the creator of the message
  // was using it.
  if ($wire === self::WIRE_LENGTH && $field->isRepeated() && $this->isPackable($type)) {
  $length = $reader->varint();
  $until = $reader->pos() + $length;
  while ($reader->pos() < $until) {
  $item = $this->decodeSimpleType($reader, $type, self::WIRE_VARINT);
  $message->_add($tag, $item);
  }
 
  } else {
 
  // Assert wire and type match
  $this->assertWireType($wire, $type);
 
  // Check if it's a sub-message
  if ($type === Protobuf::TYPE_MESSAGE) {
  $submessage = $field->getReference();
  $submessage = new $submessage;
 
  $length = $this->decodeSimpleType($reader, Protobuf::TYPE_INT64, self::WIRE_VARINT);
  $data = $reader->read($length);
 
  $value = $this->decodeMessage($submessage, $data);
  } else {
  $value = $this->decodeSimpleType($reader, $type, $wire);
  }
 
  // Support non-packed repeated fields
  if ($field->isRepeated()) {
  $message->_add($tag, $value);
  } else {
  $message->_set($tag, $value);
  }
  }
  }
 
  return $message;
  }
 
  protected function isPackable($type)
  {
  static $packable = array(
  Protobuf::TYPE_INT64,
  Protobuf::TYPE_UINT64,
  Protobuf::TYPE_INT32,
  Protobuf::TYPE_UINT32,
  Protobuf::TYPE_SINT32,
  Protobuf::TYPE_SINT64,
  Protobuf::TYPE_DOUBLE,
  Protobuf::TYPE_FIXED64,
  Protobuf::TYPE_SFIXED64,
  Protobuf::TYPE_FLOAT,
  Protobuf::TYPE_FIXED32,
  Protobuf::TYPE_SFIXED32,
  Protobuf::TYPE_BOOL,
  Protobuf::TYPE_ENUM
  );
 
  return in_array($type, $packable);
  }
 
  protected function decodeUnknown($reader, $wire)
  {
  switch ($wire) {
  case self::WIRE_VARINT:
  return $reader->varint();
  case self::WIRE_LENGTH:
  $length = $reader->varint();
  return $reader->read($length);
  case self::WIRE_FIXED32:
  return $reader->fixed32();
  case self::WIRE_FIXED64:
  return $reader->fixed64();
  case self::WIRE_GROUP_START:
  case self::WIRE_GROUP_END:
  throw new \RuntimeException('Groups are deprecated in Protocol Buffers and unsupported by this library');
  default:
  throw new \RuntimeException('Unsupported wire type (' . $wire . ') while consuming unknown field');
  }
  }
 
  protected function assertWireType($wire, $type)
  {
  $expected = $this->getWireType($type, $wire);
  if ($wire !== $expected) {
  throw new \RuntimeException("Expected wire type $expected but got $wire for type $type");
  }
  }
 
  protected function getWireType($type, $default)
  {
  switch ($type) {
  case Protobuf::TYPE_INT32:
  case Protobuf::TYPE_INT64:
  case Protobuf::TYPE_UINT32:
  case Protobuf::TYPE_UINT64:
  case Protobuf::TYPE_SINT32:
  case Protobuf::TYPE_SINT64:
  case Protobuf::TYPE_BOOL:
  case Protobuf::TYPE_ENUM:
  return self::WIRE_VARINT;
  case Protobuf::TYPE_FIXED64:
  case Protobuf::TYPE_SFIXED64:
  case Protobuf::TYPE_DOUBLE:
  return self::WIRE_FIXED64;
  case Protobuf::TYPE_STRING:
  case Protobuf::TYPE_BYTES:
  case Protobuf::TYPE_MESSAGE:
  return self::WIRE_LENGTH;
  case Protobuf::TYPE_FIXED32:
  case Protobuf::TYPE_SFIXED32:
  case Protobuf::TYPE_FLOAT:
  return self::WIRE_FIXED32;
  default:
  // Unknown fields just return the reported wire type
  return $default;
  }
  }
 
  protected function decodeSimpleType($reader, $type, $wireType)
  {
  switch ($type) {
  case Protobuf::TYPE_INT64:
  case Protobuf::TYPE_UINT64:
  case Protobuf::TYPE_INT32:
  case Protobuf::TYPE_UINT32:
  return $reader->varint();
 
  case Protobuf::TYPE_SINT32: // ZigZag
  return $reader->zigzag();
  case Protobuf::TYPE_SINT64: // ZigZag
  return $reader->zigzag();
  case Protobuf::TYPE_DOUBLE:
  return $reader->double();
  case Protobuf::TYPE_FIXED64:
  return $reader->fixed64();
  case Protobuf::TYPE_SFIXED64:
  return $reader->sFixed64();
 
  case Protobuf::TYPE_FLOAT:
  return $reader->float();
  case Protobuf::TYPE_FIXED32:
  return $reader->fixed32();
  case Protobuf::TYPE_SFIXED32:
  return $reader->sFixed32();
 
  case Protobuf::TYPE_BOOL:
  return (bool)$reader->varint();
 
  case Protobuf::TYPE_STRING:
  $length = $reader->varint();
  return $reader->read($length);
 
  case Protobuf::TYPE_MESSAGE:
  // Messages are not supported in this method
  return null;
 
  case Protobuf::TYPE_BYTES:
  $length = $reader->varint();
  return $reader->read($length);
 
  case Protobuf::TYPE_ENUM:
  return $reader->varint();
 
  default:
  // Unknown type, follow wire type rules
  switch ($wireType) {
  case self::WIRE_VARINT:
  return $reader->varint();
  case self::WIRE_FIXED32:
  return $reader->fixed32();
  case self::WIRE_FIXED64:
  return $reader->fixed64();
  case self::WIRE_LENGTH:
  $length = $reader->varint();
  return $reader->read($length);
  case self::WIRE_GROUP_START:
  case self::WIRE_GROUP_END:
  throw new \RuntimeException('Group is deprecated and not supported');
  default:
  throw new \RuntimeException('Unsupported wire type number ' . $wireType);
  }
  }
 
  }
 
  }
  <?php
 
  namespace DrSlump\Protobuf\Codec\Binary;
 
  /**
  * Implements reading primitives for Protobuf binary streams
  *
  * Important: There are no checks in place for overflows, so you must
  * be aware of PHP's integer and floating point limits.
  *
  * @note Protobuf uses little-endian order
  */
  class Reader
  {
  /** @var resource */
  protected $_fd;
 
  /**
  * Create a new reader from a file descriptor or a string of bytes
  *
  * @param resource|string $fdOrString
  */
  public function __construct($fdOrString)
  {
  if (is_resource($fdOrString)) {
  $this->_fd = $fdOrString;
  } else {
  // @todo Could this be faster by using a custom String wrapper?
  $this->_fd = fopen('data://text/plain,' . urlencode($fdOrString), 'rb');
  }
  }
 
  public function __destruct()
  {
  fclose($this->_fd);
  }
 
  /**
  * Obtain a number of bytes from the string
  *
  * @throws \RuntimeException
  * @param int $length
  * @return string
  */
  public function read($length)
  {
  // Protect against 0 byte reads when an EOF
  if ($length < 1) return '';
 
  $bytes = fread($this->_fd, $length);
  if (FALSE === $bytes) {
  throw new \RuntimeException('Failed to read ' . $length . ' bytes');
  }
 
  return $bytes;
  }
 
  /**
  * Check if we have reached the end of the stream
  *
  * @return bool
  */
  public function eof()
  {
  return feof($this->_fd);
  }
 
  /**
  * Obtain the current position in the stream
  *
  * @return int
  */
  public function pos()
  {
  return ftell($this->_fd);
  }
 
  /**
  * Obtain a byte
  *
  * @return int
  */
  public function byte()
  {
  return ord($this->read(1));
  }
 
  /**
  * Decode a varint
  *
  * @return int
  */
  public function varint()
  {
  $result = $shift = 0;
  do {
  $byte = $this->byte();
  $result |= ($byte & 0x7f) << $shift;
  $shift += 7;
  } while ($byte > 0x7f);
 
  return $result;
  }
 
  /**
  * Decodes a zigzag integer of the given bits
  *
  * @param int $bits - Either 32 or 64
  */
  public function zigzag()
  {
  $number = $this->varint();
  return ($number >> 1) ^ (-($number & 1));
  }
 
  /**
  * Decode a fixed 32bit integer with sign
  *
  * @return int
  */
  public function sFixed32()
  {
  $bytes = $this->read(4);
  if ($this->isBigEndian()) {
  $bytes = strrev($bytes);
  }
 
  list(, $result) = unpack('l', $bytes);
  return $result;
  }
 
  /**
  * Decode a fixed 32bit integer without sign
  *
  * @return int
  */
  public function fixed32()
  {
  $bytes = $this->read(4);
 
  if (PHP_INT_SIZE < 8) {
  list(, $lo, $hi) = unpack('v*', $bytes);
  $result = $hi << 16 | $lo;
  } else {
  list(, $result) = unpack('V*', $bytes);
  }
 
  return $result;
  }
 
  /**
  * Decode a fixed 62bit integer with sign
  *
  * @return int
  */
  public function sFixed64()
  {
  $bytes = $this->read(8);
 
  list(, $lo0, $lo1, $hi0, $hi1) = unpack('v*', $bytes);
  return ($hi1 << 16 | $hi0) << 32 | ($lo1 << 16 | $lo0);
  }
 
  /**
  * Decode a fixed 62bit integer without sign
  *
  * @return int
  */
  public function fixed64()
  {
  return $this->sFixed64();
  }
 
  /**
  * Decode a 32bit float
  *
  * @return float
  */
  public function float()
  {
  $bytes = $this->read(4);
  if ($this->isBigEndian()) {
  $bytes = strrev($bytes);
  }
 
  list(, $result) = unpack('f', $bytes);
  return $result;
  }
 
  /**
  * Decode a 64bit double
  *
  * @return float
  */
  public function double()
  {
  $bytes = $this->read(8);
  if ($this->isBigEndian()) {
  $bytes = strrev($bytes);
  }
 
  list(, $result) = unpack('d', $bytes);
  return $result;
  }
 
  /**
  * Check if the current architecture is Big Endian
  *
  * @return bool
  */
  public function isBigEndian()
  {
  static $endianness;
 
  if (NULL === $endianness) {
  list(,$result) = unpack('L', pack('V', 1));
  $endianness = $result !== 1;
  }
 
  return $endianness;
  }
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec\Binary;
 
  class Unknown extends \DrSlump\Protobuf\Unknown
  {
  public function __construct($tag, $type, $data)
  {
  $this->tag = $tag;
  $this->type = $type;
  $this->data = $data;
  }
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec\Binary;
 
  /**
  * Implements writing primitives for Protobuf binary streams
  *
  * @note Protobuf uses little-endian order
  */
  class Writer
  {
  /** @var resource */
  protected $_fd;
 
 
  public function __construct()
  {
  $this->_fd = fopen('php://memory', 'wb');
  }
 
  public function __destruct()
  {
  fclose($this->_fd);
  }
 
  /**
  * Get the current bytes in the stream
  *
  * @return string
  */
  public function getBytes()
  {
  fseek($this->_fd, 0, SEEK_SET);
  return stream_get_contents($this->_fd);
  }
 
  /**
  * Store the given bytes in the stream
  *
  * @throws \RuntimeException
  * @param string $bytes
  * @param int $length
  */
  public function write($bytes, $length = null)
  {
  if ($length === NULL) {
  $length = strlen($bytes);
  }
 
  $written = fwrite($this->_fd, $bytes, $length);
  if ($written !== $length) {
  throw new \RuntimeException('Failed to write ' . $length . ' bytes');
  }
  }
 
  /**
  * Store a single byte
  *
  * @param int $value
  */
  public function byte($value)
  {
  $this->write(chr($value), 1);
  }
 
  /**
  * Store an integer encoded as varint
  *
  * @throws \OutOfBoundsException
  * @param int $value
  */
  public function varint($value)
  {
  // Small values do not need to be encoded
  if ($value >= 0 && $value < 0x80) {
  $this->byte($value);
  return;
  }
 
  // Build an array of bytes with the encoded values
  if ($value > 0) {
  $values = array();
  while ($value > 0) {
  $values[] = 0x80 | ($value & 0x7f);
  $value = $value >> 7;
  }
  } else if (function_exists('gmp_init')) {
  $value = PHP_INT_SIZE < 8
  ? gmp_and($value, '0x0ffffffffffffffff')
  : sprintf('%u', $value);
 
  $values = $this->varint_gmp($value);
  } else if (PHP_INT_SIZE < 8) {
  throw new \OutOfBoundsException(
  "PHP versions compiled with 32bit integers can only support negative integer encoding with GMP extension ($value was given)"
  );
  } else if (function_exists('bccomp')) {
  $value = sprintf('%u', $value);
  $values = $this->varint_bc($value);
  } else {
  throw new \OutOfBoundsException("Varints of negative integers are only supported with GMP or BC big integers PHP extensions ($value was given)");
  }
 
  // Remove the MSB flag from the last byte
  $values[count($values)-1] &= 0x7f;
 
  // Convert the byte sized ints to actual bytes in a string
  //$bytes = implode('', array_map('chr', $values));
  $bytes = call_user_func_array('pack', array_merge(array('C*'), $values));;
 
  $this->write($bytes);
  }
 
  public function varint_gmp($value)
  {
  static $x00, $x7f, $x80;
 
  if (NULL === $x00) {
  $x00 = \gmp_init(0x00);
  $x7f = \gmp_init(0x7f);
  $x80 = \gmp_init(0x80);
  }
 
  $values = array();
  while (\gmp_cmp($value, $x00) > 0) {
  $values[] = \gmp_intval(\gmp_and($value, $x7f)) | 0x80;
  $value = \gmp_div_q($value, $x80);
  }
 
  return $values;
  }
 
  public function varint_bc($value)
  {
  $values = array();
  while (\bccomp($value, 0, 0) > 0) {
  // Get the last 7bits of the number
  $bin = '';
  $dec = $value;
  do {
  $rest = bcmod($dec, 2);
  $dec = bcdiv($dec, 2, 0);
  $bin = $rest . $bin;
  } while ($dec > 0 && strlen($bin) < 7);
 
  // Pack as a decimal and apply the flag
  $values[] = intval($bin, 2) | 0x80;
 
  $value = bcdiv($value, 0x80, 0);
  }
 
  return $values;
  }
 
  /**
  * Encodes an integer with zigzag
  *
  * @param int $value
  * @param int $base Either 32 or 64 bits
  */
  public function zigzag($value, $base = 32)
  {
  $value = ($value << 1) ^ ($value >> $base-1);
  $this->varint($value);
  }
 
  /**
  * Encode an integer as a fixed of 32bits with sign
  *
  * @param int $value
  */
  public function sFixed32($value)
  {
  $bytes = pack('l*', $value);
  if ($this->isBigEndian()) {
  $bytes = strrev($bytes);
  }
 
  $this->write($bytes, 4);
  }
 
  /**
  * Encode an integer as a fixed of 32bits without sign
  *
  * @param int $value
  */
  public function fixed32($value)
  {
  $bytes = pack('V*', $value);
  $this->write($bytes, 4);
  }
 
  /**
  * Encode an integer as a fixed of 64bits with sign
  *
  * @param int $value
  */
  public function sFixed64($value)
  {
  if ($value >= 0) {
  $this->fixed64($value);
  } else if (function_exists('gmp_init')) {
  $this->sFixed64_gmp($value);
  } else if (function_exists('bcadd')) {
  $this->sFixed64_bc($value);
  } else {
  throw new \OutOfBoundsException("The signed Fixed64 type with negative integers is only supported with GMP or BC big integers PHP extensions ($value was given)");
  }
  }
 
  public function sFixed64_gmp($value)
  {
  static $xff, $x100;
 
  if (NULL === $xff) {
  $xff = gmp_init(0xff);
  $x100 = gmp_init(0x100);
  }
 
  $value = PHP_INT_SIZE < 8
  ? gmp_and($value, '0x0ffffffffffffffff')
  : gmp_init(sprintf('%u', $value));
 
  $bytes = '';
  for ($i=0; $i<8; $i++) {
  $bytes .= chr(gmp_intval(gmp_and($value, $xff)));
  $value = gmp_div_q($value, $x100);
  }
 
  $this->write($bytes);
  }
 
  public function sFixed64_bc($value)
  {
  if (PHP_INT_SIZE < 8) {
  throw new \OutOfBoundsException(
  "PHP versions compiled with 32bit integers can only support negative integer encoding with GMP extension ($value was given)"
  );
  }
 
  $value = sprintf('%u', $value);
 
  $bytes = '';
  for ($i=0; $i<8; $i++) {
  // Get the last 8bits of the number
  $bin = '';
  $dec = $value;
  do {
  $bin = bcmod($dec, 2) . $bin;
  $dec = bcdiv($dec, 2, 0);
  } while (strlen($bin) < 8);
 
  // Pack the byte
  $bytes .= chr(intval($bin, 2));
 
  $value = bcdiv($value, 0x100, 0);
  }
 
  $this->write($bytes);
  }
 
  /**
  * Encode an integer as a fixed of 64bits without sign
  *
  * @param int $value
  */
  public function fixed64($value)
  {
  $bytes = pack('V*', $value & 0xffffffff, $value / (0xffffffff+1));
  $this->write($bytes, 8);
  }
 
  /**
  * Encode a number as a 32bit float
  *
  * @param float $value
  */
  public function float($value)
  {
  $bytes = pack('f*', $value);
  if ($this->isBigEndian()) {
  $bytes = strrev($bytes);
  }
  $this->write($bytes, 4);
  }
 
  /**
  * Encode a number as a 64bit double
  *
  * @param float $value
  */
  public function double($value)
  {
  $bytes = pack('d*', $value);
  if ($this->isBigEndian()) {
  $bytes = strrev($bytes);
  }
  $this->write($bytes, 8);
  }
 
  /**
  * Checks if the current architecture is Big Endian
  *
  * @return bool
  */
  public function isBigEndian()
  {
  static $endianness;
 
  if (NULL === $endianness) {
  list(,$result) = unpack('L', pack('V', 1));
  $endianness = $result !== 1;
  }
 
  return $endianness;
  }
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec;
 
  use DrSlump\Protobuf;
 
  /**
  * This codec serializes and unserializes from/to Json strings
  * where the keys represent the field's name.
  *
  * It makes use of the PhpArray codec to do the heavy work to just
  * take care of converting the array to/from Json strings.
  */
  class Json extends PhpArray
  implements Protobuf\CodecInterface
  {
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @return string
  */
  public function encode(Protobuf\Message $message)
  {
  $data = $this->encodeMessage($message);
  return json_encode($data);
  }
 
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @param string $data
  * @return \DrSlump\Protobuf\Message
  */
  public function decode(Protobuf\Message $message, $data)
  {
  $data = json_decode($data);
  return $this->decodeMessage($message, $data);
  }
 
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec;
 
  use DrSlump\Protobuf;
 
  /**
  * This codec serializes and unserializes from/to Json strings
  * where the keys are packed as the first element of numeric arrays,
  * optimizing the resulting payload size.
  *
  */
  class JsonIndexed extends Json
  implements Protobuf\CodecInterface
  {
 
  protected function encodeMessage(Protobuf\Message $message)
  {
  $descriptor = Protobuf::getRegistry()->getDescriptor($message);
 
  $index = '';
  $data = array();
  foreach ($descriptor->getFields() as $tag=>$field) {
  $empty = !$message->_has($tag);
  if ($field->isRequired() && $empty) {
  throw new \UnexpectedValueException(
  'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value'
  );
  }
 
  if ($empty) {
  continue;
  }
 
  $index .= $this->i2c($tag + 48);
 
  $value = $message->_get($tag);
 
  if ($field->isRepeated()) {
  $repeats = array();
  foreach ($value as $val) {
  if ($field->getType() !== Protobuf::TYPE_MESSAGE) {
  $repeats[] = $val;
  } else {
  $repeats[] = $this->encodeMessage($val);
  }
  }
  $data[] = $repeats;
  } else {
  if ($field->getType() === Protobuf::TYPE_MESSAGE) {
  $data[] = $this->encodeMessage($value);
  } else {
  $data[] = $value;
  }
  }
  }
 
  // Insert the index at first element
  array_unshift($data, $index);
 
  return $data;
  }
 
  protected function decodeMessage(Protobuf\Message $message, $data)
  {
  // Get message descriptor
  $descriptor = Protobuf::getRegistry()->getDescriptor($message);
 
  // Split the index in UTF8 characters
  preg_match_all('/./u', $data[0], $chars);
 
  $chars = $chars[0];
  for ($i=1; $i<count($data); $i++) {
 
  $k = $this->c2i($chars[$i-1]) - 48;
  $v = $data[$i];
 
  $field = $descriptor->getField($k);
 
  if (NULL === $field) {
  // Unknown
  $unknown = new PhpArray\Unknown($k, gettype($v), $v);
  $message->addUnknown($unknown);
  continue;
  }
 
  if ($field->getType() === Protobuf::TYPE_MESSAGE) {
  $nested = $field->getReference();
  if ($field->isRepeated()) {
  foreach ($v as $vv) {
  $obj = $this->decodeMessage(new $nested, $vv);
  $message->_add($k, $obj);
  }
  } else {
  $obj = $this->decodeMessage(new $nested, $v);
  $message->_set($k, $obj);
  }
  } else {
  $message->_set($k, $v);
  }
  }
 
  return $message;
  }
 
  /**
  * Converts an Unicode codepoint number to an UTF-8 character
  *
  * @param int $codepoint
  * @return string
  */
  protected function i2c($codepoint)
  {
  return $codepoint < 128
  ? chr($codepoint)
  : html_entity_decode("&#$codepoint;", ENT_NOQUOTES, 'UTF-8');
  }
 
  /**
  * Converts an UTF-8 character to an Unicode codepoint number
  *
  * @param string $char
  * @return int
  */
  protected function c2i($char)
  {
  $value = ord($char[0]);
  if ($value < 128) return $value;
 
  if ($value < 224) {
  return (($value % 32) * 64) + (ord($char[1]) % 64);
  } else {
  return (($value % 16) * 4096) +
  ((ord($char[1]) % 64) * 64) +
  (ord($char[2]) % 64);
  }
  }
 
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec;
 
  use DrSlump\Protobuf;
 
  /**
  * This codec serializes and unserializes from/to Json strings
  * where the keys represent the field's tag numbers.
  *
  * It makes use of the PhpArray codec to do the heavy work to just
  * take care of converting the array to/from Json strings.
  */
  class JsonTagMap extends Json
  implements Protobuf\CodecInterface
  {
 
  public function __construct()
  {
  // Setup the codec to use tag numbers as keys
  $this->useTagNumberAsKey(true);
  }
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec;
 
  use DrSlump\Protobuf;
 
  /**
  * This codec serializes and unserializes data from/to PHP associative
  * arrays, allowing it to be used as a base for an arbitrary number
  * of different serializations (json, yaml, ini, xml ...).
  *
  */
  class PhpArray implements Protobuf\CodecInterface
  {
  /** @var bool */
  protected $useTagNumber = false;
 
  /**
  * Tells the codec to expect the array keys to contain the
  * field's tag number instead of the name.
  *
  * @param bool $useIt
  */
  public function useTagNumberAsKey($useIt = true)
  {
  $this->useTagNumber = $useIt;
  }
 
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @return array
  */
  public function encode(Protobuf\Message $message)
  {
  return $this->encodeMessage($message);
  }
 
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @param array $data
  * @return \DrSlump\Protobuf\Message
  */
  public function decode(Protobuf\Message $message, $data)
  {
  return $this->decodeMessage($message, $data);
  }
 
  protected function encodeMessage(Protobuf\Message $message)
  {
  $descriptor = Protobuf::getRegistry()->getDescriptor($message);
 
  $data = array();
  foreach ($descriptor->getFields() as $tag=>$field) {
 
  $empty = !$message->_has($tag);
  if ($field->isRequired() && $empty) {
  throw new \UnexpectedValueException(
  'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value'
  );
  }
 
  if ($empty) {
  continue;
  }
 
  $key = $this->useTagNumber ? $field->getNumber() : $field->getName();
  $v = $message->_get($tag);
 
  if ($field->isRepeated()) {
  // Make sure the value is an array of values
  $v = is_array($v) ? $v : array($v);
  foreach ($v as $k=>$vv) {
  $v[$k] = $this->filterValue($vv, $field);
  }
  } else {
  $v = $this->filterValue($v, $field);
  }
 
  $data[$key] = $v;
  }
 
  return $data;
  }
 
  protected function decodeMessage(Protobuf\Message $message, $data)
  {
  // Get message descriptor
  $descriptor = Protobuf::getRegistry()->getDescriptor($message);
 
  foreach ($data as $key=>$v) {
 
  // Get the field by tag number or name
  $field = $this->useTagNumber
  ? $descriptor->getField($key)
  : $descriptor->getFieldByName($key);
 
  // Unknown field found
  if (!$field) {
  $unknown = new PhpArray\Unknown($key, gettype($v), $v);
  $message->addUnknown($unknown);
  continue;
  }
 
  if ($field->isRepeated()) {
  // Make sure the value is an array of values
  $v = is_array($v) && is_int(key($v)) ? $v : array($v);
  foreach ($v as $k=>$vv) {
  $v[$k] = $this->filterValue($vv, $field);
  }
  } else {
  $v = $this->filterValue($v, $field);
  }
 
  $message->_set($field->getNumber(), $v);
  }
 
  return $message;
  }
 
  protected function filterValue($value, Protobuf\Field $field)
  {
  switch ($field->getType()) {
  case Protobuf::TYPE_MESSAGE:
  // Tell apart encoding and decoding
  if ($value instanceof Protobuf\Message) {
  return $this->encodeMessage($value);
  } else {
  $nested = $field->getReference();
  return $this->decodeMessage(new $nested, $value);
  }
  case Protobuf::TYPE_BOOL:
  return filter_var($value, FILTER_VALIDATE_BOOLEAN);
  case Protobuf::TYPE_STRING:
  case Protobuf::TYPE_BYTES:
  return (string)$value;
  case Protobuf::TYPE_FLOAT:
  case Protobuf::TYPE_DOUBLE:
  return filter_var($value, FILTER_VALIDATE_FLOAT);
  // Assume the rest are ints
  default:
  return filter_var($value, FILTER_VALIDATE_INT);
  }
  }
 
 
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec\PhpArray;
 
  class Unknown extends \DrSlump\Protobuf\Unknown
  {
  public function __construct($tag, $type, $data)
  {
  $this->tag = $tag;
  $this->type = $type;
  $this->data = $data;
  }
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Codec;
 
  use DrSlump\Protobuf;
 
  /**
  * This codec serializes to Protobuf's TextFormat, unserialization
  * is not supported.
  *
  */
  class TextFormat implements Protobuf\CodecInterface
  {
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @return string
  */
  public function encode(Protobuf\Message $message)
  {
  return $this->encodeMessage($message);
  }
 
  /**
  *
  * @throw \DrSlump\Protobuf\Exception - Decoding is not supported
  * @param \DrSlump\Protobuf\Message $message
  * @param String $data
  * @return \DrSlump\Protobuf\Message
  */
  public function decode(Protobuf\Message $message, $data)
  {
  throw new \BadMethodCallException('TextFormat codec does not support decoding');
  }
 
  protected function encodeMessage(Protobuf\Message $message, $level = 0)
  {
  $descriptor = Protobuf::getRegistry()->getDescriptor($message);
 
  $indent = str_repeat(' ', $level);
  $data = '';
  foreach ($descriptor->getFields() as $tag=>$field) {
 
  $empty = !$message->_has($tag);
  if ($field->isRequired() && $empty) {
  throw new \UnexpectedValueException(
  'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value'
  );
  }
 
  if ($empty) {
  continue;
  }
 
  $name = $field->getName();
  $value = $message->_get($tag);
 
  if ($field->isRepeated()) {
  foreach ($value as $val) {
  if ($field->getType() !== Protobuf::TYPE_MESSAGE) {
  $data .= $indent . $name . ': ' . json_encode($val) . "\n";
  } else {
  $data .= $indent . $name . " {\n";
  $data .= $this->encodeMessage($val, $level+1);
  $data .= $indent . "}\n";
  }
  }
  } else {
  if ($field->getType() === Protobuf::TYPE_MESSAGE) {
  $data .= $indent . $name . " {\n";
  $data .= $this->encodeMessage($value, $level+1);
  $data .= $indent . "}\n";
  } else {
  $data .= $indent . $name . ': ' . json_encode($value) . "\n";
  }
  }
  }
 
  return $data;
  }
  }
 
 
  <?php
 
  namespace DrSlump\Protobuf\Codec;
 
  use DrSlump\Protobuf;
 
  /**
  * This codec serializes and unserializes from/to Xml documents
  * where the elements represent the field's name.
  *
  * It makes use of the PhpArray codec to do the heavy work to just
  * take care of converting the array to/from XML.
  */
  class Xml extends PhpArray
  implements Protobuf\CodecInterface
  {
  /** @var bool */
  protected $dom = false;
  /** @var string */
  protected $root;
 
  /**
  * @param array $options
  */
  public function __construct(array $options = array())
  {
  foreach ($options as $option=>$value) {
  $this->setOption($option, $value);
  }
  }
 
  /**
  * @throws \InvalidArgumentException
  * @param string $option
  * @param mixed $value
  * @return void
  */
  public function setOption($option, $value)
  {
  switch (strtolower($option)) {
  case 'root':
  $this->root = $value;
  break;
  case 'dom':
  $this->dom = (bool)$value;
  break;
  default:
  throw new \InvalidArgumentException('Unknown option ' . $option);
  }
  }
 
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @return string | \SimpleXMLElement
  */
  public function encode(Protobuf\Message $message)
  {
  // Generate an associative array
  $data = $this->encodeMessage($message);
 
  // Build an XML representation
  $root = $this->root ?: str_replace('\\', '_', get_class($message));
  $root = new \SimpleXMLElement('<?xml version="1.0"?><' . $root . '></' . $root . '>');
  $this->arrayToXml($root, $data);
 
  return $this->dom ? $root : $root->asXML();
  }
 
  /**
  * @param \SimpleXMLElement $elem
  * @param array $data
  * @param null $label
  */
  protected function arrayToXml(\SimpleXMLElement $elem, array $data, $label = null)
  {
  foreach ($data as $k=>$v) {
  if (is_array($v)) {
  // Detect nested messages
  if (!is_int(key($v))) {
  $child = $elem->addChild($label ?: $k);
  $this->arrayToXml($child, $v);
  // Lists are forced a fixed label
  } else {
  $this->arrayToXml($elem, $v, $k);
  }
  } else {
  $elem->addChild($label ?: $k, $v);
  }
  }
  }
 
  /**
  * @param \DrSlump\Protobuf\Message $message
  * @param string | \SimpleXMLElement $xml
  * @return \DrSlump\Protobuf\Message
  */
  public function decode(Protobuf\Message $message, $xml)
  {
  if (is_string($xml)) {
  $xml = new \SimpleXMLElement($xml);
  }
 
  // Build an associative array from the XML
  $data = $this->xmlToArray($xml);
  // Generate a message from the data
  return $this->decodeMessage($message, $data);
  }
 
  /**
  * @param \SimpleXMLElement $elem
  * @return array
  */
  protected function xmlToArray(\SimpleXMLElement $elem)
  {
  $data = array();
  foreach ($elem->children() as $child) {
  if (count($child->children())) {
  $value = $this->xmlToArray($child);
  } else {
  $value = (string)$child;
  }
 
  $name = $child->getName();
  if (isset($data[$name])) {
  // If not yet a "list" array
  if (!is_array($data[$name]) || !is_int(key($data[$name]))) {
  $data[$name] = array($data[$name]);
  }
  $data[$name][] = $value;
  } else {
  $data[$name] = $value;
  }
  }
 
  return $data;
  }
 
  }
 
  <?php
 
  namespace DrSlump\Protobuf;
 
  interface CodecInterface
  {
  public function encode(\DrSlump\Protobuf\Message $message);
  public function decode(\DrSlump\Protobuf\Message $message, $data);
  }
  <?php
 
  namespace DrSlump\Protobuf;
 
  // Load descriptor messages
  require_once __DIR__ . '/Compiler/protos/descriptor.pb.php';
  require_once __DIR__ . '/Compiler/protos/plugin.pb.php';
  require_once __DIR__ . '/Compiler/protos/php.pb.php';
  require_once __DIR__ . '/Compiler/protos/json.pb.php';
 
  use DrSlump\Protobuf;
  use google\protobuf as proto;
 
  class Compiler
  {
  /** @var bool */
  protected $verbose = false;
  /** @var array */
  protected $packages = array();
  /** @var \DrSlump\Protobuf\Compiler\CommentsParser */
  protected $comments;
  /** @var bool */
  protected $skipImported = false;
  /** @var array */
  protected $options = array();
  /** @var array */
  protected $protos = array();
 
  public function __construct($verbose = false)
  {
  $this->verbose = $verbose;
  $this->comments = new Compiler\CommentsParser();
  }
 
  public function stderr($str)
  {
  $str = str_replace("\n", PHP_EOL, $str);
  fputs(STDERR, $str . PHP_EOL);
  }
 
  public function notice($str)
  {
  if ($this->verbose) {
  $this->stderr('NOTICE: ' . $str);
  }
  }
 
  public function warning($str)
  {
  $this->stderr('WARNING: ' . $str);
  }
 
  protected function error($str)
  {
  $this->stderr('ERROR: ' . $str);
  }
 
  public function getPackages()
  {
  return $this->packages;
  }
 
  public function hasPackage($package)
  {
  return isset($this->packages[$package]);
  }
 
  public function getPackage($package)
  {
  return $this->packages[$package];
  }
 
  public function setPackage($package, $namespace)
  {
  $this->packages[$package] = $namespace;
  }
 
  public function getOption($option, $type = 'string')
  {
  $value = isset($this->options[$option])
  ? $this->options[$option]
  : null;
 
  switch ($type) {
  case 'bool':
  return filter_var($value, FILTER_VALIDATE_BOOLEAN);
  default:
  return $value;
  }
  }
 
  public function camelize($name)
  {
  return preg_replace_callback(
  '/_([a-z])/i',
  function($m){ return strtoupper($m[1]); },
  $name
  );
  }
 
  public function compile($data)
  {
  // Parse the request
  $req = new \google\protobuf\compiler\CodeGeneratorRequest($data);
 
  // Set default generator class
  $generator = __CLASS__ . '\PhpGenerator';
 
  // Reset comments parser
  $this->comments->reset();
  $parseComments = false;
 
  // Get plugin arguments
  if ($req->hasParameter()) {
  parse_str($req->getParameter(), $args);
  foreach ($args as $arg=>$val) {
  switch($arg){
  case 'verbose':
  $this->verbose = filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
  break;
  case 'json':
  $this->notice("Using ProtoJson generator");
  $generator = __CLASS__ . '\JsonGenerator';
  break;
  case 'comments':
  $parseComments = filter_var($val, FILTER_VALIDATE_BOOLEAN);
  break;
  case 'protos':
  $this->protos = $val;
  break;
  case 'skip-imported':
  $this->skipImported = filter_var($val, FILTER_VALIDATE_BOOLEAN);
  break;
  case 'options':
  $this->options = $val;
  break;
  default:
  $this->warning('Skipping unknown option ' . $arg);
  }
  }
  }
 
  // Parse comments if we're told to do so
  if ($parseComments) {
  if (empty($this->protos)) {
  throw new \RuntimeException('Unable to port comments if .proto files are not passed as argument');
  }
  foreach ($this->protos as $fname) {
  $src = file_get_contents($fname);
  if (FALSE === $src) {
  throw new \RuntimeException('Unable to parse file ' . $fname . ' for comments');
  }
  $this->comments->parse($src);
  }
  }
 
  /** @var $generator \DrSlump\Protobuf\Compiler\AbstractGenerator */
  $generator = new $generator($this);
 
  // Setup response object
  $resp = new \google\protobuf\compiler\CodeGeneratorResponse();
 
  // First iterate over all the protos to get a map of namespaces
  $this->packages = array();
  foreach($req->getProtoFileList() as $proto) {
  $package = $proto->getPackage();
  $namespace = $generator->getNamespace($proto);
  if (isset($this->packages[$package]) && $namespace !== $this->packages[$package]) {
  $this->warning("Package $package was already mapped to {$this->packages[$package]} but has now been overridden to $namespace");
  }
  $this->packages[$package] = $namespace;
  $this->notice("Mapping $package to $namespace");
  }
 
  // Get the list of files to generate
  $files = $req->getFileToGenerate();
 
  // Run each file
  foreach ($req->getProtoFileList() as $file) {
  // Only compile those given to generate, not the imported ones
  if ($this->skipImported && !in_array($file->getName(), $files)) {
  $this->notice('Skipping generation of imported file "' . $file->getName() . '"');
  continue;
  }
 
  $sources = $generator->generate($file);
  foreach ($sources as $source) {
  $this->notice('Generating "' . $source->getName() . '"');
  $resp->addFile($source);
  }
  }
 
  // Finally serialize the response object
  return $resp->serialize();
  }
 
  public function getComment($ident, $prefix = '')
  {
  if (!$this->comments->hasComment($ident)) {
  return null;
  }
 
  $comment = $this->comments->getComment($ident);
  if (0 < strlen($prefix)) {
  $comment = $prefix . str_replace("\n", "\n$prefix", $comment);
  }
 
  return $comment;
  }
  }
 
 
  <?php
 
  namespace DrSlump\Protobuf\Compiler;
 
  use google\protobuf as proto;
 
  abstract class AbstractGenerator
  {
  /** @var \DrSlump\Protobuf\Compiler */
  protected $compiler;
  /** @var \google\protobuf\FileDescriptorProto */
  protected $proto;
 
  /** @var array */
  protected $extensions = array();
 
  public function __construct(\DrSlump\Protobuf\Compiler $compiler)
  {
  $this->compiler = $compiler;
  }
 
  public function getNamespace(proto\FileDescriptorProto $proto = NULL)
  {
  return NULL === $proto
  ? $this->proto->getPackage()
  : $proto->getPackage();
  }
 
  public function generate(proto\FileDescriptorProto $proto)
  {
  $this->proto = $proto;
  }
 
 
  abstract protected function compileEnum(proto\EnumDescriptorProto $enum, $namespace);
 
  abstract protected function compileMessage(proto\DescriptorProto $msg, $namespace);
 
  abstract protected function compileExtension(proto\FieldDescriptorProto $field, $ns, $indent);
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Compiler;
 
  require_once 'Console/CommandLine.php';
 
  use DrSlump\Protobuf;
 
  class Cli
  {
  public static function run($pluginExecutable)
  {
  // Open STDIN in non-blocking mode
  $fp = fopen('php://stdin', 'rb');
  stream_set_blocking($fp, FALSE);
 
  // Loop until STDIN is closed or we've waited too long for data
  $cnt = 0;
  $stdin = '';
  while (!feof($fp) && $cnt++ < 10) {
  // give protoc some time to feed the data
  usleep(10000);
  // read the bytes
  $bytes = fread($fp, 1024);
  if (strlen($bytes)) {
  $cnt = 0;
  $stdin .= $bytes;
  }
  }
 
  // If no input was given we launch protoc from here
  if (0 === strlen($stdin)) {
  self::runProtoc($pluginExecutable);
  exit(0);
  }
 
  // We have data from stdin so compile it
  try {
  // Create a compiler interface
  $comp = new Protobuf\Compiler();
  echo $comp->compile($stdin);
  exit(0);
  } catch(\Exception $e) {
  fputs(STDERR, 'ERROR: ' . $e->getMessage());
  fputs(STDERR, $e->getTraceAsString());
  exit(255);
  }
  }
 
  public static function runProtoc($pluginExecutable)
  {
  $result = self::parseArguments();
 
  $protocBin = $result->options['protoc'];
 
  // Check if protoc is available
  exec("$protocBin --version", $output, $return);
 
  if (0 !== $return && 1 !== $return) {
  fputs(STDERR, "ERROR: Unable to find the protoc command.". PHP_EOL);
  fputs(STDERR, " Please make sure it's installed and available in the path." . PHP_EOL);
  exit(1);
  }
 
  if (!preg_match('/[0-9\.]+/', $output[0], $m)) {
  fputs(STDERR, "ERROR: Unable to get protoc command version.". PHP_EOL);
  fputs(STDERR, " Please make sure it's installed and available in the path." . PHP_EOL);
  exit(1);
  }
 
  if (version_compare($m[0], '2.3.0') < 0) {
  fputs(STDERR, "ERROR: The protoc command in your system is too old." . PHP_EOL);
  fputs(STDERR, " Minimum version required is 2.3.0 but found {$m[0]}." . PHP_EOL);
  exit(1);
  }
 
  $cmd[] = $protocBin;
  $cmd[] = '--plugin=protoc-gen-php=' . escapeshellarg($pluginExecutable);
 
  // Include paths
  $cmd[] = '--proto_path=' . escapeshellarg(__DIR__ . DIRECTORY_SEPARATOR . 'protos');
  if (!empty($result->options['include'])) {
  foreach($result->options['include'] as $include) {
  $include = realpath($include);
  $cmd[] = '--proto_path=' . escapeshellarg($include);
  }
  }
 
  // Convert proto files to absolute paths
  $protos = array();
  foreach ($result->args['protos'] as $proto) {
  $realpath = realpath($proto);
  if (FALSE === $realpath) {
  fputs(STDERR, "ERROR: File '$proto' does not exists");
  exit(1);
  }
 
  $protos[] = $realpath;
  }
 
  // Protoc will pass custom arguments to the plugin if they are given
  // before a colon character. ie: --php_out="foo=bar:/path/to/plugin"
  // We make use of it to pass arguments encoded as an URI query string
 
  $args = array();
  if ($result->options['comments']) {
  $args['comments'] = 1;
  // Protos are only needed for comments right now
  $args['protos'] = $protos;
  }
  if ($result->options['verbose']) {
  $args['verbose'] = 1;
  }
  if ($result->options['json']) {
  $args['json'] = 1;
  }
  if ($result->options['skipImported']) {
  $args['skip-imported'] = 1;
  }
  if ($result->options['define']) {
  $args['options'] = array();
  foreach($result->options['define'] as $define) {
  $parts = explode('=', $define);
  $parts = array_filter(array_map('trim', $parts));
  if (count($parts) === 1) {
  $parts[1] = 1;
  }
  $args['options'][$parts[0]] = $parts[1];
  }
  }
 
  $cmd[] = '--php_out=' .
  escapeshellarg(
  http_build_query($args, '', '&') .
  ':' .
  $result->options['out']
  );
 
  // Add the chosen proto files to generate
  foreach ($protos as $proto) {
  $cmd[] = escapeshellarg($proto);
  }
 
  $cmdStr = implode(' ', $cmd);
 
  // Run command with stderr redirected to stdout
  passthru($cmdStr . ' 2>&1', $return);
 
  if ($return !== 0) {
  fputs(STDERR, PHP_EOL);
  fputs(STDERR, 'ERROR: protoc exited with an error (' . $return . ') when executed with: ' . PHP_EOL);
  fputs(STDERR, ' ' . implode(" \\\n ", $cmd) . PHP_EOL);
  exit($return);
  }
  }
 
 
  public static function parseArguments()
  {
  $main = new \Console_CommandLine();
 
  $main->addOption('out', array(
  'short_name' => '-o',
  'long_name' => '--out',
  'action' => 'StoreString',
  'description' => 'destination directory for generated files',
  'default' => './',
  ));
 
  $main->addOption('include', array(
  'short_name' => '-i',
  'long_name' => '--include',
  'action' => 'StoreArray',
  'description' => 'define an include path (can be repeated)',
  'multiple' => true,
  ));
 
 
  $main->addOption('json', array(
  'short_name' => '-j',
  'long_name' => '--json',
  'action' => 'StoreTrue',
  'description' => 'turn on ProtoJson Javascript file generation',
  ));
 
  $main->addOption('protoc', array(
  'long_name' => '--protoc',
  'action' => 'StoreString',
  'default' => 'protoc',
  'description' => 'protoc compiler executable path',
  ));
 
  $main->addOption('skipImported', array(
  'long_name' => '--skip-imported',
  'action' => 'StoreTrue',
  'default' => false,
  'description' => 'do not generate imported proto files',
  ));
 
  $main->addOption('comments', array(
  'long_name' => '--comments',
  'action' => 'StoreTrue',
  'description' => 'port .proto comments to generated code',
  ));
 
  $main->addOption('define', array(
  'short_name' => '-D',
  'long_name' => '--define',
  'action' => 'StoreArray',
  'multiple' => true,
  'description' => 'define a generator option (ie: -Dmultifile -Dsuffix=pb.php)',
  ));
 
  $main->addOption('verbose', array(
  'short_name' => '-v',
  'long_name' => '--verbose',
  'action' => 'StoreTrue',
  'description' => 'turn on verbose output',
  ));
 
 
  $main->addArgument('protos', array(
  'multiple' => true,
  'description' => 'proto files',
  ));
 
  try {
  echo 'Protobuf-PHP ' . Protobuf::VERSION . ' by Ivan -DrSlump- Montes' . PHP_EOL . PHP_EOL;
  $result = $main->parse();
  return $result;
  } catch (\Exception $e) {
  $main->displayError($e->getMessage());
  exit(1);
  }
  }
 
  }
 
  <?php
 
  namespace DrSlump\Protobuf\Compiler;
 
  class CommentsParser
  {
  /** @var array - Hold a mapping of entity => comment */
  protected $comments = array();
 
  /** @var array - Define tokenizer regular expressions */
  protected $tokens = array(
  'comment' => '/\*([\S\s]+?)\*/',
  'package' => 'package\s+([A-Z0-9_]+)',
  'struct' => '(?:message|enum|service)\s+([A-Z0-9_]+)',
  'close' => '}',
  'field' => '(?:required|optional|repeated)\s+[^=]+=\s*([0-9]+)[^;]*;',
  'rpc' => 'rpc\s+([A-Z0-9_]+)[^;]+'
  );
 
  /** @var string - The regular expresion for the tokenizer */
  protected $regexp;
 
  public function __construct()
  {
  // Generate a regular expression for all tokens
  $regexp = array();
  foreach ($this->tokens as $token=>$exp) {
  $regexp[] = '(?<' . $token . '>' . $exp . ')';
  }
  $this->regexp = '@' . implode('|', $regexp) . '@i';
  }
 
  /**
  * Reset the currently stored comments
  */
  public function reset()
  {
  $this->comments = array();
  }
 
  /**
  * Parse a Proto file source code to fetch comments
  *
  * @param string $src
  */
  public function parse($src)
  {
  // Build an stream of tokens from the regular expression
  $tokens = array();
  $offset = 0;
  while (preg_match($this->regexp, $src, $m, PREG_OFFSET_CAPTURE, $offset)) {
  foreach ($this->tokens as $k=>$v) {
  if (!empty($m[$k]) && 0 < strlen($m[$k][0])) {
  $tokens[] = array(
  'token' => $k,
  'value' => array_shift(array_pop($m)),
  );
  }
  }
  $offset = $m[0][1] + strlen($m[0][0]);
  }
 
  // Parse the tokens stream to assign comments
  $comment = null;
  $stack = array();
  foreach ($tokens as $token) {
  if ($token['token'] === 'comment') {
  $comment = $token['value'];
  } elseif ($token['token'] === 'package') {
  $stack[] = $token['value'];
  $comment = null;
  } elseif ($token['token'] === 'struct') {
  $stack[] = $token['value'];
  if ($comment) {
  $this->setComment(implode('.', $stack), $comment);
  $comment = null;
  }
  } elseif ($token['token'] === 'close') {
  array_pop($stack);
  $comment = null;
  } elseif ($token['token'] === 'field' || $token['token'] === 'rpc') {
  if ($comment) {
  $this->setComment(implode('.', $stack) . '.' . $token['value'], $comment);
  $comment = null;
  }
  }
  }
  }
 
  /**
  * Set a comment for the given identifier. The identifier is composed
  * of the package, followed by the message (and nested messages). Field
  * comments are suffixed with the tag number.
  *
  * @example
  *
  * $this->setComment('MyPackage.MyMessage.Nested.2', 'field comment');
  *
  * @param string $ident
  * @param string $comment
  */
  public function setComment($ident, $comment)
  {
  $comment = str_replace("\r\n", "\n", $comment);
  $comment = preg_replace('/^[\s\*]+/m', '', $comment);
  $comment = trim($comment, "* \n");
  $this->comments[$ident] = $comment;
  }
 
  /**
  * Get the comment for a given identifier
  *
  * @param string $ident
  * @return string|null
  */
  public function getComment($ident)
  {
  return isset($this->comments[$ident])
  ? $this->comments[$ident]
  : null;
  }
 
  /**
  * Checks if a comment exists for a given identifier
  *
  * @param string $ident
  * @return bool
  */
  public function hasComment($ident)
  {
  return isset($this->comments[$ident]);
  }
  }
 
 
 
  <?php
 
  namespace DrSlump\Protobuf\Compiler;
 
  use DrSlump\Protobuf;
  use google\protobuf as proto;
 
  class JsonGenerator extends AbstractGenerator
  {
  public function getNamespace(proto\FileDescriptorProto $proto)
  {
  $namespace = $proto->getPackage();
  $opts = $proto->getOptions();
  if (isset($opts['json.package'])) {
  $namespace = $opts['jsonpackage'];
  }
  if (isset($opts['json.namespace'])) {
  $namespace = $opts['json.namespace'];
  }
 
  $namespace = trim($namespace, '.');
  return $namespace;
  }
 
  public function compileEnum(proto\EnumDescriptorProto $enum, $namespace)
  {
  $s[]= "$namespace.$enum->name = {";
  $lines = array();
  foreach ($enum->getValueList() as $value) {
  $lines[] = " /** @const */ $value->name: $value->number";
  }
  $s[]= implode(",\n", $lines);
  $s[]= '};';
  $s[]= '';
  return implode("\n", $s);
  }
 
  public function compileExtension(proto\FieldDescriptorProto $field, $ns, $indent)
  {
  $extendee = $this->normalizeReference($field->getExtendee());
  $name = $field->getName();
  if ($ns) {
  $name = $ns . '.' . $name;
  }
  $field->setName($name);
 
  $s[]= "ProtoJson.extend($extendee, {";
  $s[]= " $field->number: " . $this->generateField($field);
  $s[]= "});";
  $s[]= '';
 
  return $indent . implode("\n$indent", $s);
  }
 
  public function compileMessage(proto\DescriptorProto $msg, $namespace)
  {
  $s[]= "/**";
  $s[]= " * @constructor";
  $s[]= " * @augments {ProtoJson.Message}";
  $s[]= " * @extends ProtoJson.Message";
  $s[]= " * @memberOf $namespace";
  $s[]= " * @param {object} data - Optional, provide initial data to parse";
  $s[]= " */";
  $s[]= "$namespace.$msg->name = ProtoJson.create({";
  $s[]= " fields: {";
 
  $lines = array();
  foreach ($msg->getFieldList() as $field) {
  $lines[] = " $field->number: " . $this->generateField($field);
  }
  $s[] = implode(",\n", $lines);
 
  $s[]= " },";
  $s[]= " ranges: [";
  // @todo dump extension ranges
  $s[]= " ]";
  $s[]= "});";
  $s[]= "";
 
  // Compute a new namespace with the message name as suffix
  $namespace .= "." . $msg->getName();
 
  // Generate getters/setters
  foreach ($msg->getFieldList() as $field) {
  $s[]= $this->generateAccessors($field, $namespace);
  }
 
  // Generate Enums
  foreach ($msg->getEnumTypeList() as $enum):
  $s[]= $this->compileEnum($enum, $namespace);
  endforeach;
 
  // Generate nested messages
  foreach ($msg->getNestedTypeList() as $msg):
  $s[]= $this->compileMessage($msg, $namespace);
  endforeach;
 
  // Collect extensions
  foreach ($msg->getExtensionList() as $field) {
  $this->extensions[$field->getExtendee()][] = array($namespace, $field);
  }
 
  return implode("\n", $s);
  }
 
  public function compileProtoFile(proto\FileDescriptorProto $proto)
  {
  $file = new proto\compiler\CodeGeneratorResponse\File();
 
  $opts = $proto->getOptions();
  $name = pathinfo($proto->getName(), PATHINFO_FILENAME);
  $name .= isset($opts['json.suffix'])
  ? $opts['json.suffix']
  : '.js';
  $file->setName($name);
 
  $namespace = $this->getNamespace($proto);
 
  $s[]= "// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin " . Protobuf::VERSION;
  $s[]= "// Source: " . $proto->getName();
  $s[]= "// Date: " . date('Y-m-d H:i:s');
  $s[]= "";
 
  $s[]= "(function(){";
  $s[]= "/** @namespace */";
  $s[]= "var $namespace = $namespace || {};";
  $s[]= "";
  $s[]= "// Make it CommonJS compatible";
  $s[]= "if (typeof exports !== 'undefined') {";
  $s[]= " var ProtoJson = this.ProtoJson;";
  $s[]= " if (!ProtoJson && typeof require !== 'undefined')";
  $s[]= " ProtoJson = require('ProtoJson');";
  $s[]= " $namespace = exports;";
  $s[]= "} else {";
  $s[]= " this.$namespace = $namespace;";
  $s[]= "}";
  $s[]= "";
 
 
  // Generate Enums
  foreach ($proto->getEnumTypeList() as $enum) {
  $s[]= $this->compileEnum($enum, $namespace);
  }
 
  // Generate Messages
  foreach ($proto->getMessageTypeList() as $msg) {
  $s[] = $this->compileMessage($msg, $namespace);
  }
 
  // Collect extensions
  if ($proto->hasExtension()) {
  foreach ($proto->getExtensionList() as $field) {
  $this->extensions[$field->getExtendee()][] = array($namespace, $field);
  }
  }
 
  // Dump all extensions found in this proto file
  if (count($this->extensions)) {
  foreach ($this->extensions as $extendee => $fields) {
  foreach ($fields as $pair) {
  list($ns, $field) = $pair;
  $s[]= $this->compileExtension($field, $ns, '');
  }
  }
  }
 
  $s[]= "})();";
 
  $src = implode("\n", $s);
  $file->setContent($src);
  return array($file);
  }
 
  public function generateField(proto\FieldDescriptorProto $field)
  {
  $reference = 'null';
  if ($field->hasTypeName()) {
  $reference = $field->getTypeName();
  if (substr($reference, 0, 1) !== '.') {
  throw new \RuntimeException('Only fully qualified names are supported: ' . $reference);
  }
  $reference = "'" . $this->normalizeReference($reference) . "'";
  }
 
  $default = 'null';
  if ($field->hasDefaultValue()):
  switch ($field->getType()) {
  case Protobuf::TYPE_BOOL:
  $default = $field->getDefaultValue() ? 'true' : 'false';
  break;
  case Protobuf::TYPE_STRING:
  $default = '"' . addcslashes($field->getDefaultValue(), '"\\') . '"';
  break;
  case Protobuf::TYPE_ENUM:
  $default = $this->normalizeReference($field->getTypeName()) . '.' . $field->getDefaultValue();
  break;
  default: // Numbers
  $default = $field->getDefaultValue();
  }
  endif;
 
  $data = array(
  "'" . $field->getName() . "'",
  $field->getLabel(),
  $field->getType(),
  $reference,
  $default,
  '{}'
  );
 
  return '[' . implode(', ', $data) . ']';
  }
 
  public function generateAccessors($field, $namespace)
  {
  $camel = $this->comp->camelize(ucfirst($field->getName()));
 
  $s[]= "/**";
  $s[]= " * Check <$field->name> value";
  $s[]= " * @return {Boolean}";
  $s[]= " */";
  $s[]= "$namespace.prototype.has$camel = function(){";
  $s[]= " return this._has($field->number);";
  $s[]= "};";
  $s[]= "";
 
  $s[]= "/**";
  $s[]= " * Set a value for <$field->name>";
  $s[]= " * @param {" . $this->getJsDoc($field) . "} value";
  $s[]= " * @return {". $namespace . "}";
  $s[]= " */";
  $s[]= "$namespace.prototype.set$camel = function(value){";
  $s[]= " return this._set($field->number, value);";
  $s[]= "};";
  $s[]= "";
 
 
  $s[]= "/**";
  $s[]= " * Clear the value of <$field->name>";
  $s[]= " * @return {". $namespace . "}";
  $s[]= " */";
  $s[]= "$namespace.prototype.clear$camel = function(){";
  $s[]= " return this._clear($field->number);";
  $s[]= "};";
  $s[]= "";
 
 
  if ($field->getLabel() !== Protobuf::RULE_REPEATED):
 
  $s[]= "/**";
  $s[]= " * Get <$field->name> value";
  $s[]= " * @return {" . $this->getJsDoc($field) . "}";
  $s[]= " */";
  $s[]= "$namespace.prototype.get$camel = function(){";
  $s[]= " return this._get($field->number);";
  $s[]= "};";
  $s[]= "";
 
  else:
 
  $s[]= "/**";
  $s[]= " * Get an item from <$field->name>";
  $s[]= " * @param {int} idx";
  $s[]= " * @return {" . $this->getJsDoc($field) . "}";
  $s[]= " */";
  $s[]= "$namespace.prototype.get$camel = function(idx){";
  $s[]= " return this._get($field->number, idx);";
  $s[]= "};";
  $s[]= "";
 
 
  $s[]= "/**";
  $s[]= " * Get <$field->name> value";
  $s[]= " * @return {" . $this->getJsDoc($field) . "[]}";
  $s[]= " */";
  $s[]= "$namespace.prototype.get{$camel}List = function(){";
  $s[]= " return this._get($field->number);";
  $s[]= "};";
  $s[]= "";
 
  $s[]= "/**";
  $s[]= " * Add a value to <$field->name>";
  $s[]= " * @param {" . $this->getJsDoc($field) . "} value";
  $s[]= " * @return {" . $namespace . "}";
  $s[]= " */";
  $s[]= "$namespace.prototype.add$camel = function(value){";
  $s[]= " return this._add($field->number, value);";
  $s[]= "};";
  $s[]= "";
 
  endif;
 
 
  return implode("\n", $s);
  }
 
  public function getJsDoc(proto\FieldDescriptorProto $field)
  {
  switch ($field->getType()) {
  case Protobuf::TYPE_DOUBLE:
  case Protobuf::TYPE_FLOAT:
  return 'Float';
  case Protobuf::TYPE_INT64:
  case Protobuf::TYPE_UINT64:
  case Protobuf::TYPE_INT32:
  case Protobuf::TYPE_FIXED64:
  case Protobuf::TYPE_FIXED32:
  case Protobuf::TYPE_UINT32:
  case Protobuf::TYPE_SFIXED32:
  case Protobuf::TYPE_SFIXED64:
  case Protobuf::TYPE_SINT32:
  case Protobuf::TYPE_SINT64:
  return 'Int';
  case Protobuf::TYPE_BOOL:
  return 'Boolean';
  case Protobuf::TYPE_STRING:
  return 'String';
  case Protobuf::TYPE_MESSAGE:
  return $this->normalizeReference($field->getTypeName());
  case Protobuf::TYPE_BYTES:
  return 'String';
  case Protobuf::TYPE_ENUM:
  return 'Int (' . $this->normalizeReference($field->getTypeName()) . ')';
 
  case Protobuf::TYPE_GROUP:
  default:
  return 'unknown';
  }
  }
 
  public function normalizeReference($reference)
  {
  // Remove leading dot
  $reference = ltrim($reference, '.');
 
  if (!$this->comp->hasPackage($reference)) {
  $found = false;
  foreach ($this->comp->getPackages() as $package=>$namespace) {
  if (0 === strpos($reference, $package.'.')) {
  $reference = $namespace . substr($reference, strlen($package));
  $found = true;
  }
  }
  if (!$found) {
  $this->comp->warning('Non tracked package name found "' . $reference . '"');
  }
  } else {
  $reference = $this->comp->getPackage($reference);
  }
 
  return $reference;
  }
  }
  <?php
 
  namespace DrSlump\Protobuf\Compiler;
 
  use DrSlump\Protobuf;
  use google\protobuf as proto;
 
  class PhpGenerator extends AbstractGenerator
  {
  protected $components = array();
 
  protected function addComponent($ns, $name, $src)
  {
  if (NULL !== $ns) {
  $name = $this->normalizeNS($ns . '.' . $name);
  }
  $this->components[$name] = $src;
  }
 
  /**
  * Get an option from the compiler arguments or from the proto file.
  *
  * @param string $name
  * @return string|null
  */
  protected function getOption($name)
  {
  $opt = $this->compiler->getOption($name);
 
  if (NULL === $opt) {
  $opts = $this->proto->getOptions();
  if (!empty($opts) && isset($opts['php.' . $name])) {
  $opt = $opts['php.' . $name];
  }
  }
 
  return $opt;
  }
 
  public function getNamespace(proto\FileDescriptorProto $proto = NULL)
  {
  $proto = $proto ?: $this->proto;
 
  $opts = $proto->getOptions();
  if ($this->compiler->getOption('namespace')) {
  $namespace = $this->compiler->getOption('namespace');
  } else if ($this->compiler->getOption('package')) {
  $namespace = $this->compiler->getOption('package');
  } else if (isset($opts['php.namespace'])) {
  $namespace = $opts['php.namespace'];
  } else {
  $namespace = parent::getNamespace($proto);
  }
 
  $namespace = trim($namespace, '.\\');
  return str_replace('.', '\\', $namespace);
  }
 
  public function generate(proto\FileDescriptorProto $proto)
  {
  parent::generate($proto);
 
  $this->components = array();
  $namespace = $proto->getPackage();
 
  // Generate Enums
  foreach ($proto->getEnumType() as $enum) {
  $src = $this->compileEnum($enum, $namespace);
  $this->addComponent($namespace, $enum->getName(), $src);
  }
 
  // Generate Messages
  foreach ($proto->getMessageType() as $msg) {
  $src = $this->compileMessage($msg, $namespace);
  $this->addComponent($namespace, $msg->getName(), $src);
  }
 
  // Generate services
  if ($this->getOption('generic_services') && count($proto->hasService())):
  foreach ($proto->getServiceList() as $service) {
  $src = $this->compileService($service, $namespace);
  $this->addComponent($namespace, $service->getName(), $src);
  }
  endif;
 
  // Collect extensions
  if ($proto->hasExtension()) {
  foreach ($proto->getExtensionList() as $field) {
  $this->extensions[$field->getExtendee()][] = array($namespace, $field);
  }
  }
 
  // Dump all extensions found in this proto file
  if (count($this->extensions)):
  $s[]= 'namespace {';
  foreach ($this->extensions as $extendee => $fields) {
  foreach ($fields as $pair) {
  list($ns, $field) = $pair;
  $s[] = $this->compileExtension($field, $ns, ' ');
  }
  }
  $s[]= '}';
 
  $src = implode(PHP_EOL, $s);
 
  // In multifile mode we output all the extensions in a file named after
  // the proto file, since it's not trivial or even possible in all cases
  // to include the extensions with the extended message file.
  $fname = pathinfo($proto->getName(), PATHINFO_FILENAME);
  $this->addComponent(null, $fname . '-extensions', $src);
 
  // Reset extensions for next proto file
  $this->extensions = array();
  endif;
 
 
  $files = array();
  if (!$this->getOption('multifile')) {
  $src = '';
  foreach ($this->components as $content) {
  $src .= $content;
  }
  $fname = pathinfo($proto->getName(), PATHINFO_FILENAME);
  $files[] = $this->buildFile($proto, $fname, $src);
  } else {
  foreach ($this->components as $ns => $content) {
  $fname = str_replace('\\', '/', $ns);
  $files[] = $this->buildFile($proto, $fname, $content);
  }
  }
 
  return $files;
  }
 
  protected function buildFile(proto\FileDescriptorProto $proto, $fname, $contents)
  {
  $suffix = $this->getOption('suffix') ?: '.php';
  $fname .= $suffix;
 
  $file = new \google\protobuf\compiler\CodeGeneratorResponse\File();
  $file->setName($fname);
 
  $s = array();
  $s[]= "<?php";
  $s[]= "// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin " . Protobuf::VERSION;
  $s[]= "// Source: " . $proto->getName();
  $s[]= "// Date: " . date('Y-m-d H:i:s');
  $s[]= "";
  $s[]= "// @@protoc_insertion_point(scope_file)";
  $s[]= "";
 
  $contents = implode(PHP_EOL, $s) . PHP_EOL . $contents;
  $file->setContent($contents);
  return $file;
  }
 
  protected function compileEnum(proto\EnumDescriptorProto $enum, $ns)
  {
  $s = array();
 
  $s[]= "namespace " . $this->normalizeNS($ns) . " {";
  $s[]= "";
  $s[]= " // @@protoc_insertion_point(scope_namespace)";
  $s[]= " // @@protoc_insertion_point(namespace_$ns)";
  $s[]= "";
 
  $cmt = $this->compiler->getComment($ns . '.' . $enum->getName(), ' * ');
  if ($cmt):
  $s[]= " /**";
  $s[]= $cmt;
  $s[]= " */";
  endif;
 
  $s[]= " class " . $enum->getName() . " {";
  foreach ($enum->getValueList() as $value):
  $s[]= " const " . $value->getName() . " = " . $value->getNumber() . ";";
  endforeach;
  $s[]= "";
  $s[]= " // @@protoc_insertion_point(scope_class)";
  $s[]= ' // @@protoc_insertion_point(class_' . $ns . '.' . $enum->getName() . ')';
  $s[]= " }";
  $s[]= "}";
  $s[]= "";
 
  return implode(PHP_EOL, $s);
  }
 
  protected function compileMessage(proto\DescriptorProto $msg, $ns)
  {
  $s = array();
  $s[]= "namespace " . $this->normalizeNS($ns) . " {";
  $s[]= "";
  $s[]= " // @@protoc_insertion_point(scope_namespace)";
  $s[]= " // @@protoc_insertion_point(namespace_$ns)";
  $s[]= "";
 
  $cmt = $this->compiler->getComment($ns . '.' . $msg->getName(), ' * ');
  if ($cmt):
  $s[]= " /**";
  $s[]= $cmt;
  $s[]= " */";
  endif;
 
  // Compute a new namespace with the message name as suffix
  $ns .= '.' . $msg->getName();
 
  $s[]= ' class ' . $msg->getName() . ' extends \DrSlump\Protobuf\Message {';
  $s[]= "";
  $s[]= ' /** @var \Closure[] */';
  $s[]= ' protected static $__extensions = array();';
  $s[]= '';
  $s[]= ' public static function descriptor()';
  $s[]= ' {';
  $s[]= ' $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, \'' . $ns . '\');';
  $s[]= '';
  foreach ($msg->getField() as $field):
  $s[]= $this->compileField($field, $ns, " ");
  $s[]= ' $descriptor->addField($f);';
  $s[]= '';
  endforeach;
  $s[]= ' foreach (self::$__extensions as $cb) {';
  $s[]= ' $descriptor->addField($cb(), true);';
  $s[]= ' }';
  $s[]= '';
  $s[]= ' // @@protoc_insertion_point(scope_descriptor)';
  $s[]= ' // @@protoc_insertion_point(descriptor_' . $ns . ')';
  $s[]= '';
  $s[]= ' return $descriptor;';
  $s[]= ' }';
  $s[]= '';
 
  //$s[]= " protected static \$__exts = array(";
  //foreach ($msg->getExtensionRange() as $range):
  //$s[]= ' array(' . $range->getStart() . ', ' . ($range->getEnd()-1) . '),';
  //endforeach;
  //$s[]= " );";
  //$s[]= "";
 
  foreach ($msg->getField() as $field):
  $s[]= $this->generatePublicField($field, $ns, " ");
  endforeach;
  $s[]= "";
 
  foreach ($msg->getField() as $field):
  $s[]= $this->generateAccessors($field, $ns, " ");
  endforeach;
 
  $s[]= "";
  $s[]= " // @@protoc_insertion_point(scope_class)";
  $s[]= ' // @@protoc_insertion_point(class_' . $ns . ')';
  $s[]= " }";
  $s[]= "}";
  $s[]= "";
 
  // Generate Enums
  if ($msg->hasEnumType()):
  foreach ($msg->getEnumType() as $enum):
  $src = $this->compileEnum($enum, $ns);
  $this->addComponent($ns, $enum->getName(), $src);
  endforeach;
  endif;
 
  // Generate nested messages
  if ($msg->hasNestedType()):
  foreach ($msg->getNestedType() as $msg):
  $src = $this->compileMessage($msg, $ns);
  $this->addComponent($ns, $msg->getName(), $src);
  endforeach;
  endif;
 
  // Collect extensions
  if ($msg->hasExtension()) {
  foreach ($msg->getExtensionList() as $field) {
  $this->_extensions[$field->getExtendee()][] = array($ns, $field);
  }
  }
 
  return implode(PHP_EOL, $s) . PHP_EOL;
  }
 
 
  protected function compileField(proto\FieldDescriptorProto $field, $ns, $indent)
  {
  switch ($field->getLabel()) {
  case Protobuf::RULE_REQUIRED:
  $rule = 'required';
  break;
  case Protobuf::RULE_OPTIONAL:
  $rule = 'optional';
  break;
  case Protobuf::RULE_REPEATED:
  $rule = 'repeated';
  break;
  }
 
  $s[]= "// $rule " . $field->getTypeName() . " " . $field->getName() . " = " . $field->getNumber();
  $s[]= '$f = new \DrSlump\Protobuf\Field();';
  $s[]= '$f->number = ' . $field->getNumber() . ';';
  $s[]= '$f->name = "'. $field->getName() . '";';
  $s[]= '$f->type = ' . $field->getType() . ';';
  $s[]= '$f->rule = ' . $field->getLabel() . ';';
 
  if ($field->hasTypeName()):
  $ref = $field->getTypeName();
  if (substr($ref, 0, 1) !== '.') {
  throw new \RuntimeException("Only fully qualified names are supported but found '$ref' at $ns");
  }
  $s[]= '$f->reference = \'\\' . $this->normalizeNS($ref) . "';";
  endif;
 
  if ($field->hasDefaultValue()):
  switch ($field->getType()) {
  case Protobuf::TYPE_BOOL:
  $bool = filter_var($field->getDefaultValue(), FILTER_VALIDATE_BOOLEAN);
  $s[]= '$f->default = ' . ($bool ? 'true' : 'false') . ';';
  break;
  case Protobuf::TYPE_STRING:
  $s[]= '$f->default = "' . addcslashes($field->getDefaultValue(), '"\\') . '";';
  break;
  case Protobuf::TYPE_ENUM:
  $value = '\\' . $this->normalizeNS($field->getTypeName()) . '::' . $field->getDefaultValue();
  $s[]= '$f->default = ' . $value . ';';
  break;
  default: // Numbers
  $s[]= '$f->default = ' . $field->getDefaultValue() . ';';
  }
  endif;
 
  $s[]= '// @@protoc_insertion_point(scope_field)';
  $s[]= '// @@protoc_insertion_point(field_' . $ns . ':' . $field->getName() . ')';
 
  return $indent . implode(PHP_EOL.$indent, $s);
  }
 
  protected function compileExtension(proto\FieldDescriptorProto $field, $ns, $indent)
  {
  $extendee = $this->normalizeNS($field->getExtendee());
  $name = $this->normalizeNS($ns . '.' . $field->getName());
  $field->setName($name);
 
  $s[]= "\\$extendee::extension(function(){";
  $s[]= $this->compileField($field, $ns, $indent.' ');
  $s[]= ' // @@protoc_insertion_point(scope_extension)';
  $s[]= ' // @@protoc_insertion_point(extension_' . $ns . ':' . $field->getName() . ')';
  $s[]= ' return $f;';
  $s[]= "});";
 
  return $indent . implode(PHP_EOL.$indent, $s);
  }
 
  protected function compileService(proto\ServiceDescriptorProto $service, $ns)
  {
  $s = array();
  $s[]= 'namespace ' . $this->normalizeNS($ns) . ' {';
  $s[]= '';
  $s[]= " // @@protoc_insertion_point(scope_namespace)";
  $s[]= " // @@protoc_insertion_point(namespace_$ns)";
  $s[]= '';
 
  $cmt = $this->compiler->getComment($ns . '.' . $service->getName(), ' * ');
  if ($cmt):
  $s[]= " /**";
  $s[]= $cmt;
  $s[]= " */";
  endif;
 
  $s[]= ' interface ' . $service->getName();
  $s[]= ' {';
  $s[]= ' // @@protoc_insertion_point(scope_interface)';
  $s[]= ' // @@protoc_insertion_point(interface_' . $ns . '.' . $service->getName() . ')';
  $s[]= '';
 
  foreach ($service->getMethodList() as $method):
  $s[]= ' /**';
 
  $cmt = $this->compiler->getComment($ns . '.' . $service->getName() . '.' . $method->getName(), ' * ');
  if ($cmt):
  $s[]= $cmt;
  $s[]= ' * ';
  endif;
 
  $s[]= ' * @param ' . $this->normalizeNS($method->getInputType()) . ' $input';
  $s[]= ' * @return ' . $this->normalizeNS($method->getOutputType());
  $s[]= ' */';
  $s[]= ' public function ' . $method->getName() . '(' . $this->normalizeNS($method->getInputType()) . ' $input);';
  $s[]= '';
  endforeach;
  $s[]= ' }';
  $s[]= '}';
  $s[]= '';
 
  return implode(PHP_EOL, $s) . PHP_EOL;
  }
 
  protected function generatePublicField(proto\FieldDescriptorProto $field, $ns, $indent)
  {
  $cmt = $this->compiler->getComment($ns . '.' . $field->getNumber(), "$indent * ");
  if ($cmt) {
  $cmt = "\n" . $cmt . "\n$indent *";
  }
 
  if ($field->getLabel() === Protobuf::RULE_REPEATED) {
  $s[]= "/** $cmt @var " . $this->getJavaDocType($field) . "[] " . ($cmt ? "\n$indent" : '') . " */";
  $s[]= 'public $' . $field->getName() . " = array();";
  } else {
  $s[]= "/** $cmt @var " . $this->getJavaDocType($field) . ($cmt ? "\n$indent" : '') . " */";
  $default = 'null';
  if ($field->hasDefaultValue()) {
  switch ($field->getType()) {
  case Protobuf::TYPE_BOOL:
  $default = $field->getDefaultValue() ? 'true' : 'false';
  break;
  case Protobuf::TYPE_STRING:
  $default = '"' . addcslashes($field->getDefaultValue(), '"\\') . '"';
  break;
  case Protobuf::TYPE_ENUM:
  $default = '\\' . $this->normalizeNS($field->getTypeName()) . '::' . $field->getDefaultValue();
  break;
  default: // Numbers
  $default = $field->getDefaultValue();
  }
  }
  $s[]= 'public $' . $field->getName() . ' = ' . $default . ';';
  }
  $s[]= "";
 
  return $indent . implode(PHP_EOL.$indent, $s);
  }
 
  protected function generateAccessors(proto\FieldDescriptorProto $field, $ns, $indent)
  {
  $tag = $field->getNumber();
  $name = $field->getName();
  $camel = $this->compiler->camelize(ucfirst($name));
 
  $typehint = '';
  $typedoc = $this->getJavaDocType($field);
  if (0 === strpos($typedoc, '\\')) {
  $typehint = $typedoc;
  }
 
  // hasXXX
  $s[]= "/**";
  $s[]= " * Check if <$name> has a value";
  $s[]= " *";
  $s[]= " * @return boolean";
  $s[]= " */";
  $s[]= "public function has$camel(){";
  $s[]= " return \$this->_has($tag);";
  $s[]= "}";
  $s[]= "";
 
  // clearXXX
  $s[]= "/**";
  $s[]= " * Clear <$name> value";
  $s[]= " *";
  $s[]= " * @return \\" . $this->normalizeNS($ns);
  $s[]= " */";
  $s[]= "public function clear$camel(){";
  $s[]= " return \$this->_clear($tag);";
  $s[]= "}";
  $s[]= "";
 
 
  if ($field->getLabel() === Protobuf::RULE_REPEATED):
 
  // getXXX
  $s[]= "/**";
  $s[]= " * Get <$name> value";
  $s[]= " *";
  $s[]= " * @param int \$idx";
  $s[]= " * @return $typedoc";
  $s[]= " */";
  $s[]= "public function get$camel(\$idx = NULL){";
  $s[]= " return \$this->_get($tag, \$idx);";
  $s[]= "}";
  $s[]= "";
 
  // setXXX
  $s[]= "/**";
  $s[]= " * Set <$name> value";
  $s[]= " *";
  $s[]= " * @param $typedoc \$value";
  $s[]= " * @return \\" . $this->normalizeNS($ns);
  $s[]= " */";
  $s[]= "public function set$camel($typehint \$value, \$idx = NULL){";
  $s[]= " return \$this->_set($tag, \$value, \$idx);";
  $s[]= "}";
  $s[]= "";
 
  $s[]= "/**";
  $s[]= " * Get all elements of <$name>";
  $s[]= " *";
  $s[]= " * @return {$typedoc}[]";
  $s[]= " */";
  $s[]= "public function get{$camel}List(){";
  $s[]= " return \$this->_get($tag);";
  $s[]= "}";
  $s[]= "";
 
  $s[]= "/**";
  $s[]= " * Add a new element to <$name>";
  $s[]= " *";
  $s[]= " * @param $typedoc \$value";
  $s[]= " * @return \\" . $this->normalizeNS($ns);
  $s[]= " */";
  $s[]= "public function add$camel($typehint \$value){";
  $s[]= " return \$this->_add($tag, \$value);";
  $s[]= "}";
  $s[]= "";
 
  else:
 
  // getXXX
  $s[]= "/**";
  $s[]= " * Get <$name> value";
  $s[]= " *";
  $s[]= " * @return $typedoc";
  $s[]= " */";
  $s[]= "public function get$camel(){";
  $s[]= " return \$this->_get($tag);";
  $s[]= "}";
  $s[]= "";
 
  // setXXX
  $s[]= "/**";
  $s[]= " * Set <$name> value";
  $s[]= " *";
  $s[]= " * @param $typedoc \$value";
  $s[]= " * @return \\" . $this->normalizeNS($ns);
  $s[]= " */";
  $s[]= "public function set$camel($typehint \$value){";
  $s[]= " return \$this->_set($tag, \$value);";
  $s[]= "}";
  $s[]= "";
 
  endif;
 
  return $indent . implode(PHP_EOL.$indent, $s);
  }
 
  protected function getJavaDocType(proto\FieldDescriptorProto $field)
  {
  switch ($field->getType()) {
  case Protobuf::TYPE_DOUBLE:
  case Protobuf::TYPE_FLOAT:
  return 'float';
  case Protobuf::TYPE_INT64:
  case Protobuf::TYPE_UINT64:
  case Protobuf::TYPE_INT32:
  case Protobuf::TYPE_FIXED64:
  case Protobuf::TYPE_FIXED32:
  case Protobuf::TYPE_UINT32:
  case Protobuf::TYPE_SFIXED32:
  case Protobuf::TYPE_SFIXED64:
  case Protobuf::TYPE_SINT32:
  case Protobuf::TYPE_SINT64:
  return 'int';
  case Protobuf::TYPE_BOOL:
  return 'boolean';
  case Protobuf::TYPE_STRING:
  return 'string';
  case Protobuf::TYPE_MESSAGE:
  return '\\' . $this->normalizeNS($field->getTypeName());
  case Protobuf::TYPE_BYTES:
  return 'string';
  case Protobuf::TYPE_ENUM:
  return 'int - \\' . $this->normalizeNS($field->getTypeName());
 
  case Protobuf::TYPE_GROUP:
  default:
  return 'unknown';
  }
  }
 
  protected function normalizeNS($package)
  {
  // Remove leading dot (used in references)
  $package = ltrim($package, '.');
 
  if ($this->compiler->hasPackage($package)) {
  return $this->compiler->getPackage($package);
  }
 
  // Check the currently registered packages to find a root one
  $found = null;
  foreach ($this->compiler->getPackages() as $pkg=>$ns) {
  // Keep only the longest match
  if (0 === strpos($package, $pkg.'.') && strlen($found) < strlen($pkg)) {
  $found = $pkg;
  }
  }
 
  // If no matching package was found issue a warning and use the package name
  if (!$found) {
  $this->compiler->warning('Non tracked package name found "' . $package . '"');
  $namespace = str_replace('.', '\\', $package);
  } else {
  // Complete the namespace with the remaining package
  $namespace = $this->compiler->getPackage($found);
  $namespace .= substr($package, strlen($found));
  $namespace = str_replace('.', '\\', $namespace);
  // Set the newly found namespace in the registry
  $this->compiler->setPackage($package, $namespace);
  }
 
  return $namespace;
  }
  }
 
  <?php
  // DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@
  // Source: descriptor.proto
  // Date: 2011-03-20 01:26:49
 
  namespace google\protobuf {
 
  class FileDescriptorSet extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FileDescriptorSet");
 
  // repeated .google.protobuf.FileDescriptorProto file = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "file";
  $f->nameOrig = "file";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\FileDescriptorProto";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var \google\protobuf\FileDescriptorProto[] */
  public $file = array();
 
 
  /**
  * Check if <file> has a value
  *
  * @return boolean
  */
  public function hasFile(){
  return $this->_has(1);
  }
 
  /**
  * Clear <file> value
  *
  * @return \google\protobuf\FileDescriptorSet
  */
  public function clearFile(){
  return $this->_clear(1);
  }
 
  /**
  * Get <file> value
  *
  * @param int $idx
  * @return \google\protobuf\FileDescriptorProto
  */
  public function getFile($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <file> value
  *
  * @param \google\protobuf\FileDescriptorProto $value
  * @return \google\protobuf\FileDescriptorSet
  */
  public function setFile(\google\protobuf\FileDescriptorProto $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <file>
  *
  * @return \google\protobuf\FileDescriptorProto[]
  */
  public function getFileList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <file>
  *
  * @param \google\protobuf\FileDescriptorProto $value
  * @return \google\protobuf\FileDescriptorSet
  */
  public function addFile(\google\protobuf\FileDescriptorProto $value){
  return $this->_add(1, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class FileDescriptorProto extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FileDescriptorProto");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional package = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "package";
  $f->nameOrig = "package";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated dependency = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "dependency";
  $f->nameOrig = "dependency";
  $f->type = 9;
  $f->rule = 3;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.DescriptorProto message_type = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "message_type";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\DescriptorProto";
  $descriptor->addField($f);
 
  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "enum_type";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\EnumDescriptorProto";
  $descriptor->addField($f);
 
  // repeated .google.protobuf.ServiceDescriptorProto service = 6
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 6;
  $f->name = "service";
  $f->nameOrig = "service";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\ServiceDescriptorProto";
  $descriptor->addField($f);
 
  // repeated .google.protobuf.FieldDescriptorProto extension = 7
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 7;
  $f->name = "extension";
  $f->nameOrig = "extension";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\FieldDescriptorProto";
  $descriptor->addField($f);
 
  // optional .google.protobuf.FileOptions options = 8
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 8;
  $f->name = "options";
  $f->nameOrig = "options";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\FileOptions";
  $descriptor->addField($f);
 
  // optional .google.protobuf.SourceCodeInfo source_code_info = 9
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 9;
  $f->name = "source_code_info";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\SourceCodeInfo";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var string */
  public $package = null;
 
  /** @var string[] */
  public $dependency = array();
 
  /** @var \google\protobuf\DescriptorProto[] */
  public $message_type = array();
 
  /** @var \google\protobuf\EnumDescriptorProto[] */
  public $enum_type = array();
 
  /** @var \google\protobuf\ServiceDescriptorProto[] */
  public $service = array();
 
  /** @var \google\protobuf\FieldDescriptorProto[] */
  public $extension = array();
 
  /** @var \google\protobuf\FileOptions */
  public $options = null;
 
  /** @var \google\protobuf\SourceCodeInfo */
  public $source_code_info = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <package> has a value
  *
  * @return boolean
  */
  public function hasPackage(){
  return $this->_has(2);
  }
 
  /**
  * Clear <package> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearPackage(){
  return $this->_clear(2);
  }
 
  /**
  * Get <package> value
  *
  * @return string
  */
  public function getPackage(){
  return $this->_get(2);
  }
 
  /**
  * Set <package> value
  *
  * @param string $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setPackage( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <dependency> has a value
  *
  * @return boolean
  */
  public function hasDependency(){
  return $this->_has(3);
  }
 
  /**
  * Clear <dependency> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearDependency(){
  return $this->_clear(3);
  }
 
  /**
  * Get <dependency> value
  *
  * @param int $idx
  * @return string
  */
  public function getDependency($idx = NULL){
  return $this->_get(3, $idx);
  }
 
  /**
  * Set <dependency> value
  *
  * @param string $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setDependency( $value, $idx = NULL){
  return $this->_set(3, $value, $idx);
  }
 
  /**
  * Get all elements of <dependency>
  *
  * @return string[]
  */
  public function getDependencyList(){
  return $this->_get(3);
  }
 
  /**
  * Add a new element to <dependency>
  *
  * @param string $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function addDependency( $value){
  return $this->_add(3, $value);
  }
 
  /**
  * Check if <message_type> has a value
  *
  * @return boolean
  */
  public function hasMessageType(){
  return $this->_has(4);
  }
 
  /**
  * Clear <message_type> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearMessageType(){
  return $this->_clear(4);
  }
 
  /**
  * Get <message_type> value
  *
  * @param int $idx
  * @return \google\protobuf\DescriptorProto
  */
  public function getMessageType($idx = NULL){
  return $this->_get(4, $idx);
  }
 
  /**
  * Set <message_type> value
  *
  * @param \google\protobuf\DescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setMessageType(\google\protobuf\DescriptorProto $value, $idx = NULL){
  return $this->_set(4, $value, $idx);
  }
 
  /**
  * Get all elements of <message_type>
  *
  * @return \google\protobuf\DescriptorProto[]
  */
  public function getMessageTypeList(){
  return $this->_get(4);
  }
 
  /**
  * Add a new element to <message_type>
  *
  * @param \google\protobuf\DescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function addMessageType(\google\protobuf\DescriptorProto $value){
  return $this->_add(4, $value);
  }
 
  /**
  * Check if <enum_type> has a value
  *
  * @return boolean
  */
  public function hasEnumType(){
  return $this->_has(5);
  }
 
  /**
  * Clear <enum_type> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearEnumType(){
  return $this->_clear(5);
  }
 
  /**
  * Get <enum_type> value
  *
  * @param int $idx
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function getEnumType($idx = NULL){
  return $this->_get(5, $idx);
  }
 
  /**
  * Set <enum_type> value
  *
  * @param \google\protobuf\EnumDescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setEnumType(\google\protobuf\EnumDescriptorProto $value, $idx = NULL){
  return $this->_set(5, $value, $idx);
  }
 
  /**
  * Get all elements of <enum_type>
  *
  * @return \google\protobuf\EnumDescriptorProto[]
  */
  public function getEnumTypeList(){
  return $this->_get(5);
  }
 
  /**
  * Add a new element to <enum_type>
  *
  * @param \google\protobuf\EnumDescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function addEnumType(\google\protobuf\EnumDescriptorProto $value){
  return $this->_add(5, $value);
  }
 
  /**
  * Check if <service> has a value
  *
  * @return boolean
  */
  public function hasService(){
  return $this->_has(6);
  }
 
  /**
  * Clear <service> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearService(){
  return $this->_clear(6);
  }
 
  /**
  * Get <service> value
  *
  * @param int $idx
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function getService($idx = NULL){
  return $this->_get(6, $idx);
  }
 
  /**
  * Set <service> value
  *
  * @param \google\protobuf\ServiceDescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setService(\google\protobuf\ServiceDescriptorProto $value, $idx = NULL){
  return $this->_set(6, $value, $idx);
  }
 
  /**
  * Get all elements of <service>
  *
  * @return \google\protobuf\ServiceDescriptorProto[]
  */
  public function getServiceList(){
  return $this->_get(6);
  }
 
  /**
  * Add a new element to <service>
  *
  * @param \google\protobuf\ServiceDescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function addService(\google\protobuf\ServiceDescriptorProto $value){
  return $this->_add(6, $value);
  }
 
  /**
  * Check if <extension> has a value
  *
  * @return boolean
  */
  public function hasExtension(){
  return $this->_has(7);
  }
 
  /**
  * Clear <extension> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearExtension(){
  return $this->_clear(7);
  }
 
  /**
  * Get <extension> value
  *
  * @param int $idx
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function getExtension($idx = NULL){
  return $this->_get(7, $idx);
  }
 
  /**
  * Set <extension> value
  *
  * @param \google\protobuf\FieldDescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setExtension(\google\protobuf\FieldDescriptorProto $value, $idx = NULL){
  return $this->_set(7, $value, $idx);
  }
 
  /**
  * Get all elements of <extension>
  *
  * @return \google\protobuf\FieldDescriptorProto[]
  */
  public function getExtensionList(){
  return $this->_get(7);
  }
 
  /**
  * Add a new element to <extension>
  *
  * @param \google\protobuf\FieldDescriptorProto $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function addExtension(\google\protobuf\FieldDescriptorProto $value){
  return $this->_add(7, $value);
  }
 
  /**
  * Check if <options> has a value
  *
  * @return boolean
  */
  public function hasOptions(){
  return $this->_has(8);
  }
 
  /**
  * Clear <options> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearOptions(){
  return $this->_clear(8);
  }
 
  /**
  * Get <options> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function getOptions(){
  return $this->_get(8);
  }
 
  /**
  * Set <options> value
  *
  * @param \google\protobuf\FileOptions $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setOptions(\google\protobuf\FileOptions $value){
  return $this->_set(8, $value);
  }
 
  /**
  * Check if <source_code_info> has a value
  *
  * @return boolean
  */
  public function hasSourceCodeInfo(){
  return $this->_has(9);
  }
 
  /**
  * Clear <source_code_info> value
  *
  * @return \google\protobuf\FileDescriptorProto
  */
  public function clearSourceCodeInfo(){
  return $this->_clear(9);
  }
 
  /**
  * Get <source_code_info> value
  *
  * @return \google\protobuf\SourceCodeInfo
  */
  public function getSourceCodeInfo(){
  return $this->_get(9);
  }
 
  /**
  * Set <source_code_info> value
  *
  * @param \google\protobuf\SourceCodeInfo $value
  * @return \google\protobuf\FileDescriptorProto
  */
  public function setSourceCodeInfo(\google\protobuf\SourceCodeInfo $value){
  return $this->_set(9, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class DescriptorProto extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\DescriptorProto");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.FieldDescriptorProto field = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "field";
  $f->nameOrig = "field";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\FieldDescriptorProto";
  $descriptor->addField($f);
 
  // repeated .google.protobuf.FieldDescriptorProto extension = 6
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 6;
  $f->name = "extension";
  $f->nameOrig = "extension";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\FieldDescriptorProto";
  $descriptor->addField($f);
 
  // repeated .google.protobuf.DescriptorProto nested_type = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "nested_type";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\DescriptorProto";
  $descriptor->addField($f);
 
  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "enum_type";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\EnumDescriptorProto";
  $descriptor->addField($f);
 
  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "extension_range";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\DescriptorProto\ExtensionRange";
  $descriptor->addField($f);
 
  // optional .google.protobuf.MessageOptions options = 7
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 7;
  $f->name = "options";
  $f->nameOrig = "options";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\MessageOptions";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var \google\protobuf\FieldDescriptorProto[] */
  public $field = array();
 
  /** @var \google\protobuf\FieldDescriptorProto[] */
  public $extension = array();
 
  /** @var \google\protobuf\DescriptorProto[] */
  public $nested_type = array();
 
  /** @var \google\protobuf\EnumDescriptorProto[] */
  public $enum_type = array();
 
  /** @var \google\protobuf\DescriptorProto\ExtensionRange[] */
  public $extension_range = array();
 
  /** @var \google\protobuf\MessageOptions */
  public $options = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\DescriptorProto
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\DescriptorProto
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <field> has a value
  *
  * @return boolean
  */
  public function hasField(){
  return $this->_has(2);
  }
 
  /**
  * Clear <field> value
  *
  * @return \google\protobuf\DescriptorProto
  */
  public function clearField(){
  return $this->_clear(2);
  }
 
  /**
  * Get <field> value
  *
  * @param int $idx
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function getField($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <field> value
  *
  * @param \google\protobuf\FieldDescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function setField(\google\protobuf\FieldDescriptorProto $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <field>
  *
  * @return \google\protobuf\FieldDescriptorProto[]
  */
  public function getFieldList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <field>
  *
  * @param \google\protobuf\FieldDescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function addField(\google\protobuf\FieldDescriptorProto $value){
  return $this->_add(2, $value);
  }
 
  /**
  * Check if <extension> has a value
  *
  * @return boolean
  */
  public function hasExtension(){
  return $this->_has(6);
  }
 
  /**
  * Clear <extension> value
  *
  * @return \google\protobuf\DescriptorProto
  */
  public function clearExtension(){
  return $this->_clear(6);
  }
 
  /**
  * Get <extension> value
  *
  * @param int $idx
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function getExtension($idx = NULL){
  return $this->_get(6, $idx);
  }
 
  /**
  * Set <extension> value
  *
  * @param \google\protobuf\FieldDescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function setExtension(\google\protobuf\FieldDescriptorProto $value, $idx = NULL){
  return $this->_set(6, $value, $idx);
  }
 
  /**
  * Get all elements of <extension>
  *
  * @return \google\protobuf\FieldDescriptorProto[]
  */
  public function getExtensionList(){
  return $this->_get(6);
  }
 
  /**
  * Add a new element to <extension>
  *
  * @param \google\protobuf\FieldDescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function addExtension(\google\protobuf\FieldDescriptorProto $value){
  return $this->_add(6, $value);
  }
 
  /**
  * Check if <nested_type> has a value
  *
  * @return boolean
  */
  public function hasNestedType(){
  return $this->_has(3);
  }
 
  /**
  * Clear <nested_type> value
  *
  * @return \google\protobuf\DescriptorProto
  */
  public function clearNestedType(){
  return $this->_clear(3);
  }
 
  /**
  * Get <nested_type> value
  *
  * @param int $idx
  * @return \google\protobuf\DescriptorProto
  */
  public function getNestedType($idx = NULL){
  return $this->_get(3, $idx);
  }
 
  /**
  * Set <nested_type> value
  *
  * @param \google\protobuf\DescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function setNestedType(\google\protobuf\DescriptorProto $value, $idx = NULL){
  return $this->_set(3, $value, $idx);
  }
 
  /**
  * Get all elements of <nested_type>
  *
  * @return \google\protobuf\DescriptorProto[]
  */
  public function getNestedTypeList(){
  return $this->_get(3);
  }
 
  /**
  * Add a new element to <nested_type>
  *
  * @param \google\protobuf\DescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function addNestedType(\google\protobuf\DescriptorProto $value){
  return $this->_add(3, $value);
  }
 
  /**
  * Check if <enum_type> has a value
  *
  * @return boolean
  */
  public function hasEnumType(){
  return $this->_has(4);
  }
 
  /**
  * Clear <enum_type> value
  *
  * @return \google\protobuf\DescriptorProto
  */
  public function clearEnumType(){
  return $this->_clear(4);
  }
 
  /**
  * Get <enum_type> value
  *
  * @param int $idx
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function getEnumType($idx = NULL){
  return $this->_get(4, $idx);
  }
 
  /**
  * Set <enum_type> value
  *
  * @param \google\protobuf\EnumDescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function setEnumType(\google\protobuf\EnumDescriptorProto $value, $idx = NULL){
  return $this->_set(4, $value, $idx);
  }
 
  /**
  * Get all elements of <enum_type>
  *
  * @return \google\protobuf\EnumDescriptorProto[]
  */
  public function getEnumTypeList(){
  return $this->_get(4);
  }
 
  /**
  * Add a new element to <enum_type>
  *
  * @param \google\protobuf\EnumDescriptorProto $value
  * @return \google\protobuf\DescriptorProto
  */
  public function addEnumType(\google\protobuf\EnumDescriptorProto $value){
  return $this->_add(4, $value);
  }
 
  /**
  * Check if <extension_range> has a value
  *
  * @return boolean
  */
  public function hasExtensionRange(){
  return $this->_has(5);
  }
 
  /**
  * Clear <extension_range> value
  *
  * @return \google\protobuf\DescriptorProto
  */
  public function clearExtensionRange(){
  return $this->_clear(5);
  }
 
  /**
  * Get <extension_range> value
  *
  * @param int $idx
  * @return \google\protobuf\DescriptorProto\ExtensionRange
  */
  public function getExtensionRange($idx = NULL){
  return $this->_get(5, $idx);
  }
 
  /**
  * Set <extension_range> value
  *
  * @param \google\protobuf\DescriptorProto\ExtensionRange $value
  * @return \google\protobuf\DescriptorProto
  */
  public function setExtensionRange(\google\protobuf\DescriptorProto\ExtensionRange $value, $idx = NULL){
  return $this->_set(5, $value, $idx);
  }
 
  /**
  * Get all elements of <extension_range>
  *
  * @return \google\protobuf\DescriptorProto\ExtensionRange[]
  */
  public function getExtensionRangeList(){
  return $this->_get(5);
  }
 
  /**
  * Add a new element to <extension_range>
  *
  * @param \google\protobuf\DescriptorProto\ExtensionRange $value
  * @return \google\protobuf\DescriptorProto
  */
  public function addExtensionRange(\google\protobuf\DescriptorProto\ExtensionRange $value){
  return $this->_add(5, $value);
  }
 
  /**
  * Check if <options> has a value
  *
  * @return boolean
  */
  public function hasOptions(){
  return $this->_has(7);
  }
 
  /**
  * Clear <options> value
  *
  * @return \google\protobuf\DescriptorProto
  */
  public function clearOptions(){
  return $this->_clear(7);
  }
 
  /**
  * Get <options> value
  *
  * @return \google\protobuf\MessageOptions
  */
  public function getOptions(){
  return $this->_get(7);
  }
 
  /**
  * Set <options> value
  *
  * @param \google\protobuf\MessageOptions $value
  * @return \google\protobuf\DescriptorProto
  */
  public function setOptions(\google\protobuf\MessageOptions $value){
  return $this->_set(7, $value);
  }
 
  }
  }
 
  namespace google\protobuf\DescriptorProto {
 
  class ExtensionRange extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\DescriptorProto\ExtensionRange");
 
  // optional start = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "start";
  $f->nameOrig = "start";
  $f->type = 5;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional end = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "end";
  $f->nameOrig = "end";
  $f->type = 5;
  $f->rule = 1;
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var int */
  public $start = null;
 
  /** @var int */
  public $end = null;
 
 
  /**
  * Check if <start> has a value
  *
  * @return boolean
  */
  public function hasStart(){
  return $this->_has(1);
  }
 
  /**
  * Clear <start> value
  *
  * @return \google\protobuf\DescriptorProto\ExtensionRange
  */
  public function clearStart(){
  return $this->_clear(1);
  }
 
  /**
  * Get <start> value
  *
  * @return int
  */
  public function getStart(){
  return $this->_get(1);
  }
 
  /**
  * Set <start> value
  *
  * @param int $value
  * @return \google\protobuf\DescriptorProto\ExtensionRange
  */
  public function setStart( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <end> has a value
  *
  * @return boolean
  */
  public function hasEnd(){
  return $this->_has(2);
  }
 
  /**
  * Clear <end> value
  *
  * @return \google\protobuf\DescriptorProto\ExtensionRange
  */
  public function clearEnd(){
  return $this->_clear(2);
  }
 
  /**
  * Get <end> value
  *
  * @return int
  */
  public function getEnd(){
  return $this->_get(2);
  }
 
  /**
  * Set <end> value
  *
  * @param int $value
  * @return \google\protobuf\DescriptorProto\ExtensionRange
  */
  public function setEnd( $value){
  return $this->_set(2, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class FieldDescriptorProto extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FieldDescriptorProto");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional number = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "number";
  $f->nameOrig = "number";
  $f->type = 5;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional .google.protobuf.FieldDescriptorProto.Label label = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "label";
  $f->nameOrig = "label";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = "\google\protobuf\FieldDescriptorProto\Label";
  $descriptor->addField($f);
 
  // optional .google.protobuf.FieldDescriptorProto.Type type = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "type";
  $f->nameOrig = "type";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = "\google\protobuf\FieldDescriptorProto\Type";
  $descriptor->addField($f);
 
  // optional type_name = 6
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 6;
  $f->name = "type_name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional extendee = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "extendee";
  $f->nameOrig = "extendee";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional default_value = 7
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 7;
  $f->name = "default_value";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional .google.protobuf.FieldOptions options = 8
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 8;
  $f->name = "options";
  $f->nameOrig = "options";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\FieldOptions";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var int */
  public $number = null;
 
  /** @var int - \google\protobuf\FieldDescriptorProto\Label */
  public $label = null;
 
  /** @var int - \google\protobuf\FieldDescriptorProto\Type */
  public $type = null;
 
  /** @var string */
  public $type_name = null;
 
  /** @var string */
  public $extendee = null;
 
  /** @var string */
  public $default_value = null;
 
  /** @var \google\protobuf\FieldOptions */
  public $options = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <number> has a value
  *
  * @return boolean
  */
  public function hasNumber(){
  return $this->_has(3);
  }
 
  /**
  * Clear <number> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearNumber(){
  return $this->_clear(3);
  }
 
  /**
  * Get <number> value
  *
  * @return int
  */
  public function getNumber(){
  return $this->_get(3);
  }
 
  /**
  * Set <number> value
  *
  * @param int $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setNumber( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <label> has a value
  *
  * @return boolean
  */
  public function hasLabel(){
  return $this->_has(4);
  }
 
  /**
  * Clear <label> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearLabel(){
  return $this->_clear(4);
  }
 
  /**
  * Get <label> value
  *
  * @return int - \google\protobuf\FieldDescriptorProto\Label
  */
  public function getLabel(){
  return $this->_get(4);
  }
 
  /**
  * Set <label> value
  *
  * @param int - \google\protobuf\FieldDescriptorProto\Label $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setLabel( $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <type> has a value
  *
  * @return boolean
  */
  public function hasType(){
  return $this->_has(5);
  }
 
  /**
  * Clear <type> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearType(){
  return $this->_clear(5);
  }
 
  /**
  * Get <type> value
  *
  * @return int - \google\protobuf\FieldDescriptorProto\Type
  */
  public function getType(){
  return $this->_get(5);
  }
 
  /**
  * Set <type> value
  *
  * @param int - \google\protobuf\FieldDescriptorProto\Type $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setType( $value){
  return $this->_set(5, $value);
  }
 
  /**
  * Check if <type_name> has a value
  *
  * @return boolean
  */
  public function hasTypeName(){
  return $this->_has(6);
  }
 
  /**
  * Clear <type_name> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearTypeName(){
  return $this->_clear(6);
  }
 
  /**
  * Get <type_name> value
  *
  * @return string
  */
  public function getTypeName(){
  return $this->_get(6);
  }
 
  /**
  * Set <type_name> value
  *
  * @param string $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setTypeName( $value){
  return $this->_set(6, $value);
  }
 
  /**
  * Check if <extendee> has a value
  *
  * @return boolean
  */
  public function hasExtendee(){
  return $this->_has(2);
  }
 
  /**
  * Clear <extendee> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearExtendee(){
  return $this->_clear(2);
  }
 
  /**
  * Get <extendee> value
  *
  * @return string
  */
  public function getExtendee(){
  return $this->_get(2);
  }
 
  /**
  * Set <extendee> value
  *
  * @param string $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setExtendee( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <default_value> has a value
  *
  * @return boolean
  */
  public function hasDefaultValue(){
  return $this->_has(7);
  }
 
  /**
  * Clear <default_value> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearDefaultValue(){
  return $this->_clear(7);
  }
 
  /**
  * Get <default_value> value
  *
  * @return string
  */
  public function getDefaultValue(){
  return $this->_get(7);
  }
 
  /**
  * Set <default_value> value
  *
  * @param string $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setDefaultValue( $value){
  return $this->_set(7, $value);
  }
 
  /**
  * Check if <options> has a value
  *
  * @return boolean
  */
  public function hasOptions(){
  return $this->_has(8);
  }
 
  /**
  * Clear <options> value
  *
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function clearOptions(){
  return $this->_clear(8);
  }
 
  /**
  * Get <options> value
  *
  * @return \google\protobuf\FieldOptions
  */
  public function getOptions(){
  return $this->_get(8);
  }
 
  /**
  * Set <options> value
  *
  * @param \google\protobuf\FieldOptions $value
  * @return \google\protobuf\FieldDescriptorProto
  */
  public function setOptions(\google\protobuf\FieldOptions $value){
  return $this->_set(8, $value);
  }
 
  }
  }
 
  namespace google\protobuf\FieldDescriptorProto {
 
  class Type {
  const TYPE_DOUBLE = 1;
  const TYPE_FLOAT = 2;
  const TYPE_INT64 = 3;
  const TYPE_UINT64 = 4;
  const TYPE_INT32 = 5;
  const TYPE_FIXED64 = 6;
  const TYPE_FIXED32 = 7;
  const TYPE_BOOL = 8;
  const TYPE_STRING = 9;
  const TYPE_GROUP = 10;
  const TYPE_MESSAGE = 11;
  const TYPE_BYTES = 12;
  const TYPE_UINT32 = 13;
  const TYPE_ENUM = 14;
  const TYPE_SFIXED32 = 15;
  const TYPE_SFIXED64 = 16;
  const TYPE_SINT32 = 17;
  const TYPE_SINT64 = 18;
  }
  }
 
  namespace google\protobuf\FieldDescriptorProto {
 
  class Label {
  const LABEL_OPTIONAL = 1;
  const LABEL_REQUIRED = 2;
  const LABEL_REPEATED = 3;
  }
  }
 
  namespace google\protobuf {
 
  class EnumDescriptorProto extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumDescriptorProto");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.EnumValueDescriptorProto value = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "value";
  $f->nameOrig = "value";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\EnumValueDescriptorProto";
  $descriptor->addField($f);
 
  // optional .google.protobuf.EnumOptions options = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "options";
  $f->nameOrig = "options";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\EnumOptions";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var \google\protobuf\EnumValueDescriptorProto[] */
  public $value = array();
 
  /** @var \google\protobuf\EnumOptions */
  public $options = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <value> has a value
  *
  * @return boolean
  */
  public function hasValue(){
  return $this->_has(2);
  }
 
  /**
  * Clear <value> value
  *
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function clearValue(){
  return $this->_clear(2);
  }
 
  /**
  * Get <value> value
  *
  * @param int $idx
  * @return \google\protobuf\EnumValueDescriptorProto
  */
  public function getValue($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <value> value
  *
  * @param \google\protobuf\EnumValueDescriptorProto $value
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function setValue(\google\protobuf\EnumValueDescriptorProto $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <value>
  *
  * @return \google\protobuf\EnumValueDescriptorProto[]
  */
  public function getValueList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <value>
  *
  * @param \google\protobuf\EnumValueDescriptorProto $value
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function addValue(\google\protobuf\EnumValueDescriptorProto $value){
  return $this->_add(2, $value);
  }
 
  /**
  * Check if <options> has a value
  *
  * @return boolean
  */
  public function hasOptions(){
  return $this->_has(3);
  }
 
  /**
  * Clear <options> value
  *
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function clearOptions(){
  return $this->_clear(3);
  }
 
  /**
  * Get <options> value
  *
  * @return \google\protobuf\EnumOptions
  */
  public function getOptions(){
  return $this->_get(3);
  }
 
  /**
  * Set <options> value
  *
  * @param \google\protobuf\EnumOptions $value
  * @return \google\protobuf\EnumDescriptorProto
  */
  public function setOptions(\google\protobuf\EnumOptions $value){
  return $this->_set(3, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class EnumValueDescriptorProto extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumValueDescriptorProto");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional number = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "number";
  $f->nameOrig = "number";
  $f->type = 5;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional .google.protobuf.EnumValueOptions options = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "options";
  $f->nameOrig = "options";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\EnumValueOptions";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var int */
  public $number = null;
 
  /** @var \google\protobuf\EnumValueOptions */
  public $options = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\EnumValueDescriptorProto
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\EnumValueDescriptorProto
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <number> has a value
  *
  * @return boolean
  */
  public function hasNumber(){
  return $this->_has(2);
  }
 
  /**
  * Clear <number> value
  *
  * @return \google\protobuf\EnumValueDescriptorProto
  */
  public function clearNumber(){
  return $this->_clear(2);
  }
 
  /**
  * Get <number> value
  *
  * @return int
  */
  public function getNumber(){
  return $this->_get(2);
  }
 
  /**
  * Set <number> value
  *
  * @param int $value
  * @return \google\protobuf\EnumValueDescriptorProto
  */
  public function setNumber( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <options> has a value
  *
  * @return boolean
  */
  public function hasOptions(){
  return $this->_has(3);
  }
 
  /**
  * Clear <options> value
  *
  * @return \google\protobuf\EnumValueDescriptorProto
  */
  public function clearOptions(){
  return $this->_clear(3);
  }
 
  /**
  * Get <options> value
  *
  * @return \google\protobuf\EnumValueOptions
  */
  public function getOptions(){
  return $this->_get(3);
  }
 
  /**
  * Set <options> value
  *
  * @param \google\protobuf\EnumValueOptions $value
  * @return \google\protobuf\EnumValueDescriptorProto
  */
  public function setOptions(\google\protobuf\EnumValueOptions $value){
  return $this->_set(3, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class ServiceDescriptorProto extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\ServiceDescriptorProto");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.MethodDescriptorProto method = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "method";
  $f->nameOrig = "method";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\MethodDescriptorProto";
  $descriptor->addField($f);
 
  // optional .google.protobuf.ServiceOptions options = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "options";
  $f->nameOrig = "options";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\ServiceOptions";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var \google\protobuf\MethodDescriptorProto[] */
  public $method = array();
 
  /** @var \google\protobuf\ServiceOptions */
  public $options = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <method> has a value
  *
  * @return boolean
  */
  public function hasMethod(){
  return $this->_has(2);
  }
 
  /**
  * Clear <method> value
  *
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function clearMethod(){
  return $this->_clear(2);
  }
 
  /**
  * Get <method> value
  *
  * @param int $idx
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function getMethod($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <method> value
  *
  * @param \google\protobuf\MethodDescriptorProto $value
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function setMethod(\google\protobuf\MethodDescriptorProto $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <method>
  *
  * @return \google\protobuf\MethodDescriptorProto[]
  */
  public function getMethodList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <method>
  *
  * @param \google\protobuf\MethodDescriptorProto $value
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function addMethod(\google\protobuf\MethodDescriptorProto $value){
  return $this->_add(2, $value);
  }
 
  /**
  * Check if <options> has a value
  *
  * @return boolean
  */
  public function hasOptions(){
  return $this->_has(3);
  }
 
  /**
  * Clear <options> value
  *
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function clearOptions(){
  return $this->_clear(3);
  }
 
  /**
  * Get <options> value
  *
  * @return \google\protobuf\ServiceOptions
  */
  public function getOptions(){
  return $this->_get(3);
  }
 
  /**
  * Set <options> value
  *
  * @param \google\protobuf\ServiceOptions $value
  * @return \google\protobuf\ServiceDescriptorProto
  */
  public function setOptions(\google\protobuf\ServiceOptions $value){
  return $this->_set(3, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class MethodDescriptorProto extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\MethodDescriptorProto");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional input_type = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "input_type";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional output_type = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "output_type";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional .google.protobuf.MethodOptions options = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "options";
  $f->nameOrig = "options";
  $f->type = 11;
  $f->rule = 1;
  $f->reference = "\google\protobuf\MethodOptions";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var string */
  public $input_type = null;
 
  /** @var string */
  public $output_type = null;
 
  /** @var \google\protobuf\MethodOptions */
  public $options = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <input_type> has a value
  *
  * @return boolean
  */
  public function hasInputType(){
  return $this->_has(2);
  }
 
  /**
  * Clear <input_type> value
  *
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function clearInputType(){
  return $this->_clear(2);
  }
 
  /**
  * Get <input_type> value
  *
  * @return string
  */
  public function getInputType(){
  return $this->_get(2);
  }
 
  /**
  * Set <input_type> value
  *
  * @param string $value
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function setInputType( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <output_type> has a value
  *
  * @return boolean
  */
  public function hasOutputType(){
  return $this->_has(3);
  }
 
  /**
  * Clear <output_type> value
  *
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function clearOutputType(){
  return $this->_clear(3);
  }
 
  /**
  * Get <output_type> value
  *
  * @return string
  */
  public function getOutputType(){
  return $this->_get(3);
  }
 
  /**
  * Set <output_type> value
  *
  * @param string $value
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function setOutputType( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <options> has a value
  *
  * @return boolean
  */
  public function hasOptions(){
  return $this->_has(4);
  }
 
  /**
  * Clear <options> value
  *
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function clearOptions(){
  return $this->_clear(4);
  }
 
  /**
  * Get <options> value
  *
  * @return \google\protobuf\MethodOptions
  */
  public function getOptions(){
  return $this->_get(4);
  }
 
  /**
  * Set <options> value
  *
  * @param \google\protobuf\MethodOptions $value
  * @return \google\protobuf\MethodDescriptorProto
  */
  public function setOptions(\google\protobuf\MethodOptions $value){
  return $this->_set(4, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class FileOptions extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FileOptions");
 
  // optional java_package = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "java_package";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional java_outer_classname = 8
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 8;
  $f->name = "java_outer_classname";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional java_multiple_files = 10
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 10;
  $f->name = "java_multiple_files";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // optional java_generate_equals_and_hash = 20
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 20;
  $f->name = "java_generate_equals_and_hash";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 9;
  $f->name = "optimize_for";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = "\google\protobuf\FileOptions\OptimizeMode";
  $f->default = "SPEED";
  $descriptor->addField($f);
 
  // optional cc_generic_services = 16
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 16;
  $f->name = "cc_generic_services";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // optional java_generic_services = 17
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 17;
  $f->name = "java_generic_services";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // optional py_generic_services = 18
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 18;
  $f->name = "py_generic_services";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 999;
  $f->name = "uninterpreted_option";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $java_package = null;
 
  /** @var string */
  public $java_outer_classname = null;
 
  /** @var boolean */
  public $java_multiple_files = true;
 
  /** @var boolean */
  public $java_generate_equals_and_hash = true;
 
  /** @var int - \google\protobuf\FileOptions\OptimizeMode */
  public $optimize_for = "SPEED";
 
  /** @var boolean */
  public $cc_generic_services = true;
 
  /** @var boolean */
  public $java_generic_services = true;
 
  /** @var boolean */
  public $py_generic_services = true;
 
  /** @var \google\protobuf\UninterpretedOption[] */
  public $uninterpreted_option = array();
 
 
  /**
  * Check if <java_package> has a value
  *
  * @return boolean
  */
  public function hasJavaPackage(){
  return $this->_has(1);
  }
 
  /**
  * Clear <java_package> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearJavaPackage(){
  return $this->_clear(1);
  }
 
  /**
  * Get <java_package> value
  *
  * @return string
  */
  public function getJavaPackage(){
  return $this->_get(1);
  }
 
  /**
  * Set <java_package> value
  *
  * @param string $value
  * @return \google\protobuf\FileOptions
  */
  public function setJavaPackage( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <java_outer_classname> has a value
  *
  * @return boolean
  */
  public function hasJavaOuterClassname(){
  return $this->_has(8);
  }
 
  /**
  * Clear <java_outer_classname> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearJavaOuterClassname(){
  return $this->_clear(8);
  }
 
  /**
  * Get <java_outer_classname> value
  *
  * @return string
  */
  public function getJavaOuterClassname(){
  return $this->_get(8);
  }
 
  /**
  * Set <java_outer_classname> value
  *
  * @param string $value
  * @return \google\protobuf\FileOptions
  */
  public function setJavaOuterClassname( $value){
  return $this->_set(8, $value);
  }
 
  /**
  * Check if <java_multiple_files> has a value
  *
  * @return boolean
  */
  public function hasJavaMultipleFiles(){
  return $this->_has(10);
  }
 
  /**
  * Clear <java_multiple_files> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearJavaMultipleFiles(){
  return $this->_clear(10);
  }
 
  /**
  * Get <java_multiple_files> value
  *
  * @return boolean
  */
  public function getJavaMultipleFiles(){
  return $this->_get(10);
  }
 
  /**
  * Set <java_multiple_files> value
  *
  * @param boolean $value
  * @return \google\protobuf\FileOptions
  */
  public function setJavaMultipleFiles( $value){
  return $this->_set(10, $value);
  }
 
  /**
  * Check if <java_generate_equals_and_hash> has a value
  *
  * @return boolean
  */
  public function hasJavaGenerateEqualsAndHash(){
  return $this->_has(20);
  }
 
  /**
  * Clear <java_generate_equals_and_hash> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearJavaGenerateEqualsAndHash(){
  return $this->_clear(20);
  }
 
  /**
  * Get <java_generate_equals_and_hash> value
  *
  * @return boolean
  */
  public function getJavaGenerateEqualsAndHash(){
  return $this->_get(20);
  }
 
  /**
  * Set <java_generate_equals_and_hash> value
  *
  * @param boolean $value
  * @return \google\protobuf\FileOptions
  */
  public function setJavaGenerateEqualsAndHash( $value){
  return $this->_set(20, $value);
  }
 
  /**
  * Check if <optimize_for> has a value
  *
  * @return boolean
  */
  public function hasOptimizeFor(){
  return $this->_has(9);
  }
 
  /**
  * Clear <optimize_for> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearOptimizeFor(){
  return $this->_clear(9);
  }
 
  /**
  * Get <optimize_for> value
  *
  * @return int - \google\protobuf\FileOptions\OptimizeMode
  */
  public function getOptimizeFor(){
  return $this->_get(9);
  }
 
  /**
  * Set <optimize_for> value
  *
  * @param int - \google\protobuf\FileOptions\OptimizeMode $value
  * @return \google\protobuf\FileOptions
  */
  public function setOptimizeFor( $value){
  return $this->_set(9, $value);
  }
 
  /**
  * Check if <cc_generic_services> has a value
  *
  * @return boolean
  */
  public function hasCcGenericServices(){
  return $this->_has(16);
  }
 
  /**
  * Clear <cc_generic_services> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearCcGenericServices(){
  return $this->_clear(16);
  }
 
  /**
  * Get <cc_generic_services> value
  *
  * @return boolean
  */
  public function getCcGenericServices(){
  return $this->_get(16);
  }
 
  /**
  * Set <cc_generic_services> value
  *
  * @param boolean $value
  * @return \google\protobuf\FileOptions
  */
  public function setCcGenericServices( $value){
  return $this->_set(16, $value);
  }
 
  /**
  * Check if <java_generic_services> has a value
  *
  * @return boolean
  */
  public function hasJavaGenericServices(){
  return $this->_has(17);
  }
 
  /**
  * Clear <java_generic_services> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearJavaGenericServices(){
  return $this->_clear(17);
  }
 
  /**
  * Get <java_generic_services> value
  *
  * @return boolean
  */
  public function getJavaGenericServices(){
  return $this->_get(17);
  }
 
  /**
  * Set <java_generic_services> value
  *
  * @param boolean $value
  * @return \google\protobuf\FileOptions
  */
  public function setJavaGenericServices( $value){
  return $this->_set(17, $value);
  }
 
  /**
  * Check if <py_generic_services> has a value
  *
  * @return boolean
  */
  public function hasPyGenericServices(){
  return $this->_has(18);
  }
 
  /**
  * Clear <py_generic_services> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearPyGenericServices(){
  return $this->_clear(18);
  }
 
  /**
  * Get <py_generic_services> value
  *
  * @return boolean
  */
  public function getPyGenericServices(){
  return $this->_get(18);
  }
 
  /**
  * Set <py_generic_services> value
  *
  * @param boolean $value
  * @return \google\protobuf\FileOptions
  */
  public function setPyGenericServices( $value){
  return $this->_set(18, $value);
  }
 
  /**
  * Check if <uninterpreted_option> has a value
  *
  * @return boolean
  */
  public function hasUninterpretedOption(){
  return $this->_has(999);
  }
 
  /**
  * Clear <uninterpreted_option> value
  *
  * @return \google\protobuf\FileOptions
  */
  public function clearUninterpretedOption(){
  return $this->_clear(999);
  }
 
  /**
  * Get <uninterpreted_option> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption
  */
  public function getUninterpretedOption($idx = NULL){
  return $this->_get(999, $idx);
  }
 
  /**
  * Set <uninterpreted_option> value
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\FileOptions
  */
  public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){
  return $this->_set(999, $value, $idx);
  }
 
  /**
  * Get all elements of <uninterpreted_option>
  *
  * @return \google\protobuf\UninterpretedOption[]
  */
  public function getUninterpretedOptionList(){
  return $this->_get(999);
  }
 
  /**
  * Add a new element to <uninterpreted_option>
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\FileOptions
  */
  public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){
  return $this->_add(999, $value);
  }
 
  }
  }
 
  namespace google\protobuf\FileOptions {
 
  class OptimizeMode {
  const SPEED = 1;
  const CODE_SIZE = 2;
  const LITE_RUNTIME = 3;
  }
  }
 
  namespace google\protobuf {
 
  class MessageOptions extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\MessageOptions");
 
  // optional message_set_wire_format = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "message_set_wire_format";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // optional no_standard_descriptor_accessor = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "no_standard_descriptor_accessor";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 999;
  $f->name = "uninterpreted_option";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var boolean */
  public $message_set_wire_format = true;
 
  /** @var boolean */
  public $no_standard_descriptor_accessor = true;
 
  /** @var \google\protobuf\UninterpretedOption[] */
  public $uninterpreted_option = array();
 
 
  /**
  * Check if <message_set_wire_format> has a value
  *
  * @return boolean
  */
  public function hasMessageSetWireFormat(){
  return $this->_has(1);
  }
 
  /**
  * Clear <message_set_wire_format> value
  *
  * @return \google\protobuf\MessageOptions
  */
  public function clearMessageSetWireFormat(){
  return $this->_clear(1);
  }
 
  /**
  * Get <message_set_wire_format> value
  *
  * @return boolean
  */
  public function getMessageSetWireFormat(){
  return $this->_get(1);
  }
 
  /**
  * Set <message_set_wire_format> value
  *
  * @param boolean $value
  * @return \google\protobuf\MessageOptions
  */
  public function setMessageSetWireFormat( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <no_standard_descriptor_accessor> has a value
  *
  * @return boolean
  */
  public function hasNoStandardDescriptorAccessor(){
  return $this->_has(2);
  }
 
  /**
  * Clear <no_standard_descriptor_accessor> value
  *
  * @return \google\protobuf\MessageOptions
  */
  public function clearNoStandardDescriptorAccessor(){
  return $this->_clear(2);
  }
 
  /**
  * Get <no_standard_descriptor_accessor> value
  *
  * @return boolean
  */
  public function getNoStandardDescriptorAccessor(){
  return $this->_get(2);
  }
 
  /**
  * Set <no_standard_descriptor_accessor> value
  *
  * @param boolean $value
  * @return \google\protobuf\MessageOptions
  */
  public function setNoStandardDescriptorAccessor( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <uninterpreted_option> has a value
  *
  * @return boolean
  */
  public function hasUninterpretedOption(){
  return $this->_has(999);
  }
 
  /**
  * Clear <uninterpreted_option> value
  *
  * @return \google\protobuf\MessageOptions
  */
  public function clearUninterpretedOption(){
  return $this->_clear(999);
  }
 
  /**
  * Get <uninterpreted_option> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption
  */
  public function getUninterpretedOption($idx = NULL){
  return $this->_get(999, $idx);
  }
 
  /**
  * Set <uninterpreted_option> value
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\MessageOptions
  */
  public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){
  return $this->_set(999, $value, $idx);
  }
 
  /**
  * Get all elements of <uninterpreted_option>
  *
  * @return \google\protobuf\UninterpretedOption[]
  */
  public function getUninterpretedOptionList(){
  return $this->_get(999);
  }
 
  /**
  * Add a new element to <uninterpreted_option>
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\MessageOptions
  */
  public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){
  return $this->_add(999, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class FieldOptions extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FieldOptions");
 
  // optional .google.protobuf.FieldOptions.CType ctype = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "ctype";
  $f->nameOrig = "ctype";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = "\google\protobuf\FieldOptions\CType";
  $f->default = "STRING";
  $descriptor->addField($f);
 
  // optional packed = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "packed";
  $f->nameOrig = "packed";
  $f->type = 8;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional deprecated = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "deprecated";
  $f->nameOrig = "deprecated";
  $f->type = 8;
  $f->rule = 1;
  $f->default = true;
  $descriptor->addField($f);
 
  // optional experimental_map_key = 9
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 9;
  $f->name = "experimental_map_key";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 999;
  $f->name = "uninterpreted_option";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var int - \google\protobuf\FieldOptions\CType */
  public $ctype = "STRING";
 
  /** @var boolean */
  public $packed = null;
 
  /** @var boolean */
  public $deprecated = true;
 
  /** @var string */
  public $experimental_map_key = null;
 
  /** @var \google\protobuf\UninterpretedOption[] */
  public $uninterpreted_option = array();
 
 
  /**
  * Check if <ctype> has a value
  *
  * @return boolean
  */
  public function hasCtype(){
  return $this->_has(1);
  }
 
  /**
  * Clear <ctype> value
  *
  * @return \google\protobuf\FieldOptions
  */
  public function clearCtype(){
  return $this->_clear(1);
  }
 
  /**
  * Get <ctype> value
  *
  * @return int - \google\protobuf\FieldOptions\CType
  */
  public function getCtype(){
  return $this->_get(1);
  }
 
  /**
  * Set <ctype> value
  *
  * @param int - \google\protobuf\FieldOptions\CType $value
  * @return \google\protobuf\FieldOptions
  */
  public function setCtype( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <packed> has a value
  *
  * @return boolean
  */
  public function hasPacked(){
  return $this->_has(2);
  }
 
  /**
  * Clear <packed> value
  *
  * @return \google\protobuf\FieldOptions
  */
  public function clearPacked(){
  return $this->_clear(2);
  }
 
  /**
  * Get <packed> value
  *
  * @return boolean
  */
  public function getPacked(){
  return $this->_get(2);
  }
 
  /**
  * Set <packed> value
  *
  * @param boolean $value
  * @return \google\protobuf\FieldOptions
  */
  public function setPacked( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <deprecated> has a value
  *
  * @return boolean
  */
  public function hasDeprecated(){
  return $this->_has(3);
  }
 
  /**
  * Clear <deprecated> value
  *
  * @return \google\protobuf\FieldOptions
  */
  public function clearDeprecated(){
  return $this->_clear(3);
  }
 
  /**
  * Get <deprecated> value
  *
  * @return boolean
  */
  public function getDeprecated(){
  return $this->_get(3);
  }
 
  /**
  * Set <deprecated> value
  *
  * @param boolean $value
  * @return \google\protobuf\FieldOptions
  */
  public function setDeprecated( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <experimental_map_key> has a value
  *
  * @return boolean
  */
  public function hasExperimentalMapKey(){
  return $this->_has(9);
  }
 
  /**
  * Clear <experimental_map_key> value
  *
  * @return \google\protobuf\FieldOptions
  */
  public function clearExperimentalMapKey(){
  return $this->_clear(9);
  }
 
  /**
  * Get <experimental_map_key> value
  *
  * @return string
  */
  public function getExperimentalMapKey(){
  return $this->_get(9);
  }
 
  /**
  * Set <experimental_map_key> value
  *
  * @param string $value
  * @return \google\protobuf\FieldOptions
  */
  public function setExperimentalMapKey( $value){
  return $this->_set(9, $value);
  }
 
  /**
  * Check if <uninterpreted_option> has a value
  *
  * @return boolean
  */
  public function hasUninterpretedOption(){
  return $this->_has(999);
  }
 
  /**
  * Clear <uninterpreted_option> value
  *
  * @return \google\protobuf\FieldOptions
  */
  public function clearUninterpretedOption(){
  return $this->_clear(999);
  }
 
  /**
  * Get <uninterpreted_option> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption
  */
  public function getUninterpretedOption($idx = NULL){
  return $this->_get(999, $idx);
  }
 
  /**
  * Set <uninterpreted_option> value
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\FieldOptions
  */
  public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){
  return $this->_set(999, $value, $idx);
  }
 
  /**
  * Get all elements of <uninterpreted_option>
  *
  * @return \google\protobuf\UninterpretedOption[]
  */
  public function getUninterpretedOptionList(){
  return $this->_get(999);
  }
 
  /**
  * Add a new element to <uninterpreted_option>
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\FieldOptions
  */
  public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){
  return $this->_add(999, $value);
  }
 
  }
  }
 
  namespace google\protobuf\FieldOptions {
 
  class CType {
  const STRING = 0;
  const CORD = 1;
  const STRING_PIECE = 2;
  }
  }
 
  namespace google\protobuf {
 
  class EnumOptions extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumOptions");
 
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 999;
  $f->name = "uninterpreted_option";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var \google\protobuf\UninterpretedOption[] */
  public $uninterpreted_option = array();
 
 
  /**
  * Check if <uninterpreted_option> has a value
  *
  * @return boolean
  */
  public function hasUninterpretedOption(){
  return $this->_has(999);
  }
 
  /**
  * Clear <uninterpreted_option> value
  *
  * @return \google\protobuf\EnumOptions
  */
  public function clearUninterpretedOption(){
  return $this->_clear(999);
  }
 
  /**
  * Get <uninterpreted_option> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption
  */
  public function getUninterpretedOption($idx = NULL){
  return $this->_get(999, $idx);
  }
 
  /**
  * Set <uninterpreted_option> value
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\EnumOptions
  */
  public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){
  return $this->_set(999, $value, $idx);
  }
 
  /**
  * Get all elements of <uninterpreted_option>
  *
  * @return \google\protobuf\UninterpretedOption[]
  */
  public function getUninterpretedOptionList(){
  return $this->_get(999);
  }
 
  /**
  * Add a new element to <uninterpreted_option>
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\EnumOptions
  */
  public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){
  return $this->_add(999, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class EnumValueOptions extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumValueOptions");
 
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 999;
  $f->name = "uninterpreted_option";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var \google\protobuf\UninterpretedOption[] */
  public $uninterpreted_option = array();
 
 
  /**
  * Check if <uninterpreted_option> has a value
  *
  * @return boolean
  */
  public function hasUninterpretedOption(){
  return $this->_has(999);
  }
 
  /**
  * Clear <uninterpreted_option> value
  *
  * @return \google\protobuf\EnumValueOptions
  */
  public function clearUninterpretedOption(){
  return $this->_clear(999);
  }
 
  /**
  * Get <uninterpreted_option> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption
  */
  public function getUninterpretedOption($idx = NULL){
  return $this->_get(999, $idx);
  }
 
  /**
  * Set <uninterpreted_option> value
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\EnumValueOptions
  */
  public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){
  return $this->_set(999, $value, $idx);
  }
 
  /**
  * Get all elements of <uninterpreted_option>
  *
  * @return \google\protobuf\UninterpretedOption[]
  */
  public function getUninterpretedOptionList(){
  return $this->_get(999);
  }
 
  /**
  * Add a new element to <uninterpreted_option>
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\EnumValueOptions
  */
  public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){
  return $this->_add(999, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class ServiceOptions extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\ServiceOptions");
 
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 999;
  $f->name = "uninterpreted_option";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var \google\protobuf\UninterpretedOption[] */
  public $uninterpreted_option = array();
 
 
  /**
  * Check if <uninterpreted_option> has a value
  *
  * @return boolean
  */
  public function hasUninterpretedOption(){
  return $this->_has(999);
  }
 
  /**
  * Clear <uninterpreted_option> value
  *
  * @return \google\protobuf\ServiceOptions
  */
  public function clearUninterpretedOption(){
  return $this->_clear(999);
  }
 
  /**
  * Get <uninterpreted_option> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption
  */
  public function getUninterpretedOption($idx = NULL){
  return $this->_get(999, $idx);
  }
 
  /**
  * Set <uninterpreted_option> value
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\ServiceOptions
  */
  public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){
  return $this->_set(999, $value, $idx);
  }
 
  /**
  * Get all elements of <uninterpreted_option>
  *
  * @return \google\protobuf\UninterpretedOption[]
  */
  public function getUninterpretedOptionList(){
  return $this->_get(999);
  }
 
  /**
  * Add a new element to <uninterpreted_option>
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\ServiceOptions
  */
  public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){
  return $this->_add(999, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class MethodOptions extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\MethodOptions");
 
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 999;
  $f->name = "uninterpreted_option";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var \google\protobuf\UninterpretedOption[] */
  public $uninterpreted_option = array();
 
 
  /**
  * Check if <uninterpreted_option> has a value
  *
  * @return boolean
  */
  public function hasUninterpretedOption(){
  return $this->_has(999);
  }
 
  /**
  * Clear <uninterpreted_option> value
  *
  * @return \google\protobuf\MethodOptions
  */
  public function clearUninterpretedOption(){
  return $this->_clear(999);
  }
 
  /**
  * Get <uninterpreted_option> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption
  */
  public function getUninterpretedOption($idx = NULL){
  return $this->_get(999, $idx);
  }
 
  /**
  * Set <uninterpreted_option> value
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\MethodOptions
  */
  public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){
  return $this->_set(999, $value, $idx);
  }
 
  /**
  * Get all elements of <uninterpreted_option>
  *
  * @return \google\protobuf\UninterpretedOption[]
  */
  public function getUninterpretedOptionList(){
  return $this->_get(999);
  }
 
  /**
  * Add a new element to <uninterpreted_option>
  *
  * @param \google\protobuf\UninterpretedOption $value
  * @return \google\protobuf\MethodOptions
  */
  public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){
  return $this->_add(999, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class UninterpretedOption extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\UninterpretedOption");
 
  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\UninterpretedOption\NamePart";
  $descriptor->addField($f);
 
  // optional identifier_value = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "identifier_value";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional positive_int_value = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "positive_int_value";
  $f->type = 4;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional negative_int_value = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "negative_int_value";
  $f->type = 3;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional double_value = 6
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 6;
  $f->name = "double_value";
  $f->type = 1;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional string_value = 7
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 7;
  $f->name = "string_value";
  $f->type = 12;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional aggregate_value = 8
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 8;
  $f->name = "aggregate_value";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var \google\protobuf\UninterpretedOption\NamePart[] */
  public $name = array();
 
  /** @var string */
  public $identifier_value = null;
 
  /** @var int */
  public $positive_int_value = null;
 
  /** @var int */
  public $negative_int_value = null;
 
  /** @var float */
  public $double_value = null;
 
  /** @var string */
  public $string_value = null;
 
  /** @var string */
  public $aggregate_value = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(2);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\UninterpretedOption
  */
  public function clearName(){
  return $this->_clear(2);
  }
 
  /**
  * Get <name> value
  *
  * @param int $idx
  * @return \google\protobuf\UninterpretedOption\NamePart
  */
  public function getName($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <name> value
  *
  * @param \google\protobuf\UninterpretedOption\NamePart $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function setName(\google\protobuf\UninterpretedOption\NamePart $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <name>
  *
  * @return \google\protobuf\UninterpretedOption\NamePart[]
  */
  public function getNameList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <name>
  *
  * @param \google\protobuf\UninterpretedOption\NamePart $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function addName(\google\protobuf\UninterpretedOption\NamePart $value){
  return $this->_add(2, $value);
  }
 
  /**
  * Check if <identifier_value> has a value
  *
  * @return boolean
  */
  public function hasIdentifierValue(){
  return $this->_has(3);
  }
 
  /**
  * Clear <identifier_value> value
  *
  * @return \google\protobuf\UninterpretedOption
  */
  public function clearIdentifierValue(){
  return $this->_clear(3);
  }
 
  /**
  * Get <identifier_value> value
  *
  * @return string
  */
  public function getIdentifierValue(){
  return $this->_get(3);
  }
 
  /**
  * Set <identifier_value> value
  *
  * @param string $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function setIdentifierValue( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <positive_int_value> has a value
  *
  * @return boolean
  */
  public function hasPositiveIntValue(){
  return $this->_has(4);
  }
 
  /**
  * Clear <positive_int_value> value
  *
  * @return \google\protobuf\UninterpretedOption
  */
  public function clearPositiveIntValue(){
  return $this->_clear(4);
  }
 
  /**
  * Get <positive_int_value> value
  *
  * @return int
  */
  public function getPositiveIntValue(){
  return $this->_get(4);
  }
 
  /**
  * Set <positive_int_value> value
  *
  * @param int $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function setPositiveIntValue( $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <negative_int_value> has a value
  *
  * @return boolean
  */
  public function hasNegativeIntValue(){
  return $this->_has(5);
  }
 
  /**
  * Clear <negative_int_value> value
  *
  * @return \google\protobuf\UninterpretedOption
  */
  public function clearNegativeIntValue(){
  return $this->_clear(5);
  }
 
  /**
  * Get <negative_int_value> value
  *
  * @return int
  */
  public function getNegativeIntValue(){
  return $this->_get(5);
  }
 
  /**
  * Set <negative_int_value> value
  *
  * @param int $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function setNegativeIntValue( $value){
  return $this->_set(5, $value);
  }
 
  /**
  * Check if <double_value> has a value
  *
  * @return boolean
  */
  public function hasDoubleValue(){
  return $this->_has(6);
  }
 
  /**
  * Clear <double_value> value
  *
  * @return \google\protobuf\UninterpretedOption
  */
  public function clearDoubleValue(){
  return $this->_clear(6);
  }
 
  /**
  * Get <double_value> value
  *
  * @return float
  */
  public function getDoubleValue(){
  return $this->_get(6);
  }
 
  /**
  * Set <double_value> value
  *
  * @param float $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function setDoubleValue( $value){
  return $this->_set(6, $value);
  }
 
  /**
  * Check if <string_value> has a value
  *
  * @return boolean
  */
  public function hasStringValue(){
  return $this->_has(7);
  }
 
  /**
  * Clear <string_value> value
  *
  * @return \google\protobuf\UninterpretedOption
  */
  public function clearStringValue(){
  return $this->_clear(7);
  }
 
  /**
  * Get <string_value> value
  *
  * @return string
  */
  public function getStringValue(){
  return $this->_get(7);
  }
 
  /**
  * Set <string_value> value
  *
  * @param string $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function setStringValue( $value){
  return $this->_set(7, $value);
  }
 
  /**
  * Check if <aggregate_value> has a value
  *
  * @return boolean
  */
  public function hasAggregateValue(){
  return $this->_has(8);
  }
 
  /**
  * Clear <aggregate_value> value
  *
  * @return \google\protobuf\UninterpretedOption
  */
  public function clearAggregateValue(){
  return $this->_clear(8);
  }
 
  /**
  * Get <aggregate_value> value
  *
  * @return string
  */
  public function getAggregateValue(){
  return $this->_get(8);
  }
 
  /**
  * Set <aggregate_value> value
  *
  * @param string $value
  * @return \google\protobuf\UninterpretedOption
  */
  public function setAggregateValue( $value){
  return $this->_set(8, $value);
  }
 
  }
  }
 
  namespace google\protobuf\UninterpretedOption {
 
  class NamePart extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\UninterpretedOption\NamePart");
 
  // required name_part = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name_part";
  $f->type = 9;
  $f->rule = 2;
  $descriptor->addField($f);
 
  // required is_extension = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "is_extension";
  $f->type = 8;
  $f->rule = 2;
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name_part = null;
 
  /** @var boolean */
  public $is_extension = null;
 
 
  /**
  * Check if <name_part> has a value
  *
  * @return boolean
  */
  public function hasNamePart(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name_part> value
  *
  * @return \google\protobuf\UninterpretedOption\NamePart
  */
  public function clearNamePart(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name_part> value
  *
  * @return string
  */
  public function getNamePart(){
  return $this->_get(1);
  }
 
  /**
  * Set <name_part> value
  *
  * @param string $value
  * @return \google\protobuf\UninterpretedOption\NamePart
  */
  public function setNamePart( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <is_extension> has a value
  *
  * @return boolean
  */
  public function hasIsExtension(){
  return $this->_has(2);
  }
 
  /**
  * Clear <is_extension> value
  *
  * @return \google\protobuf\UninterpretedOption\NamePart
  */
  public function clearIsExtension(){
  return $this->_clear(2);
  }
 
  /**
  * Get <is_extension> value
  *
  * @return boolean
  */
  public function getIsExtension(){
  return $this->_get(2);
  }
 
  /**
  * Set <is_extension> value
  *
  * @param boolean $value
  * @return \google\protobuf\UninterpretedOption\NamePart
  */
  public function setIsExtension( $value){
  return $this->_set(2, $value);
  }
 
  }
  }
 
  namespace google\protobuf {
 
  class SourceCodeInfo extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\SourceCodeInfo");
 
  // repeated .google.protobuf.SourceCodeInfo.Location location = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "location";
  $f->nameOrig = "location";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\SourceCodeInfo\Location";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var \google\protobuf\SourceCodeInfo\Location[] */
  public $location = array();
 
 
  /**
  * Check if <location> has a value
  *
  * @return boolean
  */
  public function hasLocation(){
  return $this->_has(1);
  }
 
  /**
  * Clear <location> value
  *
  * @return \google\protobuf\SourceCodeInfo
  */
  public function clearLocation(){
  return $this->_clear(1);
  }
 
  /**
  * Get <location> value
  *
  * @param int $idx
  * @return \google\protobuf\SourceCodeInfo\Location
  */
  public function getLocation($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <location> value
  *
  * @param \google\protobuf\SourceCodeInfo\Location $value
  * @return \google\protobuf\SourceCodeInfo
  */
  public function setLocation(\google\protobuf\SourceCodeInfo\Location $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <location>
  *
  * @return \google\protobuf\SourceCodeInfo\Location[]
  */
  public function getLocationList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <location>
  *
  * @param \google\protobuf\SourceCodeInfo\Location $value
  * @return \google\protobuf\SourceCodeInfo
  */
  public function addLocation(\google\protobuf\SourceCodeInfo\Location $value){
  return $this->_add(1, $value);
  }
 
  }
  }
 
  namespace google\protobuf\SourceCodeInfo {
 
  class Location extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\SourceCodeInfo\Location");
 
  // repeated path = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "path";
  $f->nameOrig = "path";
  $f->type = 5;
  $f->rule = 3;
  $descriptor->addField($f);
 
  // repeated span = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "span";
  $f->nameOrig = "span";
  $f->type = 5;
  $f->rule = 3;
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var int[] */
  public $path = array();
 
  /** @var int[] */
  public $span = array();
 
 
  /**
  * Check if <path> has a value
  *
  * @return boolean
  */
  public function hasPath(){
  return $this->_has(1);
  }
 
  /**
  * Clear <path> value
  *
  * @return \google\protobuf\SourceCodeInfo\Location
  */
  public function clearPath(){
  return $this->_clear(1);
  }
 
  /**
  * Get <path> value
  *
  * @param int $idx
  * @return int
  */
  public function getPath($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <path> value
  *
  * @param int $value
  * @return \google\protobuf\SourceCodeInfo\Location
  */
  public function setPath( $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <path>
  *
  * @return int[]
  */
  public function getPathList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <path>
  *
  * @param int $value
  * @return \google\protobuf\SourceCodeInfo\Location
  */
  public function addPath( $value){
  return $this->_add(1, $value);
  }
 
  /**
  * Check if <span> has a value
  *
  * @return boolean
  */
  public function hasSpan(){
  return $this->_has(2);
  }
 
  /**
  * Clear <span> value
  *
  * @return \google\protobuf\SourceCodeInfo\Location
  */
  public function clearSpan(){
  return $this->_clear(2);
  }
 
  /**
  * Get <span> value
  *
  * @param int $idx
  * @return int
  */
  public function getSpan($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <span> value
  *
  * @param int $value
  * @return \google\protobuf\SourceCodeInfo\Location
  */
  public function setSpan( $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <span>
  *
  * @return int[]
  */
  public function getSpanList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <span>
  *
  * @param int $value
  * @return \google\protobuf\SourceCodeInfo\Location
  */
  public function addSpan( $value){
  return $this->_add(2, $value);
  }
 
  }
  }
 
  // Protocol Buffers - Google's data interchange format
  // Copyright 2008 Google Inc. All rights reserved.
  // http://code.google.com/p/protobuf/
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
  //
  // * Redistributions of source code must retain the above copyright
  // notice, this list of conditions and the following disclaimer.
  // * Redistributions in binary form must reproduce the above
  // copyright notice, this list of conditions and the following disclaimer
  // in the documentation and/or other materials provided with the
  // distribution.
  // * Neither the name of Google Inc. nor the names of its
  // contributors may be used to endorse or promote products derived from
  // this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  // Author: kenton@google.com (Kenton Varda)
  // Based on original Protocol Buffers design by
  // Sanjay Ghemawat, Jeff Dean, and others.
  //
  // The messages in this file describe the definitions found in .proto files.
  // A valid .proto file can be translated directly to a FileDescriptorProto
  // without any other information (e.g. without reading its imports).
 
 
 
  package google.protobuf;
 
  option java_package = "com.google.protobuf";
  option java_outer_classname = "DescriptorProtos";
 
  // descriptor.proto must be optimized for speed because reflection-based
  // algorithms don't work during bootstrapping.
  option optimize_for = SPEED;
 
  // The protocol compiler can output a FileDescriptorSet containing the .proto
  // files it parses.
  message FileDescriptorSet {
  repeated FileDescriptorProto file = 1;
  }
 
  // Describes a complete .proto file.
  message FileDescriptorProto {
  optional string name = 1; // file name, relative to root of source tree
  optional string package = 2; // e.g. "foo", "foo.bar", etc.
 
  // Names of files imported by this file.
  repeated string dependency = 3;
 
  // All top-level definitions in this file.
  repeated DescriptorProto message_type = 4;
  repeated EnumDescriptorProto enum_type = 5;
  repeated ServiceDescriptorProto service = 6;
  repeated FieldDescriptorProto extension = 7;
 
  optional FileOptions options = 8;
 
  // This field contains optional information about the original source code.
  // You may safely remove this entire field whithout harming runtime
  // functionality of the descriptors -- the information is needed only by
  // development tools.
  optional SourceCodeInfo source_code_info = 9;
  }
 
  // Describes a message type.
  message DescriptorProto {
  optional string name = 1;
 
  repeated FieldDescriptorProto field = 2;
  repeated FieldDescriptorProto extension = 6;
 
  repeated DescriptorProto nested_type = 3;
  repeated EnumDescriptorProto enum_type = 4;
 
  message ExtensionRange {
  optional int32 start = 1;
  optional int32 end = 2;
  }
  repeated ExtensionRange extension_range = 5;
 
  optional MessageOptions options = 7;
  }
 
  // Describes a field within a message.
  message FieldDescriptorProto {
  enum Type {
  // 0 is reserved for errors.
  // Order is weird for historical reasons.
  TYPE_DOUBLE = 1;
  TYPE_FLOAT = 2;
  TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers
  // take 10 bytes. Use TYPE_SINT64 if negative
  // values are likely.
  TYPE_UINT64 = 4;
  TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers
  // take 10 bytes. Use TYPE_SINT32 if negative
  // values are likely.
  TYPE_FIXED64 = 6;
  TYPE_FIXED32 = 7;
  TYPE_BOOL = 8;
  TYPE_STRING = 9;
  TYPE_GROUP = 10; // Tag-delimited aggregate.
  TYPE_MESSAGE = 11; // Length-delimited aggregate.
 
  // New in version 2.
  TYPE_BYTES = 12;
  TYPE_UINT32 = 13;
  TYPE_ENUM = 14;
  TYPE_SFIXED32 = 15;
  TYPE_SFIXED64 = 16;
  TYPE_SINT32 = 17; // Uses ZigZag encoding.
  TYPE_SINT64 = 18; // Uses ZigZag encoding.
  };
 
  enum Label {
  // 0 is reserved for errors
  LABEL_OPTIONAL = 1;
  LABEL_REQUIRED = 2;
  LABEL_REPEATED = 3;
  // TODO(sanjay): Should we add LABEL_MAP?
  };
 
  optional string name = 1;
  optional int32 number = 3;
  optional Label label = 4;
 
  // If type_name is set, this need not be set. If both this and type_name
  // are set, this must be either TYPE_ENUM or TYPE_MESSAGE.
  optional Type type = 5;
 
  // For message and enum types, this is the name of the type. If the name
  // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
  // rules are used to find the type (i.e. first the nested types within this
  // message are searched, then within the parent, on up to the root
  // namespace).
  optional string type_name = 6;
 
  // For extensions, this is the name of the type being extended. It is
  // resolved in the same manner as type_name.
  optional string extendee = 2;
 
  // For numeric types, contains the original text representation of the value.
  // For booleans, "true" or "false".
  // For strings, contains the default text contents (not escaped in any way).
  // For bytes, contains the C escaped value. All bytes >= 128 are escaped.
  // TODO(kenton): Base-64 encode?
  optional string default_value = 7;
 
  optional FieldOptions options = 8;
  }
 
  // Describes an enum type.
  message EnumDescriptorProto {
  optional string name = 1;
 
  repeated EnumValueDescriptorProto value = 2;
 
  optional EnumOptions options = 3;
  }
 
  // Describes a value within an enum.
  message EnumValueDescriptorProto {
  optional string name = 1;
  optional int32 number = 2;
 
  optional EnumValueOptions options = 3;
  }
 
  // Describes a service.
  message ServiceDescriptorProto {
  optional string name = 1;
  repeated MethodDescriptorProto method = 2;
 
  optional ServiceOptions options = 3;
  }
 
  // Describes a method of a service.
  message MethodDescriptorProto {
  optional string name = 1;
 
  // Input and output type names. These are resolved in the same way as
  // FieldDescriptorProto.type_name, but must refer to a message type.
  optional string input_type = 2;
  optional string output_type = 3;
 
  optional MethodOptions options = 4;
  }
 
  // ===================================================================
  // Options
 
  // Each of the definitions above may have "options" attached. These are
  // just annotations which may cause code to be generated slightly differently
  // or may contain hints for code that manipulates protocol messages.
  //
  // Clients may define custom options as extensions of the *Options messages.
  // These extensions may not yet be known at parsing time, so the parser cannot
  // store the values in them. Instead it stores them in a field in the *Options
  // message called uninterpreted_option. This field must have the same name
  // across all *Options messages. We then use this field to populate the
  // extensions when we build a descriptor, at which point all protos have been
  // parsed and so all extensions are known.
  //
  // Extension numbers for custom options may be chosen as follows:
  // * For options which will only be used within a single application or
  // organization, or for experimental options, use field numbers 50000
  // through 99999. It is up to you to ensure that you do not use the
  // same number for multiple options.
  // * For options which will be published and used publicly by multiple
  // independent entities, e-mail kenton@google.com to reserve extension
  // numbers. Simply tell me how many you need and I'll send you back a
  // set of numbers to use -- there's no need to explain how you intend to
  // use them. If this turns out to be popular, a web service will be set up
  // to automatically assign option numbers.
 
 
  message FileOptions {
 
  // Sets the Java package where classes generated from this .proto will be
  // placed. By default, the proto package is used, but this is often
  // inappropriate because proto packages do not normally start with backwards
  // domain names.
  optional string java_package = 1;
 
 
  // If set, all the classes from the .proto file are wrapped in a single
  // outer class with the given name. This applies to both Proto1
  // (equivalent to the old "--one_java_file" option) and Proto2 (where
  // a .proto always translates to a single class, but you may want to
  // explicitly choose the class name).
  optional string java_outer_classname = 8;
 
  // If set true, then the Java code generator will generate a separate .java
  // file for each top-level message, enum, and service defined in the .proto
  // file. Thus, these types will *not* be nested inside the outer class
  // named by java_outer_classname. However, the outer class will still be
  // generated to contain the file's getDescriptor() method as well as any
  // top-level extensions defined in the file.
  optional bool java_multiple_files = 10 [default=false];
 
  // If set true, then the Java code generator will generate equals() and
  // hashCode() methods for all messages defined in the .proto file. This is
  // purely a speed optimization, as the AbstractMessage base class includes
  // reflection-based implementations of these methods.
  optional bool java_generate_equals_and_hash = 20 [default=false];
 
  // Generated classes can be optimized for speed or code size.
  enum OptimizeMode {
  SPEED = 1; // Generate complete code for parsing, serialization,
  // etc.
  CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
  LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
  }
  optional OptimizeMode optimize_for = 9 [default=SPEED];
 
 
 
 
  // Should generic services be generated in each language? "Generic" services
  // are not specific to any particular RPC system. They are generated by the
  // main code generators in each language (without additional plugins).
  // Generic services were the only kind of service generation supported by
  // early versions of proto2.
  //
  // Generic services are now considered deprecated in favor of using plugins
  // that generate code specific to your particular RPC system. Therefore,
  // these default to false. Old code which depends on generic services should
  // explicitly set them to true.
  optional bool cc_generic_services = 16 [default=false];
  optional bool java_generic_services = 17 [default=false];
  optional bool py_generic_services = 18 [default=false];
 
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;
 
  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
  }
 
  message MessageOptions {
  // Set true to use the old proto1 MessageSet wire format for extensions.
  // This is provided for backwards-compatibility with the MessageSet wire
  // format. You should not use this for any other reason: It's less
  // efficient, has fewer features, and is more complicated.
  //
  // The message must be defined exactly as follows:
  // message Foo {
  // option message_set_wire_format = true;
  // extensions 4 to max;
  // }
  // Note that the message cannot have any defined fields; MessageSets only
  // have extensions.
  //
  // All extensions of your type must be singular messages; e.g. they cannot
  // be int32s, enums, or repeated messages.
  //
  // Because this is an option, the above two restrictions are not enforced by
  // the protocol compiler.
  optional bool message_set_wire_format = 1 [default=false];
 
  // Disables the generation of the standard "descriptor()" accessor, which can
  // conflict with a field of the same name. This is meant to make migration
  // from proto1 easier; new code should avoid fields named "descriptor".
  optional bool no_standard_descriptor_accessor = 2 [default=false];
 
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;
 
  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
  }
 
  message FieldOptions {
  // The ctype option instructs the C++ code generator to use a different
  // representation of the field than it normally would. See the specific
  // options below. This option is not yet implemented in the open source
  // release -- sorry, we'll try to include it in a future version!
  optional CType ctype = 1 [default = STRING];
  enum CType {
  // Default mode.
  STRING = 0;
 
  CORD = 1;
 
  STRING_PIECE = 2;
  }
  // The packed option can be enabled for repeated primitive fields to enable
  // a more efficient representation on the wire. Rather than repeatedly
  // writing the tag and type for each element, the entire array is encoded as
  // a single length-delimited blob.
  optional bool packed = 2;
 
 
  // Is this field deprecated?
  // Depending on the target platform, this can emit Deprecated annotations
  // for accessors, or it will be completely ignored; in the very least, this
  // is a formalization for deprecating fields.
  optional bool deprecated = 3 [default=false];
 
  // EXPERIMENTAL. DO NOT USE.
  // For "map" fields, the name of the field in the enclosed type that
  // is the key for this map. For example, suppose we have:
  // message Item {
  // required string name = 1;
  // required string value = 2;
  // }
  // message Config {
  // repeated Item items = 1 [experimental_map_key="name"];
  // }
  // In this situation, the map key for Item will be set to "name".
  // TODO: Fully-implement this, then remove the "experimental_" prefix.
  optional string experimental_map_key = 9;
 
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;
 
  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
  }
 
  message EnumOptions {
 
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;
 
  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
  }
 
  message EnumValueOptions {
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;
 
  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
  }
 
  message ServiceOptions {
 
  // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
  // framework. We apologize for hoarding these numbers to ourselves, but
  // we were already using them long before we decided to release Protocol
  // Buffers.
 
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;
 
  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
  }
 
  message MethodOptions {
 
  // Note: Field numbers 1 through 32 are reserved for Google's internal RPC
  // framework. We apologize for hoarding these numbers to ourselves, but
  // we were already using them long before we decided to release Protocol
  // Buffers.
 
  // The parser stores options it doesn't recognize here. See above.
  repeated UninterpretedOption uninterpreted_option = 999;
 
  // Clients can define custom options in extensions of this message. See above.
  extensions 1000 to max;
  }
 
  // 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.
  message UninterpretedOption {
  // The name of the uninterpreted option. Each string represents a segment in
  // a dot-separated name. is_extension is true iff a segment represents an
  // extension (denoted with parentheses in options specs in .proto files).
  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
  // "foo.(bar.baz).qux".
  message NamePart {
  required string name_part = 1;
  required bool is_extension = 2;
  }
  repeated NamePart name = 2;
 
  // The value of the uninterpreted option, in whatever type the tokenizer
  // identified it as during parsing. Exactly one of these should be set.
  optional string identifier_value = 3;
  optional uint64 positive_int_value = 4;
  optional int64 negative_int_value = 5;
  optional double double_value = 6;
  optional bytes string_value = 7;
  optional string aggregate_value = 8;
  }
 
  // ===================================================================
  // Optional source code info
 
  // Encapsulates information about the original source file from which a
  // FileDescriptorProto was generated.
  message SourceCodeInfo {
  // A Location identifies a piece of source code in a .proto file which
  // corresponds to a particular definition. This information is intended
  // to be useful to IDEs, code indexers, documentation generators, and similar
  // tools.
  //
  // For example, say we have a file like:
  // message Foo {
  // optional string foo = 1;
  // }
  // Let's look at just the field definition:
  // optional string foo = 1;
  // ^ ^^ ^^ ^ ^^^
  // a bc de f ghi
  // We have the following locations:
  // span path represents
  // [a,i) [ 4, 0, 2, 0 ] The whole field definition.
  // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
  // [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
  // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
  // [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
  //
  // Notes:
  // - A location may refer to a repeated field itself (i.e. not to any
  // particular index within it). This is used whenever a set of elements are
  // logically enclosed in a single code segment. For example, an entire
  // extend block (possibly containing multiple extension definitions) will
  // have an outer location whose path refers to the "extensions" repeated
  // field without an index.
  // - Multiple locations may have the same path. This happens when a single
  // logical declaration is spread out across multiple places. The most
  // obvious example is the "extend" block again -- there may be multiple
  // extend blocks in the same scope, each of which will have the same path.
  // - A location's span is not always a subset of its parent's span. For
  // example, the "extendee" of an extension declaration appears at the
  // beginning of the "extend" block and is shared by all extensions within
  // the block.
  // - Just because a location's span is a subset of some other location's span
  // does not mean that it is a descendent. For example, a "group" defines
  // both a type and a field in a single declaration. Thus, the locations
  // corresponding to the type and field and their components will overlap.
  // - Code which tries to interpret locations should probably be designed to
  // ignore those that it doesn't understand, as more types of locations could
  // be recorded in the future.
  repeated Location location = 1;
  message Location {
  // Identifies which part of the FileDescriptorProto was defined at this
  // location.
  //
  // Each element is a field number or an index. They form a path from
  // the root FileDescriptorProto to the place where the definition. For
  // example, this path:
  // [ 4, 3, 2, 7, 1 ]
  // refers to:
  // file.message_type(3) // 4, 3
  // .field(7) // 2, 7
  // .name() // 1
  // This is because FileDescriptorProto.message_type has field number 4:
  // repeated DescriptorProto message_type = 4;
  // and DescriptorProto.field has field number 2:
  // repeated FieldDescriptorProto field = 2;
  // and FieldDescriptorProto.name has field number 1:
  // optional string name = 1;
  //
  // Thus, the above path gives the location of a field name. If we removed
  // the last element:
  // [ 4, 3, 2, 7 ]
  // this path refers to the whole field declaration (from the beginning
  // of the label to the terminating semicolon).
  repeated int32 path = 1 [packed=true];
 
  // Always has exactly three or four elements: start line, start column,
  // end line (optional, otherwise assumed same as start line), end column.
  // These are packed into a single field for efficiency. Note that line
  // and column numbers are zero-based -- typically you will want to add
  // 1 to each before displaying to a user.
  repeated int32 span = 2 [packed=true];
 
  // TODO(kenton): Record comments appearing before and after the
  // declaration.
  }
  }
 
  <?php
  // DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@
  // Source: php.proto
  // Date: 2011-03-20 01:27:38
 
  namespace {
 
  \google\protobuf\FileOptions::extension(function(){
  // optional php.namespace = 50002
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 50102;
  $f->name = "json.namespace";
  $f->type = 9;
  $f->rule = 1;
  return $f;
  });
  \google\protobuf\FileOptions::extension(function(){
  // optional php.suffix = 50003
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 50103;
  $f->name = "json.suffix";
  $f->type = 9;
  $f->rule = 1;
  $f->default = ".pb.js";
  return $f;
  });
  }
 
  import "descriptor.proto";
 
  package json;
 
  extend google.protobuf.FileOptions {
 
  // Set the namespace (overrides package)
  optional string namespace = 50102;
  // Suffix for file names
  optional string suffix = 50103 [default = ".pb.js"];
 
  }
 
  //extend google.protobuf.MessageOptions {
  //
  //}
  //
  //extend google.protobuf.FieldOptions {
  //
  //}
  //
  //extend google.protobuf.EnumOptions {
  //
  //}
  //
  //extend google.protobuf.EnumValueOptions {
  //
  //}
  //
  //extend google.protobuf.ServiceOptions {
  //
  //}
  //
  //extend google.protobuf.MethodOptions {
  //
  //}
 
  <?php
  // DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@
  // Source: php.proto
  // Date: 2011-03-20 01:27:38
 
  namespace {
 
  \google\protobuf\FileOptions::extension(function(){
  // optional php.namespace = 50002
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 50002;
  $f->name = "php.namespace";
  $f->type = 9;
  $f->rule = 1;
  return $f;
  });
  \google\protobuf\FileOptions::extension(function(){
  // optional php.suffix = 50003
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 50003;
  $f->name = "php.suffix";
  $f->type = 9;
  $f->rule = 1;
  $f->default = ".php";
  return $f;
  });
  \google\protobuf\FileOptions::extension(function(){
  // optional php.multiple = 50004
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 50004;
  $f->name = "php.multifile";
  $f->type = 8;
  $f->rule = 1;
  $f->default = false;
  return $f;
  });
  \google\protobuf\FileOptions::extension(function(){
  // optional php.generic_services = 50005
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 50005;
  $f->name = "php.generic_services";
  $f->type = 8;
  $f->rule = 1;
  $f->default = false;
  return $f;
  });
  }
 
  import "descriptor.proto";
 
  package php;
 
  extend google.protobuf.FileOptions {
 
  // Set the namespace (overrides package)
  optional string namespace = 50002;
  // Suffix for file names
  optional string suffix = 50003 [default = ".php"];
  // Generate a file for each structure in the proto
  optional bool multifile = 50004 [default = false];
  // Generate interfaces for service definitions
  optional bool generic_services = 50005 [default = false];
 
  }
 
  //extend google.protobuf.MessageOptions {
  //
  //}
  //
  //extend google.protobuf.FieldOptions {
  //
  //}
  //
  //extend google.protobuf.EnumOptions {
  //
  //}
  //
  //extend google.protobuf.EnumValueOptions {
  //
  //}
  //
  //extend google.protobuf.ServiceOptions {
  //
  //}
  //
  //extend google.protobuf.MethodOptions {
  //
  //}
 
  <?php
  // DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@
  // Source: plugin.proto
  // Date: 2011-03-20 01:27:33
 
  namespace google\protobuf\compiler {
 
  class CodeGeneratorRequest extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\compiler\CodeGeneratorRequest");
 
  // repeated file_to_generate = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "file_to_generate";
  $f->type = 9;
  $f->rule = 3;
  $descriptor->addField($f);
 
  // optional parameter = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "parameter";
  $f->nameOrig = "parameter";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.FileDescriptorProto proto_file = 15
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 15;
  $f->name = "proto_file";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\FileDescriptorProto";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string[] */
  public $file_to_generate = array();
 
  /** @var string */
  public $parameter = null;
 
  /** @var \google\protobuf\FileDescriptorProto[] */
  public $proto_file = array();
 
 
  /**
  * Check if <file_to_generate> has a value
  *
  * @return boolean
  */
  public function hasFileToGenerate(){
  return $this->_has(1);
  }
 
  /**
  * Clear <file_to_generate> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function clearFileToGenerate(){
  return $this->_clear(1);
  }
 
  /**
  * Get <file_to_generate> value
  *
  * @param int $idx
  * @return string
  */
  public function getFileToGenerate($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <file_to_generate> value
  *
  * @param string $value
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function setFileToGenerate( $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <file_to_generate>
  *
  * @return string[]
  */
  public function getFileToGenerateList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <file_to_generate>
  *
  * @param string $value
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function addFileToGenerate( $value){
  return $this->_add(1, $value);
  }
 
  /**
  * Check if <parameter> has a value
  *
  * @return boolean
  */
  public function hasParameter(){
  return $this->_has(2);
  }
 
  /**
  * Clear <parameter> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function clearParameter(){
  return $this->_clear(2);
  }
 
  /**
  * Get <parameter> value
  *
  * @return string
  */
  public function getParameter(){
  return $this->_get(2);
  }
 
  /**
  * Set <parameter> value
  *
  * @param string $value
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function setParameter( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <proto_file> has a value
  *
  * @return boolean
  */
  public function hasProtoFile(){
  return $this->_has(15);
  }
 
  /**
  * Clear <proto_file> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function clearProtoFile(){
  return $this->_clear(15);
  }
 
  /**
  * Get <proto_file> value
  *
  * @param int $idx
  * @return \google\protobuf\FileDescriptorProto
  */
  public function getProtoFile($idx = NULL){
  return $this->_get(15, $idx);
  }
 
  /**
  * Set <proto_file> value
  *
  * @param \google\protobuf\FileDescriptorProto $value
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function setProtoFile(\google\protobuf\FileDescriptorProto $value, $idx = NULL){
  return $this->_set(15, $value, $idx);
  }
 
  /**
  * Get all elements of <proto_file>
  *
  * @return \google\protobuf\FileDescriptorProto[]
  */
  public function getProtoFileList(){
  return $this->_get(15);
  }
 
  /**
  * Add a new element to <proto_file>
  *
  * @param \google\protobuf\FileDescriptorProto $value
  * @return \google\protobuf\compiler\CodeGeneratorRequest
  */
  public function addProtoFile(\google\protobuf\FileDescriptorProto $value){
  return $this->_add(15, $value);
  }
 
  }
  }
 
  namespace google\protobuf\compiler {
 
  class CodeGeneratorResponse extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\compiler\CodeGeneratorResponse");
 
  // optional error = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "error";
  $f->nameOrig = "error";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 15;
  $f->name = "file";
  $f->nameOrig = "file";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = "\google\protobuf\compiler\CodeGeneratorResponse\File";
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $error = null;
 
  /** @var \google\protobuf\compiler\CodeGeneratorResponse\File[] */
  public $file = array();
 
 
  /**
  * Check if <error> has a value
  *
  * @return boolean
  */
  public function hasError(){
  return $this->_has(1);
  }
 
  /**
  * Clear <error> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorResponse
  */
  public function clearError(){
  return $this->_clear(1);
  }
 
  /**
  * Get <error> value
  *
  * @return string
  */
  public function getError(){
  return $this->_get(1);
  }
 
  /**
  * Set <error> value
  *
  * @param string $value
  * @return \google\protobuf\compiler\CodeGeneratorResponse
  */
  public function setError( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <file> has a value
  *
  * @return boolean
  */
  public function hasFile(){
  return $this->_has(15);
  }
 
  /**
  * Clear <file> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorResponse
  */
  public function clearFile(){
  return $this->_clear(15);
  }
 
  /**
  * Get <file> value
  *
  * @param int $idx
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File
  */
  public function getFile($idx = NULL){
  return $this->_get(15, $idx);
  }
 
  /**
  * Set <file> value
  *
  * @param \google\protobuf\compiler\CodeGeneratorResponse\File $value
  * @return \google\protobuf\compiler\CodeGeneratorResponse
  */
  public function setFile(\google\protobuf\compiler\CodeGeneratorResponse\File $value, $idx = NULL){
  return $this->_set(15, $value, $idx);
  }
 
  /**
  * Get all elements of <file>
  *
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File[]
  */
  public function getFileList(){
  return $this->_get(15);
  }
 
  /**
  * Add a new element to <file>
  *
  * @param \google\protobuf\compiler\CodeGeneratorResponse\File $value
  * @return \google\protobuf\compiler\CodeGeneratorResponse
  */
  public function addFile(\google\protobuf\compiler\CodeGeneratorResponse\File $value){
  return $this->_add(15, $value);
  }
 
  }
  }
 
  namespace google\protobuf\compiler\CodeGeneratorResponse {
 
  class File extends \DrSlump\Protobuf\Message {
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected static $__descriptor;
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  if (NULL !== $descriptor) {
  self::$__descriptor = $descriptor;
  return self::$__descriptor;
  }
 
  if (!self::$__descriptor) {
  $descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\compiler\CodeGeneratorResponse\File");
 
  // optional name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->nameOrig = "name";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional insertion_point = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "insertion_point";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // optional content = 15
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 15;
  $f->name = "content";
  $f->nameOrig = "content";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  self::$__descriptor = $descriptor;
  }
 
  return self::$__descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var string */
  public $insertion_point = null;
 
  /** @var string */
  public $content = null;
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <insertion_point> has a value
  *
  * @return boolean
  */
  public function hasInsertionPoint(){
  return $this->_has(2);
  }
 
  /**
  * Clear <insertion_point> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File
  */
  public function clearInsertionPoint(){
  return $this->_clear(2);
  }
 
  /**
  * Get <insertion_point> value
  *
  * @return string
  */
  public function getInsertionPoint(){
  return $this->_get(2);
  }
 
  /**
  * Set <insertion_point> value
  *
  * @param string $value
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File
  */
  public function setInsertionPoint( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <content> has a value
  *
  * @return boolean
  */
  public function hasContent(){
  return $this->_has(15);
  }
 
  /**
  * Clear <content> value
  *
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File
  */
  public function clearContent(){
  return $this->_clear(15);
  }
 
  /**
  * Get <content> value
  *
  * @return string
  */
  public function getContent(){
  return $this->_get(15);
  }
 
  /**
  * Set <content> value
  *
  * @param string $value
  * @return \google\protobuf\compiler\CodeGeneratorResponse\File
  */
  public function setContent( $value){
  return $this->_set(15, $value);
  }
 
  }
  }
 
  // Protocol Buffers - Google's data interchange format
  // Copyright 2008 Google Inc. All rights reserved.
  // http://code.google.com/p/protobuf/
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are
  // met:
  //
  // * Redistributions of source code must retain the above copyright
  // notice, this list of conditions and the following disclaimer.
  // * Redistributions in binary form must reproduce the above
  // copyright notice, this list of conditions and the following disclaimer
  // in the documentation and/or other materials provided with the
  // distribution.
  // * Neither the name of Google Inc. nor the names of its
  // contributors may be used to endorse or promote products derived from
  // this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
  // Author: kenton@google.com (Kenton Varda)
  //
  // WARNING: The plugin interface is currently EXPERIMENTAL and is subject to
  // change.
  //
  // protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
  // just a program that reads a CodeGeneratorRequest from stdin and writes a
  // CodeGeneratorResponse to stdout.
  //
  // Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
  // of dealing with the raw protocol defined here.
  //
  // A plugin executable needs only to be placed somewhere in the path. The
  // plugin should be named "protoc-gen-$NAME", and will then be used when the
  // flag "--${NAME}_out" is passed to protoc.
 
  package google.protobuf.compiler;
 
  import "descriptor.proto";
 
  // An encoded CodeGeneratorRequest is written to the plugin's stdin.
  message CodeGeneratorRequest {
  // The .proto files that were explicitly listed on the command-line. The
  // code generator should generate code only for these files. Each file's
  // descriptor will be included in proto_file, below.
  repeated string file_to_generate = 1;
 
  // The generator parameter passed on the command-line.
  optional string parameter = 2;
 
  // FileDescriptorProtos for all files in files_to_generate and everything
  // they import. The files will appear in topological order, so each file
  // appears before any file that imports it.
  //
  // protoc guarantees that all proto_files will be written after
  // the fields above, even though this is not technically guaranteed by the
  // protobuf wire format. This theoretically could allow a plugin to stream
  // in the FileDescriptorProtos and handle them one by one rather than read
  // the entire set into memory at once. However, as of this writing, this
  // is not similarly optimized on protoc's end -- it will store all fields in
  // memory at once before sending them to the plugin.
  repeated FileDescriptorProto proto_file = 15;
  }
 
  // The plugin writes an encoded CodeGeneratorResponse to stdout.
  message CodeGeneratorResponse {
  // Error message. If non-empty, code generation failed. The plugin process
  // should exit with status code zero even if it reports an error in this way.
  //
  // This should be used to indicate errors in .proto files which prevent the
  // code generator from generating correct code. Errors which indicate a
  // problem in protoc itself -- such as the input CodeGeneratorRequest being
  // unparseable -- should be reported by writing a message to stderr and
  // exiting with a non-zero status code.
  optional string error = 1;
 
  // Represents a single generated file.
  message File {
  // The file name, relative to the output directory. The name must not
  // contain "." or ".." components and must be relative, not be absolute (so,
  // the file cannot lie outside the output directory). "/" must be used as
  // the path separator, not "\".
  //
  // If the name is omitted, the content will be appended to the previous
  // file. This allows the generator to break large files into small chunks,
  // and allows the generated text to be streamed back to protoc so that large
  // files need not reside completely in memory at one time. Note that as of
  // this writing protoc does not optimize for this -- it will read the entire
  // CodeGeneratorResponse before writing files to disk.
  optional string name = 1;
 
  // If non-empty, indicates that the named file should already exist, and the
  // content here is to be inserted into that file at a defined insertion
  // point. This feature allows a code generator to extend the output
  // produced by another code generator. The original generator may provide
  // insertion points by placing special annotations in the file that look
  // like:
  // @@protoc_insertion_point(NAME)
  // The annotation can have arbitrary text before and after it on the line,
  // which allows it to be placed in a comment. NAME should be replaced with
  // an identifier naming the point -- this is what other generators will use
  // as the insertion_point. Code inserted at this point will be placed
  // immediately above the line containing the insertion point (thus multiple
  // insertions to the same point will come out in the order they were added).
  // The double-@ is intended to make it unlikely that the generated code
  // could contain things that look like insertion points by accident.
  //
  // For example, the C++ code generator places the following line in the
  // .pb.h files that it generates:
  // // @@protoc_insertion_point(namespace_scope)
  // This line appears within the scope of the file's package namespace, but
  // outside of any particular class. Another plugin can then specify the
  // insertion_point "namespace_scope" to generate additional classes or
  // other declarations that should be placed in this scope.
  //
  // Note that if the line containing the insertion point begins with
  // whitespace, the same whitespace will be added to every line of the
  // inserted text. This is useful for languages like Python, where
  // indentation matters. In these languages, the insertion point comment
  // should be indented the same amount as any inserted code will need to be
  // in order to work correctly in that context.
  //
  // The code generator that generates the initial file and the one which
  // inserts into it must both run as part of a single invocation of protoc.
  // Code generators are executed in the order in which they appear on the
  // command line.
  //
  // If |insertion_point| is present, |name| must also be present.
  optional string insertion_point = 2;
 
  // The file contents.
  optional string content = 15;
  }
  repeated File file = 15;
  }
 
  <?php
 
  namespace DrSlump\Protobuf;
 
  use DrSlump\Protobuf;
 
  class Descriptor
  {
  /** @var String Holds the class name of the message */
  protected $class;
 
  /** @var String Holds the original proto name */
  protected $name;
 
  /** @var \DrSlump\Protobuf\Field[] */
  protected $fields = array();
 
  /** @var array - Cache the relation between names and tags */
  protected $names = array();
 
 
  /**
  * @param string $class
  * @param string $name
  */
  public function __construct($class, $name = null)
  {
  $this->class = trim($class, '\\ ');
  $this->name = $name ? trim($name, '. ') : NULL;
  }
 
  /**
  * @return string
  */
  public function getClass()
  {
  return $this->class;
  }
 
  /**
  * @return string|null
  */
  public function getName()
  {
  return $this->name;
  }
 
  /**
  * Obtain the list of fields in the message
  *
  * @return \DrSlump\Protobuf\Field[]
  */
  public function getFields()
  {
  return $this->fields;
  }
 
  /**
  * Adds a field to the message
  *
  * @param \DrSlump\Protobuf\Field $field
  * @param bool $isExtension
  */
  public function addField(Protobuf\Field $field, $isExtension = false)
  {
  $field->extension = $isExtension;
  $this->fields[ $field->number ] = $field;
  }
 
  /**
  * Obtain a field descriptor by its tag number
  *
  * @param int $tag
  * @return \DrSlump\Protobuf\Field | NULL
  */
  public function getField($tag)
  {
  return isset($this->fields[$tag])
  ? $this->fields[$tag]
  : NULL;
  }
 
  /**
  * Obtain a field descriptor by its name
  *
  * @param string $name
  * @return \DrSlump\Protobuf\Field | NULL
  */
  public function getFieldByName($name)
  {
  // Check cached map
  if (isset($this->names[$name])) {
  return $this->getField($this->names[$name]);
  }
 
  // Loop thru all fields to find it
  foreach ($this->fields as $tag=>$field) {
  // Cache it for next calls
  $fname = $field->getName();
  $this->names[$fname] = $tag;
 
  if ($name === $fname) {
  return $field;
  }
  }
 
  return null;
  }
 
  /**
  * Check if the given tag number matches a field
  *
  * @param int $tag
  * @return bool
  */
  public function hasField($tag)
  {
  return isset($this->fields[$tag]);
  }
  }
 
  <?php
 
  namespace DrSlump\Protobuf;
 
  class Exception extends \Exception
  {
 
  }
  <?php
 
  namespace DrSlump\Protobuf;
 
  use DrSlump\Protobuf;
 
  class Field
  {
  public $number;
  public $name;
  public $type = Protobuf::TYPE_UNKNOWN;
  public $rule = Protobuf::RULE_OPTIONAL;
  public $reference;
  public $default;
  public $packed = false;
  public $extension = false;
 
  public function __construct(array $opts = array())
  {
  if (!empty($opts)) {
  if (isset($opts['number'])) $this->number = (int)$opts['number'];
  if (isset($opts['name'])) $this->name = $opts['name'];
  if (isset($opts['type'])) $this->type = (int)$opts['type'];
  if (isset($opts['rule'])) $this->rule = (int)$opts['rule'];
  if (isset($opts['packed'])) $this->packed = (bool)$opts['packed'];
  if (isset($opts['reference'])) $this->reference = $opts['reference'];
  if (isset($opts['default'])) $this->default = $opts['default'];
  if (isset($opts['extension'])) $this->extension = (bool)$opts['extension'];
  }
  }
 
  public function getNumber()
  {
  return $this->number;
  }
 
  public function getType()
  {
  return $this->type;
  }
 
  public function getName()
  {
  return $this->name;
  }
 
  public function getReference()
  {
  return $this->reference;
  }
 
  public function getDefault()
  {
  return $this->default;
  }
 
  public function hasDefault()
  {
  return $this->default !== NULL;
  }
 
  public function isOptional()
  {
  return $this->rule === Protobuf::RULE_OPTIONAL;
  }
 
  public function isRequired()
  {
  return $this->rule === Protobuf::RULE_REQUIRED;
  }
 
  public function isRepeated()
  {
  return $this->rule === Protobuf::RULE_REPEATED;
  }
 
  public function isPacked()
  {
  return $this->packed;
  }
 
  public function isExtension()
  {
  return $this->extension;
  }
  }
  <?php
 
  namespace DrSlump\Protobuf;
 
  use DrSlump\Protobuf;
 
  abstract class Message implements \ArrayAccess
  {
  /** @var \Closure[] */
  static protected $__extensions = array();
 
  /** @var \DrSlump\Protobuf\Descriptor */
  protected $_descriptor;
  /** @var array Store data for extension fields */
  protected $_extensions = array();
  /** @var array Store data for unknown values */
  protected $_unknown = array();
 
  /**
  * @static
  * @abstract
  * @return \DrSlump\Protobuf\Descriptor
  */
  public static function descriptor()
  {
  throw new \BadMethodCallException('This method should be implemented in inherited classes');
  }
 
  /**
  * Register an extension configuration callback
  *
  * @static
  * @param \Closure $fn
  */
  public static function extension(\Closure $fn)
  {
  static::$__extensions[] = $fn;
  }
 
  /**
  * @param string $data
  */
  public function __construct($data = null)
  {
  // Cache the descriptor instance
  $this->_descriptor = Protobuf::getRegistry()->getDescriptor($this);
 
  // Assign default values to extensions
  foreach ($this->_descriptor->getFields() as $f) {
  if ($f->isExtension() && $f->hasDefault()) {
  $this->_extensions[$f->getName()] = $f->getDefault();
  }
  }
 
  if (NULL !== $data) {
  $this->parse($data);
  }
  }
 
  // Implements ArrayAccess for extensions and unknown fields
 
  public function offsetExists($offset)
  {
  if (is_numeric($offset)) {
  return $this->_has($offset);
  } else {
  return $this->hasExtension($offset);
  }
  }
 
  public function offsetSet($offset, $value)
  {
  if (is_numeric($offset)) {
  $this->_set($offset, $value);
  } else {
  $this->setExtension($offset, $value);
  }
  }
 
  public function offsetGet( $offset )
  {
  if (is_numeric($offset)) {
  return $this->_get($offset);
  } else {
  return $this->getExtension($offset);
  }
  }
 
  public function offsetUnset( $offset )
  {
  if (is_numeric($offset)) {
  $this->_clear($offset);
  } else {
  $this->clearExtension($offset);
  }
  }
 
  /**
  * Parse the given data to hydrate the object
  *
  * @param string $data
  * @param CodecInterface|null $codec
  */
  public function parse($data, Protobuf\CodecInterface $codec = null)
  {
  $codec = Protobuf::getCodec($codec);
  $codec->decode($this, $data);
  }
 
  /**
  * Serialize the current object data
  *
  * @param CodecInterface|null $codec
  * @return string
  */
  public function serialize(Protobuf\CodecInterface $codec = null)
  {
  $codec = Protobuf::getCodec($codec);
  return $codec->encode($this);
  }
 
 
  /**
  * Checks if the given tag number is set
  *
  * @param int $tag
  * @return bool
  */
  public function _has($tag)
  {
  if ($this->_descriptor->hasField($tag)) {
  $f = $this->_descriptor->getField($tag);
  $name = $f->getName();
 
  if ($f->isExtension()) {
  return $f->isRepeated()
  ? count($this->_extensions[$name]) > 0
  : $this->_extensions[$name] !== NULL;
  } else {
  return $f->isRepeated()
  ? count($this->$name) > 0
  : $this->$name !== NULL;
  }
  }
 
  return false;
  }
 
  /**
  * Get the value by tag number
  *
  * @param int $tag
  * @param int|null $idx
  * @return mixed
  */
  public function _get($tag, $idx = null)
  {
  $f = $this->_descriptor->getField($tag);
 
  if (!$f) {
  return null;
  }
 
  $name = $f->getName();
 
  if (!$f->isExtension()) {
 
  return $idx !== NULL
  ? $this->{$name}[$idx]
  : $this->$name;
 
  } else {
 
  return $idx !== NULL
  ? $this->_extensions[$name][$idx]
  : $this->_extensions[$name];
 
  }
 
  }
 
  /**
  * Sets the value by tag number
  *
  * @throws \Exception If trying to set an unknown field
  * @param int $tag
  * @param mixed $value
  * @param int|null $idx
  * @return \DrSlump\Protobuf\Message - Fluent interface
  */
  public function _set($tag, $value, $idx = null)
  {
  $f = $this->_descriptor->getField($tag);
 
  if (!$f) {
  throw new \Exception('Unknown fields not supported');
  }
 
  $name = $f->getName();
  if (!$f->isExtension()) {
 
  if ($idx === NULL) {
  $this->$name = $value;
  } else {
  $this->{$name}[$idx] = $value;
  }
 
  } else {
  if ($idx === NULL) {
  $this->_extensions[$name] = $value;
  } else {
  $this->_extensions[$name][$idx] = $value;
  }
  }
 
  return $this;
  }
 
  /**
  * Adds a new value to a repeated field by tag number
  *
  * @throws \Exception If trying to modify an unknown field
  * @param int $tag
  * @param mixed $value
  * @return Message
  */
  public function _add($tag, $value)
  {
  $f = $this->_descriptor->getField($tag);
 
  if (!$f) {
  throw new \Exception('Unknown fields not supported');
  }
 
  $name = $f->getName();
  if (!$f->isExtension()) {
  $this->{$name}[] = $value;
  } else {
  $this->_extensions[$name][] = $value;
  }
 
  return $this;
  }
 
  /**
  * Clears/Resets a field by tag number
  *
  * @throws \Exception If trying to modify an unknown field
  * @param int $tag
  * @return \DrSlump\Protobuf\Message - Fluent interface
  */
  public function _clear($tag)
  {
  $f = $this->_descriptor->getField($tag);
 
  if (!$f) {
  throw new \Exception('Unknown fields not supported');
  }
 
  $name = $f->getName();
  if (!$f->isExtension()) {
  $this->$name = $f->isRepeated()
  ? array()
  : NULL;
  } else {
  $this->_extensions[$name] = $f->isRepeated()
  ? array()
  : NULL;
  }
 
  return $this;
  }
 
  // Extensions public methods.
  // @todo Check if extension name is defined
 
  /**
  * Checks if an extension field is set
  *
  * @param string $extname
  * @return bool
  */
  public function hasExtension($extname)
  {
  return isset($this->_extensions[$extname]);
  }
 
  /**
  * Get the value of an extension field
  *
  * @param string $extname
  * @param int|null $idx
  * @return mixed
  */
  public function getExtension($extname, $idx = null)
  {
  if (!isset($this->_extensions[$extname])) return NULL;
 
  return $idx === NULL
  ? $this->_extensions[$extname]
  : $this->_extensions[$extname][$idx];
  }
 
  /**
  * Get all the values of a repeated extension field
  *
  * @param string $extname
  * @return array
  */
  public function getExtensionList($extname)
  {
  return isset($this->_extensions[$extname])
  ? $this->_extensions[$extname]
  : array();
  }
 
  /**
  * Set the value for an extension field
  *
  * @param string $extname
  * @param mixed $value
  * @param int|null $idx
  * @return \DrSlump\Protobuf\Message - Fluent Interface
  */
  public function setExtension($extname, $value, $idx = null)
  {
  if (NULL !== $idx) {
  if (empty($this->_extensions)) {
  $this->_extensions[$extname] = array();
  }
  $this->_extensions[$extname][$idx] = $value;
  }
 
  $this->_extensions[$extname] = $value;
 
  return $this;
  }
 
  /**
  * Adds a value to repeated extension field
  *
  * @param string $extname
  * @param mixed $value
  * @return \DrSlump\Protobuf\Message - Fluent Interface
  */
  public function addExtension($extname, $value)
  {
  $this->_extensions[$extname][] = $value;
  }
 
  /**
  * @param $extname
  * @return void
  */
  public function clearExtension($extname)
  {
  unset($this->_extensions[$extname]);
  }
 
 
  public function addUnknown(Unknown $unknown)
  {
  $this->_unknown[] = $unknown;
  }
 
  public function getUnknown()
  {
  return $this->_unknown;
  }
 
  public function clearUnknown()
  {
  $this->_unknown = array();
  }
 
  }
 
  <?php
 
  namespace DrSlump\Protobuf;
 
  use DrSlump\Protobuf;
 
  /**
  * Keeps instances of the different message descriptors used.
  *
  */
  class Registry
  {
  /** @var array */
  protected $descriptors = array();
 
  /**
  * @param string|\DrSlump\Protobuf\Message $message
  * @param \DrSlump\Protobuf\Descriptor $descriptor
  */
  public function setDescriptor($message, Descriptor $descriptor)
  {
  $message = is_object($message) ? get_class($message) : $message;
  $message = ltrim($message, '\\');
 
  $this->descriptors[$message] = $descriptor;
  }
 
  /**
  * Obtains the descriptor for the given message class, obtaining
  * it if not yet loaded.
  *
  * @param string|\DrSlump\Protobuf\Message $message
  * @return \DrSlump\Protobuf\Descriptor
  */
  public function getDescriptor($message)
  {
  $message = is_object($message) ? get_class($message) : $message;
  $message = ltrim($message, '\\');
 
  // Build a descriptor for the message
  if (!isset($this->descriptors[$message])) {
  $class = '\\' . $message;
  if (!class_exists($class)) {
  throw Protobuf\Exception('Message class "' . $class . '" not available');
  }
 
  $this->descriptors[$message] = $class::descriptor();
  }
 
  return $this->descriptors[$message];
  }
 
  /**
  * @param string|\DrSlump\Protobuf\Message $message
  * @return bool
  */
  public function hasDescriptor($message)
  {
  $message = is_object($message) ? get_class($message) : $message;
  $message = ltrim($message, '\\');
 
  return isset($this->descriptors[$message]);
  }
 
  /**
  * @param string|\DrSlump\Protobuf\Message $message
  */
  public function unsetDescriptor($message)
  {
  $message = is_object($message) ? get_class($message) : $message;
  $message = ltrim($message, '\\');
 
  unset($this->descriptors[$message]);
  }
  }
  <?php
 
  namespace DrSlump\Protobuf;
 
  abstract class Unknown
  {
  public $tag = 0;
  public $data = null;
  }
 
  protobuf-php(3) -- The framework
  ================================
 
  ## SYNOPSIS
 
  <?php
  require_once 'DrSlump\Protobuf.php';
 
  use DrSlump\Protobuf;
 
  $data = file_get_contents('data.pb');
  $person = new Tutorial\Person($data);
  echo $person->getName();
 
 
  ## DESCRIPTION
 
  Protobuf-PHP is a library to generate, parse and serialize data structures
  compatible with Google's Protocol Buffers using the PHP language.
 
  ## CODECS
 
  The library is designed to work with a pluggable mechanism for encoding and decoding
  messages, allowing it to be used not only to communicate using the standard binary
  format but also with Json or XML based formats.
 
  You can create your own codecs by either extending a provided one or implementing the
  `Protobuf\CodecInterface`. Creating custom codecs offers the possibility to use
  Protobuf-PHP code generation tool to work with legacy formats or even as a simple
  way to interact with database adapters.
 
  ### Standard Binary
 
  This is the standard binary format supported by the official libraries distributed
  by Google. It's pretty much compatible with the official implementations although
  there are some known issues, mostly regarding big integer numbers, which are documented
  in the readme file that comes with the library.
 
  ### Standard TextFormat
 
  The official libraries also support a text based format for debugging purposes. The
  current implementation of this codec only supports encoding or serialization.
 
  ### PhpArray
 
  This is more of an internal codec to ease the implementation of some others. It is
  able to serializa message objects to PHP's associative arrays and intantiate message
  objects from them.
 
  Since most serialization libraries in PHP will natively support associative arrays, this
  codec can be used as an easy way to incorporate those formats for their use
  with Protobuf messages. The Json and XML codecs are examples of this use case.
 
  ### JSON
 
  It allows to generate or consume JSON formatted strings, which is a very popular
  format for REST based web services for example. This codec can be used to communicate
  with JavaScript in the browser or with third party REST web services.
 
  ### ProtoJson
 
  [ProtoJson](https://github.com/drslump/ProtoJson) allows to apply some payload
  minification strategies when working with JSON formatted messages. Taking advantatge
  of Protobuf's property names mapping to a integer number, it offers two encoding
  variants (_TagMap_ and _Indexed_) that use that number instead of the field name
  as key in the messages to reduce the total size of the payload.
 
  ### XML
 
  A very simple codec to work with XML based messages. It has no knowledge of namespaces
  and other advanced XML features but should be enough to integrate with third parties
  that are restricted to simple XML payloads. It can also serve as a base for more
  customized integrations, by extendind this codec to consume and generate XML messages
  specific to your service.
 
 
 
  ## ANNOTATED MESSAGES
 
  While the most common use case is to use the protoc-gen-php(1) `protoc` plugin to
  generate source code representing the messages defined in .proto files, it's also
  possible to define messages at runtime without the code generation step.
 
  An easy way to define messages directly in your code is to use the `Protobuf\AnnotatedMessage`
  abstract class, which allows to annotate your classes so that the _codecs_ know how
  to parse and serialize those messages.
 
  class Person extends \DrSlump\Protobuf\AnnotatedMessage {
  /** @protobuf(tag=1, type=string, required) */
  public $name;
  /** @protobuf(tag=2, type=int32, required) */
  public $id;
  /** @protobuf(tag=3, type=string, optional) */
  public $email;
  /** @protobuf(tag=4, repeated, type=message, reference=Person) */
  public $friends = array();
  }
 
 
  ## EXAMPLES
 
 
 
  ## BUGS
 
  Please report bugs using GitHub's issue tracker at http://github.com/drslump/protobuf-php/issues
 
 
  ## COPYRIGHT
 
  Protobuf for PHP is Copyright (C) 2011 Ivan -DrSlump- Montes <http://pollinimini.net>
 
 
  ## SEE ALSO
 
  protoc-gen-php(1), protobuf-php(5),
  <http://github.com/drslump/protobuf-php>
 
  protobuf-php(5) -- Proto files
  ================================
 
  ## SYNOPSIS
 
  Protobuf for PHP supports a few custom options for proto files.
 
 
  ## DESCRIPTION
 
  Proto files processed with Protobuf for PHP can use a number of custom options
  that affect the generated source code.
 
  * `php.suffix` <string>:
  Sets a custom suffix for the generated PHP files. By default ".php" is used.
 
  * `php.namespace` <string>:
  Defines the namespace to use for the generated PHP classes.
 
  * `php.package` <string>:
  An alias for `php.namespace`
 
  * `php.multifile` <boolean>:
  By default a single PHP file is generated for each Proto file processed,
  including in it all the messages, enums and extensions defined in the proto
  definition. If this option is set to `true` then each message and enum is
  generated in a separate file, following PEAR's conventions, and if extensions
  are pressent in the proto definition a file named after the proto file with the
  suffix "-extensions" will contain them.
 
  * `php.generic_services` <boolean>:
  By default no service interfaces will be generated. If this option is set
  to true then Interfaces will be created for each `service` definition found,
  including a method named after each `rpc` entry.
 
 
 
  ## EXAMPLES ##
 
  option (php.suffix) = ".pb.php"
  option (php.namespace) = "MyOrg.Protos"
  option (php.multifile) = true
  option (php.generic_services) = true
 
 
  ## BUGS ##
 
  Please report bugs using GitHub's issue tracker at http://github.com/drslump/protobuf-php/issues
 
 
  ## COPYRIGHT ##
 
  Protobuf for PHP is Copyright (C) 2011 Ivan -DrSlump- Montes <http://pollinimini.net>
 
 
  ## SEE ALSO
 
  protoc-gen-php(1), protobuf-php(3),
  <http://github.com/drslump/protobuf-php>
 
  protoc-gen-php(1) -- protoc compiler plugin
  ===========================================
 
  ## SYNOPSIS
 
  `protoc-gen-php` [`-v`] [`-o` _directory_] [`-i` _directory_] <file>...
 
 
  ## DESCRIPTION
 
  **protoc-gen-php** is a Google's Protocol Buffers compiler plugin
  for the `protoc` tool. It generates PHP classes compatible with
  **Protobuf for PHP** from .proto files.
 
 
  ## REQUIREMENTS ##
 
  **protoc-gen-php** is written in PHP using features first found on
  PHP 5.3. It also requires the Console_CommandLine package from Pear.
 
  Additionally you'll also need to have a working copy of Google Protocol
  Buffers's _protoc_ command, version 2.3 or above, available on your path.
 
 
  ## OPTIONS ##
 
  The command accepts the following command-line options (switches).
 
  * `-v`, `--verbose`:
  Enables verbose mode. Additional information will be printed when
  processing the files.
 
  * `-h`, `--help`:
  Prints the usage help message and quits.
 
  * `-i` _directory_, `--include`=_directory_:
  Tells the protoc compiler to look into that directory when resolving
  import statements. Note that you can use this switch more than once
  to configure multiple directories.
 
  * `-o` _directory_, `--out`=_directory_:
  Tells the protoc compiler to create generated files in the given
  directory. If not set it will create the files in the working
  directory.
 
  * `--protoc`=_path to protoc binary_:
  If you don't happen to have the `protoc` binary in your path, you can
  use this option to indicate a path to it.
 
  * `--skip-imported`
  Flags the compiler to only generate source code for the proto file
  explicitely given on the command line. This means that imported files
  will not be generated when using this option.
 
  * `--comments`
  Parses the .proto files looking for multiline comments (/* ... */) to
  include them in the generated files.
 
  * `-Ddefine`, `-Ddefine`=_value_:
  Defines an option (defaults to true if no value given) to pass to
  the generator. See protobuf-php(5) for supported options, noting that
  the `php.` prefix shall not be used here.
 
 
  ## EXAMPLES ##
 
  Generate a PHP file from a proto file:
 
  $ protoc-gen-php tutorial.proto
 
  Generate PHP files in the "build" directory for each proto file found the
  "protos" directory:
 
  $ protoc-gen-php -o build protos/*.proto
 
  Generate a PHP file from a proto file using imports from an include path:
 
  $ protoc-gen-php -i ./protos protos/tutorial.proto
 
  Generate a PHP file with a custom extension
 
  $ protoc-gen-php -Dsuffix=pb.php tutorial.proto
 
 
  ## BUGS ##
 
  Please report bugs using GitHub's issue tracker at http://github.com/drslump/protobuf-php/issues
 
 
  ## COPYRIGHT ##
 
  Protobuf for PHP is Copyright (C) 2011 Ivan -DrSlump- Montes <http://pollinimini.net>
 
 
  ## SEE ALSO
 
  protobuf-php(3), protobuf-php(5),
  <http://github.com/drslump/protobuf-php>
 
  <?xml version="1.0" encoding="UTF-8"?>
  <package packagerversion="1.8.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
  http://pear.php.net/dtd/tasks-1.0.xsd
  http://pear.php.net/dtd/package-2.0
  http://pear.php.net/dtd/package-2.0.xsd">
  <name>Protobuf</name>
  <channel>pear.pollinimini.net</channel>
  <summary>PHP implementation of Google's Protocol Buffers</summary>
  <description>
  Protobuf for PHP is an implementation of Google's Protocol Buffers for the
  PHP language, supporting its binary data serialization and including a
  protoc plugin to generate PHP classes from .proto files.
  </description>
  <lead>
  <name>Iván -DrSlump- Montes</name>
  <user>drslump</user>
  <email>drslump@pollinimini.net</email>
  <active>yes</active>
  </lead>
  <date>{DATE}</date>
  <time>{TIME}</time>
  <version>
  <release>{VERSION}</release>
  <api>{VERSION}</api>
  </version>
  <stability>
  <release>beta</release>
  <api>beta</api>
  </stability>
  <license uri="http://creativecommons.org/licenses/MIT">The MIT License</license>
  <notes>http://github.com/drslump/Protobuf-PHP</notes>
  <contents>
  <dir name="/">
  <file baseinstalldir="/" name="LICENSE" role="doc"/>
  <file baseinstalldir="/" name="README.md" role="doc"/>
  <file baseinstalldir="/" name="protoc-gen-php.php" role="script">
  <tasks:replace from="/usr/bin/env php" to="php_bin" type="pear-config"/>
  <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" />
  <tasks:replace from="@package_version@" to="version" type="package-info" />
  </file>
  <file baseinstalldir="/" name="protoc-gen-php.bat" role="script">
  <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" />
  <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" />
  <tasks:replace from="@package_version@" to="version" type="package-info" />
  </file>
 
  {DIRS}
  </dir>
  </contents>
  <dependencies>
  <required>
  <php>
  <min>5.3.0</min>
  </php>
  <pearinstaller>
  <min>1.9.2</min>
  </pearinstaller>
  <package>
  <name>Console_CommandLine</name>
  <channel>pear.php.net</channel>
  <min>1.1.0</min>
  </package>
  </required>
  </dependencies>
  <phprelease>
  <installconditions>
  <os>
  <name>windows</name>
  </os>
  </installconditions>
  <filelist>
  <install as="protoc-gen-php" name="protoc-gen-php.php" />
  <install as="protoc-gen-php.bat" name="protoc-gen-php.bat" />
  </filelist>
  </phprelease>
  <phprelease>
  <filelist>
  <install as="protoc-gen-php" name="protoc-gen-php.php" />
  <ignore name="protoc-gen-php.bat" />
  </filelist>
  </phprelease>
  </package>
 
  @echo off
  REM Protobuf-PHP
  REM Copyright (C) 2011 Iván -DrSlump- Montes <drslump@pollinimini.net>
  REM
  REM This source file is subject to the MIT license that is bundled
  REM with this package in the file LICENSE.
  REM It is also available through the world-wide-web at this URL:
  REM http://creativecommons.org/licenses/MIT/
 
  if "%PHPBIN%" == "" set PHPBIN=@php_bin@
  if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH
  GOTO RUN
 
  :USE_PEAR_PATH
  set PHPBIN=%PHP_PEAR_PHP_BIN%
 
  :RUN
  "%PHPBIN%" "@bin_dir@\protoc-gen-php" %*
 
  #!/usr/bin/env php
  <?php
  // The MIT License
  //
  // Copyright (c) 2011 Iván -DrSlump- Montes
  //
  // Permission is hereby granted, free of charge, to any person obtaining a copy
  // of this software and associated documentation files (the "Software"), to deal
  // in the Software without restriction, including without limitation the rights
  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  // copies of the Software, and to permit persons to whom the Software is
  // furnished to do so, subject to the following conditions:
  //
  // The above copyright notice and this permission notice shall be included in
  // all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  // THE SOFTWARE.
 
  // Set up default timezone
  date_default_timezone_set('GMT');
 
  // For non pear packaged versions use relative include path
  if (strpos('@php_bin@', '@php_bin') === 0) {
  set_include_path(__DIR__ . DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR . get_include_path());
  }
 
  require_once 'DrSlump/Protobuf.php';
 
  // Setup autoloader
  \DrSlump\Protobuf::autoload();
 
  try {
  // Run the cli interface
  \DrSlump\Protobuf\Compiler\Cli::run(__FILE__);
  exit(0);
 
  } catch(Exception $e) {
  fputs(STDERR, (string)$e . PHP_EOL);
  exit(1);
  }
 
 Binary files /dev/null and b/lib/Protobuf-PHP/protoc.exe differ
  <?php
  include_once("library/DrSlump/Protobuf.php");
  include_once("library/DrSlump/Protobuf/Message.php");
  include_once("library/DrSlump/Protobuf/Registry.php");
  include_once("library/DrSlump/Protobuf/Descriptor.php");
  include_once("library/DrSlump/Protobuf/Field.php");
 
  include_once("gtfs-realtime.php");
  include_once("library/DrSlump/Protobuf/CodecInterface.php");
  include_once("library/DrSlump/Protobuf/Codec/PhpArray.php");
  include_once("library/DrSlump/Protobuf/Codec/Binary.php");
  include_once("library/DrSlump/Protobuf/Codec/Binary/Writer.php");
  include_once("library/DrSlump/Protobuf/Codec/Json.php");
  //print_r(get_declared_classes());
  $fm = new transit_realtime\FeedMessage();
  $fh = new transit_realtime\FeedHeader();
  $fh->setGtfsRealtimeVersion(1);
  $fh->setTimestamp(time());
  $fm->setHeader($fh);
  $fe = new transit_realtime\FeedEntity();
  $fe->setId("1234");
  $fe->setIsDeleted(false);
  $alert = new transit_realtime\Alert();
  $tr = new transit_realtime\TimeRange();
  $tr->setStart(000);
  $tr->setEnd(001);
  $alert-> addActivePeriod($tr);
  $es = new transit_realtime\EntitySelector();
  $es->setAgencyId("0");
  $es->setStopId("0");
  $es->setRouteId("0");
  $td = new transit_realtime\TripDescriptor();
  $td->setTripId("0");
  $es->setTrip($td);
  $alert-> addInformedEntity($es);
  $alert->setCause(constant("transit_realtime\Alert\Cause::"."UNKNOWN_CAUSE"));
  $alert->setEffect(constant("transit_realtime\Alert\Effect::"."UNKNOWN_EFFECT"));
  $tsUrl = new transit_realtime\TranslatedString();
  $tUrl = new transit_realtime\TranslatedString\Translation();
  $tUrl->setText("http");
  $tUrl->setLanguage("en");
  $tsUrl->addTranslation($tUrl);
  $alert->setUrl($tsUrl);
  $tsHeaderText= new transit_realtime\TranslatedString();
  $tHeaderText = new transit_realtime\TranslatedString\Translation();
  $tHeaderText->setText("http");
  $tHeaderText->setLanguage("en");
  $tsHeaderText->addTranslation($tHeaderText);
  $alert->setHeaderText($tsHeaderText);
  $tsDescriptionText= new transit_realtime\TranslatedString();
  $tDescriptionText = new transit_realtime\TranslatedString\Translation();
  $tDescriptionText->setText("http");
  $tDescriptionText->setLanguage("en");
  $tsDescriptionText->addTranslation($tDescriptionText);
  $alert->setDescriptionText($tsDescriptionText);
  $fe->setAlert($alert);
  $fm->addEntity($fe);
  //var_dump($fm);
 
  //$codec = new DrSlump\Protobuf\Codec\Binary();
  //echo $codec->encode($fm);
 
  //$codec = new DrSlump\Protobuf\Codec\Json();
  //echo $codec->encode($fm);
 
  $codec = new DrSlump\Protobuf\Codec\PhpArray();
  print_r($codec->encode($fm));
 
  ?>
  <?php
  include_once("library/DrSlump/Protobuf.php");
  include_once("library/DrSlump/Protobuf/Message.php");
  include_once("library/DrSlump/Protobuf/Registry.php");
  include_once("library/DrSlump/Protobuf/Descriptor.php");
  include_once("library/DrSlump/Protobuf/Field.php");
 
  include_once("gtfs-realtime.php");
  include_once("library/DrSlump/Protobuf/CodecInterface.php");
  include_once("library/DrSlump/Protobuf/Codec/PhpArray.php");
  include_once("library/DrSlump/Protobuf/Codec/Binary.php");
  include_once("library/DrSlump/Protobuf/Codec/Binary/Writer.php");
  include_once("library/DrSlump/Protobuf/Codec/Json.php");
  //print_r(get_declared_classes());
  $fm = new transit_realtime\FeedMessage();
  $fh = new transit_realtime\FeedHeader();
  $fh->setGtfsRealtimeVersion(1);
  $fh->setTimestamp(time());
  $fm->setHeader($fh);
  $fe = new transit_realtime\FeedEntity();
  $fe->setId("1234");
  $fe->setIsDeleted(false);
  $tu = new transit_realtime\TripUpdate();
  $td = new transit_realtime\TripDescriptor();
  $td->setRouteId("0");
  $tu->setTrip($td);
  $stu = new transit_realtime\TripUpdate\StopTimeUpdate();
  $stu->setStopId("1");
  $stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED);
  $tu->addStopTimeUpdate($stu);
  $fe->setTripUpdate($tu);
  $fm->addEntity($fe);
  //var_dump($fm);
 
  //$codec = new DrSlump\Protobuf\Codec\Binary();
  //echo $codec->encode($fm);
 
  //$codec = new DrSlump\Protobuf\Codec\Json();
  //echo $codec->encode($fm);
 
  $codec = new DrSlump\Protobuf\Codec\PhpArray();
  print_r($codec->encode($fm));
 
  ?>
  <?php
 
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  error_reporting(E_ALL);
 
  use \DrSlump\Protobuf;
 
  Protobuf::autoload();
 
  include_once __DIR__ . '/protos/simple.php';
  include_once __DIR__ . '/protos/repeated.php';
  include_once __DIR__ . '/protos/addressbook.php';
 
  describe "Binary Codec"
 
  before
 
  $codec = new Protobuf\Codec\Binary();
  Protobuf::setDefaultCodec($codec);
 
  $W->bin_simple = file_get_contents(__DIR__ . '/protos/simple.bin');
  $W->bin_book = file_get_contents(__DIR__ . '/protos/addressbook.bin');
  $W->bin_repeated_string = file_get_contents(__DIR__ . '/protos/repeated-string.bin');
  $W->bin_repeated_int32 = file_get_contents(__DIR__ . '/protos/repeated-int32.bin');
  $W->bin_repeated_nested = file_get_contents(__DIR__ . '/protos/repeated-nested.bin');
  end;
 
  describe "serialize"
 
  it "a simple message comparing types with protoc"
 
  $max = pow(2, 54)-1;
  $min = -$max;
 
  $fields = array(
  'double' => array(1, 0.1, 1.0, -1, -0.1, -100000, 123456789.12345, -123456789.12345),
  'float' => array(1, 0.1, 1.0, -1, -0.1, -100000, 12345.123, -12345.123),
  'int64' => array(0, 1, -1, 123456789123456789, -123456789123456789, $min),
  'uint64' => array(0, 1, 1000, 123456789123456789, PHP_INT_MAX, $max),
  'int32' => array(0, 1, -1, 123456789, -123456789),
  'fixed64' => array(0, 1, 1000, 123456789123456789),
  'fixed32' => array(0, 1, 1000, 123456789),
  'bool' => array(0, 1),
  'string' => array("", "foo"),
  'bytes' => array("", "foo"),
  'uint32' => array(0, 1, 1000, 123456789),
  'sfixed32' => array(0, 1, -1, 123456789, -123456789),
  'sfixed64' => array(0, 1, -1, 123456789123456789, -123456789123456789),
  'sint32' => array(0, 1, -1, 123456789, -123456789),
  'sint64' => array(0, 1, -1, 123456789123456789, -123456789123456789, $min, $max),
  );
 
 
  foreach ($fields as $field=>$values) {
  foreach ($values as $value) {
  $simple = new Tests\Simple();
  $simple->$field = $value;
  $bin = Protobuf::encode($simple);
 
  if (is_string($value)) $value = '"' . $value . '"';
 
  exec("echo '$field: $value' | protoc --encode=tests.Simple -Itests tests/protos/simple.proto", $out);
 
  $out = implode("\n", $out);
 
  $printValue = var_export($value, true);
  bin2hex($bin) should eq (bin2hex($out)) as "Encoding $field with value $printValue";
  }
  }
 
  foreach ($fields as $field=>$values) {
  foreach ($values as $value) {
  $cmdValue = is_string($value)
  ? '"' . $value . '"'
  : $value;
 
  exec("echo '$field: $cmdValue' | protoc --encode=tests.Simple -Itests tests/protos/simple.proto", $out);
  $out = implode("\n", $out);
 
  $simple = Protobuf::decode('\tests\Simple', $out);
 
  // Hack the comparison for float precision
  if (is_float($simple->$field)) {
  $precision = strlen($value) - strpos($value, '.');
  $simple->$field = round($simple->$field, $precision);
  }
 
  $printValue = var_export($value, true);
  $simple->$field should eq $value as "Decoding $field with value $printValue";
  }
  }
  end.
 
  it. "a message with repeated fields"
 
  $repeated = new Tests\Repeated();
  $repeated->addString('one');
  $repeated->addString('two');
  $repeated->addString('three');
  $bin = Protobuf::encode($repeated);
  $bin should be $W->bin_repeated_string;
 
  $repeated = new Tests\Repeated();
  $repeated->addInt(1);
  $repeated->addInt(2);
  $repeated->addInt(3);
  $bin = Protobuf::encode($repeated);
  $bin should be $W->bin_repeated_int32;
 
 
  $repeated = new Tests\Repeated();
  $nested = new Tests\Repeated\Nested();
  $nested->setId(1);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(2);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(3);
  $repeated->addNested($nested);
  $bin = Protobuf::encode($repeated);
  $bin should eq $W->bin_repeated_nested;
  end.
 
  it. "a complex message"
 
  $book = new Tests\AddressBook();
  $person = new Tests\Person();
  $person->name = 'John Doe';
  $person->id = 2051;
  $person->email = 'john.doe@gmail.com';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '1231231212';
  $phone->type = Tests\Person\PhoneType::HOME;
  $person->addPhone($phone);
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '55512321312';
  $phone->type = Tests\Person\PhoneType::MOBILE;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $person = new Tests\Person();
  $person->name = 'Iván Montes';
  $person->id = 23;
  $person->email = 'drslump@pollinimini.net';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '3493123123';
  $phone->type = Tests\Person\PhoneType::WORK;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $bin = Protobuf::encode($book);
  $bin should eq $W->bin_book but not be false;
 
  end.
 
  end;
 
  describe "unserialize"
 
  it "a simple message"
  $simple = Protobuf::decode('Tests\Simple', $W->bin_simple);
  $simple should be instanceof 'Tests\Simple';
  $simple->string should be 'foo';
  $simple->int32 should be -123456789;
  end.
 
  it "a message with repeated fields"
 
  $repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_string);
  $repeated should be instanceof 'Tests\Repeated';
  $repeated->getString() should eq array('one', 'two', 'three');
 
  $repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_int32);
  $repeated should be instanceof 'Tests\Repeated';
  $repeated->getInt() should eq array(1,2,3);
 
  $repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_nested);
  $repeated should be instanceof 'Tests\Repeated';
  foreach ($repeated->getNested() as $i=>$nested) {
  $nested->getId() should eq ($i+1);
  }
  end.
 
  it "a complex message"
  $complex = Protobuf::decode('Tests\AddressBook', $W->bin_book);
  count($complex->person) should eq 2;
  $complex->getPerson(0)->name should eq 'John Doe';
  $complex->getPerson(1)->name should eq 'Iván Montes';
  $complex->getPerson(0)->getPhone(1)->number should eq '55512321312';
  end.
 
  end;
 
  describe "multi codec"
 
  before
  $W->jsonCodec = new Protobuf\Codec\Json();
  end
 
  it "a simple message"
 
  $simple = Protobuf::decode('Tests\Simple', $W->bin_simple);
  $json = $W->jsonCodec->encode($simple);
  $simple = $W->jsonCodec->decode(new \Tests\Simple, $json);
  $bin = Protobuf::encode($simple);
  $bin should be $W->bin_simple;
 
  end.
 
  it "a message with repeated fields"
  $repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_nested);
  $json = $W->jsonCodec->encode($repeated);
  $repeated = $W->jsonCodec->decode(new \Tests\Repeated, $json);
  $bin = Protobuf::encode($repeated);
  $bin should be $W->bin_repeated_nested;
  end.
 
  end;
  end;
 
  <?php
 
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  use \DrSlump\Protobuf;
 
  Protobuf::autoload();
 
  include_once __DIR__ . '/protos/simple.php';
  include_once __DIR__ . '/protos/repeated.php';
  include_once __DIR__ . '/protos/addressbook.php';
 
  include_once __DIR__ . '/protos/Annotated/Simple.php';
  include_once __DIR__ . '/protos/Annotated/Repeated.php';
  include_once __DIR__ . '/protos/Annotated/Addressbook.php';
 
 
  describe "JSON Codec"
 
  before
  Protobuf::setDefaultCodec(new ProtoBuf\Codec\Json);
  end
 
  describe "serialize"
 
  it "a simple message"
  $simple = new Tests\Simple();
  $simple->string = 'FOO';
  $simple->int32 = 1000;
  $json = Protobuf::encode($simple);
  $json. should. eq. '{"int32":1000,"string":"FOO"}';
  end.
 
  it. "a message with repeated fields"
 
  $repeated = new \Tests\Repeated();
  $repeated->addString('one');
  $repeated->addString('two');
  $repeated->addString('three');
  $bin = Protobuf::encode($repeated);
  $bin should be '{"string":["one","two","three"]}';
 
  $repeated = new Tests\Repeated();
  $repeated->addInt(1);
  $repeated->addInt(2);
  $repeated->addInt(3);
  $bin = Protobuf::encode($repeated);
  $bin should be '{"int":[1,2,3]}';
 
  $repeated = new Tests\Repeated();
  $nested = new Tests\Repeated\Nested();
  $nested->setId(1);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(2);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(3);
  $repeated->addNested($nested);
  $json = Protobuf::encode($repeated);
  $json should eq '{"nested":[{"id":1},{"id":2},{"id":3}]}';
  end.
 
  it. "a complex message"
 
  $book = new Tests\AddressBook();
  $person = new Tests\Person();
  $person->name = 'John Doe';
  $person->id = 2051;
  $person->email = 'john.doe@gmail.com';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '1231231212';
  $phone->type = Tests\Person\PhoneType::HOME;
  $person->addPhone($phone);
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '55512321312';
  $phone->type = Tests\Person\PhoneType::MOBILE;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $person = new Tests\Person();
  $person->name = 'Iván Montes';
  $person->id = 23;
  $person->email = 'drslump@pollinimini.net';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '3493123123';
  $phone->type = Tests\Person\PhoneType::WORK;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $json = Protobuf::encode($book);
 
  $expected = '{
  "person":[
  {
  "name":"John Doe",
  "id":2051,
  "email":"john.doe@gmail.com",
  "phone":[
  {"number":"1231231212","type":1},
  {"number":"55512321312","type":0}
  ]
  },
  {
  "name":"Iv\u00e1n Montes",
  "id":23,
  "email":"drslump@pollinimini.net",
  "phone":[{"number":"3493123123","type":2}]
  }
  ]
  }';
 
  $expected = preg_replace('/\n\s*/', '', $expected);
 
  $json should be $expected;
  end.
 
  it "an annotated simple message"
  $simple = new tests\Annotated\Simple();
  $simple->foo = 'FOO';
  $simple->bar = 1000;
  $json = Protobuf::encode($simple);
  $json. should. eq. '{"foo":"FOO","bar":1000}';
  end.
 
  it "an annotated message with repeated fields"
  $repeated = new \Tests\Annotated\Repeated();
  $repeated->string = array('one', 'two', 'three');
  $bin = Protobuf::encode($repeated);
  $bin should be '{"string":["one","two","three"]}';
 
  $repeated = new Tests\Annotated\Repeated();
  $repeated->int = array(1,2,3);
  $bin = Protobuf::encode($repeated);
  $bin should be '{"int":[1,2,3]}';
 
  $repeated = new Tests\Annotated\Repeated();
  $repeated->nested = array();
  $nested = new Tests\Annotated\RepeatedNested();
  $nested->id = 1;
  $repeated->nested[] = $nested;
  $nested = new Tests\Annotated\RepeatedNested();
  $nested->id = 2;
  $repeated->nested[] = $nested;
  $nested = new Tests\Annotated\RepeatedNested();
  $nested->id = 3;
  $repeated->nested[] = $nested;
  $json = Protobuf::encode($repeated);
  $json should eq '{"nested":[{"id":1},{"id":2},{"id":3}]}';
  end.
  end;
 
  describe "unserialize"
 
  it "should unserialize a simple message"
  $json = '{"string":"FOO","int32":1000}';
  $simple = Protobuf::decode('Tests\Simple', $json);
  $simple should be instanceof 'Tests\Simple';
  $simple->string should equal 'FOO';
  $simple->int32 should equal 1000;
  end.
 
  it "a message with repeated fields"
 
  $json = '{"string":["one","two","three"]}';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated->getString() should eq array('one', 'two', 'three');
 
  $json = '{"int":[1,2,3]}';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated should be instanceof 'Tests\Repeated';
  $repeated->getInt() should eq array(1,2,3);
 
  $json = '{"nested":[{"id":1},{"id":2},{"id":3}]}';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated should be instanceof 'Tests\Repeated';
  foreach ($repeated->getNested() as $i=>$nested) {
  $nested->getId() should eq ($i+1);
  }
  end.
 
  it "a complex message"
  $json = '{
  "person":[
  {
  "name":"John Doe",
  "id":2051,
  "email":"john.doe@gmail.com",
  "phone":[
  {"number":"1231231212","type":1},
  {"number":"55512321312","type":0}
  ]
  },
  {
  "name":"Iv\u00e1n Montes",
  "id":23,
  "email":"drslump@pollinimini.net",
  "phone":[{"number":"3493123123","type":2}]
  }
  ]
  }';
 
  $json = preg_replace('/\n\s*/', '', $json);
 
  $complex = Protobuf::decode('Tests\AddressBook', $json);
  count($complex->person) should eq 2;
  $complex->getPerson(0)->name should eq 'John Doe';
  $complex->getPerson(1)->name should eq 'Iván Montes';
  $complex->getPerson(0)->getPhone(1)->number should eq '55512321312';
  end.
 
  end;
  end;
 
  <?php
 
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  use \DrSlump\Protobuf;
 
  Protobuf::autoload();
 
  include_once __DIR__ . '/protos/simple.php';
  include_once __DIR__ . '/protos/repeated.php';
  include_once __DIR__ . '/protos/addressbook.php';
 
  describe "JSON Indexed Codec"
 
  before
  Protobuf::setDefaultCodec(new Protobuf\Codec\JsonIndexed);
  end
 
  describe "serialize"
 
  it "should serialize a simple message"
  $simple = new Tests\Simple();
  $simple->string = 'FOO';
  $simple->int32 = 1000;
  $json = Protobuf::encode($simple);
  $json. should. eq. '["59",1000,"FOO"]';
  end.
 
  it. "a message with repeated fields"
 
  $repeated = new Tests\Repeated();
  $repeated->addString('one');
  $repeated->addString('two');
  $repeated->addString('three');
  $bin = Protobuf::encode($repeated);
  $bin should be '["1",["one","two","three"]]';
 
  $repeated = new Tests\Repeated();
  $repeated->addInt(1);
  $repeated->addInt(2);
  $repeated->addInt(3);
  $bin = Protobuf::encode($repeated);
  $bin should be '["2",[1,2,3]]';
 
  $repeated = new Tests\Repeated();
  $nested = new Tests\Repeated\Nested();
  $nested->setId(1);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(2);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(3);
  $repeated->addNested($nested);
  $json = Protobuf::encode($repeated);
  $json should eq '["3",[["1",1],["1",2],["1",3]]]';
  end.
 
  it. "a complex message"
 
  $book = new Tests\AddressBook();
  $person = new Tests\Person();
  $person->name = 'John Doe';
  $person->id = 2051;
  $person->email = 'john.doe@gmail.com';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '1231231212';
  $phone->type = Tests\Person\PhoneType::HOME;
  $person->addPhone($phone);
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '55512321312';
  $phone->type = Tests\Person\PhoneType::MOBILE;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $person = new Tests\Person();
  $person->name = 'Iván Montes';
  $person->id = 23;
  $person->email = 'drslump@pollinimini.net';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '3493123123';
  $phone->type = Tests\Person\PhoneType::WORK;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $json = Protobuf::encode($book);
 
  $expected = '[
  "1",
  [
  [
  "1234",
  "John Doe",
  2051,
  "john.doe@gmail.com",
  [
  ["12","1231231212",1],
  ["12","55512321312",0]
  ]
  ],
  [
  "1234",
  "Iv\u00e1n Montes",
  23,
  "drslump@pollinimini.net",
  [
  ["12","3493123123",2]
  ]
  ]
  ]
  ]';
 
  $expected = preg_replace('/\n\s*/', '', $expected);
 
  $json should be $expected;
  end.
  end;
 
  describe "unserialize"
 
  it "should unserialize a simple message"
  $json = '["59",1000,"FOO"]';
  $simple = Protobuf::decode('Tests\Simple', $json);
  $simple should be instanceof 'Tests\Simple';
  $simple->string should equal 'FOO';
  $simple->int32 should equal 1000;
  end.
 
  it "a message with repeated fields"
 
  $json = '["1",["one","two","three"]]';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated->getString() should eq array('one', 'two', 'three');
 
  $json = '["2",[1,2,3]]';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated should be instanceof 'Tests\Repeated';
  $repeated->getInt() should eq array(1,2,3);
 
  $json = '["3",[["1",1],["1",2],["1",3]]]';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated should be instanceof 'Tests\Repeated';
  foreach ($repeated->getNested() as $i=>$nested) {
  $nested->getId() should eq ($i+1);
  }
  end.
 
  it "a complex message"
  $json = '[
  "1",
  [
  [
  "1234",
  "John Doe",
  2051,
  "john.doe@gmail.com",
  [
  ["12","1231231212",1],
  ["12","55512321312",0]
  ]
  ],
  [
  "1234",
  "Iv\u00e1n Montes",
  23,
  "drslump@pollinimini.net",
  [
  ["12","3493123123",2]
  ]
  ]
  ]
  ]';
 
  $json = preg_replace('/\n\s*/', '', $json);
 
  $complex = Protobuf::decode('Tests\AddressBook', $json);
  count($complex->person) should eq 2;
  $complex->getPerson(0)->name should eq 'John Doe';
  $complex->getPerson(1)->name should eq 'Iván Montes';
  $complex->getPerson(0)->getPhone(1)->number should eq '55512321312';
  end.
 
 
 
  end;
  end;
 
  <?php
 
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  use \DrSlump\Protobuf;
 
  Protobuf::autoload();
 
  include_once __DIR__ . '/protos/simple.php';
  include_once __DIR__ . '/protos/repeated.php';
  include_once __DIR__ . '/protos/addressbook.php';
 
  describe "JSON TagMap Codec"
 
  before
  Protobuf::setDefaultCodec(new Protobuf\Codec\JsonTagMap);
  end
 
  describe "serialize"
 
  it "should serialize a simple message"
  $simple = new Tests\Simple();
  $simple->string = 'FOO';
  $simple->int32 = 1000;
  $json = Protobuf::encode($simple);
  $json. should. eq. '{"5":1000,"9":"FOO"}';
  end.
 
  it. "a message with repeated fields"
 
  $repeated = new Tests\Repeated();
  $repeated->addString('one');
  $repeated->addString('two');
  $repeated->addString('three');
  $bin = Protobuf::encode($repeated);
  $bin should be '{"1":["one","two","three"]}';
 
  $repeated = new Tests\Repeated();
  $repeated->addInt(1);
  $repeated->addInt(2);
  $repeated->addInt(3);
  $bin = Protobuf::encode($repeated);
  $bin should be '{"2":[1,2,3]}';
 
  $repeated = new Tests\Repeated();
  $nested = new Tests\Repeated\Nested();
  $nested->setId(1);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(2);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(3);
  $repeated->addNested($nested);
  $json = Protobuf::encode($repeated);
  $json should eq '{"3":[{"1":1},{"1":2},{"1":3}]}';
  end.
 
  it. "a complex message"
 
  $book = new Tests\AddressBook();
  $person = new Tests\Person();
  $person->name = 'John Doe';
  $person->id = 2051;
  $person->email = 'john.doe@gmail.com';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '1231231212';
  $phone->type = Tests\Person\PhoneType::HOME;
  $person->addPhone($phone);
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '55512321312';
  $phone->type = Tests\Person\PhoneType::MOBILE;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $person = new Tests\Person();
  $person->name = 'Iván Montes';
  $person->id = 23;
  $person->email = 'drslump@pollinimini.net';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '3493123123';
  $phone->type = Tests\Person\PhoneType::WORK;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $json = Protobuf::encode($book);
 
  $expected = '{
  "1":[
  {
  "1":"John Doe",
  "2":2051,
  "3":"john.doe@gmail.com",
  "4":[
  {"1":"1231231212","2":1},
  {"1":"55512321312","2":0}
  ]
  },
  {
  "1":"Iv\u00e1n Montes",
  "2":23,
  "3":"drslump@pollinimini.net",
  "4":[{"1":"3493123123","2":2}]
  }
  ]
  }';
 
  $expected = preg_replace('/\n\s*/', '', $expected);
 
  $json should be $expected;
  end.
  end;
 
  describe "unserialize"
 
  it "should unserialize a simple message"
  $json = '{"9":"FOO","5":1000}';
  $simple = Protobuf::decode('Tests\Simple', $json);
  $simple should be instanceof 'Tests\Simple';
  $simple->string should equal 'FOO';
  $simple->int32 should equal 1000;
  end.
 
  it "a message with repeated fields"
 
  $json = '{"1":["one","two","three"]}';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated->getString() should eq array('one', 'two', 'three');
 
  $json = '{"2":[1,2,3]}';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated should be instanceof 'Tests\Repeated';
  $repeated->getInt() should eq array(1,2,3);
 
  $json = '{"3":[{"1":1},{"1":2},{"1":3}]}';
  $repeated = Protobuf::decode('Tests\Repeated', $json);
  $repeated should be instanceof 'Tests\Repeated';
  foreach ($repeated->getNested() as $i=>$nested) {
  $nested->getId() should eq ($i+1);
  }
  end.
 
  it "a complex message"
  $json = '{
  "1":[
  {
  "1":"John Doe",
  "2":2051,
  "3":"john.doe@gmail.com",
  "4":[
  {"1":"1231231212","2":1},
  {"1":"55512321312","2":0}
  ]
  },
  {
  "1":"Iv\u00e1n Montes",
  "2":23,
  "3":"drslump@pollinimini.net",
  "4":[{"1":"3493123123","2":2}]
  }
  ]
  }';
 
  $json = preg_replace('/\n\s*/', '', $json);
 
  $complex = Protobuf::decode('Tests\AddressBook', $json);
  count($complex->person) should eq 2;
  $complex->getPerson(0)->name should eq 'John Doe';
  $complex->getPerson(1)->name should eq 'Iván Montes';
  $complex->getPerson(0)->getPhone(1)->number should eq '55512321312';
  end.
 
  end;
  end;
 
  <?php
 
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  use \DrSlump\Protobuf;
 
  Protobuf::autoload();
 
  include_once __DIR__ . '/protos/simple.php';
  include_once __DIR__ . '/protos/repeated.php';
  include_once __DIR__ . '/protos/addressbook.php';
 
  describe "TextFormat Codec"
 
  before
  Protobuf::setDefaultCodec(new ProtoBuf\Codec\TextFormat);
  end
 
  describe "serialize"
 
  it "should serialize a simple message"
  $simple = new Tests\Simple();
  $simple->string = 'FOO';
  $simple->int32 = 1000;
  $txt = Protobuf::encode($simple);
  $txt . should. be. "int32: 1000\nstring: \"FOO\"\n";
  end.
 
  it. "a message with repeated fields"
 
  $repeated = new \Tests\Repeated();
  $repeated->addString('one');
  $repeated->addString('two');
  $repeated->addString('three');
  $txt = Protobuf::encode($repeated);
  $txt should be "string: \"one\"\nstring: \"two\"\nstring: \"three\"\n";
 
  $repeated = new Tests\Repeated();
  $repeated->addInt(1);
  $repeated->addInt(2);
  $repeated->addInt(3);
  $txt = Protobuf::encode($repeated);
  $txt should be "int: 1\nint: 2\nint: 3\n";
 
  $repeated = new Tests\Repeated();
  $nested = new Tests\Repeated\Nested();
  $nested->setId(1);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(2);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(3);
  $repeated->addNested($nested);
  $txt = Protobuf::encode($repeated);
  $txt should eq "nested {\n id: 1\n}\nnested {\n id: 2\n}\nnested {\n id: 3\n}\n";
  end.
 
  it. "a complex message"
 
  $book = new Tests\AddressBook();
  $person = new Tests\Person();
  $person->name = 'John Doe';
  $person->id = 2051;
  $person->email = 'john.doe@gmail.com';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '1231231212';
  $phone->type = Tests\Person\PhoneType::HOME;
  $person->addPhone($phone);
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '55512321312';
  $phone->type = Tests\Person\PhoneType::MOBILE;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $person = new Tests\Person();
  $person->name = 'Iván Montes';
  $person->id = 23;
  $person->email = 'drslump@pollinimini.net';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '3493123123';
  $phone->type = Tests\Person\PhoneType::WORK;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $txt = Protobuf::encode($book);
  $txt = str_replace(' ', '', $txt);
  $txt = trim($txt);
 
  $expected = '
  person {
  name: "John Doe"
  id: 2051
  email: "john.doe@gmail.com"
  phone {
  number: "1231231212"
  type: 1
  }
  phone {
  number: "55512321312"
  type: 0
  }
  }
  person {
  name: "Iv\u00e1n Montes"
  id: 23
  email: "drslump@pollinimini.net"
  phone {
  number: "3493123123"
  type: 2
  }
  }
  ';
 
  $expected = str_replace(' ', '', $expected);
  $expected = trim($expected);
 
  $txt should be $expected;
  end.
  end;
 
  describe "unserialize"
 
  # throws \BadMethodCallException
  it "TextFormat does not implement decoding"
  $txt = "foo: \"FOO\"\nbar: \"BAR\"\n";
  $simple = Protobuf::decode('Tests\Simple', $txt);
  end.
  end;
  end;
 
  <?php
 
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  use \DrSlump\Protobuf;
 
  Protobuf::autoload();
 
  include_once __DIR__ . '/protos/simple.php';
  include_once __DIR__ . '/protos/repeated.php';
  include_once __DIR__ . '/protos/addressbook.php';
 
  describe "XML Codec"
 
  before
  Protobuf::setDefaultCodec(new ProtoBuf\Codec\Xml);
  end
 
  describe "serialize"
 
  it "a simple message"
  $simple = new Tests\Simple();
  $simple->string = 'FOO';
  $simple->int32 = 1000;
  $xml = Protobuf::encode($simple);
  $sxe = simplexml_load_string($xml);
  $sxe->string should eq "FOO";
  $sxe->int32 should eq 1000;
  end.
 
  it. "a message with repeated fields"
 
  $repeated = new \Tests\Repeated();
  $repeated->addString('one');
  $repeated->addString('two');
  $repeated->addString('three');
  $xml = Protobuf::encode($repeated);
  $xml = simplexml_load_string($xml);
  $xml->string[0] should eq 'one';
  $xml->string[1] should eq 'two';
  $xml->string[2] should eq 'three';
 
  $repeated = new Tests\Repeated();
  $repeated->addInt(1);
  $repeated->addInt(2);
  $repeated->addInt(3);
  $xml = Protobuf::encode($repeated);
  $xml = simplexml_load_string($xml);
  $xml->int[0] should eq 1;
  $xml->int[1] should eq 2;
  $xml->int[2] should eq 3;
 
  $repeated = new Tests\Repeated();
  $nested = new Tests\Repeated\Nested();
  $nested->setId(1);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(2);
  $repeated->addNested($nested);
  $nested = new Tests\Repeated\Nested();
  $nested->setId(3);
  $repeated->addNested($nested);
  $xml = Protobuf::encode($repeated);
  $xml = simplexml_load_string($xml);
  $xml->nested[0]->id should eq 1;
  $xml->nested[1]->id should eq 2;
  $xml->nested[2]->id should eq 3;
  end.
 
  it. "a complex message"
 
  $book = new Tests\AddressBook();
  $person = new Tests\Person();
  $person->name = 'John Doe';
  $person->id = 2051;
  $person->email = 'john.doe@gmail.com';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '1231231212';
  $phone->type = Tests\Person\PhoneType::HOME;
  $person->addPhone($phone);
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '55512321312';
  $phone->type = Tests\Person\PhoneType::MOBILE;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $person = new Tests\Person();
  $person->name = 'Iván Montes';
  $person->id = 23;
  $person->email = 'drslump@pollinimini.net';
  $phone = new Tests\Person\PhoneNumber;
  $phone->number = '3493123123';
  $phone->type = Tests\Person\PhoneType::WORK;
  $person->addPhone($phone);
  $book->addPerson($person);
 
  $xml = Protobuf::encode($book);
  $xml = simplexml_load_string($xml);
 
  $xml->person[0]->name should eq "John Doe";
  $xml->person[0]->phone[1]->number should eq "55512321312";
  $xml->person[1]->id should eq 23;
  $xml->person[1]->phone[0]->type should eq 2;
  end.
  end;
 
  describe "unserialize"
 
  it "should unserialize a simple message"
  $xml = new SimpleXmlElement('<root></root>');
  $xml->addChild('string', 'FOO');
  $xml->addChild('int32', 1000);
 
  $simple = Protobuf::decode('Tests\Simple', $xml);
  $simple should be instanceof 'Tests\Simple';
  $simple->string should equal 'FOO';
  $simple->int32 should equal 1000;
  end.
 
  it "a message with repeated fields"
 
  $xml = new SimpleXMLElement('<root></root>');
  $xml->addChild('string', 'one');
  $xml->addChild('string', 'two');
  $xml->addChild('string', 'three');
 
  $repeated = Protobuf::decode('Tests\Repeated', $xml);
  $repeated->getString() should eq array('one', 'two', 'three');
 
  $xml = new SimpleXMLElement('<root></root>');
  $xml->addChild('int', 1);
  $xml->addChild('int', 2);
  $xml->addChild('int', 3);
 
  $repeated = Protobuf::decode('Tests\Repeated', $xml);
  $repeated should be instanceof 'Tests\Repeated';
  $repeated->getInt() should eq array(1,2,3);
 
  $xml = new SimpleXMLElement('<root></root>');
  $xml->addChild('nested')->addChild('id', 1);
  $xml->addChild('nested')->addChild('id', 2);
  $xml->addChild('nested')->addChild('id', 3);
 
  $repeated = Protobuf::decode('Tests\Repeated', $xml);
  $repeated should be instanceof 'Tests\Repeated';
  foreach ($repeated->getNested() as $i=>$nested) {
  $nested->getId() should eq ($i+1);
  }
  end.
 
  it "a complex message"
 
  $xml = new SimpleXMLElement('<root></root>');
  $p = $xml->addChild('person');
  $p->addChild('name', 'John Doe');
  $p->addChild('id', 2051);
  $p->addChild('email', 'john.doe@gmail.com');
  $p = $p->addChild('phone');
  $p->addChild('number', '1231231212');
  $p->addChild('type', 1);
  $p = $xml->addChild('person');
  $p->addChild('name', 'Iván Montes');
  $p->addChild('id', 23);
  $p->addChild('email', 'drslump@pollinimini.net');
  $p = $p->addChild('phone');
  $p->addChild('number', '3493123123');
  $p->addChild('type', 2);
 
  $complex = Protobuf::decode('Tests\AddressBook', $xml->asXML());
  count($complex->person) should eq 2;
  $complex->getPerson(0)->name should eq 'John Doe';
  $complex->getPerson(1)->name should eq 'Iván Montes';
  $complex->getPerson(1)->getPhone(0)->number should eq '3493123123';
  end.
 
  end;
  end;
 
  <?php
 
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  use DrSlump\Protobuf;
 
  describe 'Protobuf'
 
  //before
  Protobuf::autoload();
  //end
 
  it 'should autoload classes'
  new Protobuf\Codec\Binary();
  end.
 
  describe 'codecs registry'
  it 'should get a default codec if none set'
  $codec = Protobuf::getCodec();
  $codec should be an instance of '\DrSlump\Protobuf\CodecInterface';
  end.
 
  it 'should return the passed codec instance'
  $passed = new Protobuf\Codec\Binary();
  $getted = Protobuf::getCodec($passed);
  $getted should be $passed
  end.
 
  it. 'should register a new codec'
  $setted = new Protobuf\Codec\Binary();
  Protobuf::registerCodec('test', $setted);
  $getted = Protobuf::getCodec('test');
  $getted should be $setted
  end.
 
  it 'should register a new default codec'
  $setted = new Protobuf\Codec\Binary();
  Protobuf::setDefaultCodec($setted);
  Protobuf::getCodec() should be $setted
  end.
 
  # throws DrSlump\Protobuf\Exception
  it. 'should unregister a codec'
  $setted = new Protobuf\Codec\Binary();
  Protobuf::registerCodec('test', $setted);
  $result = Protobuf::unregisterCodec('test');
  $result should be true;
  // If not set throws an exception
  Protobuf::getCodec('test');
  end.
 
  it. 'should unregister the default codec'
  $result = Protobuf::unregisterCodec('default');
  $result should be true;
  // Ensure a new default is given
  $getted = Protobuf::getCodec();
  $getted should be instanceof 'DrSlump\Protobuf\Codec\Binary'
  end.
  end;
  end;
 
 
 
 
 
  <?php
 
  require_once 'Benchmark/Profiler.php';
  require_once __DIR__ . '/../library/DrSlump/Protobuf.php';
 
  use \DrSlump\Protobuf;
 
  Protobuf::autoload();
 
  include_once __DIR__ . '/protos/simple.php';
  include_once __DIR__ . '/protos/addressbook.php';
 
 
  class Benchmark {
 
  protected $tests = array(
  'DecodeBinarySimple',
  'DecodeJsonSimple',
  );
 
  public function run($iterations = 1000)
  {
  $profiler = new Benchmark_Profiler(true);
  foreach ($this->tests as $test) {
  $method = 'config' . $test;
  $args = $this->$method();
 
  $method = 'run' . $test;
  $profiler->enterSection($test);
  for ($i=0; $i<$iterations; $i++) {
  call_user_func_array(array($this, $method), $args);
  }
  $profiler->leaveSection($test);
  }
 
  $profiler->stop();
  $profiler->display();
  }
 
  protected function configDecodeBinarySimple()
  {
  return array(
  new Protobuf\Codec\Binary(),
  file_get_contents(__DIR__ . '/protos/simple.bin')
  );
  }
 
  protected function runDecodeBinarySimple($codec, $data)
  {
  $codec->decode(new tests\Simple(), $data);
  }
 
  protected function configDecodeJsonSimple()
  {
  $codecBin = new Protobuf\Codec\Binary();
  $codecJson = new Protobuf\Codec\Json();
 
  $bin = $this->configDecodeBinarySimple();
  $simple = $codecBin->decode(new tests\Simple(), $bin[1]);
  $data = $codecJson->encode($simple);
  return array($codecJson, $data);
  }
 
  protected function runDecodeJsonSimple($codec, $data)
  {
  $codec->decode(new tests\Simple(), $data);
  }
  }
 
 
  $bench = new Benchmark();
  $bench->run(1000);
 
 
  <?php
  /**
  * Created by IntelliJ IDEA.
  * User: drslump
  * Date: 6/27/11
  * Time: 12:48 AM
  * To change this template use File | Settings | File Templates.
  */
 
 
  <?php
 
  namespace Tests\Annotated;
 
  class Repeated extends \DrSlump\Protobuf\AnnotatedMessage
  {
  /** @protobuf(tag=1, type=string, repeated) */
  public $string;
  /** @protobuf(tag=2, type=int32, repeated) */
  public $int;
  /** @protobuf(tag=3, type=message, reference=tests\Annotated\RepeatedNested, repeated) */
  public $nested;
  }
 
  class RepeatedNested extends \DrSlump\Protobuf\AnnotatedMessage
  {
  /** @protobuf(tag=1, type=int32) */
  public $id;
  }
 
  <?php
 
  namespace Tests\Annotated;
 
  class Simple extends \DrSlump\Protobuf\AnnotatedMessage
  {
  /** @protobuf(tag=1, type=string, required) */
  public $foo;
  /** @protobuf(tag=2, type=int32, required) */
  public $bar;
  /** @protobuf(tag=3, type=string, optional) */
  public $baz;
  }
 
 Binary files /dev/null and b/lib/Protobuf-PHP/tests/protos/addressbook.bin differ
  <?php
  // DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@
  // Source: addressbook.proto
  // Date: 2011-04-13 17:07:17
 
  namespace tests {
 
  class Person extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Person');
 
  // required name = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "name";
  $f->type = 9;
  $f->rule = 2;
  $descriptor->addField($f);
 
  // required id = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "id";
  $f->type = 5;
  $f->rule = 2;
  $descriptor->addField($f);
 
  // optional email = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "email";
  $f->type = 9;
  $f->rule = 1;
  $descriptor->addField($f);
 
  // repeated .tests.Person.PhoneNumber phone = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "phone";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\tests\Person\PhoneNumber';
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  return $descriptor;
  }
 
  /** @var string */
  public $name = null;
 
  /** @var int */
  public $id = null;
 
  /** @var string */
  public $email = null;
 
  /** @var \tests\Person\PhoneNumber[] */
  public $phone = array();
 
 
  /**
  * Check if <name> has a value
  *
  * @return boolean
  */
  public function hasName(){
  return $this->_has(1);
  }
 
  /**
  * Clear <name> value
  *
  * @return \tests\Person
  */
  public function clearName(){
  return $this->_clear(1);
  }
 
  /**
  * Get <name> value
  *
  * @return string
  */
  public function getName(){
  return $this->_get(1);
  }
 
  /**
  * Set <name> value
  *
  * @param string $value
  * @return \tests\Person
  */
  public function setName( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <id> has a value
  *
  * @return boolean
  */
  public function hasId(){
  return $this->_has(2);
  }
 
  /**
  * Clear <id> value
  *
  * @return \tests\Person
  */
  public function clearId(){
  return $this->_clear(2);
  }
 
  /**
  * Get <id> value
  *
  * @return int
  */
  public function getId(){
  return $this->_get(2);
  }
 
  /**
  * Set <id> value
  *
  * @param int $value
  * @return \tests\Person
  */
  public function setId( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <email> has a value
  *
  * @return boolean
  */
  public function hasEmail(){
  return $this->_has(3);
  }
 
  /**
  * Clear <email> value
  *
  * @return \tests\Person
  */
  public function clearEmail(){
  return $this->_clear(3);
  }
 
  /**
  * Get <email> value
  *
  * @return string
  */
  public function getEmail(){
  return $this->_get(3);
  }
 
  /**
  * Set <email> value
  *
  * @param string $value
  * @return \tests\Person
  */
  public function setEmail( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <phone> has a value
  *
  * @return boolean
  */
  public function hasPhone(){
  return $this->_has(4);
  }
 
  /**
  * Clear <phone> value
  *
  * @return \tests\Person
  */
  public function clearPhone(){
  return $this->_clear(4);
  }
 
  /**
  * Get <phone> value
  *
  * @param int $idx
  * @return \tests\Person\PhoneNumber
  */
  public function getPhone($idx = NULL){
  return $this->_get(4, $idx);
  }
 
  /**
  * Set <phone> value
  *
  * @param \tests\Person\PhoneNumber $value
  * @return \tests\Person
  */
  public function setPhone(\tests\Person\PhoneNumber $value, $idx = NULL){
  return $this->_set(4, $value, $idx);
  }
 
  /**
  * Get all elements of <phone>
  *
  * @return \tests\Person\PhoneNumber[]
  */
  public function getPhoneList(){
  return $this->_get(4);
  }
 
  /**
  * Add a new element to <phone>
  *
  * @param \tests\Person\PhoneNumber $value
  * @return \tests\Person
  */
  public function addPhone(\tests\Person\PhoneNumber $value){
  return $this->_add(4, $value);
  }
 
  }
  }
 
  namespace tests\Person {
 
  class PhoneType {
  const MOBILE = 0;
  const HOME = 1;
  const WORK = 2;
  }
  }
 
  namespace tests\Person {
 
  class PhoneNumber extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Person\PhoneNumber');
 
  // required number = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "number";
  $f->type = 9;
  $f->rule = 2;
  $descriptor->addField($f);
 
  // optional .tests.Person.PhoneType type = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "type";
  $f->type = 14;
  $f->rule = 1;
  $f->reference = '\tests\Person\PhoneType';
  $f->default = \tests\Person\PhoneType::HOME;
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  return $descriptor;
  }
 
  /** @var string */
  public $number = null;
 
  /** @var int - \tests\Person\PhoneType */
  public $type = \tests\Person\PhoneType::HOME;
 
 
  /**
  * Check if <number> has a value
  *
  * @return boolean
  */
  public function hasNumber(){
  return $this->_has(1);
  }
 
  /**
  * Clear <number> value
  *
  * @return \tests\Person\PhoneNumber
  */
  public function clearNumber(){
  return $this->_clear(1);
  }
 
  /**
  * Get <number> value
  *
  * @return string
  */
  public function getNumber(){
  return $this->_get(1);
  }
 
  /**
  * Set <number> value
  *
  * @param string $value
  * @return \tests\Person\PhoneNumber
  */
  public function setNumber( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <type> has a value
  *
  * @return boolean
  */
  public function hasType(){
  return $this->_has(2);
  }
 
  /**
  * Clear <type> value
  *
  * @return \tests\Person\PhoneNumber
  */
  public function clearType(){
  return $this->_clear(2);
  }
 
  /**
  * Get <type> value
  *
  * @return int - \tests\Person\PhoneType
  */
  public function getType(){
  return $this->_get(2);
  }
 
  /**
  * Set <type> value
  *
  * @param int - \tests\Person\PhoneType $value
  * @return \tests\Person\PhoneNumber
  */
  public function setType( $value){
  return $this->_set(2, $value);
  }
 
  }
  }
 
  namespace tests {
 
  class AddressBook extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor('\tests\AddressBook');
 
  // repeated .tests.Person person = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "person";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\tests\Person';
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  return $descriptor;
  }
 
  /** @var \tests\Person[] */
  public $person = array();
 
 
  /**
  * Check if <person> has a value
  *
  * @return boolean
  */
  public function hasPerson(){
  return $this->_has(1);
  }
 
  /**
  * Clear <person> value
  *
  * @return \tests\AddressBook
  */
  public function clearPerson(){
  return $this->_clear(1);
  }
 
  /**
  * Get <person> value
  *
  * @param int $idx
  * @return \tests\Person
  */
  public function getPerson($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <person> value
  *
  * @param \tests\Person $value
  * @return \tests\AddressBook
  */
  public function setPerson(\tests\Person $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <person>
  *
  * @return \tests\Person[]
  */
  public function getPersonList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <person>
  *
  * @param \tests\Person $value
  * @return \tests\AddressBook
  */
  public function addPerson(\tests\Person $value){
  return $this->_add(1, $value);
  }
 
  }
  }
 
  import "php.proto";
 
  package tests;
 
  //option (php.namespace) = "Example";
  //option (php.multifile) = true;
 
  /**
  * Defines a Person in the addressbook
  */
  message Person {
  /* The full name of the person */
  required string name = 1;
  /* The person Id in the database */
  required int32 id = 2;
  /* The person email */
  optional string email = 3;
 
  /* Different types of phones */
  enum PhoneType {
  MOBILE = 0;
  HOME = 1;
  WORK = 2;
  }
 
  /*
  A phone number record
  */
  message PhoneNumber {
  required string number = 1;
  optional PhoneType type = 2 [default = HOME];
  }
 
  /* The different phone numbers associated to a person */
  repeated PhoneNumber phone = 4;
  }
 
  /* A collection of persons contact details */
  message AddressBook {
  repeated Person person = 1;
 
  extensions 1000 to max;
  }
 
  person {
  name: "John Doe"
  id: 2051
  email: "john.doe@gmail.com"
  phone {
  number: "1231231212"
  type: HOME
  }
  phone {
  number: "55512321312"
  type: MOBILE
  }
  }
  person {
  name: "Iván Montes"
  id: 23
  email: "drslump@pollinimini.net"
  phone {
  number: "3493123123"
  type: WORK
  }
  }
 
  int: 1
  int: 2
  int: 3
 
  nested {
  id: 1
  }
  nested {
  id: 2
  }
  nested {
  id: 3
  }
 
 
  one
  two
  three
  string: "one"
  string: "two"
  string: "three"
 
  <?php
  // DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@
  // Source: repeated.proto
  // Date: 2011-04-12 14:07:42
 
  namespace tests {
 
  class Repeated extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Repeated');
 
  // repeated string = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "string";
  $f->type = 9;
  $f->rule = 3;
  $descriptor->addField($f);
 
  // repeated int = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "int";
  $f->type = 5;
  $f->rule = 3;
  $descriptor->addField($f);
 
  // repeated .tests.Repeated.Nested nested = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "nested";
  $f->type = 11;
  $f->rule = 3;
  $f->reference = '\tests\Repeated\Nested';
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  return $descriptor;
  }
 
  /** @var string[] */
  public $string = array();
 
  /** @var int[] */
  public $int = array();
 
  /** @var \tests\Repeated\Nested[] */
  public $nested = array();
 
 
  /**
  * Check if <string> has a value
  *
  * @return boolean
  */
  public function hasString(){
  return $this->_has(1);
  }
 
  /**
  * Clear <string> value
  *
  * @return \tests\Repeated
  */
  public function clearString(){
  return $this->_clear(1);
  }
 
  /**
  * Get <string> value
  *
  * @param int $idx
  * @return string
  */
  public function getString($idx = NULL){
  return $this->_get(1, $idx);
  }
 
  /**
  * Set <string> value
  *
  * @param string $value
  * @return \tests\Repeated
  */
  public function setString( $value, $idx = NULL){
  return $this->_set(1, $value, $idx);
  }
 
  /**
  * Get all elements of <string>
  *
  * @return string[]
  */
  public function getStringList(){
  return $this->_get(1);
  }
 
  /**
  * Add a new element to <string>
  *
  * @param string $value
  * @return \tests\Repeated
  */
  public function addString( $value){
  return $this->_add(1, $value);
  }
 
  /**
  * Check if <int> has a value
  *
  * @return boolean
  */
  public function hasInt(){
  return $this->_has(2);
  }
 
  /**
  * Clear <int> value
  *
  * @return \tests\Repeated
  */
  public function clearInt(){
  return $this->_clear(2);
  }
 
  /**
  * Get <int> value
  *
  * @param int $idx
  * @return int
  */
  public function getInt($idx = NULL){
  return $this->_get(2, $idx);
  }
 
  /**
  * Set <int> value
  *
  * @param int $value
  * @return \tests\Repeated
  */
  public function setInt( $value, $idx = NULL){
  return $this->_set(2, $value, $idx);
  }
 
  /**
  * Get all elements of <int>
  *
  * @return int[]
  */
  public function getIntList(){
  return $this->_get(2);
  }
 
  /**
  * Add a new element to <int>
  *
  * @param int $value
  * @return \tests\Repeated
  */
  public function addInt( $value){
  return $this->_add(2, $value);
  }
 
  /**
  * Check if <nested> has a value
  *
  * @return boolean
  */
  public function hasNested(){
  return $this->_has(3);
  }
 
  /**
  * Clear <nested> value
  *
  * @return \tests\Repeated
  */
  public function clearNested(){
  return $this->_clear(3);
  }
 
  /**
  * Get <nested> value
  *
  * @param int $idx
  * @return \tests\Repeated\Nested
  */
  public function getNested($idx = NULL){
  return $this->_get(3, $idx);
  }
 
  /**
  * Set <nested> value
  *
  * @param \tests\Repeated\Nested $value
  * @return \tests\Repeated
  */
  public function setNested(\tests\Repeated\Nested $value, $idx = NULL){
  return $this->_set(3, $value, $idx);
  }
 
  /**
  * Get all elements of <nested>
  *
  * @return \tests\Repeated\Nested[]
  */
  public function getNestedList(){
  return $this->_get(3);
  }
 
  /**
  * Add a new element to <nested>
  *
  * @param \tests\Repeated\Nested $value
  * @return \tests\Repeated
  */
  public function addNested(\tests\Repeated\Nested $value){
  return $this->_add(3, $value);
  }
 
  }
  }
 
  namespace tests\Repeated {
 
  class Nested extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL)
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Repeated\Nested');
 
  // optional id = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "id";
  $f->type = 5;
  $f->rule = 1;
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  return $descriptor;
  }
 
  /** @var int */
  public $id = null;
 
 
  /**
  * Check if <id> has a value
  *
  * @return boolean
  */
  public function hasId(){
  return $this->_has(1);
  }
 
  /**
  * Clear <id> value
  *
  * @return \tests\Repeated\Nested
  */
  public function clearId(){
  return $this->_clear(1);
  }
 
  /**
  * Get <id> value
  *
  * @return int
  */
  public function getId(){
  return $this->_get(1);
  }
 
  /**
  * Set <id> value
  *
  * @param int $value
  * @return \tests\Repeated\Nested
  */
  public function setId( $value){
  return $this->_set(1, $value);
  }
 
  }
  }
 
  package tests;
 
  message Repeated {
 
  message Nested {
  optional int32 id = 1;
  }
 
  repeated string string = 1;
  repeated int32 int = 2;
  repeated Nested nested = 3;
  }
 
  <?php
  // DO NOT EDIT! Generated by Protobuf-PHP protoc plugin @package_version@
  // Source: simple.proto
  // Date: 2011-07-10 10:05:44
 
  // @@protoc_insertion_point(scope_file)
 
  namespace tests {
 
  // @@protoc_insertion_point(scope_namespace)
  // @@protoc_insertion_point(namespace_tests)
 
  class Simple extends \DrSlump\Protobuf\Message {
 
  /** @var \Closure[] */
  protected static $__extensions = array();
 
  public static function descriptor()
  {
  $descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Simple');
 
  // optional double = 1
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 1;
  $f->name = "double";
  $f->type = 1;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:double)
  $descriptor->addField($f);
 
  // optional float = 2
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 2;
  $f->name = "float";
  $f->type = 2;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:float)
  $descriptor->addField($f);
 
  // optional int64 = 3
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 3;
  $f->name = "int64";
  $f->type = 3;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:int64)
  $descriptor->addField($f);
 
  // optional uint64 = 4
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 4;
  $f->name = "uint64";
  $f->type = 4;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:uint64)
  $descriptor->addField($f);
 
  // optional int32 = 5
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 5;
  $f->name = "int32";
  $f->type = 5;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:int32)
  $descriptor->addField($f);
 
  // optional fixed64 = 6
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 6;
  $f->name = "fixed64";
  $f->type = 6;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:fixed64)
  $descriptor->addField($f);
 
  // optional fixed32 = 7
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 7;
  $f->name = "fixed32";
  $f->type = 7;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:fixed32)
  $descriptor->addField($f);
 
  // optional bool = 8
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 8;
  $f->name = "bool";
  $f->type = 8;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:bool)
  $descriptor->addField($f);
 
  // optional string = 9
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 9;
  $f->name = "string";
  $f->type = 9;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:string)
  $descriptor->addField($f);
 
  // optional bytes = 12
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 12;
  $f->name = "bytes";
  $f->type = 12;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:bytes)
  $descriptor->addField($f);
 
  // optional uint32 = 13
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 13;
  $f->name = "uint32";
  $f->type = 13;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:uint32)
  $descriptor->addField($f);
 
  // optional sfixed32 = 15
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 15;
  $f->name = "sfixed32";
  $f->type = 15;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:sfixed32)
  $descriptor->addField($f);
 
  // optional sfixed64 = 16
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 16;
  $f->name = "sfixed64";
  $f->type = 16;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:sfixed64)
  $descriptor->addField($f);
 
  // optional sint32 = 17
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 17;
  $f->name = "sint32";
  $f->type = 17;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:sint32)
  $descriptor->addField($f);
 
  // optional sint64 = 18
  $f = new \DrSlump\Protobuf\Field();
  $f->number = 18;
  $f->name = "sint64";
  $f->type = 18;
  $f->rule = 1;
  // @@protoc_insertion_point(scope_field)
  // @@protoc_insertion_point(field_tests.Simple:sint64)
  $descriptor->addField($f);
 
  foreach (self::$__extensions as $cb) {
  $descriptor->addField($cb(), true);
  }
 
  // @@protoc_insertion_point(scope_descriptor)
  // @@protoc_insertion_point(descriptor_tests.Simple)
 
  return $descriptor;
  }
 
  /** @var float */
  public $double = null;
 
  /** @var float */
  public $float = null;
 
  /** @var int */
  public $int64 = null;
 
  /** @var int */
  public $uint64 = null;
 
  /** @var int */
  public $int32 = null;
 
  /** @var int */
  public $fixed64 = null;
 
  /** @var int */
  public $fixed32 = null;
 
  /** @var boolean */
  public $bool = null;
 
  /** @var string */
  public $string = null;
 
  /** @var string */
  public $bytes = null;
 
  /** @var int */
  public $uint32 = null;
 
  /** @var int */
  public $sfixed32 = null;
 
  /** @var int */
  public $sfixed64 = null;
 
  /** @var int */
  public $sint32 = null;
 
  /** @var int */
  public $sint64 = null;
 
 
  /**
  * Check if <double> has a value
  *
  * @return boolean
  */
  public function hasDouble(){
  return $this->_has(1);
  }
 
  /**
  * Clear <double> value
  *
  * @return \tests\Simple
  */
  public function clearDouble(){
  return $this->_clear(1);
  }
 
  /**
  * Get <double> value
  *
  * @return float
  */
  public function getDouble(){
  return $this->_get(1);
  }
 
  /**
  * Set <double> value
  *
  * @param float $value
  * @return \tests\Simple
  */
  public function setDouble( $value){
  return $this->_set(1, $value);
  }
 
  /**
  * Check if <float> has a value
  *
  * @return boolean
  */
  public function hasFloat(){
  return $this->_has(2);
  }
 
  /**
  * Clear <float> value
  *
  * @return \tests\Simple
  */
  public function clearFloat(){
  return $this->_clear(2);
  }
 
  /**
  * Get <float> value
  *
  * @return float
  */
  public function getFloat(){
  return $this->_get(2);
  }
 
  /**
  * Set <float> value
  *
  * @param float $value
  * @return \tests\Simple
  */
  public function setFloat( $value){
  return $this->_set(2, $value);
  }
 
  /**
  * Check if <int64> has a value
  *
  * @return boolean
  */
  public function hasInt64(){
  return $this->_has(3);
  }
 
  /**
  * Clear <int64> value
  *
  * @return \tests\Simple
  */
  public function clearInt64(){
  return $this->_clear(3);
  }
 
  /**
  * Get <int64> value
  *
  * @return int
  */
  public function getInt64(){
  return $this->_get(3);
  }
 
  /**
  * Set <int64> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setInt64( $value){
  return $this->_set(3, $value);
  }
 
  /**
  * Check if <uint64> has a value
  *
  * @return boolean
  */
  public function hasUint64(){
  return $this->_has(4);
  }
 
  /**
  * Clear <uint64> value
  *
  * @return \tests\Simple
  */
  public function clearUint64(){
  return $this->_clear(4);
  }
 
  /**
  * Get <uint64> value
  *
  * @return int
  */
  public function getUint64(){
  return $this->_get(4);
  }
 
  /**
  * Set <uint64> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setUint64( $value){
  return $this->_set(4, $value);
  }
 
  /**
  * Check if <int32> has a value
  *
  * @return boolean
  */
  public function hasInt32(){
  return $this->_has(5);
  }
 
  /**
  * Clear <int32> value
  *
  * @return \tests\Simple
  */
  public function clearInt32(){
  return $this->_clear(5);
  }
 
  /**
  * Get <int32> value
  *
  * @return int
  */
  public function getInt32(){
  return $this->_get(5);
  }
 
  /**
  * Set <int32> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setInt32( $value){
  return $this->_set(5, $value);
  }
 
  /**
  * Check if <fixed64> has a value
  *
  * @return boolean
  */
  public function hasFixed64(){
  return $this->_has(6);
  }
 
  /**
  * Clear <fixed64> value
  *
  * @return \tests\Simple
  */
  public function clearFixed64(){
  return $this->_clear(6);
  }
 
  /**
  * Get <fixed64> value
  *
  * @return int
  */
  public function getFixed64(){
  return $this->_get(6);
  }
 
  /**
  * Set <fixed64> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setFixed64( $value){
  return $this->_set(6, $value);
  }
 
  /**
  * Check if <fixed32> has a value
  *
  * @return boolean
  */
  public function hasFixed32(){
  return $this->_has(7);
  }
 
  /**
  * Clear <fixed32> value
  *
  * @return \tests\Simple
  */
  public function clearFixed32(){
  return $this->_clear(7);
  }
 
  /**
  * Get <fixed32> value
  *
  * @return int
  */
  public function getFixed32(){
  return $this->_get(7);
  }
 
  /**
  * Set <fixed32> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setFixed32( $value){
  return $this->_set(7, $value);
  }
 
  /**
  * Check if <bool> has a value
  *
  * @return boolean
  */
  public function hasBool(){
  return $this->_has(8);
  }
 
  /**
  * Clear <bool> value
  *
  * @return \tests\Simple
  */
  public function clearBool(){
  return $this->_clear(8);
  }
 
  /**
  * Get <bool> value
  *
  * @return boolean
  */
  public function getBool(){
  return $this->_get(8);
  }
 
  /**
  * Set <bool> value
  *
  * @param boolean $value
  * @return \tests\Simple
  */
  public function setBool( $value){
  return $this->_set(8, $value);
  }
 
  /**
  * Check if <string> has a value
  *
  * @return boolean
  */
  public function hasString(){
  return $this->_has(9);
  }
 
  /**
  * Clear <string> value
  *
  * @return \tests\Simple
  */
  public function clearString(){
  return $this->_clear(9);
  }
 
  /**
  * Get <string> value
  *
  * @return string
  */
  public function getString(){
  return $this->_get(9);
  }
 
  /**
  * Set <string> value
  *
  * @param string $value
  * @return \tests\Simple
  */
  public function setString( $value){
  return $this->_set(9, $value);
  }
 
  /**
  * Check if <bytes> has a value
  *
  * @return boolean
  */
  public function hasBytes(){
  return $this->_has(12);
  }
 
  /**
  * Clear <bytes> value
  *
  * @return \tests\Simple
  */
  public function clearBytes(){
  return $this->_clear(12);
  }
 
  /**
  * Get <bytes> value
  *
  * @return string
  */
  public function getBytes(){
  return $this->_get(12);
  }
 
  /**
  * Set <bytes> value
  *
  * @param string $value
  * @return \tests\Simple
  */
  public function setBytes( $value){
  return $this->_set(12, $value);
  }
 
  /**
  * Check if <uint32> has a value
  *
  * @return boolean
  */
  public function hasUint32(){
  return $this->_has(13);
  }
 
  /**
  * Clear <uint32> value
  *
  * @return \tests\Simple
  */
  public function clearUint32(){
  return $this->_clear(13);
  }
 
  /**
  * Get <uint32> value
  *
  * @return int
  */
  public function getUint32(){
  return $this->_get(13);
  }
 
  /**
  * Set <uint32> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setUint32( $value){
  return $this->_set(13, $value);
  }
 
  /**
  * Check if <sfixed32> has a value
  *
  * @return boolean
  */
  public function hasSfixed32(){
  return $this->_has(15);
  }
 
  /**
  * Clear <sfixed32> value
  *
  * @return \tests\Simple
  */
  public function clearSfixed32(){
  return $this->_clear(15);
  }
 
  /**
  * Get <sfixed32> value
  *
  * @return int
  */
  public function getSfixed32(){
  return $this->_get(15);
  }
 
  /**
  * Set <sfixed32> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setSfixed32( $value){
  return $this->_set(15, $value);
  }
 
  /**
  * Check if <sfixed64> has a value
  *
  * @return boolean
  */
  public function hasSfixed64(){
  return $this->_has(16);
  }
 
  /**
  * Clear <sfixed64> value
  *
  * @return \tests\Simple
  */
  public function clearSfixed64(){
  return $this->_clear(16);
  }
 
  /**
  * Get <sfixed64> value
  *
  * @return int
  */
  public function getSfixed64(){
  return $this->_get(16);
  }
 
  /**
  * Set <sfixed64> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setSfixed64( $value){
  return $this->_set(16, $value);
  }
 
  /**
  * Check if <sint32> has a value
  *
  * @return boolean
  */
  public function hasSint32(){
  return $this->_has(17);
  }
 
  /**
  * Clear <sint32> value
  *
  * @return \tests\Simple
  */
  public function clearSint32(){
  return $this->_clear(17);
  }
 
  /**
  * Get <sint32> value
  *
  * @return int
  */
  public function getSint32(){
  return $this->_get(17);
  }
 
  /**
  * Set <sint32> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setSint32( $value){
  return $this->_set(17, $value);
  }
 
  /**
  * Check if <sint64> has a value
  *
  * @return boolean
  */
  public function hasSint64(){
  return $this->_has(18);
  }
 
  /**
  * Clear <sint64> value
  *
  * @return \tests\Simple
  */
  public function clearSint64(){
  return $this->_clear(18);
  }
 
  /**
  * Get <sint64> value
  *
  * @return int
  */
  public function getSint64(){
  return $this->_get(18);
  }
 
  /**
  * Set <sint64> value
  *
  * @param int $value
  * @return \tests\Simple
  */
  public function setSint64( $value){
  return $this->_set(18, $value);
  }
 
 
  // @@protoc_insertion_point(scope_class)
  // @@protoc_insertion_point(class_tests.Simple)
  }
  }
 
 
  package tests;
 
  message Simple {
  optional double double = 1;
  optional float float = 2;
  optional int64 int64 = 3;
  optional uint64 uint64 = 4;
  optional int32 int32 = 5;
  optional fixed64 fixed64 = 6;
  optional fixed32 fixed32 = 7;
  optional bool bool = 8;
  optional string string = 9;
  optional bytes bytes = 12;
  optional uint32 uint32 = 13;
  optional sfixed32 sfixed32 = 15;
  optional sfixed64 sfixed64 = 16;
  optional sint32 sint32 = 17;
  optional sint64 sint64 = 18;
  }
 
  double: 123456789.12345
  float: 12345.123
  int64: -123456789123456789
  uint64: 123456789123456789
  int32: -123456789
  fixed64: 123456789123456789
  fixed32: 123456789
  bool: 1
  string: "foo"
  bytes: "bar"
  uint32: 123456789
  sfixed32: -123456789
  sfixed64: -123456789123456789
  sint32: -123456789
  sint64: -123456789123456789
 
<?php <?php
include ('include/common.inc.php'); include ('include/common.inc.php');
   
if (basename(__FILE__) == "servicealerts_api.php") { if (basename(__FILE__) == "servicealerts_api.php") {
$return = getServiceAlerts($_REQUEST['filter_class'],$_REQUEST['filter_id']); $return = getServiceAlertsAsJSON($_REQUEST['filter_class'],$_REQUEST['filter_id']);
header('Content-Type: text/javascript; charset=utf8'); header('Content-Type: text/javascript; charset=utf8');
// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/'); // header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/');
header('Access-Control-Max-Age: 3628800'); header('Access-Control-Max-Age: 3628800');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
if (isset($_GET['callback'])) { if (isset($_GET['callback'])) {
$json = '(' . json_encode($return) . ');'; //must wrap in parens and end with semicolon $json = '(' . $return . ');'; //must wrap in parens and end with semicolon
//print_r($_GET['callback'] . $json); //callback is prepended for json-p //print_r($_GET['callback'] . $json); //callback is prepended for json-p
} }
else echo json_encode($return); else echo $return;
} }
?> ?>