Merge branch 'master' into advertiser
diff --git a/go/src/v.io/x/mojo/transcoder/type.go b/go/src/v.io/x/mojo/transcoder/type.go
index 128b75e..c54612c 100644
--- a/go/src/v.io/x/mojo/transcoder/type.go
+++ b/go/src/v.io/x/mojo/transcoder/type.go
@@ -6,6 +6,7 @@
 
 import (
 	"fmt"
+	"strings"
 
 	"mojo/public/interfaces/bindings/mojom_types"
 
@@ -47,7 +48,7 @@
 			labels[int(ev.IntValue)] = *ev.DeclData.ShortName
 		}
 
-		vt = vdl.NamedType(*me.DeclData.ShortName, vdl.EnumType(labels...))
+		vt = vdl.NamedType(mojomToVdlPath(*me.DeclData.FullIdentifier), vdl.EnumType(labels...))
 	case *mojom_types.UserDefinedTypeStructType: // struct
 		ms := u.Value
 
@@ -62,7 +63,7 @@
 				Type: MojomToVDLType(mfield.Type, mp),
 			}
 		}
-		vt = vdl.NamedType(*mu.DeclData.ShortName, vdl.UnionType(vfields...))
+		vt = vdl.NamedType(mojomToVdlPath(*mu.DeclData.FullIdentifier), vdl.UnionType(vfields...))
 	case *mojom_types.UserDefinedTypeInterfaceType: // interface
 		panic("interfaces don't exist in vdl")
 	default: // unknown
@@ -79,7 +80,7 @@
 			Type: MojomToVDLType(mfield.Type, mp),
 		}
 	}
-	vt = vdl.NamedType(*ms.DeclData.ShortName, vdl.StructType(vfields...))
+	vt = vdl.NamedType(mojomToVdlPath(*ms.DeclData.FullIdentifier), vdl.StructType(vfields...))
 	return vt
 }
 
@@ -157,11 +158,11 @@
 
 func VDLToMojomType(t *vdl.Type) (mojomtype mojom_types.Type, mp map[string]mojom_types.UserDefinedType) {
 	mp = map[string]mojom_types.UserDefinedType{}
-	mojomtype = vdlToMojomTypeInternal(t, false, mp)
+	mojomtype = vdlToMojomTypeInternal(t, true, false, mp)
 	return
 }
 
