| Index: mojo/dart/test/bindings_generation_test.dart
 | 
| diff --git a/mojo/dart/test/bindings_generation_test.dart b/mojo/dart/test/bindings_generation_test.dart
 | 
| index c68cb3cbb9bffe144dfd4a6ada4f1c8d492e368e..7c39c9dc6d283a6fee0b601fc0154c836dbbca07 100644
 | 
| --- a/mojo/dart/test/bindings_generation_test.dart
 | 
| +++ b/mojo/dart/test/bindings_generation_test.dart
 | 
| @@ -10,9 +10,13 @@ import 'dart:convert';
 | 
|  import 'package:_mojo_for_test_only/expect.dart';
 | 
|  import 'package:mojo/bindings.dart' as bindings;
 | 
|  import 'package:mojo/core.dart' as core;
 | 
| +import 'package:mojo/mojo/mojom_types.mojom.dart' as mojom_types;
 | 
| +import 'package:mojo/mojo/service_describer.mojom.dart' as service_describer;
 | 
|  import 'package:_mojo_for_test_only/sample/sample_interfaces.mojom.dart' as sample;
 | 
|  import 'package:_mojo_for_test_only/mojo/test/test_structs.mojom.dart' as structs;
 | 
|  import 'package:_mojo_for_test_only/mojo/test/test_unions.mojom.dart' as unions;
 | 
| +import 'package:_mojo_for_test_only/mojo/test/validation_test_interfaces.mojom.dart'
 | 
| +    as validation;
 | 
|  import 'package:_mojo_for_test_only/mojo/test/rect.mojom.dart' as rect;
 | 
|  import 'package:_mojo_for_test_only/mojo/test/serialization_test_structs.mojom.dart'
 | 
|      as serialization;
 | 
