v23proxy: Migrate example mojom files over

This also demonstrates their use with the new ServiceDescriber in
the work of https://codereview.chromium.org/1345263002/

The Makefile has a few more commands, notably start-v23proxy,
start-echo-client and start-fortune-client. These ought to interact
properly with Vanadium services and clients if the proper REMOTE_ENDPOINT
is passed (unfortunately that was not tested). Additionally, in
order to run more than one of these at a time, you'll need to
delete a LOCK file for a Mojo cache (noted in the Makefile).

This CL has also identified that we will want to add a method to
Mojo's bindings.Encoder that helps to WriteRawBytes.

Change-Id: If3a57d612a0e6d5082013378a647495e59a4603d
diff --git a/Makefile b/Makefile
index b48cd9c..1a94de4 100644
--- a/Makefile
+++ b/Makefile
@@ -10,14 +10,38 @@
 	MOJO_SHARED_LIB := $(PWD)/gen/lib/linux_amd64/libsystem_thunk.a
 endif
 
-build: $(BUILD_DIR)/v23proxy.mojo
+# Build the v23proxy and the associated examples.
+.PHONY: build
+build: $(BUILD_DIR)/v23proxy.mojo build-examples
+
+build-examples: $(BUILD_DIR)/echo_client.mojo $(BUILD_DIR)/echo_server.mojo $(BUILD_DIR)/fortune_client.mojo $(BUILD_DIR)/fortune_server.mojo
+
+$(BUILD_DIR)/echo_client.mojo: $(MOJO_SHARED_LIB) gen/go/src/mojom/examples/echo/echo.mojom.go
+	$(call MOGO_BUILD,examples/echo/client,$@)
+
+$(BUILD_DIR)/echo_server.mojo: $(MOJO_SHARED_LIB) gen/go/src/mojom/examples/echo/echo.mojom.go
+	$(call MOGO_BUILD,examples/echo/server,$@)
+
+gen/go/src/mojom/examples/echo/echo.mojom.go: mojom/mojom/examples/echo.mojom | mojo-env-check
+	$(call MOJOM_GEN,$<,mojom,gen,go)
+	gofmt -w $@
+
+$(BUILD_DIR)/fortune_client.mojo: $(MOJO_SHARED_LIB) gen/go/src/mojom/examples/fortune/fortune.mojom.go
+	$(call MOGO_BUILD,examples/fortune/client,$@)
+
+$(BUILD_DIR)/fortune_server.mojo: $(MOJO_SHARED_LIB) gen/go/src/mojom/examples/fortune/fortune.mojom.go
+	$(call MOGO_BUILD,examples/fortune/server,$@)
+
+gen/go/src/mojom/examples/fortune/fortune.mojom.go: mojom/mojom/examples/fortune.mojom | mojo-env-check
+	$(call MOJOM_GEN,$<,mojom,gen,go)
+	gofmt -w $@
 
 $(BUILD_DIR)/v23proxy.mojo: $(MOJO_SHARED_LIB) gen/go/src/mojom/v23proxy/v23proxy.mojom.go | mojo-env-check
 	$(call MOGO_BUILD,v.io/x/mojo/proxy,$@)
 
 mojom/mojo/public/interfaces/bindings/mojom_types.mojom: $(MOJO_DIR)/src/mojo/public/interfaces/bindings/mojom_types.mojom
 	mkdir -p mojom/mojo/public/interfaces/bindings
-	ln -s $(MOJO_DIR)/src/mojo/public/interfaces/bindings/mojom_types.mojom mojom/mojo/public/interfaces/bindings/mojom_types.mojom
+	ln -sf $(MOJO_DIR)/src/mojo/public/interfaces/bindings/mojom_types.mojom mojom/mojo/public/interfaces/bindings/mojom_types.mojom
 
 gen/go/src/mojo/public/interfaces/bindings/mojom_types/mojom_types.mojom.go: mojom/mojo/public/interfaces/bindings/mojom_types.mojom | mojo-env-check
 	$(call MOJOM_GEN,$<,mojom,gen,go)
@@ -27,5 +51,52 @@
 	$(call MOJOM_GEN,$<,mojom,gen,go)
 	gofmt -w $@
 
+define RUN_MOJO_SHELL
+	$(MOJO_DIR)/src/mojo/devtools/common/mojo_run \
+	$1 \
+	--config-file mojoconfig \
+	--config-alias BUILD_DIR=$(BUILD_DIR) \
+	--config-alias PORT=$2 \
+	https://mojo.v.io/$3
+endef
 
