Add a tool to build the proto files externally (#43)

* add a tool for building the proto files externally

* regenerate the proto files

* update changelog/pubspec
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5bee2f7..22cb208 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.1.23-dev
+
+* Added a tool for updating generated proto files and updated them
+  using the latest version of the protoc_plugin package.
+  * This required a lower bound bump of the `protobuf` package to `0.14.4`.
+
 ## 0.1.22
 
 * Require protobuf 0.14.0.
diff --git a/lib/src/worker_protocol.pb.dart b/lib/src/worker_protocol.pb.dart
index f14589a..b15b03b 100644
--- a/lib/src/worker_protocol.pb.dart
+++ b/lib/src/worker_protocol.pb.dart
@@ -1,130 +1,181 @@
 ///
 //  Generated code. Do not modify.
-//  source: third_party/bazel/src/main/protobuf/worker_protocol.proto
+//  source: worker_protocol.proto
+//
+// @dart = 2.3
+// ignore_for_file: camel_case_types,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type
 
-// ignore: UNUSED_SHOWN_NAME
-import 'dart:core' show int, bool, double, String, List, Map, override;
+import 'dart:core' as $core;
 
 import 'package:protobuf/protobuf.dart' as $pb;
 
 class Input extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('Input',
-      package: const $pb.PackageName('blaze.worker'))
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo('Input',
+      package: const $pb.PackageName('blaze.worker'),
+      createEmptyInstance: create)
     ..aOS(1, 'path')
-    ..a<List<int>>(2, 'digest', $pb.PbFieldType.OY)
+    ..a<$core.List<$core.int>>(2, 'digest', $pb.PbFieldType.OY)
     ..hasRequiredFields = false;
 
-  Input() : super();
-  Input.fromBuffer(List<int> i,
-      [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
-      : super.fromBuffer(i, r);
-  Input.fromJson(String i,
-      [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
-      : super.fromJson(i, r);
-  Input clone() => new Input()..mergeFromMessage(this);
+  Input._() : super();
+  factory Input() => create();
+  factory Input.fromBuffer($core.List<$core.int> i,
+          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+      create()..mergeFromBuffer(i, r);
+  factory Input.fromJson($core.String i,
+          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+      create()..mergeFromJson(i, r);
+  Input clone() => Input()..mergeFromMessage(this);
   Input copyWith(void Function(Input) updates) =>
       super.copyWith((message) => updates(message as Input));
   $pb.BuilderInfo get info_ => _i;
-  static Input create() => new Input();
+  @$core.pragma('dart2js:noInline')
+  static Input create() => Input._();
   Input createEmptyInstance() => create();
-  static $pb.PbList<Input> createRepeated() => new $pb.PbList<Input>();
-  static Input getDefault() => _defaultInstance ??= create()..freeze();
+  static $pb.PbList<Input> createRepeated() => $pb.PbList<Input>();
+  @$core.pragma('dart2js:noInline')
+  static Input getDefault() =>
+      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Input>(create);
   static Input _defaultInstance;
-  static void $checkItem(Input v) {
-    if (v is! Input) $pb.checkItemFailed(v, _i.qualifiedMessageName);
-  }
 
-  String get path => $_getS(0, '');
-  set path(String v) {
+  @$pb.TagNumber(1)
+  $core.String get path => $_getSZ(0);
+  @$pb.TagNumber(1)
+  set path($core.String v) {
     $_setString(0, v);
   }
 
-  bool hasPath() => $_has(0);
+  @$pb.TagNumber(1)
+  $core.bool hasPath() => $_has(0);
+  @$pb.TagNumber(1)
   void clearPath() => clearField(1);
 
-  List<int> get digest => $_getN(1);
-  set digest(List<int> v) {
+  @$pb.TagNumber(2)
+  $core.List<$core.int> get digest => $_getN(1);
+  @$pb.TagNumber(2)
+  set digest($core.List<$core.int> v) {
     $_setBytes(1, v);
   }
 
-  bool hasDigest() => $_has(1);
+  @$pb.TagNumber(2)
+  $core.bool hasDigest() => $_has(1);
+  @$pb.TagNumber(2)
   void clearDigest() => clearField(2);
 }
 
 class WorkRequest extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('WorkRequest',
-      package: const $pb.PackageName('blaze.worker'))
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo('WorkRequest',
+      package: const $pb.PackageName('blaze.worker'),
+      createEmptyInstance: create)
     ..pPS(1, 'arguments')
     ..pc<Input>(2, 'inputs', $pb.PbFieldType.PM, subBuilder: Input.create)
+    ..a<$core.int>(3, 'requestId', $pb.PbFieldType.O3)
     ..hasRequiredFields = false;
 
-  WorkRequest() : super();
-  WorkRequest.fromBuffer(List<int> i,
-      [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
-      : super.fromBuffer(i, r);
-  WorkRequest.fromJson(String i,
-      [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
-      : super.fromJson(i, r);
-  WorkRequest clone() => new WorkRequest()..mergeFromMessage(this);
+  WorkRequest._() : super();
+  factory WorkRequest() => create();
+  factory WorkRequest.fromBuffer($core.List<$core.int> i,
+          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+      create()..mergeFromBuffer(i, r);
+  factory WorkRequest.fromJson($core.String i,
+          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+      create()..mergeFromJson(i, r);
+  WorkRequest clone() => WorkRequest()..mergeFromMessage(this);
   WorkRequest copyWith(void Function(WorkRequest) updates) =>
       super.copyWith((message) => updates(message as WorkRequest));
   $pb.BuilderInfo get info_ => _i;
-  static WorkRequest create() => new WorkRequest();
+  @$core.pragma('dart2js:noInline')
+  static WorkRequest create() => WorkRequest._();
   WorkRequest createEmptyInstance() => create();
-  static $pb.PbList<WorkRequest> createRepeated() =>
-      new $pb.PbList<WorkRequest>();
-  static WorkRequest getDefault() => _defaultInstance ??= create()..freeze();
+  static $pb.PbList<WorkRequest> createRepeated() => $pb.PbList<WorkRequest>();
+  @$core.pragma('dart2js:noInline')
+  static WorkRequest getDefault() => _defaultInstance ??=
+      $pb.GeneratedMessage.$_defaultFor<WorkRequest>(create);
   static WorkRequest _defaultInstance;
-  static void $checkItem(WorkRequest v) {
-    if (v is! WorkRequest) $pb.checkItemFailed(v, _i.qualifiedMessageName);
+
+  @$pb.TagNumber(1)
+  $core.List<$core.String> get arguments => $_getList(0);
+
+  @$pb.TagNumber(2)
+  $core.List<Input> get inputs => $_getList(1);
+
+  @$pb.TagNumber(3)
+  $core.int get requestId => $_getIZ(2);
+  @$pb.TagNumber(3)
+  set requestId($core.int v) {
+    $_setSignedInt32(2, v);
   }
 
-  List<String> get arguments => $_getList(0);
-
-  List<Input> get inputs => $_getList(1);
+  @$pb.TagNumber(3)
+  $core.bool hasRequestId() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearRequestId() => clearField(3);
 }
 
 class WorkResponse extends $pb.GeneratedMessage {
-  static final $pb.BuilderInfo _i = new $pb.BuilderInfo('WorkResponse',
-      package: const $pb.PackageName('blaze.worker'))
-    ..a<int>(1, 'exitCode', $pb.PbFieldType.O3)
+  static final $pb.BuilderInfo _i = $pb.BuilderInfo('WorkResponse',
+      package: const $pb.PackageName('blaze.worker'),
+      createEmptyInstance: create)
+    ..a<$core.int>(1, 'exitCode', $pb.PbFieldType.O3)
     ..aOS(2, 'output')
+    ..a<$core.int>(3, 'requestId', $pb.PbFieldType.O3)
     ..hasRequiredFields = false;
 
-  WorkResponse() : super();
-  WorkResponse.fromBuffer(List<int> i,
-      [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
-      : super.fromBuffer(i, r);
-  WorkResponse.fromJson(String i,
-      [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY])
-      : super.fromJson(i, r);
-  WorkResponse clone() => new WorkResponse()..mergeFromMessage(this);
+  WorkResponse._() : super();
+  factory WorkResponse() => create();
+  factory WorkResponse.fromBuffer($core.List<$core.int> i,
+          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+      create()..mergeFromBuffer(i, r);
+  factory WorkResponse.fromJson($core.String i,
+          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
+      create()..mergeFromJson(i, r);
+  WorkResponse clone() => WorkResponse()..mergeFromMessage(this);
   WorkResponse copyWith(void Function(WorkResponse) updates) =>
       super.copyWith((message) => updates(message as WorkResponse));
   $pb.BuilderInfo get info_ => _i;
-  static WorkResponse create() => new WorkResponse();
+  @$core.pragma('dart2js:noInline')
+  static WorkResponse create() => WorkResponse._();
   WorkResponse createEmptyInstance() => create();
   static $pb.PbList<WorkResponse> createRepeated() =>
-      new $pb.PbList<WorkResponse>();
-  static WorkResponse getDefault() => _defaultInstance ??= create()..freeze();
+      $pb.PbList<WorkResponse>();
+  @$core.pragma('dart2js:noInline')
+  static WorkResponse getDefault() => _defaultInstance ??=
+      $pb.GeneratedMessage.$_defaultFor<WorkResponse>(create);
   static WorkResponse _defaultInstance;
-  static void $checkItem(WorkResponse v) {
-    if (v is! WorkResponse) $pb.checkItemFailed(v, _i.qualifiedMessageName);
-  }
 
-  int get exitCode => $_get(0, 0);
-  set exitCode(int v) {
+  @$pb.TagNumber(1)
+  $core.int get exitCode => $_getIZ(0);
+  @$pb.TagNumber(1)
+  set exitCode($core.int v) {
     $_setSignedInt32(0, v);
   }
 
-  bool hasExitCode() => $_has(0);
+  @$pb.TagNumber(1)
+  $core.bool hasExitCode() => $_has(0);
+  @$pb.TagNumber(1)
   void clearExitCode() => clearField(1);
 
-  String get output => $_getS(1, '');
-  set output(String v) {
+  @$pb.TagNumber(2)
+  $core.String get output => $_getSZ(1);
+  @$pb.TagNumber(2)
+  set output($core.String v) {
     $_setString(1, v);
   }
 
-  bool hasOutput() => $_has(1);
+  @$pb.TagNumber(2)
+  $core.bool hasOutput() => $_has(1);
+  @$pb.TagNumber(2)
   void clearOutput() => clearField(2);
+
+  @$pb.TagNumber(3)
+  $core.int get requestId => $_getIZ(2);
+  @$pb.TagNumber(3)
+  set requestId($core.int v) {
+    $_setSignedInt32(2, v);
+  }
+
+  @$pb.TagNumber(3)
+  $core.bool hasRequestId() => $_has(2);
+  @$pb.TagNumber(3)
+  void clearRequestId() => clearField(3);
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 1d63f92..b996b68 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: bazel_worker
-version: 0.1.22
+version: 0.1.23-dev
 
 description: Tools for creating a bazel persistent worker.
 author: Dart Team <misc@dartlang.org>
@@ -11,7 +11,7 @@
 dependencies:
   async: '>1.9.0 <3.0.0'
   pedantic: ^1.8.0
-  protobuf: '>=0.14.0 <2.0.0'
+  protobuf: '>=0.14.4 <2.0.0'
 
 dev_dependencies:
   test: ^1.2.0
diff --git a/tool/update_proto.sh b/tool/update_proto.sh
new file mode 100755
index 0000000..b224694
--- /dev/null
+++ b/tool/update_proto.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -e
+
+if [ -z "$1" ]; then
+    echo "Expected exactly one argument which is the protoc_plugin version to use"
+else
+    echo "Using protoc_plugin version $1"
+    pub global activate protoc_plugin "$1"
+fi
+
+BAZEL_REPO=.dart_tool/bazel_worker/bazel.git/
+# Bash away old versions if they exist
+rm -rf "$BAZEL_REPO"
+git clone https://github.com/bazelbuild/bazel.git "$BAZEL_REPO"
+
+protoc --proto_path="${BAZEL_REPO}/src/main/protobuf" --dart_out=lib/src worker_protocol.proto
+dartfmt -w lib/src/worker_protocol.pb.dart
+
+# We only care about the *.pb.dart file, not the extra files
+rm lib/src/worker_protocol.pbenum.dart
+rm lib/src/worker_protocol.pbjson.dart
+rm lib/src/worker_protocol.pbserver.dart
+
+rm -rf "$BAZEL_REPO"