ether: beginnings of syncbase mojo client/server

Change-Id: If4bae2e6750ee0bb2c56adc2aa036612b79d4abf
diff --git a/Makefile b/Makefile
index 48ce1b8..8534ec7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,12 @@
-PWD=$(shell pwd)
-DART_FILES=$(shell find $(PWD)/dart -name *.dart ! -name *.part.dart)
-V23_GOPATH=$(shell echo `v23 run env | grep GOPATH | cut -d\= -f2`)
+SHELL := /bin/bash -euo pipefail
+PWD := $(shell pwd)
+V23_GOPATH := $(shell echo `v23 run env | grep GOPATH | cut -d\= -f2`)
+DART_FILES := $(shell find $(PWD)/dart -name *.dart ! -name *.part.dart)
+GO_FILES := $(shell find go/src -name "*.go")
+V23_GO_FILES := $(shell find $(V23_ROOT) -name "*.go")
 
 ifndef MOJO_DIR
-	$(error MOJO_DIR is not set: ${MOJO_DIR})
+	$(error MOJO_DIR is not set: $(MOJO_DIR))
 endif
 
 ifdef ANDROID
@@ -13,18 +16,18 @@
 	$(error Android is currently not supported.)
 
 	# 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
+	GO_BIN := $(MOJO_DIR)/src/third_party/go/tool/android_arm/bin/go
+	GO_FLAGS := -tags=mojo -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
+	GO_BIN := $(MOJO_DIR)/src/third_party/go/tool/linux_amd64/bin/go
+	GO_FLAGS := -tags=mojo -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.
@@ -34,8 +37,8 @@
 # MOGO_BIN).
 #
 # MOJO_GOPATH must be exported so it can be picked up by MOGO_BIN.
-export MOJO_GOPATH=$(V23_GOPATH):$(PWD)/gen/go:$(PWD)/go:$(MOJO_BUILD_DIR)/gen/go
-MOGO_BIN=$(MOJO_DIR)/src/mojo/go/go.py
+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) -- \
@@ -46,14 +49,14 @@
 		$(PWD)/gen \
 		"-I$(MOJO_DIR)/src" \
 		"-L$(dir $(MOJO_SHARED_LIB)) -lsystem_thunk" \
-		build $(GO_FLAGS) $(PWD)/$1
+		build $(GO_FLAGS) $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
+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
@@ -90,8 +93,11 @@
 	$(call MOJOM_GEN,$<,gen,go)
 	gofmt -w $@
 
-gen/mojo/echo_server.mojo: go/src/echo_server.go gen-mojom $(MOJO_SHARED_LIB)
-	$(call MOGO_BUILD,$<,$@)
+gen/mojo/echo_server.mojo: $(GO_FILES) gen-mojom $(MOJO_SHARED_LIB)
+	$(call MOGO_BUILD,$(PWD)/go/src/echo_server.go,$@)
+
+gen/mojo/syncbase_server.mojo: $(GO_FILES) $(V23_GO_FILES) gen-mojom $(MOJO_SHARED_LIB)
+	$(call MOGO_BUILD,v.io/syncbase/x/ref/services/syncbase/syncbased,$@)
 
 # Check that the dart-style is being met. Note: Comments are ignored when
 # checking whitespace.
@@ -112,6 +118,10 @@
 run-echo-app: gen/mojo/echo_server.mojo gen-mojom dart/packages
 	$(MOJO_DIR)/src/mojo/devtools/common/mojo_run $(MOJO_FLAGS) -v --enable-multiprocess $(PWD)/dart/bin/echo_client.dart
 
+.PHONY: run-syncbase-app
+run-syncbase-app: gen/mojo/syncbase_server.mojo gen-mojom dart/packages
+	$(MOJO_DIR)/src/mojo/devtools/common/mojo_run $(MOJO_FLAGS) -v --enable-multiprocess $(PWD)/dart/bin/syncbase_client.dart
+
 # TODO(nlacasse): This should run real tests once we have them.
 .PHONY: test
 test: dartanalyzer
diff --git a/dart/bin/echo_client.dart b/dart/bin/echo_client.dart
index 1a040fa..b919391 100644
--- a/dart/bin/echo_client.dart
+++ b/dart/bin/echo_client.dart
@@ -18,12 +18,12 @@
     // either broken or unsupported.  In any case, this will never work on
     // Android, so we should switch to serving these files over http rather
     // than directly from the filesystem.
-    String echoServerUrl = url.replaceFirst('dart/bin/echo_client.dart', 'gen/mojo/echo_server.mojo');
+    String serviceUrl = url.replaceFirst('dart/bin/echo_client.dart', 'gen/mojo/echo_server.mojo');
 
-    print('connecting to $echoServerUrl');
+    print('connecting to $serviceUrl');
 
-    EchoProxy ep = new EchoProxy.unbound();
-    connectToService(echoServerUrl, ep);
+    EchoProxy p = new EchoProxy.unbound();
+    connectToService(serviceUrl, p);
 
     print('connected');
 
