Initial setup for generating Dart and Go bindings from echo.mojom

Change-Id: I58b32b1e642790e5ff3552b8c40e15eb57d38006
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..66750a4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,78 @@
+PWD=$(shell pwd)
+V23_GOPATH=$(shell echo `v23 run env | grep GOPATH | cut -d\= -f2`)
+
+ifndef MOJO_DIR
+	$(error MOJO_DIR is not set: ${MOJO_DIR})
+endif
+
+ifdef ANDROID
+	# Configure compiler and linker for Android.
+	GO_BIN=$(MOJO_DIR)/src/third_party/go/tool/android_arm/bin/go
+	GO_FLAGS=-ldflags=-shared
+	MOJO_BUILD_DIR=$(MOJO_DIR)/src/out/android_Debug
+	MOJO_FLAGS=--android
+	MOJO_SHARED_LIB=$(PWD)/gen/lib/android/libsystem_thunk.a
+else
+	# Configure compiler and linker for Linux.
+	GO_BIN=$(MOJO_DIR)/src/third_party/go/tool/linux_amd64/bin/go
+	GO_FLAGS=-ldflags=-shared -buildmode=c-shared
+	MOJO_FLAGS=
+	MOJO_BUILD_DIR=$(MOJO_DIR)/src/out/Debug
+	MOJO_SHARED_LIB=$(PWD)/gen/lib/linux_amd64/libsystem_thunk.a
+endif
+
+# Compiles a Go program and links against the Mojo C shared library.
+# $1 is input filename.
+# $2 is output filename.
+# See $(MOJO_DIR)/mojo/go/go.py for description of arguments to go.py (aka MOGO_BIN).
+#
+# MOJO_GOPATH must be exported so it can be picked up by MOGO_BIN.
+#
+# TODO(nlacasse): Add make task to build syncbase service using this MOGO_BUILD
+# function.
+export MOJO_GOPATH=$(V23_GOPATH):$(PWD)/gen/go:$(PWD)/go:$(MOJO_BUILD_DIR)/gen/go
+MOGO_BIN=$(MOJO_DIR)/src/mojo/go/go.py
+define MOGO_BUILD
+	mkdir -p $(dir $2)
+	$(MOGO_BIN) $(MOJO_FLAGS) -- \
+		$(GO_BIN) \
+		$(shell mktemp -d) \
+		$(PWD)/$(2) \
+		$(MOJO_DIR)/src \
+		$(PWD)/gen \
+		"-I$(MOJO_DIR)/src" \
+		"-L$(dir $(MOJO_SHARED_LIB)) -lsystem_thunk" \
+		build $(GO_FLAGS) $(PWD)/$1
+endef
+
+# Generates go bindings from .mojom file.
+# $1 is input filename.
+# $2 is output directory.
+# $3 is language (go, dart, ...).
+MOJOM_BIN=$(MOJO_DIR)/src/mojo/public/tools/bindings/mojom_bindings_generator.py
+define MOJOM_GEN
+	mkdir -p $2
+	$(MOJOM_BIN) $1 -d . -o $2 -g $3
+endef
+
+all: gen
+
+# Builds the shared library that Mojo services must be linked with.
+$(MOJO_SHARED_LIB):
+ifeq ($(wildcard $(MOJO_BUILD_DIR)),)
+	$(error ERROR: $(MOJO_BUILD_DIR) does not exist.  Please see README.md for instructions on compiling Mojo resources.)
+endif
+	mkdir -p $(dir $@)
+	ar rcs $@ $(MOJO_BUILD_DIR)/obj/mojo/public/platform/native/system.system_thunks.o
+
+gen: gen/dart-pkg/mojom/lib/mojo/examples/echo.mojom.dart gen/go/src/mojom/echo/echo.mojom.go
+
+gen/dart-pkg/mojom/lib/mojo/examples/echo.mojom.dart: mojom/echo.mojom
+	$(call MOJOM_GEN,$<,gen,dart)
+
+gen/go/src/mojom/echo/echo.mojom.go: mojom/echo.mojom
+	$(call MOJOM_GEN,$<,gen,go)
+
+.PHONY: clean
+clean:
+	rm -rf gen
diff --git a/gen/dart-gen/mojom/lib/mojo/examples/echo.mojom.dart b/gen/dart-gen/mojom/lib/mojo/examples/echo.mojom.dart
new file mode 100644
index 0000000..e50c356
--- /dev/null
+++ b/gen/dart-gen/mojom/lib/mojo/examples/echo.mojom.dart
@@ -0,0 +1,319 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library echo_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+
+class EchoEchoStringParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String value = null;
+
+  EchoEchoStringParams() : super(kVersions.last.size);
+
+  static EchoEchoStringParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static EchoEchoStringParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    EchoEchoStringParams result = new EchoEchoStringParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.value = decoder0.decodeString(8, true);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(value, 8, true);
+  }
+
+  String toString() {
+    return "EchoEchoStringParams("
+           "value: $value" ")";
+  }
+}
+
+class EchoEchoStringResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String value = null;
+
+  EchoEchoStringResponseParams() : super(kVersions.last.size);
+
+  static EchoEchoStringResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static EchoEchoStringResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    EchoEchoStringResponseParams result = new EchoEchoStringResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.value = decoder0.decodeString(8, true);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(value, 8, true);
+  }
+
+  String toString() {
+    return "EchoEchoStringResponseParams("
+           "value: $value" ")";
+  }
+}
+
+const int kEcho_echoString_name = 0;
+
+const String EchoName =
+      'mojo::examples::Echo';
+
+abstract class Echo {
+  Future<EchoEchoStringResponseParams> echoString(String value,[Function responseFactory = null]);
+
+}
+
+
+class EchoProxyImpl extends bindings.Proxy {
+  EchoProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  EchoProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  EchoProxyImpl.unbound() : super.unbound();
+
+  static EchoProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For EchoProxyImpl"));
+    return new EchoProxyImpl.fromEndpoint(endpoint);
+  }
+
+  String get name => EchoName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case kEcho_echoString_name:
+        var r = EchoEchoStringResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          throw 'Expected a message with a valid request Id.';
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          throw 'Message had unknown request Id: ${message.header.requestId}';
+        }
+        completerMap.remove(message.header.requestId);
+        assert(!c.isCompleted);
+        c.complete(r);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "EchoProxyImpl($superString)";
+  }
+}
+
+
+class _EchoProxyCalls implements Echo {
+  EchoProxyImpl _proxyImpl;
+
+  _EchoProxyCalls(this._proxyImpl);
+    Future<EchoEchoStringResponseParams> echoString(String value,[Function responseFactory = null]) {
+      assert(_proxyImpl.isBound);
+      var params = new EchoEchoStringParams();
+      params.value = value;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          kEcho_echoString_name,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class EchoProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Echo ptr;
+  final String name = EchoName;
+
+  EchoProxy(EchoProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _EchoProxyCalls(proxyImpl);
+
+  EchoProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new EchoProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _EchoProxyCalls(impl);
+  }
+
+  EchoProxy.fromHandle(core.MojoHandle handle) :
+      impl = new EchoProxyImpl.fromHandle(handle) {
+    ptr = new _EchoProxyCalls(impl);
+  }
+
+  EchoProxy.unbound() :
+      impl = new EchoProxyImpl.unbound() {
+    ptr = new _EchoProxyCalls(impl);
+  }
+
+  static EchoProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For EchoProxy"));
+    return new EchoProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "EchoProxy($impl)";
+  }
+}
+
+
+class EchoStub extends bindings.Stub {
+  Echo _impl = null;
+
+  EchoStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  EchoStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  EchoStub.unbound() : super.unbound();
+
+  static EchoStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For EchoStub"));
+    return new EchoStub.fromEndpoint(endpoint);
+  }
+
+  static const String name = EchoName;
+
+
+  EchoEchoStringResponseParams _EchoEchoStringResponseParamsFactory(String value) {
+    var result = new EchoEchoStringResponseParams();
+    result.value = value;
+    return result;
+  }
+
+  Future<bindings.Message> handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case kEcho_echoString_name:
+        var params = EchoEchoStringParams.deserialize(
+            message.payload);
+        return _impl.echoString(params.value,_EchoEchoStringResponseParamsFactory).then((response) {
+          if (response != null) {
+            return buildResponseWithId(
+                response,
+                kEcho_echoString_name,
+                message.header.requestId,
+                bindings.MessageHeader.kMessageIsResponse);
+          }
+        });
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  Echo get impl => _impl;
+  set impl(Echo d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "EchoStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/gen/dart-pkg/mojom/lib/mojo/examples/echo.mojom.dart b/gen/dart-pkg/mojom/lib/mojo/examples/echo.mojom.dart
new file mode 100644
index 0000000..e50c356
--- /dev/null
+++ b/gen/dart-pkg/mojom/lib/mojo/examples/echo.mojom.dart
@@ -0,0 +1,319 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+library echo_mojom;
+
+import 'dart:async';
+
+import 'package:mojo/bindings.dart' as bindings;
+import 'package:mojo/core.dart' as core;
+
+
+class EchoEchoStringParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String value = null;
+
+  EchoEchoStringParams() : super(kVersions.last.size);
+
+  static EchoEchoStringParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static EchoEchoStringParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    EchoEchoStringParams result = new EchoEchoStringParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.value = decoder0.decodeString(8, true);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(value, 8, true);
+  }
+
+  String toString() {
+    return "EchoEchoStringParams("
+           "value: $value" ")";
+  }
+}
+
+class EchoEchoStringResponseParams extends bindings.Struct {
+  static const List<bindings.StructDataHeader> kVersions = const [
+    const bindings.StructDataHeader(16, 0)
+  ];
+  String value = null;
+
+  EchoEchoStringResponseParams() : super(kVersions.last.size);
+
+  static EchoEchoStringResponseParams deserialize(bindings.Message message) {
+    var decoder = new bindings.Decoder(message);
+    var result = decode(decoder);
+    decoder.excessHandles.forEach((h) => h.close());
+    return result;
+  }
+
+  static EchoEchoStringResponseParams decode(bindings.Decoder decoder0) {
+    if (decoder0 == null) {
+      return null;
+    }
+    EchoEchoStringResponseParams result = new EchoEchoStringResponseParams();
+
+    var mainDataHeader = decoder0.decodeStructDataHeader();
+    if (mainDataHeader.version <= kVersions.last.version) {
+      // Scan in reverse order to optimize for more recent versions.
+      for (int i = kVersions.length - 1; i >= 0; --i) {
+        if (mainDataHeader.version >= kVersions[i].version) {
+          if (mainDataHeader.size == kVersions[i].size) {
+            // Found a match.
+            break;
+          }
+          throw new bindings.MojoCodecError(
+              'Header size doesn\'t correspond to known version size.');
+        }
+      }
+    } else if (mainDataHeader.size < kVersions.last.size) {
+      throw new bindings.MojoCodecError(
+        'Message newer than the last known version cannot be shorter than '
+        'required by the last known version.');
+    }
+    if (mainDataHeader.version >= 0) {
+      
+      result.value = decoder0.decodeString(8, true);
+    }
+    return result;
+  }
+
+  void encode(bindings.Encoder encoder) {
+    var encoder0 = encoder.getStructEncoderAtOffset(kVersions.last);
+    
+    encoder0.encodeString(value, 8, true);
+  }
+
+  String toString() {
+    return "EchoEchoStringResponseParams("
+           "value: $value" ")";
+  }
+}
+
+const int kEcho_echoString_name = 0;
+
+const String EchoName =
+      'mojo::examples::Echo';
+
+abstract class Echo {
+  Future<EchoEchoStringResponseParams> echoString(String value,[Function responseFactory = null]);
+
+}
+
+
+class EchoProxyImpl extends bindings.Proxy {
+  EchoProxyImpl.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) : super.fromEndpoint(endpoint);
+
+  EchoProxyImpl.fromHandle(core.MojoHandle handle) :
+      super.fromHandle(handle);
+
+  EchoProxyImpl.unbound() : super.unbound();
+
+  static EchoProxyImpl newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For EchoProxyImpl"));
+    return new EchoProxyImpl.fromEndpoint(endpoint);
+  }
+
+  String get name => EchoName;
+
+  void handleResponse(bindings.ServiceMessage message) {
+    switch (message.header.type) {
+      case kEcho_echoString_name:
+        var r = EchoEchoStringResponseParams.deserialize(
+            message.payload);
+        if (!message.header.hasRequestId) {
+          throw 'Expected a message with a valid request Id.';
+        }
+        Completer c = completerMap[message.header.requestId];
+        if (c == null) {
+          throw 'Message had unknown request Id: ${message.header.requestId}';
+        }
+        completerMap.remove(message.header.requestId);
+        assert(!c.isCompleted);
+        c.complete(r);
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "EchoProxyImpl($superString)";
+  }
+}
+
+
+class _EchoProxyCalls implements Echo {
+  EchoProxyImpl _proxyImpl;
+
+  _EchoProxyCalls(this._proxyImpl);
+    Future<EchoEchoStringResponseParams> echoString(String value,[Function responseFactory = null]) {
+      assert(_proxyImpl.isBound);
+      var params = new EchoEchoStringParams();
+      params.value = value;
+      return _proxyImpl.sendMessageWithRequestId(
+          params,
+          kEcho_echoString_name,
+          -1,
+          bindings.MessageHeader.kMessageExpectsResponse);
+    }
+}
+
+
+class EchoProxy implements bindings.ProxyBase {
+  final bindings.Proxy impl;
+  Echo ptr;
+  final String name = EchoName;
+
+  EchoProxy(EchoProxyImpl proxyImpl) :
+      impl = proxyImpl,
+      ptr = new _EchoProxyCalls(proxyImpl);
+
+  EchoProxy.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) :
+      impl = new EchoProxyImpl.fromEndpoint(endpoint) {
+    ptr = new _EchoProxyCalls(impl);
+  }
+
+  EchoProxy.fromHandle(core.MojoHandle handle) :
+      impl = new EchoProxyImpl.fromHandle(handle) {
+    ptr = new _EchoProxyCalls(impl);
+  }
+
+  EchoProxy.unbound() :
+      impl = new EchoProxyImpl.unbound() {
+    ptr = new _EchoProxyCalls(impl);
+  }
+
+  static EchoProxy newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For EchoProxy"));
+    return new EchoProxy.fromEndpoint(endpoint);
+  }
+
+  Future close({bool immediate: false}) => impl.close(immediate: immediate);
+
+  int get version => impl.version;
+
+  Future<int> queryVersion() => impl.queryVersion();
+
+  void requireVersion(int requiredVersion) {
+    impl.requireVersion(requiredVersion);
+  }
+
+  String toString() {
+    return "EchoProxy($impl)";
+  }
+}
+
+
+class EchoStub extends bindings.Stub {
+  Echo _impl = null;
+
+  EchoStub.fromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint, [this._impl])
+      : super.fromEndpoint(endpoint);
+
+  EchoStub.fromHandle(core.MojoHandle handle, [this._impl])
+      : super.fromHandle(handle);
+
+  EchoStub.unbound() : super.unbound();
+
+  static EchoStub newFromEndpoint(
+      core.MojoMessagePipeEndpoint endpoint) {
+    assert(endpoint.setDescription("For EchoStub"));
+    return new EchoStub.fromEndpoint(endpoint);
+  }
+
+  static const String name = EchoName;
+
+
+  EchoEchoStringResponseParams _EchoEchoStringResponseParamsFactory(String value) {
+    var result = new EchoEchoStringResponseParams();
+    result.value = value;
+    return result;
+  }
+
+  Future<bindings.Message> handleMessage(bindings.ServiceMessage message) {
+    if (bindings.ControlMessageHandler.isControlMessage(message)) {
+      return bindings.ControlMessageHandler.handleMessage(this,
+                                                          0,
+                                                          message);
+    }
+    assert(_impl != null);
+    switch (message.header.type) {
+      case kEcho_echoString_name:
+        var params = EchoEchoStringParams.deserialize(
+            message.payload);
+        return _impl.echoString(params.value,_EchoEchoStringResponseParamsFactory).then((response) {
+          if (response != null) {
+            return buildResponseWithId(
+                response,
+                kEcho_echoString_name,
+                message.header.requestId,
+                bindings.MessageHeader.kMessageIsResponse);
+          }
+        });
+        break;
+      default:
+        throw new bindings.MojoCodecError("Unexpected message name");
+        break;
+    }
+    return null;
+  }
+
+  Echo get impl => _impl;
+  set impl(Echo d) {
+    assert(_impl == null);
+    _impl = d;
+  }
+
+  String toString() {
+    var superString = super.toString();
+    return "EchoStub($superString)";
+  }
+
+  int get version => 0;
+}
+
+
diff --git a/gen/go/src/mojom/echo/echo.mojom.go b/gen/go/src/mojom/echo/echo.mojom.go
new file mode 100644
index 0000000..4e92b49
--- /dev/null
+++ b/gen/go/src/mojom/echo/echo.mojom.go
@@ -0,0 +1,300 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is autogenerated by:
+//     mojo/public/tools/bindings/mojom_bindings_generator.py
+// For:
+//     mojom/echo.mojom
+//
+
+package echo
+
+import (
+	"fmt"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+	"sort"
+)
+
+type Echo interface {
+	EchoString(inValue *string) (outValue *string, err error)
+}
+
+var echo_Name = "mojo::examples::Echo"
+
+type Echo_Request bindings.InterfaceRequest
+
+func (r *Echo_Request) Name() string {
+	return echo_Name
+}
+
+type Echo_Pointer bindings.InterfacePointer
+
+func (p *Echo_Pointer) Name() string {
+	return echo_Name
+}
+
+type Echo_ServiceFactory struct{
+	Delegate Echo_Factory
+}
+
+type Echo_Factory interface {
+	Create(request Echo_Request)
+}
+
+func (f *Echo_ServiceFactory) Name() string {
+	return echo_Name
+}
+
+func (f *Echo_ServiceFactory) Create(messagePipe system.MessagePipeHandle) {
+	request := Echo_Request{bindings.NewMessagePipeHandleOwner(messagePipe)}
+	f.Delegate.Create(request)
+}
+
+// CreateMessagePipeForEcho creates a message pipe for use with the
+// Echo interface with a Echo_Request on one end and a Echo_Pointer on the other.
+func CreateMessagePipeForEcho() (Echo_Request, Echo_Pointer) {
+        r, p := bindings.CreateMessagePipeForMojoInterface()
+        return Echo_Request(r), Echo_Pointer(p)
+}
+
+const echo_EchoString_Name uint32 = 0
+
+type Echo_Proxy struct {
+	router *bindings.Router
+	ids bindings.Counter
+}
+
+func NewEchoProxy(p Echo_Pointer, waiter bindings.AsyncWaiter) *Echo_Proxy {
+	return &Echo_Proxy{
+		bindings.NewRouter(p.PassMessagePipe(), waiter),
+		bindings.NewCounter(),
+	}
+}
+
+func (p *Echo_Proxy) Close_Proxy() {
+	p.router.Close()
+}
+
+type echo_EchoString_Params struct {
+	inValue *string
+}
+
+func (s *echo_EchoString_Params) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if s.inValue == nil {
+		encoder.WriteNullPointer()
+	} else {
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		if err := encoder.WriteString((*s.inValue)); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var echo_EchoString_Params_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *echo_EchoString_Params) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(echo_EchoString_Params_Versions), func(i int) bool {
+		return echo_EchoString_Params_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(echo_EchoString_Params_Versions) {
+		if echo_EchoString_Params_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := echo_EchoString_Params_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			s.inValue = nil
+		} else {
+			s.inValue = new(string)
+			value0, err := decoder.ReadString()
+			if err != nil {
+				return err
+			}
+			(*s.inValue) = value0
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+type echo_EchoString_ResponseParams struct {
+	outValue *string
+}
+
+func (s *echo_EchoString_ResponseParams) Encode(encoder *bindings.Encoder) error {
+	encoder.StartStruct(8, 0)
+	if s.outValue == nil {
+		encoder.WriteNullPointer()
+	} else {
+		if err := encoder.WritePointer(); err != nil {
+			return err
+		}
+		if err := encoder.WriteString((*s.outValue)); err != nil {
+			return err
+		}
+	}
+	if err := encoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+var echo_EchoString_ResponseParams_Versions []bindings.DataHeader = []bindings.DataHeader{
+	bindings.DataHeader{16, 0},
+}
+
+func (s *echo_EchoString_ResponseParams) Decode(decoder *bindings.Decoder) error {
+	header, err := decoder.StartStruct()
+	if err != nil {
+		return err
+	}
+	index := sort.Search(len(echo_EchoString_ResponseParams_Versions), func(i int) bool {
+		return echo_EchoString_ResponseParams_Versions[i].ElementsOrVersion >= header.ElementsOrVersion
+	})
+	if index < len(echo_EchoString_ResponseParams_Versions) {
+		if echo_EchoString_ResponseParams_Versions[index].ElementsOrVersion > header.ElementsOrVersion {
+			index--
+		}
+		expectedSize := echo_EchoString_ResponseParams_Versions[index].Size
+		if expectedSize != header.Size {
+			return &bindings.ValidationError{bindings.UnexpectedStructHeader,
+				fmt.Sprintf("invalid struct header size: should be %d, but was %d", expectedSize, header.Size),
+			}
+		}
+	}
+	if header.ElementsOrVersion >= 0 {
+		pointer0, err := decoder.ReadPointer()
+		if err != nil {
+			return err
+		}
+		if pointer0 == 0 {
+			s.outValue = nil
+		} else {
+			s.outValue = new(string)
+			value0, err := decoder.ReadString()
+			if err != nil {
+				return err
+			}
+			(*s.outValue) = value0
+		}
+	}
+	if err := decoder.Finish(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p *Echo_Proxy) EchoString(inValue *string) (outValue *string, err error) {
+	payload := &echo_EchoString_Params{
+		inValue,
+	}
+	header := bindings.MessageHeader{
+		Type: echo_EchoString_Name,
+		Flags: bindings.MessageExpectsResponseFlag,
+		RequestId: p.ids.Count(),
+	}
+	var message *bindings.Message
+	if message, err = bindings.EncodeMessage(header, payload); err != nil {
+		err = fmt.Errorf("can't encode request: %v", err.Error())
+		p.Close_Proxy()
+		return
+	}
+	readResult := <-p.router.AcceptWithResponse(message)
+	if err = readResult.Error; err != nil {
+		p.Close_Proxy()
+		return
+	}
+	if readResult.Message.Header.Flags != bindings.MessageIsResponseFlag {
+		err = &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+			fmt.Sprintf("invalid message header flag: %v", readResult.Message.Header.Flags),
+		}
+		return
+	}
+	if got, want := readResult.Message.Header.Type, echo_EchoString_Name; got != want {
+		err = &bindings.ValidationError{bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("invalid method in response: expected %v, got %v", want, got),
+		}
+		return
+	}
+	var response echo_EchoString_ResponseParams
+	if err = readResult.Message.DecodePayload(&response); err != nil {
+		p.Close_Proxy()
+		return
+	}
+	outValue = response.outValue
+	return
+}
+
+type echo_Stub struct {
+	connector *bindings.Connector
+	impl Echo
+}
+
+func NewEchoStub(r Echo_Request, impl Echo, waiter bindings.AsyncWaiter) *bindings.Stub {
+	connector := bindings.NewConnector(r.PassMessagePipe(), waiter)
+	return bindings.NewStub(connector, &echo_Stub{connector, impl})
+}
+
+func (s *echo_Stub) Accept(message *bindings.Message) (err error) {
+	switch message.Header.Type {
+	case echo_EchoString_Name:
+		if message.Header.Flags != bindings.MessageExpectsResponseFlag {
+			return &bindings.ValidationError{bindings.MessageHeaderInvalidFlags,
+				fmt.Sprintf("invalid message header flag: %v", message.Header.Flags),
+			}
+		}
+		var request echo_EchoString_Params
+		if err := message.DecodePayload(&request); err != nil {
+			return err
+		}
+		var response echo_EchoString_ResponseParams
+		response.outValue, err = s.impl.EchoString(request.inValue)
+		if err != nil {
+			return
+		}
+		header := bindings.MessageHeader{
+			Type: echo_EchoString_Name,
+			Flags: bindings.MessageIsResponseFlag,
+			RequestId: message.Header.RequestId,
+		}
+		message, err = bindings.EncodeMessage(header, &response)
+		if err != nil {
+			return err
+		}
+		return s.connector.WriteMessage(message)
+	default:
+		return &bindings.ValidationError{
+			bindings.MessageHeaderUnknownMethod,
+			fmt.Sprintf("unknown method %v", message.Header.Type),
+		}
+	}
+	return
+}
+
diff --git a/gen/mojom/echo.mojom.dart b/gen/mojom/echo.mojom.dart
new file mode 120000
index 0000000..ba586ca
--- /dev/null
+++ b/gen/mojom/echo.mojom.dart
@@ -0,0 +1 @@
+gen/dart-gen/mojom/lib/mojo/examples/echo.mojom.dart
\ No newline at end of file
diff --git a/mojom/echo.mojom b/mojom/echo.mojom
new file mode 100644
index 0000000..7604377
--- /dev/null
+++ b/mojom/echo.mojom
@@ -0,0 +1,10 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[JavaPackage="org.chromium.mojo.examples.echo"]
+module mojo.examples;
+
+interface Echo {
+  EchoString(string? value) => (string? value);
+};