| @@ -32,7 +36,7 @@ class ProviderImpl implements sample.Provider {
 | 
|    echoStrings(String a, String b, Function responseFactory) =>
 | 
|        new Future.value(responseFactory(a, b));
 | 
|  
 | 
| -  echoMessagePipeHanlde(core.MojoHandle a, Function responseFactory) =>
 | 
| +  echoMessagePipeHandle(core.MojoHandle a, Function responseFactory) =>
 | 
|        new Future.value(responseFactory(a));
 | 
|  
 | 
|    echoEnum(sample.Enum a, Function responseFactory) =>
 | 
| @@ -240,6 +244,309 @@ testUnions() {
 | 
|    testUnionsToString();
 | 
|  }
 | 
|  
 | 
| +testValidateMojomTypes() {
 | 
| +  testValidateEnumType();
 | 
| +  testValidateStructType();
 | 
| +  testValidateUnionType();
 | 
| +  testValidateTestStructWithImportType();
 | 
| +  testValidateInterfaceType();
 | 
| +}
 | 
| +
 | 
| +// Test that mojom type descriptors were generated correctly for validation's
 | 
| +// BasicEnum.
 | 
| +testValidateEnumType() {
 | 
| +  var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
 | 
| +  String enumID = "_validation_test_interfaces_BasicEnum__";
 | 
| +  String shortName = "BasicEnum";
 | 
| +  Map<String, int> labelMap = <String, int>{
 | 
| +    "A": 0,
 | 
| +    "B": 1,
 | 
| +    "C": 0,
 | 
| +    "D": -3,
 | 
| +    "E": 0xA,
 | 
| +  };
 | 
| +
 | 
| +  // Extract the UserDefinedType from the descriptor using enumID.
 | 
| +  mojom_types.UserDefinedType udt = testValidationDescriptor[enumID];
 | 
| +  Expect.isNotNull(udt);
 | 
| +
 | 
| +  // The enumType must be present and declared properly.
 | 
| +  mojom_types.MojomEnum me = udt.enumType;
 | 
| +  Expect.isNotNull(me);
 | 
| +  Expect.isNotNull(me.declData);
 | 
| +  Expect.equals(me.declData.shortName, shortName);
 | 
| +
 | 
| +  // Now compare the labels to verify that the enum labels match the expected
 | 
| +  // ones.
 | 
| +  Expect.equals(me.values.length, labelMap.length);
 | 
| +  me.values.forEach((mojom_types.EnumValue ev) {
 | 
| +    // Check that the declData is correct...
 | 
| +    Expect.isNotNull(ev.declData);
 | 
| +    Expect.isNotNull(labelMap[ev.declData.shortName]);
 | 
| +
 | 
| +    // Check that the enumTypeKey matches the enumID.
 | 
| +    Expect.equals(ev.enumTypeKey, enumID);
 | 
| +    Expect.equals(ev.intValue, labelMap[ev.declData.shortName]);
 | 
| +  });
 | 
| +}
 | 
| +
 | 
| +// Test that mojom type descriptors were generated correctly for validation's
 | 
| +// StructE.
 | 
| +testValidateStructType() {
 | 
| +  var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
 | 
| +  String structID = "_validation_test_interfaces_StructE__";
 | 
| +  String shortName = "StructE";
 | 
| +  Map<int, String> expectedFields = <int, String>{
 | 
| +    0: "StructD",
 | 
| +    1: "DataPipeConsumer",
 | 
| +  };
 | 
| +
 | 
| +  // Extract the UserDefinedType from the descriptor using structID.
 | 
| +  mojom_types.UserDefinedType udt = testValidationDescriptor[structID];
 | 
| +  Expect.isNotNull(udt);
 | 
| +
 | 
| +  // The structType must be present and declared properly.
 | 
| +  mojom_types.MojomStruct ms = udt.structType;
 | 
| +  Expect.isNotNull(ms);
 | 
| +  Expect.isNotNull(ms.declData);
 | 
| +  Expect.equals(ms.declData.shortName, shortName);
 | 
| +
 | 
| +  // Now compare the fields to verify that the struct fields match the expected
 | 
| +  // ones.
 | 
| +  Expect.equals(ms.fields.length, expectedFields.length);
 | 
| +  int i = 0;
 | 
| +  ms.fields.forEach((mojom_types.StructField field) {
 | 
| +    // Check that the declData is correct...
 | 
| +    Expect.isNotNull(field.declData);
 | 
| +    Expect.equals(expectedFields[i], field.declData.shortName);
 | 
| +
 | 
| +    // Special case each field since we already know what should be inside.
 | 
| +    switch (i) {
 | 
| +      case 0: // This is a TypeReference to StructD.
 | 
| +        mojom_types.Type t = field.type;
 | 
| +        Expect.isNotNull(t.typeReference);
 | 
| +
 | 
| +        // Type key, identifier, and expected reference id should match up.
 | 
| +        mojom_types.TypeReference tr = t.typeReference;
 | 
| +        String expectedRefID = "_validation_test_interfaces_StructD__";
 | 
| +        Expect.equals(expectedRefID, tr.identifier);
 | 
| +        Expect.equals(expectedRefID, tr.typeKey);
 | 
| +        break;
 | 
| +      case 1: // This is a non-nullable DataPipeConsumer HandleType.
 | 
| +        mojom_types.Type t = field.type;
 | 
| +        Expect.isNotNull(t.handleType);
 | 
| +
 | 
| +        mojom_types.HandleType ht = t.handleType;
 | 
| +        Expect.isFalse(ht.nullable);
 | 
| +        Expect.equals(mojom_types.HandleTypeKind.DATA_PIPE_CONSUMER, ht.kind);
 | 
| +        break;
 | 
| +      default:
 | 
| +        assert(false);
 | 
| +    }
 | 
| +
 | 
| +    i++;
 | 
| +  });
 | 
| +}
 | 
| +
 | 
| +// Test that mojom type descriptors were generated correctly for validation's
 | 
| +// UnionB.
 | 
| +testValidateUnionType() {
 | 
| +  var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
 | 
| +  String unionID = "_validation_test_interfaces_UnionB__";
 | 
| +  String shortName = "UnionB";
 | 
| +  Map<int, String> expectedFields = <int, String>{
 | 
| +    0: "A",
 | 
| +    1: "B",
 | 
| +    2: "C",
 | 
| +    3: "D",
 | 
| +  };
 | 
| +
 | 
| +  // Extract the UserDefinedType from the descriptor using unionID.
 | 
| +  mojom_types.UserDefinedType udt = testValidationDescriptor[unionID];
 | 
| +  Expect.isNotNull(udt);
 | 
| +
 | 
| +  // The unionType must be present and declared properly.
 | 
| +  mojom_types.MojomUnion mu = udt.unionType;
 | 
| +  Expect.isNotNull(mu);
 | 
| +  Expect.isNotNull(mu.declData);
 | 
| +  Expect.equals(mu.declData.shortName, shortName);
 | 
| +
 | 
| +  // Now compare the fields to verify that the union fields match the expected
 | 
| +  // ones.
 | 
| +  Expect.equals(mu.fields.length, expectedFields.length);
 | 
| +  mu.fields.forEach((mojom_types.UnionField field) {
 | 
| +    int ordinal = field.tag;
 | 
| +
 | 
| +    // Check that the declData is correct...
 | 
| +    Expect.isNotNull(field.declData);
 | 
| +    Expect.equals(expectedFields[ordinal], field.declData.shortName);
 | 
| +
 | 
| +    // Special: It turns out that all types are simple types.
 | 
| +    mojom_types.Type t = field.type;
 | 
| +    Expect.isNotNull(t.simpleType);
 | 
| +    mojom_types.SimpleType st = t.simpleType;
 | 
| +
 | 
| +    // Special case each field since we already know what should be inside.
 | 
| +    switch (ordinal) {
 | 
| +      case 0: // Uint16
 | 
| +        Expect.equals(st, mojom_types.SimpleType.UINT16);
 | 
| +        break;
 | 
| +      case 1: // Uint32
 | 
| +      case 3:
 | 
| +        Expect.equals(st, mojom_types.SimpleType.UINT32);
 | 
| +        break;
 | 
| +      case 2: // Uint64
 | 
| +        Expect.equals(st, mojom_types.SimpleType.UINT64);
 | 
| +        break;
 | 
| +      default:
 | 
| +        assert(false);
 | 
| +    }
 | 
| +  });
 | 
| +}
 | 
| +
 | 
| +// Test that mojom type descriptors were generated correctly for validation's
 | 
| +// IncludingStruct, which contains a union imported from test_included_unions.
 | 
| +testValidateTestStructWithImportType() {
 | 
| +  var testUnionsDescriptor = unions.getAllMojomTypeDefinitions();
 | 
| +  String structID = "_test_unions_IncludingStruct__";
 | 
| +  String shortName = "IncludingStruct";
 | 
| +  Map<int, String> expectedFields = <int, String>{0: "A",};
 | 
| +
 | 
| +  // Extract the UserDefinedType from the descriptor using structID.
 | 
| +  mojom_types.UserDefinedType udt = testUnionsDescriptor[structID];
 | 
| +  Expect.isNotNull(udt);
 | 
| +
 | 
| +  // The structType must be present and declared properly.
 | 
| +  mojom_types.MojomStruct ms = udt.structType;
 | 
| +  Expect.isNotNull(ms);
 | 
| +  Expect.isNotNull(ms.declData);
 | 
| +  Expect.equals(ms.declData.shortName, shortName);
 | 
| +
 | 
| +  // Now compare the fields to verify that the struct fields match the expected
 | 
| +  // ones.
 | 
| +  Expect.equals(ms.fields.length, expectedFields.length);
 | 
| +  int i = 0;
 | 
| +  ms.fields.forEach((mojom_types.StructField field) {
 | 
| +    // Check that the declData is correct...
 | 
| +    Expect.isNotNull(field.declData);
 | 
| +    Expect.equals(expectedFields[i], field.declData.shortName);
 | 
| +
 | 
| +    // Special case each field since we already know what should be inside.
 | 
| +    switch (i) {
 | 
| +      case 0: // This is a TypeReference to a Union.
 | 
| +        mojom_types.Type t = field.type;
 | 
| +        Expect.isNotNull(t.typeReference);
 | 
| +
 | 
| +        // Type key, identifier, and expected reference id should match up.
 | 
| +        mojom_types.TypeReference tr = t.typeReference;
 | 
| +        String expectedRefID = "_test_included_unions_IncludedUnion__";
 | 
| +        Expect.equals(expectedRefID, tr.identifier);
 | 
| +        Expect.equals(expectedRefID, tr.typeKey);
 | 
| +        break;
 | 
| +      default:
 | 
| +        assert(false);
 | 
| +    }
 | 
| +
 | 
| +    i++;
 | 
| +  });
 | 
| +}
 | 
| +
 | 
| +// Test that mojom type descriptors were generated correctly for validation's
 | 
| +// BoundsCheckTestInterface.
 | 
| +testValidateInterfaceType() {
 | 
| +  // interface BoundsCheckTestInterface {
 | 
| +  //   Method0(uint8 param0) => (uint8 param0);
 | 
| +  //   Method1(uint8 param0);
 | 
| +  // };
 | 
| +
 | 
| +  var testValidationDescriptor = validation.getAllMojomTypeDefinitions();
 | 
| +  String interfaceID = "_validation_test_interfaces_BoundsCheckTestInterface__";
 | 
| +  String shortName = "BoundsCheckTestInterface";
 | 
| +  Map<int, String> methodMap = <int, String>{0: "Method0", 1: "Method1",};
 | 
| +
 | 
| +  mojom_types.UserDefinedType udt = testValidationDescriptor[interfaceID];
 | 
| +  Expect.isNotNull(udt);
 | 
| +
 | 
| +  mojom_types.MojomInterface mi = udt.interfaceType;
 | 
| +  Expect.isNotNull(mi);
 | 
| +
 | 
| +  _checkMojomInterface(mi, shortName, methodMap);
 | 
| +
 | 
| +  // The proxy and stub need to have a valid serviceDescription.
 | 
| +  var bcti_p = new validation.BoundsCheckTestInterfaceProxyImpl.unbound();
 | 
| +  var bcti_s = new validation.BoundsCheckTestInterfaceStub.unbound();
 | 
| +
 | 
| +  _checkServiceDescription(
 | 
| +      bcti_p.serviceDescription, interfaceID, shortName, methodMap);
 | 
| +  _checkServiceDescription(
 | 
| +      bcti_s.serviceDescription, interfaceID, shortName, methodMap);
 | 
| +}
 | 
| +
 | 
| +_checkServiceDescription(service_describer.ServiceDescription sd,
 | 
| +    String interfaceID, String shortName, Map<int, String> methodMap) {
 | 
| +  // Check the top level interface, which must pass _checkMojomInterface.
 | 
| +  mojom_types.MojomInterface mi = sd.getTopLevelInterface();
 | 
| +  _checkMojomInterface(mi, shortName, methodMap);
 | 
| +
 | 
| +  // Try out sd.GetTypeDefinition with the given interfaceID.
 | 
| +  mojom_types.UserDefinedType udt = sd.getTypeDefinition(interfaceID);
 | 
| +  Expect.isNotNull(udt.interfaceType);
 | 
| +  _checkMojomInterface(udt.interfaceType, shortName, methodMap);
 | 
| +
 | 
| +  // Check all type definitions. Reflect-wise, all data inside should match the
 | 
| +  // imported Descriptor.
 | 
| +  var actualDescriptions = sd.getAllTypeDefinitions();
 | 
| +  var expectedDescriptions = validation.getAllMojomTypeDefinitions();
 | 
| +  Expect.mapEquals(actualDescriptions, expectedDescriptions);
 | 
| +}
 | 
| +
 | 
| +_checkMojomInterface(mojom_types.MojomInterface mi, String shortName,
 | 
| +    Map<int, String> methodMap) {
 | 
| +  // check the generated short name.
 | 
| +  Expect.isNotNull(mi.declData);
 | 
| +  Expect.equals(mi.declData.shortName, shortName);
 | 
| +
 | 
| +  // Verify that the number of methods matches the expected ones.
 | 
| +  Expect.equals(mi.methods.length, methodMap.length);
 | 
| +
 | 
| +  // Each MojomMethod must be named, typed, and "ordinal"ed correctly.
 | 
| +  mi.methods.forEach((int ordinal, mojom_types.MojomMethod method) {
 | 
| +    Expect.isNotNull(method.declData);
 | 
| +    Expect.equals(methodMap[ordinal], method.declData.shortName);
 | 
| +
 | 
| +    // Special case each method since we know what's inside.
 | 
| +    switch (ordinal) {
 | 
| +      case 0: // Has request and response params.
 | 
| +        // Request is a single uint8 input.
 | 
| +        mojom_types.MojomStruct params = method.parameters;
 | 
| +        Expect.equals(params.fields.length, 1);
 | 
| +        Expect.equals(
 | 
| +            params.fields[0].type.simpleType, mojom_types.SimpleType.UINT8);
 | 
| +
 | 
| +        // Response is a single uint8 output.
 | 
| +        mojom_types.MojomStruct response = method.responseParams;
 | 
| +        Expect.isNotNull(response);
 | 
| +        Expect.equals(response.fields.length, 1);
 | 
| +        Expect.equals(
 | 
| +            response.fields[0].type.simpleType, mojom_types.SimpleType.UINT8);
 | 
| +        break;
 | 
| +      case 1: // Only has request params.
 | 
| +        // Request is a single uint8 input.
 | 
| +        mojom_types.MojomStruct params = method.parameters;
 | 
| +        Expect.equals(params.fields.length, 1);
 | 
| +        Expect.equals(
 | 
| +            params.fields[0].type.simpleType, mojom_types.SimpleType.UINT8);
 | 
| +
 | 
| +        // Response is a single uint8 output.
 | 
| +        mojom_types.MojomStruct response = method.responseParams;
 | 
| +        Expect.isNull(response);
 | 
| +        break;
 | 
| +      default:
 | 
| +        assert(false);
 | 
| +    }
 | 
| +  });
 | 
| +}
 | 
| +
 | 
|  class CheckEnumCapsImpl implements regression.CheckEnumCaps {
 | 
|    regression.CheckEnumCapsStub _stub;
 | 
|  
 | 
| @@ -331,6 +638,7 @@ Future<bool> testRegression551() {
 | 
|  main() async {
 | 
|    testSerializeStructs();
 | 
|    testUnions();
 | 
| +  testValidateMojomTypes();
 | 
|    await testEnums();
 | 
|    await testCallResponse();
 | 
|    await testAwaitCallResponse();
 | 
| 
 |