-.PHONY: build
+# Start the v23proxy (server-side). This runs the v23proxy in its own shell and
+# will print an endpoint to stdout. That endpoint needs to be passed to the clients.
+#
+# Highly recommended: Prefix this command with HOME={a unique tmp directory}
+# We cannot disable the db LOCK that is created, so one workaround is to use a
+# different HOME directory per mojo shell.
+.PHONY: start-v23proxy
+start-v23proxy: build
+	$(call RUN_MOJO_SHELL,--enable-multiprocess,31941,v23proxy.mojo)
+
+# Start the echo client. This uses the v23proxy (client-side) to speak Vanadium
+# over to the v23proxy (server-side) [OR a 0-authentication Vanadium echo server].
+#
+# Note: Does not use --enable-multiprocess since small Go programs can omit it.
+# Don't forget to prepend REMOTE_ENDPOINT={endpoint}/https://mojo.v.io/echo_server.mojo/mojo::examples::RemoteEcho
+#
+# Highly recommended: Prefix this command with HOME={a unique tmp directory}
+# We cannot disable the db LOCK that is created, so one workaround is to use a
+# different HOME directory per mojo shell.
+.PHONY: start-echo-client
+start-echo-client: build
+	$(call RUN_MOJO_SHELL,,31942,echo_client.mojo)
+
+# Start the fortune client. This uses the v23proxy (client-side) to speak Vanadium
+# over to the v23proxy (server-side) [OR a 0-authentication Vanadium fortune server].
+#
+# Note: Does not use --enable-multiprocess since small Go programs can omit it.
+# Don't forget to prepend REMOTE_ENDPOINT={endpoint}/https://mojo.v.io/fortune_server.mojo/mojo::examples::Fortune
+# You may optionally prepend ADD_FORTUNE={some fortune}
+#
+# Highly recommended: Prefix this command with HOME={a unique tmp directory}
+# We cannot disable the db LOCK that is created, so one workaround is to use a
+# different HOME directory per mojo shell.
+.PHONY: start-fortune-client
+start-fortune-client: build
+	$(call RUN_MOJO_SHELL,,31943,fortune_client.mojo)
+
+.PHONY: clean
+clean:
+	rm -r gen
diff --git a/go/src/examples/echo/client/echo_client.go b/go/src/examples/echo/client/echo_client.go
new file mode 100644
index 0000000..767a1bc
--- /dev/null
+++ b/go/src/examples/echo/client/echo_client.go
@@ -0,0 +1,71 @@
+// 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.
+
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	v23 "v.io/x/mojo/client"
+
+	"mojom/examples/echo"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type RemoteEchoClientDelegate struct{}
+
+func (delegate *RemoteEchoClientDelegate) Initialize(ctx application.Context) {
+	log.Printf("RemoteEchoClientDelegate.Initialize...")
+	remoteEndpoint := os.Getenv("REMOTE_ENDPOINT")
+	r, p := echo.CreateMessagePipeForRemoteEcho()
+
+	v23.ConnectToRemoteService(ctx, &r, remoteEndpoint)
+	echoProxy := echo.NewRemoteEchoProxy(p, bindings.GetAsyncWaiter())
+
+	log.Printf("RemoteEchoClientDelegate.Initialize calling EchoString...")
+	response, err := echoProxy.EchoString("Hello, Go world!")
+	if err == nil {
+		fmt.Printf("client: %s\n", response)
+	} else {
+		log.Println(err)
+	}
+
+	log.Printf("RemoteEchoClientDelegate.Initialize calling EchoX...")
+	response2, err := echoProxy.EchoX([]bool{true, false, false, true}, echo.AInArg{"A String"})
+	if err == nil {
+		fmt.Printf("client: %v\n", response2)
+	} else {
+		log.Println("Error: ", err)
+	}
+
+	fmt.Printf("(done)\n")
+	echoProxy.Close_Proxy()
+	ctx.Close()
+}
+
+func (delegate *RemoteEchoClientDelegate) AcceptConnection(connection *application.Connection) {
+	log.Printf("RemoteEchoClientDelegate.AcceptConnection...")
+	connection.Close()
+}
+
+func (delegate *RemoteEchoClientDelegate) Quit() {
+	log.Printf("RemoteEchoClientDelegate.Quit...")
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&RemoteEchoClientDelegate{}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {
+}
diff --git a/go/src/examples/echo/server/echo_server.go b/go/src/examples/echo/server/echo_server.go
new file mode 100644
index 0000000..4e75c6b
--- /dev/null
+++ b/go/src/examples/echo/server/echo_server.go
@@ -0,0 +1,83 @@
+// 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.
+
+package main
+
+import (
+	"log"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	"mojom/examples/echo"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type RemoteEchoImpl struct{}
+
+// Note: This is pretty much identical to echo_server.go, except for the name changes.
+func (re *RemoteEchoImpl) EchoString(inValue string) (outValue string, err error) {
+	log.Printf("server EchoString: %s\n", inValue)
+	return inValue, nil
+}
+
+func (re *RemoteEchoImpl) EchoX(inArg1 []bool, inArg2 echo.AInArg) (out echo.OutArgTypes, err error) {
+	log.Printf("server EchoX: arg1: %v arg2: %v\n", inArg1, inArg2)
+	return &echo.OutArgTypesRes{echo.Result_B}, nil
+}
+
+type RemoteEchoServerDelegate struct {
+	remoteEchoFactory RemoteEchoFactory
+}
+
+type RemoteEchoFactory struct {
+	stubs []*bindings.Stub
+}
+
+func (delegate *RemoteEchoServerDelegate) Initialize(context application.Context) {
+	log.Printf("RemoteEchoServerDelegate.Initialize...")
+}
+
+func (remoteEchoFactory *RemoteEchoFactory) Create(request echo.RemoteEcho_Request) {
+	log.Printf("RemoteEchoServer's RemoteEchoFactory.Create...")
+	stub := echo.NewRemoteEchoStub(request, &RemoteEchoImpl{}, bindings.GetAsyncWaiter())
+	remoteEchoFactory.stubs = append(remoteEchoFactory.stubs, stub)
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connectionError, ok := err.(*bindings.ConnectionError)
+				if !ok || !connectionError.Closed() {
+					log.Println(err)
+				}
+				break
+			}
+		}
+	}()
+}
+
+func (delegate *RemoteEchoServerDelegate) AcceptConnection(connection *application.Connection) {
+	log.Printf("RemoteEchoServerDelegate.AcceptConnection...")
+	connection.ProvideServicesWithDescriber(
+		&echo.RemoteEcho_ServiceFactory{&delegate.remoteEchoFactory},
+	)
+}
+
+func (delegate *RemoteEchoServerDelegate) Quit() {
+	log.Printf("RemoteEchoServerDelegate.Quit...")
+	for _, stub := range delegate.remoteEchoFactory.stubs {
+		stub.Close()
+	}
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&RemoteEchoServerDelegate{}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {
+}
diff --git a/go/src/examples/fortune/client/fortune_client.go b/go/src/examples/fortune/client/fortune_client.go
new file mode 100644
index 0000000..5ea3545
--- /dev/null
+++ b/go/src/examples/fortune/client/fortune_client.go
@@ -0,0 +1,75 @@
+// 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.
+
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	v23 "v.io/x/mojo/client"
+
+	"mojom/examples/fortune"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type FortuneClientDelegate struct{}
+
+// Connects to the v23proxy and calls Get (or Add(ADD_FORTUNE) on REMOTE_ENDPOINT.
+// Receives a response, if relevant, then exits.
+func (delegate *FortuneClientDelegate) Initialize(ctx application.Context) {
+	remoteEndpoint := os.Getenv("REMOTE_ENDPOINT")
+	addFortune := os.Getenv("ADD_FORTUNE")
+
+	log.Printf("FortuneClientDelegate.Initialize... %s", remoteEndpoint)
+	fortuneRequest, fortunePointer := fortune.CreateMessagePipeForFortune()
+	v23.ConnectToRemoteService(ctx, &fortuneRequest, remoteEndpoint)
+	fortuneProxy := fortune.NewFortuneProxy(fortunePointer, bindings.GetAsyncWaiter())
+
+	if addFortune != "" {
+		log.Printf("FortuneClientDelegate.Initialize calling Add...")
+
+		if err := fortuneProxy.Add(addFortune); err != nil {
+			log.Println(err)
+		} else {
+			fmt.Printf("client added: %s\n", addFortune)
+		}
+	} else {
+		log.Printf("FortuneClientDelegate.Initialize calling Get...")
+		response, err := fortuneProxy.Get()
+		if response != "" {
+			fmt.Printf("client (get): %s\n", response)
+		} else {
+			log.Println(err)
+		}
+	}
+
+	fortuneProxy.Close_Proxy()
+	ctx.Close()
+}
+
+func (delegate *FortuneClientDelegate) AcceptConnection(connection *application.Connection) {
+	log.Printf("FortuneClientDelegate.AcceptConnection...")
+	connection.Close()
+}
+
+func (delegate *FortuneClientDelegate) Quit() {
+	log.Printf("FortuneClientDelegate.Quit...")
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&FortuneClientDelegate{}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {
+}
diff --git a/go/src/examples/fortune/server/fortune_server.go b/go/src/examples/fortune/server/fortune_server.go
new file mode 100644
index 0000000..f3fb889
--- /dev/null
+++ b/go/src/examples/fortune/server/fortune_server.go
@@ -0,0 +1,110 @@
+// 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.
+
+package main
+
+import (
+	"log"
+	"math/rand"
+	"time"
+
+	"mojo/public/go/application"
+	"mojo/public/go/bindings"
+	"mojo/public/go/system"
+
+	"mojom/examples/fortune"
+)
+
+//#include "mojo/public/c/system/types.h"
+import "C"
+
+type FortuneImpl struct {
+	wisdom []string   // All known fortunes.
+	random *rand.Rand // To pick a random index in 'wisdom'.
+}
+
+// Makes an implementation.
+func NewFortuneImpl() *FortuneImpl {
+	return &FortuneImpl{
+		wisdom: []string{
+			"You will reach the heights of success.",
+			"Conquer your fears or they will conquer you.",
+			"Today is your lucky day!",
+		},
+		random: rand.New(rand.NewSource(time.Now().UnixNano())),
+	}
+}
+
+func (f *FortuneImpl) Add(inValue string) (err error) {
+	log.Printf("server Add: %s\n", inValue)
+
+	f.wisdom = append(f.wisdom, inValue)
+	return nil
+}
+
+func (f *FortuneImpl) Get() (outValue string, err error) {
+	log.Printf("server Get\n")
+
+	if len(f.wisdom) == 0 {
+		return "[empty]", nil
+	}
+	return f.wisdom[f.random.Intn(len(f.wisdom))], nil
+}
+
+type FortuneServerDelegate struct {
+	fortuneFactory FortuneFactory
+}
+
+type FortuneFactory struct {
+	stubs   []*bindings.Stub
+	fortune *FortuneImpl
+}
+
+func (delegate *FortuneServerDelegate) Initialize(context application.Context) {
+	log.Printf("FortuneServerDelegate.Initialize...")
+}
+
+func (ff *FortuneFactory) Create(request fortune.Fortune_Request) {
+	log.Printf("FortuneServerDelegate's FortuneFactory.Create...")
+	stub := fortune.NewFortuneStub(request, ff.fortune, bindings.GetAsyncWaiter())
+	ff.stubs = append(ff.stubs, stub)
+	go func() {
+		for {
+			if err := stub.ServeRequest(); err != nil {
+				connectionError, ok := err.(*bindings.ConnectionError)
+				if !ok || !connectionError.Closed() {
+					log.Println(err)
+				}
+				break
+			}
+		}
+	}()
+}
+
+func (delegate *FortuneServerDelegate) AcceptConnection(connection *application.Connection) {
+	log.Printf("FortuneServerDelegate.AcceptConnection...")
+	connection.ProvideServicesWithDescriber(
+		&fortune.Fortune_ServiceFactory{&delegate.fortuneFactory},
+	)
+}
+
+func (delegate *FortuneServerDelegate) Quit() {
+	log.Printf("FortuneServerDelegate.Quit...")
+	for _, stub := range delegate.fortuneFactory.stubs {
+		stub.Close()
+	}
+}
+
+//export MojoMain
+func MojoMain(handle C.MojoHandle) C.MojoResult {
+	application.Run(&FortuneServerDelegate{
+		fortuneFactory: FortuneFactory{
+			fortune: NewFortuneImpl(),
+		},
+	}, system.MojoHandle(handle))
+	return C.MOJO_RESULT_OK
+}
+
+func main() {
+}
diff --git a/go/src/v.io/x/mojo/client/client.go b/go/src/v.io/x/mojo/client/client.go
index 388ee3e..4e1e8fe 100644
--- a/go/src/v.io/x/mojo/client/client.go
+++ b/go/src/v.io/x/mojo/client/client.go
@@ -9,7 +9,19 @@
 
 func ConnectToRemoteService(ctx application.Context, r application.ServiceRequest, v23Name string) {
 	v23r, v23p := v23proxy.CreateMessagePipeForV23()
-	ctx.ConnectToApplication("mojo:v23proxy").ConnectToService(&v23r)
+	ctx.ConnectToApplication("https://mojo.v.io/v23proxy.mojo").ConnectToService(&v23r)
 	prox := v23proxy.NewV23Proxy(v23p, bindings.GetAsyncWaiter())
-	prox.SetupProxy(v23Name, r.Type(), r.Desc(), r.Name(), r.PassMessagePipe())
+	sd := r.ServiceDescription()
+	mojomInterfaceType, err := sd.GetTopLevelInterface()
+	if err != nil {
+		// The service description must have the MojomInterface type.
+		panic(err)
+	}
+	desc, err := sd.GetAllTypeDefinitions()
+	if err != nil {
+		// The service description must have the map of UserDefinedTypes.
+		panic(err)
+	}
+
+	prox.SetupProxy(v23Name, mojomInterfaceType, *desc, r.Name(), r.PassMessagePipe())
 }
diff --git a/go/src/v.io/x/mojo/proxy/fake_service.go b/go/src/v.io/x/mojo/proxy/fake_service.go
index 8865d1b..294bff3 100644
--- a/go/src/v.io/x/mojo/proxy/fake_service.go
+++ b/go/src/v.io/x/mojo/proxy/fake_service.go
@@ -51,11 +51,7 @@
 	return v.name
 }
 
-func (v *v23ServiceRequest) Type() mojom_types.MojomInterface {
-	panic("not supported")
-}
-
-func (v *v23ServiceRequest) Desc() map[string]mojom_types.UserDefinedType {
+func (v *v23ServiceRequest) ServiceDescription() service_describer.ServiceDescription {
 	panic("not supported")
 }
 
diff --git a/go/src/v.io/x/mojo/proxy/proxy.go b/go/src/v.io/x/mojo/proxy/proxy.go
index 88fb4f9..72ae21d 100644
--- a/go/src/v.io/x/mojo/proxy/proxy.go
+++ b/go/src/v.io/x/mojo/proxy/proxy.go
@@ -71,16 +71,18 @@
 	return nil
 }
 
-type byteCopyingPayload []byte
+// TODO(alexfandrianto): This assumes that bindings.Encoder has the method
+// WriteRawBytes. See the comment block below.
+// type byteCopyingPayload []byte
 
-func (bcp byteCopyingPayload) Encode(encoder *bindings.Encoder) error {
-	encoder.WriteRawBytes(bcp)
-	return nil
-}
+// func (bcp byteCopyingPayload) Encode(encoder *bindings.Encoder) error {
+// 	encoder.WriteRawBytes(bcp)
+// 	return nil
+// }
 
-func (bcp byteCopyingPayload) Decode(decoder *bindings.Decoder) error {
-	panic("not supported")
-}
+// func (bcp byteCopyingPayload) Decode(decoder *bindings.Decoder) error {
+// 	panic("not supported")
+// }
 
 type genericStub struct {
 	header    *v23HeaderReceiver
@@ -89,10 +91,6 @@
 }
 
 func (s *genericStub) Accept(message *bindings.Message) (err error) {
-	/*if int(message.Header.Type) >= len(s.header.ifaceSig.Methods) {
-		return fmt.Errorf("Method had index %d, but interface only has %d methods",
-			message.Header.Type, len(s.header.ifaceSig.Methods))
-	}*/
 	if _, ok := s.header.ifaceSig.Methods[message.Header.Type]; !ok {
 		return fmt.Errorf("Method had index %d, but interface only has %d methods",
 			message.Header.Type, len(s.header.ifaceSig.Methods))
@@ -109,16 +107,48 @@
 	if err != nil {
 		return err
 	}
+
+	// TODO(alexfandrianto): This assumes that bindings.Encoder has the method
+	// WriteRawBytes. We will need to add this to Mojo ourselves.
+	// func (e *Encoder) WriteRawBytes(data []byte) {
+	// 	first := e.end
+	// 	e.claimData(align(len(data), defaultAlignment))
+	// 	copy(e.buf[first:], data)
+	// }
+	//
+	// See: https://codereview.chromium.org/1416433002/
+
 	responseHeader := bindings.MessageHeader{
 		Type:      message.Header.Type,
 		Flags:     bindings.MessageIsResponseFlag,
 		RequestId: message.Header.RequestId,
 	}
-	responseMessage, err := bindings.EncodeMessage(responseHeader, byteCopyingPayload(response))
-	if err != nil {
+	// responseMessage, err := bindings.EncodeMessage(responseHeader, byteCopyingPayload(response))
+	// if err != nil {
+	// 	return err
+	// }
+	// return s.connector.WriteMessage(responseMessage)
+
+	// TODO(alexfandrianto): Replace this block with the above.
+	encoder := bindings.NewEncoder()
+	if err := responseHeader.Encode(encoder); err != nil {
 		return err
 	}
-	return s.connector.WriteMessage(responseMessage)
+	if bytes, handles, err := encoder.Data(); err != nil {
+		return err
+	} else {
+		// response is our payload; append to the end of our slice.
+		bytes = append(bytes, response...)
+
+		// This is analogous to bindings.newMessage
+		responseMessage := &bindings.Message{
+			Header:  responseHeader,
+			Bytes:   bytes,
+			Handles: handles,
+			Payload: response,
+		}
+		return s.connector.WriteMessage(responseMessage)
+	}
 }
 
 func (s *genericStub) Call(name, method string, value []byte, inParamsType mojom_types.MojomStruct, outParamsType *mojom_types.MojomStruct) ([]byte, error) {
diff --git a/go/src/v.io/x/mojo/transcoder/type.go b/go/src/v.io/x/mojo/transcoder/type.go
index 544e0ae..22402d7 100644
--- a/go/src/v.io/x/mojo/transcoder/type.go
+++ b/go/src/v.io/x/mojo/transcoder/type.go
@@ -76,7 +76,7 @@
 	for ix, mfield := range ms.Fields {
 		vfields[ix] = vdl.Field{
 			Name: *mfield.DeclData.ShortName,
-			Type: MojomToVDLType(mfield.FieldType, mp),
+			Type: MojomToVDLType(mfield.Type, mp),
 		}
 	}
 	vt = vdl.NamedType(*ms.DeclData.ShortName, vdl.StructType(vfields...))
diff --git a/mojoconfig b/mojoconfig
new file mode 100644
index 0000000..5339c1f
--- /dev/null
+++ b/mojoconfig
@@ -0,0 +1,35 @@
+# This is a configuration file for devtools (`mojo_run`, `mojo_test) running
+# within a Mojo checkout.
+
+# The content has to parse to a Python dictionary literal. Strings of the form
+# '@{ABC}' are aliases that will be substituted for their values before
+# evaluation:
+#  '@{BUILD_DIR}': path to the output directory
+
+{
+  # Each dev server will be configured as specified and mapped for the
+  # indicated host using --map-origin.
+  'dev_servers': [
+    {
+      'host': 'https://mojo.v.io/',
+      # At this port the server will appear to the shell. That means actually
+      # running on this port when running a Linux shell and being forwarded from
+      # this port when running on Android. Using a fixed port enables caching
+      # server responses between shell runs.
+      'port': @{PORT},
+      # First matching prefix will apply. Within the directiories specified for
+      # a prefix, first location that contains the requested path will apply.
+      'mappings': [
+        ('', [
+          # We map two directiories, so that both exploded dart apps under
+          # checkout root and built apps in the build directory are available.
+          # For example, one could refer to the apps of either type using urls:
+          #  - https://core.mojoapps.io/spinning_cube.mojo
+          #  - https://core.mojoapps.io/examples/dart/device_info/main.dart
+          '@{BUILD_DIR}',
+          '.'
+        ]),
+      ],
+    },
+  ],
+}
diff --git a/mojom/mojom/examples/echo.mojom b/mojom/mojom/examples/echo.mojom
new file mode 100644
index 0000000..ffef68a
--- /dev/null
+++ b/mojom/mojom/examples/echo.mojom
@@ -0,0 +1,25 @@
+// 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.fortune"]
+module mojo.examples;
+
+enum Result {
+  A,
+  B
+};
+
+union outArgTypes {
+  int64 i64;
+  Result res;
+};
+
+struct aInArg {
+  string str;
+};
+
+interface RemoteEcho {
+  EchoString(string value) => (string value);
+  EchoX(array<bool> arg1, aInArg arg2) => (outArgTypes out);
+};
\ No newline at end of file
diff --git a/mojom/mojom/examples/fortune.mojom b/mojom/mojom/examples/fortune.mojom
new file mode 100644
index 0000000..016de51
--- /dev/null
+++ b/mojom/mojom/examples/fortune.mojom
@@ -0,0 +1,11 @@
+// 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.fortune"]
+module mojo.examples;
+
+interface Fortune {
+  Get() => (string value);
+  Add(string wisdom) => ();
+};
\ No newline at end of file