func mojomToVDLTypeUDT(typeKey string, udt mojom_types.UserDefinedType, mp map[string]mojom_types.UserDefinedType, builder *vdl.TypeBuilder, pendingUdts map[string]vdl.TypeOrPending) (vt vdl.TypeOrPending) { u := interface{}(udt) switch u := u.(type) { // To do the type switch, udt has to be converted to interface{}. case *mojom_types.UserDefinedTypeEnumType: // enum me := u.Value // TODO: Assumes that the maximum enum index is len(me.Values) - 1. labels := make([]string, len(me.Values)) for _, ev := range me.Values { // per EnumValue... // EnumValue has DeclData, EnumTypeKey, and IntValue. // We just need the first and last. labels[int(ev.IntValue)] = upperCamelCase(*ev.DeclData.ShortName) } vt = vdl.NamedType(mojomToVdlPath(*me.DeclData.FullIdentifier), vdl.EnumType(labels...)) pendingUdts[typeKey] = vt case *mojom_types.UserDefinedTypeStructType: // struct vt = mojomStructToVDLType(typeKey, u.Value, mp, builder, pendingUdts) case *mojom_types.UserDefinedTypeUnionType: // union mu := u.Value union := builder.Union() vt = builder.Named(mojomToVdlPath(*mu.DeclData.FullIdentifier)).AssignBase(union) pendingUdts[typeKey] = vt for _, mfield := range mu.Fields { union = union.AppendField(upperCamelCase(*mfield.DeclData.ShortName), mojomToVDLType(mfield.Type, mp, builder, pendingUdts)) } case *mojom_types.UserDefinedTypeInterfaceType: // interface panic("interfaces don't exist in vdl") default: // unknown panic(fmt.Errorf("user defined type %#v with unknown tag %d", udt, udt.Tag())) } return vt }
func mojomStructToVDLType(typeKey string, ms mojom_types.MojomStruct, mp map[string]mojom_types.UserDefinedType, builder *vdl.TypeBuilder, pendingUdts map[string]vdl.TypeOrPending) (vt vdl.PendingType) { strct := builder.Struct() if ms.DeclData.FullIdentifier != nil { vt = builder.Named(mojomToVdlPath(*ms.DeclData.FullIdentifier)).AssignBase(strct) } else { vt = strct } pendingUdts[typeKey] = vt for _, mfield := range ms.Fields { strct.AppendField(upperCamelCase(*mfield.DeclData.ShortName), mojomToVDLType(mfield.Type, mp, builder, pendingUdts)) } return }
// Given a mojom Type and the descriptor mapping, produce the corresponding vdltype. func mojomToVDLType(mojomtype mojom_types.Type, mp map[string]mojom_types.UserDefinedType, builder *vdl.TypeBuilder, pendingUdts map[string]vdl.TypeOrPending) (vt vdl.TypeOrPending) { mt := interface{}(mojomtype) switch mt := interface{}(mt).(type) { // To do the type switch, mt has to be converted to interface{}. case *mojom_types.TypeSimpleType: // TypeSimpleType switch mt.Value { case mojom_types.SimpleType_Bool: vt = vdl.BoolType case mojom_types.SimpleType_Double: vt = vdl.Float64Type case mojom_types.SimpleType_Float: vt = vdl.Float32Type case mojom_types.SimpleType_Int8: vt = vdl.Int8Type case mojom_types.SimpleType_Int16: vt = vdl.Int16Type case mojom_types.SimpleType_Int32: vt = vdl.Int32Type case mojom_types.SimpleType_Int64: vt = vdl.Int64Type case mojom_types.SimpleType_Uint8: vt = vdl.ByteType case mojom_types.SimpleType_Uint16: vt = vdl.Uint16Type case mojom_types.SimpleType_Uint32: vt = vdl.Uint32Type case mojom_types.SimpleType_Uint64: vt = vdl.Uint64Type } case *mojom_types.TypeStringType: // TypeStringType st := mt.Value if st.Nullable { panic("nullable strings don't exist in vdl") } vt = vdl.StringType case *mojom_types.TypeArrayType: // TypeArrayType at := mt.Value if at.Nullable { panic("nullable arrays don't exist in vdl") } if at.FixedLength > 0 { vt = builder.Array(). AssignLen(int(at.FixedLength)). AssignElem(mojomToVDLType(at.ElementType, mp, builder, pendingUdts)) } else { vt = builder.List(). AssignElem(mojomToVDLType(at.ElementType, mp, builder, pendingUdts)) } case *mojom_types.TypeMapType: // TypeMapType // Note that mojom doesn't have sets. m := mt.Value if m.Nullable { panic("nullable maps don't exist in vdl") } vt = builder.Map(). AssignKey(mojomToVDLType(m.KeyType, mp, builder, pendingUdts)). AssignElem(mojomToVDLType(m.ValueType, mp, builder, pendingUdts)) case *mojom_types.TypeHandleType: // TypeHandleType panic("handles don't exist in vdl") case *mojom_types.TypeTypeReference: // TypeTypeReference tr := mt.Value if tr.IsInterfaceRequest { panic("interface requests don't exist in vdl") } udt := mp[*tr.TypeKey] var ok bool vt, ok = pendingUdts[*tr.TypeKey] if !ok { vt = mojomToVDLTypeUDT(*tr.TypeKey, udt, mp, builder, pendingUdts) } if tr.Nullable { if udt.Tag() != 1 { panic("nullable non-struct type reference cannot be represented in vdl") } vt = builder.Optional().AssignElem(vt) } default: panic(fmt.Errorf("%#v has unknown tag %d", mojomtype, mojomtype.Tag())) } return vt }
func TestVdlAndMojoTypeConversion(t *testing.T) { // Create types. enumType := vdl.NamedType("v23proxy/tests/transcoder_testcases.TestEnum", vdl.EnumType("A", "B", "C")) basicStructType := vdl.NamedType("v23proxy/tests/transcoder_testcases.TestBasicStruct", vdl.StructType(vdl.Field{"Enum", enumType}, vdl.Field{"A", vdl.Int32Type})) builder := vdl.TypeBuilder{} strct := builder.Struct() strct.AppendField("Enum", enumType) namedStruct := builder.Named("v23proxy/tests/transcoder_testcases.TestCyclicStruct").AssignBase(strct) strct.AppendField("CyclicStruct", builder.Optional().AssignElem(namedStruct)) strct.AppendField("A", vdl.Int32Type) builder.Build() cyclicStructType, err := namedStruct.Built() if err != nil { t.Fatalf("error building struct: %v", err) } tests := []struct { vdl *vdl.Type mojom mojom_types.Type mp map[string]mojom_types.UserDefinedType }{ { vdl.BoolType, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Bool}, map[string]mojom_types.UserDefinedType{}, }, { vdl.ByteType, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Uint8}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Uint16Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Uint16}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Uint32Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Uint32}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Uint64Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Uint64}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Int8Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int8}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Int16Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int16}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Int32Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int32}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Int64Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int64}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Float32Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Float}, map[string]mojom_types.UserDefinedType{}, }, { vdl.Float64Type, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Double}, map[string]mojom_types.UserDefinedType{}, }, { vdl.StringType, &mojom_types.TypeStringType{mojom_types.StringType{false}}, map[string]mojom_types.UserDefinedType{}, }, // ?string is currently disallowed in vdl, so skipping { vdl.ArrayType(3, vdl.Int64Type), &mojom_types.TypeArrayType{mojom_types.ArrayType{false, 3, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int64}}}, map[string]mojom_types.UserDefinedType{}, }, // ?[3]int64 is currently disallowed in vdl, so skipping { vdl.ListType(vdl.Int64Type), &mojom_types.TypeArrayType{mojom_types.ArrayType{false, -1, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int64}}}, map[string]mojom_types.UserDefinedType{}, }, // ?[]int64 is currently disallowed in vdl, so skipping { vdl.MapType(vdl.Int64Type, vdl.BoolType), &mojom_types.TypeMapType{mojom_types.MapType{false, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Int64}, &mojom_types.TypeSimpleType{mojom_types.SimpleType_Bool}}}, map[string]mojom_types.UserDefinedType{}, }, // ?map[int64]bool is currently disallowed in vdl, so skipping { enumType, &mojom_types.TypeTypeReference{mojom_types.TypeReference{Nullable: false, TypeKey: stringPtr("TYPE_KEY:v23proxy.tests.transcoder_testcases.TestEnum")}}, map[string]mojom_types.UserDefinedType{ "TYPE_KEY:v23proxy.tests.transcoder_testcases.TestEnum": transcoder_testcases.GetAllMojomTypeDefinitions()["TYPE_KEY:v23proxy.tests.transcoder_testcases.TestEnum"], }, }, { basicStructType, &mojom_types.TypeTypeReference{mojom_types.TypeReference{Nullable: false, TypeKey: stringPtr("TYPE_KEY:v23proxy.tests.transcoder_testcases.TestBasicStruct")}}, map[string]mojom_types.UserDefinedType{ "TYPE_KEY:v23proxy.tests.transcoder_testcases.TestBasicStruct": transcoder_testcases.GetAllMojomTypeDefinitions()["TYPE_KEY:v23proxy.tests.transcoder_testcases.TestBasicStruct"], "TYPE_KEY:v23proxy.tests.transcoder_testcases.TestEnum": transcoder_testcases.GetAllMojomTypeDefinitions()["TYPE_KEY:v23proxy.tests.transcoder_testcases.TestEnum"], }, }, { cyclicStructType, &mojom_types.TypeTypeReference{mojom_types.TypeReference{Nullable: false, TypeKey: stringPtr("TYPE_KEY:v23proxy.tests.transcoder_testcases.TestCyclicStruct")}}, map[string]mojom_types.UserDefinedType{ "TYPE_KEY:v23proxy.tests.transcoder_testcases.TestCyclicStruct": transcoder_testcases.GetAllMojomTypeDefinitions()["TYPE_KEY:v23proxy.tests.transcoder_testcases.TestCyclicStruct"], "TYPE_KEY:v23proxy.tests.transcoder_testcases.TestEnum": transcoder_testcases.GetAllMojomTypeDefinitions()["TYPE_KEY:v23proxy.tests.transcoder_testcases.TestEnum"], }, }, } for _, test := range tests { mojomtype, mp := transcoder.VDLToMojomType(test.vdl) // Note: Equality is only guaranteed if the casing matches up. Mojom no longer sends out UpperCamelCase values. 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) } // Note: Equality of structs is virtually impossible. The DeclarationData of the values in the map contains lots of information we cannot recover from vdl. //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, mp, test.mp) //} for k, _ := range test.mp { if _, ok := mp[k]; !ok { t.Errorf("vdl type %v, when converted to mojo type did not create an entry for %s", test.vdl, k) } } if len(mp) != len(test.mp) { t.Errorf("vdl type %v, when converted to mojo type created %d map entries, expected %d", test.vdl, len(mp), len(test.mp)) } vt, err := transcoder.MojomToVDLType(test.mojom, test.mp) if err != nil { t.Errorf("error converting mojo type %#v (with user defined types %v): %v", test.mojom, test.mp, err) } if !reflect.DeepEqual(vt, test.vdl) { t.Errorf("mojom type %#v (with user defined types %v), when converted to vdl type was %v. expected %v", test.mojom, test.mp, vt, test.vdl) } } }