Add output unit info to proto codec (#40)

diff --git a/info.proto b/info.proto
index 1470ec9..da7de44 100644
--- a/info.proto
+++ b/info.proto
@@ -1,5 +1,7 @@
 syntax = "proto3";
 
+option go_package = "dart2js_info";
+
 package dart2js_info.proto;
 
 message DependencyInfoPB {
@@ -49,8 +51,11 @@
   /** How does this function or field depend on others. */
   repeated DependencyInfoPB uses = 7;
 
+  /** The serialized_id of the output unit the element is generated into. */
+  string output_unit_id = 8;
+
   /** Reserved tags for future common fields. */
-  reserved 8 to 99;
+  reserved 9 to 99;
 
   /** The concrete info type. */
   oneof concrete {
diff --git a/lib/proto_info_codec.dart b/lib/proto_info_codec.dart
index 66de137..cbeb35c 100644
--- a/lib/proto_info_codec.dart
+++ b/lib/proto_info_codec.dart
@@ -184,6 +184,13 @@
       proto.coverageId = info.coverageId;
     }
 
+    if (info is BasicInfo && info.outputUnit != null) {
+      // TODO(lorenvs): Similar to the JSON codec, omit this for the default
+      // output unit. At the moment, there is no easy way to identify which
+      // output unit is the default on [OutputUnitInfo].
+      proto.outputUnitId = info.outputUnit.serializedId;
+    }
+
     if (info is CodeInfo) {
       proto.uses.addAll(info.uses.map(_convertToDependencyInfoPB));
     }
diff --git a/lib/src/proto/info.pb.dart b/lib/src/proto/info.pb.dart
index 786c679..b005568 100644
--- a/lib/src/proto/info.pb.dart
+++ b/lib/src/proto/info.pb.dart
@@ -164,6 +164,7 @@
     ..aOS(6, 'parentId')
     ..pp<DependencyInfoPB>(7, 'uses', PbFieldType.PM,
         DependencyInfoPB.$checkItem, DependencyInfoPB.create)
+    ..aOS(8, 'outputUnitId')
     ..a<LibraryInfoPB>(100, 'libraryInfo', PbFieldType.OM,
         LibraryInfoPB.getDefault, LibraryInfoPB.create)
     ..a<ClassInfoPB>(101, 'classInfo', PbFieldType.OM, ClassInfoPB.getDefault,
@@ -252,68 +253,76 @@
 
   List<DependencyInfoPB> get uses => $_getList(6);
 
-  LibraryInfoPB get libraryInfo => $_getN(7);
+  String get outputUnitId => $_getS(7, '');
+  set outputUnitId(String v) {
+    $_setString(7, v);
+  }
+
+  bool hasOutputUnitId() => $_has(7);
+  void clearOutputUnitId() => clearField(8);
+
+  LibraryInfoPB get libraryInfo => $_getN(8);
   set libraryInfo(LibraryInfoPB v) {
     setField(100, v);
   }
 
-  bool hasLibraryInfo() => $_has(7);
+  bool hasLibraryInfo() => $_has(8);
   void clearLibraryInfo() => clearField(100);
 
-  ClassInfoPB get classInfo => $_getN(8);
+  ClassInfoPB get classInfo => $_getN(9);
   set classInfo(ClassInfoPB v) {
     setField(101, v);
   }
 
-  bool hasClassInfo() => $_has(8);
+  bool hasClassInfo() => $_has(9);
   void clearClassInfo() => clearField(101);
 
-  FunctionInfoPB get functionInfo => $_getN(9);
+  FunctionInfoPB get functionInfo => $_getN(10);
   set functionInfo(FunctionInfoPB v) {
     setField(102, v);
   }
 
-  bool hasFunctionInfo() => $_has(9);
+  bool hasFunctionInfo() => $_has(10);
   void clearFunctionInfo() => clearField(102);
 
-  FieldInfoPB get fieldInfo => $_getN(10);
+  FieldInfoPB get fieldInfo => $_getN(11);
   set fieldInfo(FieldInfoPB v) {
     setField(103, v);
   }
 
-  bool hasFieldInfo() => $_has(10);
+  bool hasFieldInfo() => $_has(11);
   void clearFieldInfo() => clearField(103);
 
-  ConstantInfoPB get constantInfo => $_getN(11);
+  ConstantInfoPB get constantInfo => $_getN(12);
   set constantInfo(ConstantInfoPB v) {
     setField(104, v);
   }
 
-  bool hasConstantInfo() => $_has(11);
+  bool hasConstantInfo() => $_has(12);
   void clearConstantInfo() => clearField(104);
 
-  OutputUnitInfoPB get outputUnitInfo => $_getN(12);
+  OutputUnitInfoPB get outputUnitInfo => $_getN(13);
   set outputUnitInfo(OutputUnitInfoPB v) {
     setField(105, v);
   }
 
-  bool hasOutputUnitInfo() => $_has(12);
+  bool hasOutputUnitInfo() => $_has(13);
   void clearOutputUnitInfo() => clearField(105);
 
-  TypedefInfoPB get typedefInfo => $_getN(13);
+  TypedefInfoPB get typedefInfo => $_getN(14);
   set typedefInfo(TypedefInfoPB v) {
     setField(106, v);
   }
 
-  bool hasTypedefInfo() => $_has(13);
+  bool hasTypedefInfo() => $_has(14);
   void clearTypedefInfo() => clearField(106);
 
-  ClosureInfoPB get closureInfo => $_getN(14);
+  ClosureInfoPB get closureInfo => $_getN(15);
   set closureInfo(ClosureInfoPB v) {
     setField(107, v);
   }
 
-  bool hasClosureInfo() => $_has(14);
+  bool hasClosureInfo() => $_has(15);
   void clearClosureInfo() => clearField(107);
 }
 
diff --git a/lib/src/proto/info.pbjson.dart b/lib/src/proto/info.pbjson.dart
index 7c95b90..91dc8ba 100644
--- a/lib/src/proto/info.pbjson.dart
+++ b/lib/src/proto/info.pbjson.dart
@@ -75,6 +75,7 @@
       '6': '.dart2js_info.proto.DependencyInfoPB',
       '10': 'uses'
     },
+    const {'1': 'output_unit_id', '3': 8, '4': 1, '5': 9, '10': 'outputUnitId'},
     const {
       '1': 'library_info',
       '3': 100,
@@ -152,7 +153,7 @@
     const {'1': 'concrete'},
   ],
   '9': const [
-    const {'1': 8, '2': 100},
+    const {'1': 9, '2': 100},
   ],
 };
 