-func vdlToMojomTypeInternal(t *vdl.Type, nullable bool, mp map[string]mojom_types.UserDefinedType) (mojomtype mojom_types.Type) {
+func vdlToMojomTypeInternal(t *vdl.Type, outermostType bool, nullable bool, mp map[string]mojom_types.UserDefinedType) (mojomtype mojom_types.Type) {
 	switch t.Kind() {
 	case vdl.Bool, vdl.Float64, vdl.Float32, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64, vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64:
 		return &mojom_types.TypeSimpleType{
@@ -172,38 +173,44 @@
 			stringType(nullable),
 		}
 	case vdl.Array:
-		elem := vdlToMojomTypeInternal(t.Elem(), false, mp)
+		elem := vdlToMojomTypeInternal(t.Elem(), false, false, mp)
 		return &mojom_types.TypeArrayType{
 			arrayType(elem, nullable, t.Len()),
 		}
 	case vdl.List:
-		elem := vdlToMojomTypeInternal(t.Elem(), false, mp)
+		elem := vdlToMojomTypeInternal(t.Elem(), false, false, mp)
 		return &mojom_types.TypeArrayType{
 			listType(elem, nullable),
 		}
 	case vdl.Map:
-		key := vdlToMojomTypeInternal(t.Key(), false, mp)
-		elem := vdlToMojomTypeInternal(t.Elem(), false, mp)
+		key := vdlToMojomTypeInternal(t.Key(), false, false, mp)
+		elem := vdlToMojomTypeInternal(t.Elem(), false, false, mp)
 		return &mojom_types.TypeMapType{
 			mapType(key, elem, nullable),
 		}
 	case vdl.Struct, vdl.Union, vdl.Enum:
-		udtKey := userDefinedTypeKey(t, mp)
-		return &mojom_types.TypeTypeReference{
+		udtKey := addUserDefinedType(t, mp)
+		ret := &mojom_types.TypeTypeReference{
 			mojom_types.TypeReference{
 				Nullable: nullable,
 				TypeKey:  &udtKey,
 			},
 		}
+		if !outermostType {
+			// This is needed to match the output of the generator exactly, the outermost type
+			// is not given an identifier.
+			ret.Value.Identifier = ret.Value.TypeKey
+		}
+		return ret
 	case vdl.Optional:
-		return vdlToMojomTypeInternal(t.Elem(), true, mp)
+		return vdlToMojomTypeInternal(t.Elem(), false, true, mp)
 	default:
 		panic(fmt.Sprintf("conversion from VDL kind %v to mojom type not implemented", t.Kind()))
 	}
 }
 
-func userDefinedTypeKey(t *vdl.Type, mp map[string]mojom_types.UserDefinedType) string {
-	key := t.String()
+func addUserDefinedType(t *vdl.Type, mp map[string]mojom_types.UserDefinedType) string {
+	key := mojomTypeKey(t)
 	if _, ok := mp[key]; ok {
 		return key
 	}
@@ -271,17 +278,21 @@
 }
 
 func structType(t *vdl.Type, mp map[string]mojom_types.UserDefinedType) mojom_types.UserDefinedType {
-	layout := computeStructLayout(t)
 	structFields := make([]mojom_types.StructField, t.NumField())
 	for i := 0; i < t.NumField(); i++ {
-		byteOffset, _ := layout.MojoOffsetsFromVdlIndex(i)
 		structFields[i] = mojom_types.StructField{
-			Type:   vdlToMojomTypeInternal(t.Field(i).Type, false, mp),
-			Offset: int32(byteOffset),
+			DeclData: &mojom_types.DeclarationData{ShortName: strPtr(t.Field(i).Name)},
+			Type:     vdlToMojomTypeInternal(t.Field(i).Type, false, false, mp),
+			Offset:   0, // Despite the fact that we can calculated the offset, set it to zero to match the generator
 		}
 	}
+	_, name := vdl.SplitIdent(t.Name())
 	return &mojom_types.UserDefinedTypeStructType{
 		mojom_types.MojomStruct{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName:      strPtr(name),
+				FullIdentifier: strPtr(mojomIdentifier(t)),
+			},
 			Fields: structFields,
 		},
 	}
@@ -291,12 +302,18 @@
 	unionFields := make([]mojom_types.UnionField, t.NumField())
 	for i := 0; i < t.NumField(); i++ {
 		unionFields[i] = mojom_types.UnionField{
-			Type: vdlToMojomTypeInternal(t.Field(i).Type, false, mp),
-			Tag:  uint32(i),
+			DeclData: &mojom_types.DeclarationData{ShortName: strPtr(t.Field(i).Name)},
+			Type:     vdlToMojomTypeInternal(t.Field(i).Type, false, false, mp),
+			Tag:      uint32(i),
 		}
 	}
+	_, name := vdl.SplitIdent(t.Name())
 	return &mojom_types.UserDefinedTypeUnionType{
 		mojom_types.MojomUnion{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName:      strPtr(name),
+				FullIdentifier: strPtr(mojomIdentifier(t)),
+			},
 			Fields: unionFields,
 		},
 	}
@@ -306,13 +323,44 @@
 	enumValues := make([]mojom_types.EnumValue, t.NumEnumLabel())
 	for i := 0; i < t.NumEnumLabel(); i++ {
 		enumValues[i] = mojom_types.EnumValue{
-			EnumTypeKey: t.EnumLabel(i),
+			DeclData:    &mojom_types.DeclarationData{ShortName: strPtr(t.EnumLabel(i))},
 			IntValue:    int32(i),
+			EnumTypeKey: mojomTypeKey(t),
 		}
 	}
+	_, name := vdl.SplitIdent(t.Name())
 	return &mojom_types.UserDefinedTypeEnumType{
 		mojom_types.MojomEnum{
+			DeclData: &mojom_types.DeclarationData{
+				ShortName:      strPtr(name),
+				FullIdentifier: strPtr(mojomIdentifier(t)),
+			},
 			Values: enumValues,
 		},
 	}
 }
+
+func strPtr(x string) *string {
+	return &x
+}
+
+// mojomTypeKey creates a key from the vdl type's name that matches the generator's key.
+// The reason for exactly matching the generator is to simplify the tests.
+func mojomTypeKey(t *vdl.Type) string {
+	pkgPath, name := vdl.SplitIdent(t.Name())
+	pathComponents := strings.Split(pkgPath, "/")
+	return fmt.Sprintf("%s_%s__", pathComponents[len(pathComponents)-1], name)
+}
+
+func mojomIdentifier(t *vdl.Type) string {
+	return strings.Replace(t.Name(), "/", ".", -1)
+}
+
+// "a.b.c.D" -> "a/b/c.D"
+func mojomToVdlPath(path string) string {
+	lastDot := strings.LastIndex(path, ".")
+	if lastDot == -1 {
+		return path
+	}
+	return strings.Replace(path[:lastDot], ".", "/", -1) + path[lastDot:]
+}
diff --git a/go/src/v.io/x/mojo/transcoder/type_test.go b/go/src/v.io/x/mojo/transcoder/type_test.go
index 56b3e0d..e968af1 100644
--- a/go/src/v.io/x/mojo/transcoder/type_test.go
+++ b/go/src/v.io/x/mojo/transcoder/type_test.go
@@ -6,24 +6,26 @@
 
 import (
 	"mojo/public/interfaces/bindings/mojom_types"
+	"mojom/tests/transcoder_testcases"
 	"reflect"
 	"testing"
 
+	"github.com/davecgh/go-spew/spew"
+
 	"v.io/v23/vdl"
 	"v.io/x/mojo/transcoder"
 )
 
 func TestVdlAndMojoTypeConversion(t *testing.T) {
 	// Create types.
-	/* Types are commented out pending the relevant tests being added.
-	enumType := vdl.NamedType("TestEnum", vdl.EnumType("A", "B", "C"))
+	enumType := vdl.NamedType("v23proxy/tests/transcoder_testcases.TestEnum", vdl.EnumType("A", "B", "C"))
 
-	basicStructType := vdl.NamedType("TestBasicStruct", vdl.StructType(vdl.Field{"TestEnum", enumType}, vdl.Field{"A", vdl.Int32Type}))
-
+	basicStructType := vdl.NamedType("v23proxy/tests/transcoder_testcases.TestBasicStruct", vdl.StructType(vdl.Field{"TestEnum", enumType}, vdl.Field{"A", vdl.Int32Type}))
+	/* disabled until recursive test is enabled
 	builder := vdl.TypeBuilder{}
 	strct := builder.Struct()
 	strct.AppendField("TestEnum", enumType)
-	namedStruct := builder.Named("TestStruct").AssignBase(strct)
+	namedStruct := builder.Named("v23proxy/tests/transcoder_testcases.TestStruct").AssignBase(strct)
 	strct.AppendField("TestStruct", builder.Optional().AssignElem(namedStruct))
 	strct.AppendField("A", vdl.Int32Type)
 	builder.Build()
@@ -116,24 +118,21 @@
 			map[string]mojom_types.UserDefinedType{},
 		},
 		// ?map[int64]bool is currently disallowed in vdl, so skipping
-		/*
-			TODO(bprosnitz) We need a method to compare mojo types for equality
-			{
-				enumType,
-				&mojom_types.TypeTypeReference{mojom_types.TypeReference{Nullable: false, TypeKey: stringPtr("transcoder_testcases_TestEnum__")}},
-				map[string]mojom_types.UserDefinedType{
-					"transcoder_testcases_TestEnum__": transcoder_testcases.GetAllMojomTypeDefinitions()["transcoder_testcases_TestEnum__"],
-				},
+		{
+			enumType,
+			&mojom_types.TypeTypeReference{mojom_types.TypeReference{Nullable: false, TypeKey: stringPtr("transcoder_testcases_TestEnum__")}},
+			map[string]mojom_types.UserDefinedType{
+				"transcoder_testcases_TestEnum__": transcoder_testcases.GetAllMojomTypeDefinitions()["transcoder_testcases_TestEnum__"],
 			},
-			{
-				basicStructType,
-				&mojom_types.TypeTypeReference{mojom_types.TypeReference{Nullable: false, TypeKey: stringPtr("transcoder_testcases_TestBasicStruct__")}},
-				map[string]mojom_types.UserDefinedType{
-					"transcoder_testcases_TestBasicStruct__": transcoder_testcases.GetAllMojomTypeDefinitions()["transcoder_testcases_TestBasicStruct__"],
-					"transcoder_testcases_TestEnum__":        transcoder_testcases.GetAllMojomTypeDefinitions()["transcoder_testcases_TestEnum__"],
-				},
+		},
+		{
+			basicStructType,
+			&mojom_types.TypeTypeReference{mojom_types.TypeReference{Nullable: false, TypeKey: stringPtr("transcoder_testcases_TestBasicStruct__")}},
+			map[string]mojom_types.UserDefinedType{
+				"transcoder_testcases_TestBasicStruct__": transcoder_testcases.GetAllMojomTypeDefinitions()["transcoder_testcases_TestBasicStruct__"],
+				"transcoder_testcases_TestEnum__":        transcoder_testcases.GetAllMojomTypeDefinitions()["transcoder_testcases_TestEnum__"],
 			},
-		*/
+		},
 		/* mojo -> vdl currently doesn't handle cycles
 		{
 			cyclicStructType,
@@ -150,7 +149,7 @@
 	for _, test := range tests {
 		mojomtype, mp := transcoder.VDLToMojomType(test.vdl)
 		if !reflect.DeepEqual(mojomtype, test.mojom) {
-			t.Errorf("vdl type %v, when converted to mojo type was %#v. expected %#v", test.vdl, mojomtype, test.mojom)
+			t.Errorf(spew.Sprintf("vdl type %v, when converted to mojo type was %#v. expected %#v", test.vdl, mojomtype, test.mojom))
 		}
 		if !reflect.DeepEqual(mp, test.mp) {
 			t.Errorf("vdl type %v, when converted to mojo type did not match expected user defined types. got %#v, expected %#v", test.vdl, mojomtype, test.mojom)
diff --git a/mojom/mojom/tests/transcoder_testcases.mojom b/mojom/mojom/tests/transcoder_testcases.mojom
index 9c7429c..4f07a00 100644
--- a/mojom/mojom/tests/transcoder_testcases.mojom
+++ b/mojom/mojom/tests/transcoder_testcases.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-module tests;
+module v23proxy.tests.transcoder_testcases;
 
 import "mojo/public/interfaces/bindings/tests/test_unions.mojom";
 
@@ -52,4 +52,4 @@
     TestEnum TestEnum;
     TestCyclicStruct? TestCyclicStruct;
     int32 a;
-};
\ No newline at end of file
+};
diff --git a/mojom/mojom/v23proxy.mojom b/mojom/mojom/v23proxy.mojom
index 4076b36..91ff8e0 100644
--- a/mojom/mojom/v23proxy.mojom
+++ b/mojom/mojom/v23proxy.mojom
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-module v23proxy;
+module mojo.bindings.types;
+//module v23proxy; // TODO(bprosnitz) Ideally, this would be in v23proxy. This is in mojo.bindings.types because importing across modules is broken in mojo.
 
-import "../mojo/public/interfaces/bindings/mojom_types.mojom";
+import "mojo/public/interfaces/bindings/mojom_types.mojom";
 
 interface V23 {
   // Sets up a communication channel between the caller and the mojo application
@@ -21,12 +22,11 @@
   // futureMessages: Pipe over which messages can be sent to/received from
   //                 serviceName running on the remote service v23Name.
   SetupProxy(string v23Name,
-             mojo.MojomInterface ifaceSig,
-             map<string, mojo.UserDefinedType> mapping,
+             MojomInterface ifaceSig,
+             map<string, UserDefinedType> mapping,
              string serviceName,
              handle<message_pipe> futureMessages);
 
-
   // Endpoints gets the endpoints that the v23proxy serves at.
   Endpoints() => (array<string> endpoints);
 };