diff --git a/dart/bin/syncbase_client.dart b/dart/bin/syncbase_client.dart
new file mode 100644
index 0000000..536c6df
--- /dev/null
+++ b/dart/bin/syncbase_client.dart
@@ -0,0 +1,42 @@
+#!mojo mojo:dart_content_handler
+
+import 'dart:async';
+
+// TODO(nlacasse): Use 'show' or 'as' in non-stdlib import statements, per
+// Vanadium Dart convention.
+import 'package:mojo/application.dart';
+import 'package:mojo/core.dart';
+
+import '../../gen/dart-gen/mojom/lib/mojo/syncbase.mojom.dart' show SyncbaseProxy;
+
+class Client extends Application {
+  Client.fromHandle(MojoHandle handle) : super.fromHandle(handle);
+
+  void initialize(List<String> args, String url) {
+    // TODO(nlacasse): This is pretty gross, but there's no good way to get the
+    // current directory from within a Mojo app.  Dart's Directory.current() is
+    // either broken or unsupported.  In any case, this will never work on
+    // Android, so we should switch to serving these files over http rather
+    // than directly from the filesystem.
+    String serviceUrl = url.replaceFirst('dart/bin/syncbase_client.dart', 'gen/mojo/syncbase_server.mojo');
+
+    print('connecting to $serviceUrl');
+
+    SyncbaseProxy p = new SyncbaseProxy.unbound();
+    connectToService(serviceUrl, p);
+
+    print('connected');
+
+    closeApplication();
+  }
+
+  Future closeApplication() async {
+    await close();
+    assert(MojoHandle.reportLeakedHandles());
+  }
+}
+
+main(List args) {
+  MojoHandle appHandle = new MojoHandle(args[0]);
+  new Client.fromHandle(appHandle);
+}
diff --git a/go/src/echo_server.go b/go/src/echo_server.go
index 892340a..2a8ccd8 100644
--- a/go/src/echo_server.go
+++ b/go/src/echo_server.go
@@ -22,27 +22,28 @@
 //#include "mojo/public/c/system/types.h"
 import "C"
 
-type EchoImpl struct{}
+type echoImpl struct{}
 
-func (echo *EchoImpl) EchoString(inValue *string) (outValue *string, err error) {
-	log.Printf("server: %s\n", *inValue)
-	return inValue, nil
+func (e *echoImpl) EchoString(in *string) (out *string, err error) {
+	log.Printf("server: %s\n", *in)
+	return in, nil
 }
 
-type EchoServerDelegate struct {
+type delegate struct {
 	stubs []*bindings.Stub
 }
 
-func (delegate *EchoServerDelegate) Initialize(context application.Context) {}
+func (d *delegate) Initialize(ctx application.Context) {}
 
-func (delegate *EchoServerDelegate) Create(request echo.Echo_Request) {
-	stub := echo.NewEchoStub(request, &EchoImpl{}, bindings.GetAsyncWaiter())
-	delegate.stubs = append(delegate.stubs, stub)
+func (d *delegate) Create(req echo.Echo_Request) {
+	impl := &echoImpl{}
+	stub := echo.NewEchoStub(req, impl, bindings.GetAsyncWaiter())
+	d.stubs = append(d.stubs, stub)
 	go func() {
 		for {
 			if err := stub.ServeRequest(); err != nil {
-				connectionError, ok := err.(*bindings.ConnectionError)
-				if !ok || !connectionError.Closed() {
+				connErr, ok := err.(*bindings.ConnectionError)
+				if !ok || !connErr.Closed() {
 					log.Println(err)
 				}
 				break
@@ -51,19 +52,19 @@
 	}()
 }
 
-func (delegate *EchoServerDelegate) AcceptConnection(connection *application.Connection) {
-	connection.ProvideServices(&echo.Echo_ServiceFactory{delegate})
+func (d *delegate) AcceptConnection(conn *application.Connection) {
+	conn.ProvideServices(&echo.Echo_ServiceFactory{d})
 }
 
-func (delegate *EchoServerDelegate) Quit() {
-	for _, stub := range delegate.stubs {
+func (d *delegate) Quit() {
+	for _, stub := range d.stubs {
 		stub.Close()
 	}
 }
 
 //export MojoMain
 func MojoMain(handle C.MojoHandle) C.MojoResult {
-	application.Run(&EchoServerDelegate{}, system.MojoHandle(handle))
+	application.Run(&delegate{}, system.MojoHandle(handle))
 	return C.MOJO_RESULT_OK
 }
 
diff --git a/mojom/syncbase.mojom b/mojom/syncbase.mojom
index 6fd799b..84d0387 100644
--- a/mojom/syncbase.mojom
+++ b/mojom/syncbase.mojom
@@ -1,5 +1,7 @@
 // TODO(sadovsky): Copy struct and interface comments from VDL files.
-module mojo.syncbase;
+
+// TODO(sadovsky): This should probably be something else.
+module mojo;
 
 // TODO(sadovsky): Put structs in a separate types.mojom file.
 // TODO(sadovsky): Loose representation of verror. Improve this.
@@ -77,7 +79,7 @@
   AppSetPermissions(string name, Perms perms, string version) => (Error err);
 
   ////////////////////////////////////////
-  // Database
+  // nosql.Database
 
   // TODO(sadovsky): Add SchemaMetadata argument.
   DbCreate(string name, Perms perms) => (Error err);