diff --git a/pubspec.yaml b/pubspec.yaml
index 47de84b..037a3bc 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dart2js_info
-version: 0.5.8+1
+version: 0.5.9
 description: >
   Libraries and tools to process data produced when running dart2js with
   --dump-info.
diff --git a/test/json_to_proto_deferred_test.dart b/test/json_to_proto_deferred_test.dart
index 5f8410f..ac415ed 100644
--- a/test/json_to_proto_deferred_test.dart
+++ b/test/json_to_proto_deferred_test.dart
@@ -27,6 +27,24 @@
       expect(import.prefix, 'deferred_import');
       expect(import.files, hasLength(1));
       expect(import.files.first, 'hello_world_deferred.js_1.part.js');
+
+      // Dart protobuf doesn't support maps, translate the info list into
+      // a map for associative verifications.
+      final infoMap = <String, InfoPB>{};
+      infoMap.addEntries(proto.allInfos.map(
+          (entry) => new MapEntry<String, InfoPB>(entry.key, entry.value)));
+
+      final entrypoint = infoMap[proto.program.entrypointId];
+      expect(entrypoint, isNotNull);
+      expect(entrypoint.hasFunctionInfo(), isTrue);
+      expect(entrypoint.outputUnitId, isNotNull);
+
+      // The output unit of the entrypoint function should be the default
+      // entrypoint, which should have no imports.
+      final defaultOutputUnit = infoMap[entrypoint.outputUnitId];
+      expect(defaultOutputUnit, isNotNull);
+      expect(defaultOutputUnit.hasOutputUnitInfo(), isTrue);
+      expect(defaultOutputUnit.outputUnitInfo.imports, isEmpty);
     });
   });
 }