// Copyright 2016 The Go 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 bind

import (
	"path"
	"strings"

	"golang.org/x/mobile/internal/importers/objc"
)

type (
	// ObjCWrapper generates Go and C stubs for ObjC interfaces and protocols.
	ObjcWrapper struct {
		*Printer
		imported map[string]*objc.Named
		// The list of ObjC types.
		types []*objc.Named
		// The list of Go package paths with ObjC wrappers.
		pkgNames []string
		modules  []string
		// For each ObjC module, the list of ObjC types within.
		modMap map[string][]*objc.Named
		// For each module/name Go package path, the ObjC type
		// with static functions or constants.
		typePkgs map[string]*objc.Named
		// supers is the map of types that need Super methods.
		supers map[string]struct{}
	}
)

// Init initializes the ObjC types wrapper generator. Types is the
// list of types to wrap, genNames the list of generated type names.
func (g *ObjcWrapper) Init(types []*objc.Named, genNames []string) {
	g.supers = make(map[string]struct{})
	for _, s := range genNames {
		g.supers[s] = struct{}{}
	}
	g.types = types
	g.imported = make(map[string]*objc.Named)
	g.modMap = make(map[string][]*objc.Named)
	g.typePkgs = make(map[string]*objc.Named)
	pkgSet := make(map[string]struct{})
	for _, n := range types {
		g.imported[n.GoName] = n
		typePkg := n.Module + "/" + n.GoName
		g.typePkgs[typePkg] = n
		if !n.Generated {
			if _, exists := g.modMap[n.Module]; !exists {
				g.modules = append(g.modules, n.Module)
			}
		}
		g.modMap[n.Module] = append(g.modMap[n.Module], n)
		if _, exists := pkgSet[n.Module]; !exists {
			pkgSet[n.Module] = struct{}{}
			g.pkgNames = append(g.pkgNames, n.Module)
		}
		g.pkgNames = append(g.pkgNames, typePkg)
	}
}

func (g *ObjcWrapper) GenM() {
	g.Printf("//File is generated by gobind. Do not edit.\n\n")
	// For objc_msgSend* functions.
	g.Printf("@import ObjectiveC.message;\n")
	g.Printf("#include \"seq.h\"\n")
	g.Printf("#include \"interfaces.h\"\n\n")
	for _, n := range g.types {
		g.genM(n)
	}
	g.Printf("\n")
	for _, n := range g.types {
		for _, f := range n.AllMethods {
			if !g.isFuncSupported(f) {
				continue
			}
			g.genCFuncDecl("cproxy", n.GoName, f)
			g.genCFuncBody(n, f, false)
			if _, exists := g.supers[n.GoName]; exists {
				g.genCFuncDecl("csuper", n.GoName, f)
				g.genCFuncBody(n, f, true)
			}
		}
	}
}

func (g *ObjcWrapper) genCFuncBody(n *objc.Named, f *objc.Func, super bool) {
	g.Printf(" {\n")
	g.Indent()
	if !f.Static {
		g.Printf("%s _this = go_seq_from_refnum(this).obj;\n", n.ObjcType())
	}
	var errParam *objc.Param
	for i, a := range f.Params {
		if i == len(f.Params)-1 && g.isErrorType(a.Type) {
			errParam = a
			break
		}
		g.genCToObjC(a.Name, a.Type, modeTransient)
	}
	if errParam != nil {
		g.Printf("NSError *%s = nil;\n", errParam.Name)
	}
	if f.Constructor {
		g.Printf("%s _this = [%s alloc];\n", n.ObjcType(), n.Name)
	}
	if super {
		g.Printf("struct objc_super _super = {\n")
		g.Printf("	.receiver = _this,\n")
		g.Printf("	.super_class = class_getSuperclass([%s class]),\n", n.Name)
		g.Printf("};\n")
	}
	retType := "void"
	if f.Ret != nil {
		retType = g.objcType(f.Ret)
		g.Printf("%s res = ", retType)
	}
	// There is no direct way to send a message to a class' super
	// class from outside the class itself. Use objc_msgSendSuper instead
	// which is what the compiler uses itself. To keep us honest and to exercise
	// the code paths more use objc_msgSend for regular calls as well.
	//
	// A regular call looks like this:
	//
	// res = ((<return type> (*)(id, SEL, <argument_types>))objc_msgSend)(_this, @selector(...), <arguments>)
	//
	// a call to super looks like this:
	//
	// ret = ((<return type> (*)(id, SEL, <argument_types>))objc_msgSendSuper)(<struct objc_super>, <arguments>)
	if f.Ret != nil {
		switch f.Ret.Kind {
		case objc.String, objc.Bool, objc.Data, objc.Int, objc.Uint, objc.Short, objc.Ushort, objc.Char, objc.Float, objc.Double, objc.Class, objc.Protocol:
		default:
			// If support for struct results is added, objc_msgSend_stret must be used
			panic("unsupported type kind - use objc_msgSend_stret?")
		}
	}
	g.Printf("((%s (*)(", retType)
	if super {
		g.Printf("struct objc_super *")
	} else {
		g.Printf("id")
	}
	g.Printf(", SEL")
	for _, a := range f.Params {
		g.Printf(", %s", g.objcType(a.Type))
	}
	g.Printf("))")
	if super {
		g.Printf("objc_msgSendSuper")
	} else {
		g.Printf("objc_msgSend")
	}
	g.Printf(")(")
	if f.Static && !f.Constructor {
		g.Printf("[%s class]", n.Name)
	} else {
		if super {
			g.Printf("&_super")
		} else {
			g.Printf("_this")
		}
	}
	g.Printf(", @selector(%s)", f.Sig)
	for _, a := range f.Params {
		arg := "_" + a.Name
		if a == errParam {
			arg = "&" + a.Name
		}
		g.Printf(", %s", arg)
	}
	g.Printf(");\n")
	if errParam != nil {
		g.Printf("NSError *_%s = nil;\n", errParam.Name)
		if f.Ret != nil {
			g.Printf("if (!res && %s != nil) {\n", errParam.Name)
		} else {
			g.Printf("if (%s != nil) {\n", errParam.Name)
		}
		g.Printf("	_%[1]s = %[1]s;\n", errParam.Name)
		g.Printf("}\n")
		g.genObjCToC("_"+errParam.Name, g.errType(), modeRetained)
	}
	ret := f.Ret
	if ret != nil && ret.Kind == objc.Bool && errParam != nil {
		ret = nil
	}
	if ret != nil {
		g.genObjCToC("res", ret, modeRetained)
	}
	switch {
	case ret != nil && errParam != nil:
		stype := strings.Replace(g.cType(ret), " ", "_", -1)
		g.Printf("ret_%s _sres = {_res, __%s};\n", stype, errParam.Name)
		g.Printf("return _sres;\n")
	case ret != nil:
		g.Printf("return _res;\n")
	case errParam != nil:
		g.Printf("return __%s;\n", errParam.Name)
	}
	g.Outdent()
	g.Printf("}\n\n")
}

func (_ *ObjcWrapper) errType() *objc.Type {
	return &objc.Type{Kind: objc.Class, Name: "NSError"}
}

func (g *ObjcWrapper) genM(n *objc.Named) {
	for _, f := range n.Funcs {
		if !g.isFuncSupported(f) {
			continue
		}
		g.genCFuncDecl("cproxy", n.GoName, f)
		g.genCFuncBody(n, f, false)
	}
}

func (g *ObjcWrapper) GenH() {
	g.Printf("//File is generated by gobind. Do not edit.\n\n")
	g.Printf("#include \"seq.h\"\n\n")
	for _, m := range g.modules {
		g.Printf("@import %s;\n", m)
	}
	// Include header files for generated types
	for _, n := range g.pkgNames {
		hasGen := false
		for _, t := range g.modMap[n] {
			if t.Generated {
				hasGen = true
				break
			}
		}
		if hasGen {
			g.Printf("#import %q\n", n+".objc.h")
		}
	}
	for _, tn := range []string{"int", "nstring", "nbyteslice", "long", "unsigned long", "short", "unsigned short", "bool", "char", "unsigned char", "float", "double"} {
		sn := strings.Replace(tn, " ", "_", -1)
		g.Printf("typedef struct ret_%s {\n", sn)
		g.Printf("	%s res;\n", tn)
		g.Printf("	int err;\n")
		g.Printf("} ret_%s;\n", sn)
	}
	g.Printf("\n")
	for _, n := range g.types {
		for _, f := range n.AllMethods {
			if !g.isFuncSupported(f) {
				continue
			}
			g.Printf("extern ")
			g.genCFuncDecl("cproxy", n.GoName, f)
			g.Printf(";\n")
			if _, exists := g.supers[n.GoName]; exists {
				g.Printf("extern ")
				g.genCFuncDecl("csuper", n.GoName, f)
				g.Printf(";\n")
			}
		}
	}
	for _, cls := range g.types {
		g.genH(cls)
	}
}

func (g *ObjcWrapper) genH(n *objc.Named) {
	for _, f := range n.Funcs {
		if !g.isFuncSupported(f) {
			continue
		}
		g.Printf("extern ")
		g.genCFuncDecl("cproxy", n.GoName, f)
		g.Printf(";\n")
	}
}

func (g *ObjcWrapper) genCFuncDecl(prefix, name string, f *objc.Func) {
	returnsErr := len(f.Params) > 0 && g.isErrorType(f.Params[len(f.Params)-1].Type)
	ret := f.Ret
	if ret != nil && returnsErr && ret.Kind == objc.Bool {
		ret = nil
	}
	switch {
	case ret != nil && returnsErr:
		g.Printf("ret_%s", strings.Replace(g.cType(ret), " ", "_", -1))
	case ret != nil:
		g.Printf(g.cType(ret))
	case returnsErr:
		g.Printf("int")
	default:
		g.Printf("void")
	}
	g.Printf(" ")
	g.Printf(prefix)
	if f.Static {
		g.Printf("_s")
	}
	g.Printf("_%s_%s(", name, f.GoName)
	if !f.Static {
		g.Printf("int this")
	}
	for i, p := range f.Params {
		if i == len(f.Params)-1 && returnsErr {
			break
		}
		if !f.Static || i > 0 {
			g.Printf(", ")
		}
		g.Printf("%s %s", g.cType(p.Type), p.Name)
	}
	g.Printf(")")
}

func (g *ObjcWrapper) GenGo() {
	g.Printf("// File is generated by gobind. Do not edit.\n\n")
	g.Printf("package main\n\n")
	g.Printf("// #include \"interfaces.h\"\n")
	g.Printf("import \"C\"\n\n")
	g.Printf("import \"ObjC\"\n")
	g.Printf("import _seq \"golang.org/x/mobile/bind/seq\"\n")

	for _, n := range g.types {
		for _, f := range n.Funcs {
			if g.isFuncSupported(f) {
				pkgName := n.Module + "/" + n.GoName
				g.Printf("import %q\n", "ObjC/"+pkgName)
				break
			}
		}
	}
	g.Printf("\n")
	g.Printf("type proxy interface { Bind_proxy_refnum__() int32 }\n\n")
	g.Printf("// Suppress unused package error\n\n")
	g.Printf("var _ = _seq.FromRefNum\n")
	g.Printf("const _ = ObjC.Dummy\n\n")
	for _, n := range g.types {
		g.genGo(n)
	}
}

func (g *ObjcWrapper) genGo(n *objc.Named) {
	g.Printf("func init() {\n")
	g.Indent()
	for _, f := range n.Funcs {
		if !g.isFuncSupported(f) {
			continue
		}
		g.Printf("%s.%s = func", n.GoName, f.GoName)
		g.genFuncDecl(false, f)
		g.genFuncBody(n, f, "cproxy")
	}
	g.Outdent()
	g.Printf("}\n\n")
	g.Printf("type proxy_class_%s _seq.Ref\n\n", n.GoName)
	g.Printf("func (p *proxy_class_%s) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }\n\n", n.GoName)
	for _, f := range n.AllMethods {
		if !g.isFuncSupported(f) {
			continue
		}
		g.Printf("func (p *proxy_class_%s) %s", n.GoName, f.GoName)
		g.genFuncDecl(false, f)
		g.genFuncBody(n, f, "cproxy")
	}
	if _, exists := g.supers[n.GoName]; exists {
		g.Printf("func (p *proxy_class_%s) Super() ObjC.%s {\n", n.GoName, n.Module+"_"+n.GoName)
		g.Printf("  return &super_%s{p}\n", n.GoName)
		g.Printf("}\n\n")
		g.Printf("type super_%s struct {*proxy_class_%[1]s}\n\n", n.GoName)
		for _, f := range n.AllMethods {
			if !g.isFuncSupported(f) {
				continue
			}
			g.Printf("func (p *super_%s) %s", n.GoName, f.GoName)
			g.genFuncDecl(false, f)
			g.genFuncBody(n, f, "csuper")
		}
	}
}

func (g *ObjcWrapper) genFuncBody(n *objc.Named, f *objc.Func, prefix string) {
	g.Printf(" {\n")
	g.Indent()
	var errParam *objc.Param
	for i, a := range f.Params {
		if i == len(f.Params)-1 && g.isErrorType(a.Type) {
			errParam = a
			break
		}
		g.genWrite(a)
	}
	ret := f.Ret
	if ret != nil && errParam != nil && ret.Kind == objc.Bool {
		ret = nil
	}
	if ret != nil || errParam != nil {
		g.Printf("res := ")
	}
	g.Printf("C.")
	g.Printf(prefix)
	if f.Static {
		g.Printf("_s")
	}
	g.Printf("_%s_%s(", n.GoName, f.GoName)
	if !f.Static {
		g.Printf("C.int(p.Bind_proxy_refnum__())")
	}
	for i, a := range f.Params {
		if a == errParam {
			break
		}
		if !f.Static || i > 0 {
			g.Printf(", ")
		}
		g.Printf("_%s", a.Name)
	}
	g.Printf(")\n")
	switch {
	case ret != nil && errParam != nil:
		g.genRead("_res", "res.res", ret)
		g.genRefRead("_"+errParam.Name, "res.err", "error", "proxy_error")
		g.Printf("return _res, _%s\n", errParam.Name)
	case ret != nil:
		g.genRead("_res", "res", ret)
		g.Printf("return _res\n")
	case errParam != nil:
		g.genRefRead("_"+errParam.Name, "res", "error", "proxy_error")
		g.Printf("return _%s\n", errParam.Name)
	}
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *ObjcWrapper) genCToObjC(name string, t *objc.Type, mode varMode) {
	switch t.Kind {
	case objc.String:
		g.Printf("NSString *_%s = go_seq_to_objc_string(%s);\n", name, name)
	case objc.Bool:
		g.Printf("BOOL _%s = %s ? YES : NO;\n", name, name)
	case objc.Data:
		g.Printf("NSData *_%s = go_seq_to_objc_bytearray(%s, %d);\n", name, name, toCFlag(mode == modeRetained))
	case objc.Int, objc.Uint, objc.Short, objc.Ushort, objc.Char, objc.Float, objc.Double:
		g.Printf("%s _%s = (%s)%s;\n", g.objcType(t), name, g.objcType(t), name)
	case objc.Class, objc.Protocol:
		g.Printf("GoSeqRef* %s_ref = go_seq_from_refnum(%s);\n", name, name)
		g.Printf("%s _%s;\n", g.objcType(t), name)
		g.Printf("if (%s_ref != NULL) {\n", name)
		g.Printf("	_%s = %s_ref.obj;\n", name, name)
		g.Printf("}\n")
	default:
		panic("invalid kind")
	}
}

func (g *ObjcWrapper) genObjCToC(name string, t *objc.Type, mode varMode) {
	switch t.Kind {
	case objc.String:
		g.Printf("nstring _%s = go_seq_from_objc_string(%s);\n", name, name)
	case objc.Data:
		g.Printf("nbyteslice _%s = go_seq_from_objc_bytearray(%s, %d);\n", name, name, toCFlag(mode == modeRetained))
	case objc.Bool, objc.Int, objc.Uint, objc.Short, objc.Ushort, objc.Char, objc.Float, objc.Double:
		g.Printf("%s _%s = (%s)%s;\n", g.cType(t), name, g.cType(t), name)
	case objc.Protocol, objc.Class:
		g.Printf("int _%s = go_seq_to_refnum(%s);\n", name, name)
	default:
		panic("invalid kind")
	}
}

func (g *ObjcWrapper) genWrite(a *objc.Param) {
	switch a.Type.Kind {
	case objc.String:
		g.Printf("_%s := encodeString(%s)\n", a.Name, a.Name)
	case objc.Data:
		g.Printf("_%s := fromSlice(%s, 0)\n", a.Name, a.Name)
	case objc.Bool:
		g.Printf("_%s := %s(0)\n", a.Name, g.cgoType(a.Type))
		g.Printf("if %s {\n", a.Name)
		g.Printf("  _%s = %s(1)\n", a.Name, g.cgoType(a.Type))
		g.Printf("}\n")
	case objc.Int, objc.Uint, objc.Short, objc.Ushort, objc.Char, objc.Float, objc.Double:
		g.Printf("_%s := %s(%s)\n", a.Name, g.cgoType(a.Type), a.Name)
	case objc.Protocol, objc.Class:
		g.Printf("var _%s %s = _seq.NullRefNum\n", a.Name, g.cgoType(a.Type))
		g.Printf("if %s != nil {\n", a.Name)
		g.Printf("  _%s = %s(_seq.ToRefNum(%s))\n", a.Name, g.cgoType(a.Type), a.Name)
		g.Printf("}\n")
	default:
		panic("invalid kind")
	}
}

func (g *ObjcWrapper) genRead(to, from string, t *objc.Type) {
	switch t.Kind {
	case objc.Int, objc.Uint, objc.Short, objc.Ushort, objc.Char, objc.Float, objc.Double:
		g.Printf("%s := %s(%s)\n", to, g.goType(t, false), from)
	case objc.Bool:
		g.Printf("%s := %s != 0\n", to, from)
	case objc.String:
		g.Printf("%s := decodeString(%s)\n", to, from)
	case objc.Data:
		g.Printf("%s := toSlice(%s, 1)\n", to, from)
	case objc.Protocol, objc.Class:
		var proxyName string
		if n := g.lookupImported(t); n != nil {
			proxyName = "proxy_class_" + n.GoName
		}
		g.genRefRead(to, from, g.goType(t, false), proxyName)
	default:
		panic("invalid kind")
	}
}

func (g *ObjcWrapper) genRefRead(to, from string, intfName, proxyName string) {
	g.Printf("var %s %s\n", to, intfName)
	g.Printf("%s_ref := _seq.FromRefNum(int32(%s))\n", to, from)
	g.Printf("if %s_ref != nil {\n", to)
	g.Printf("	if %s < 0 { // go object\n", from)
	g.Printf("		%s = %s_ref.Get().(%s)\n", to, to, intfName)
	if proxyName != "" {
		g.Printf("	} else { // foreign object\n")
		g.Printf("		%s = (*%s)(%s_ref)\n", to, proxyName, to)
	}
	g.Printf("	}\n")
	g.Printf("}\n")
}

// Packages return the list of Go packages to be generated.
func (g *ObjcWrapper) Packages() []string {
	return g.pkgNames
}

func (g *ObjcWrapper) GenPackage(idx int) {
	pkg := g.pkgNames[idx]
	g.Printf("//File is generated by gobind. Do not edit.\n\n")
	g.Printf("package %s\n\n", path.Base(pkg))
	g.Printf("import \"ObjC\"\n\n")
	g.Printf("const _ = ObjC.Dummy\n\n")
	for _, n := range g.modMap[pkg] {
		g.Printf("type %s ObjC.%s\n", n.GoName, n.Module+"_"+n.GoName)
	}
	if n, ok := g.typePkgs[pkg]; ok {
		g.Printf("var (\n")
		g.Indent()
		// Functions
		for _, f := range n.Funcs {
			if !g.isFuncSupported(f) {
				continue
			}
			g.Printf("%s func", f.GoName)
			g.genFuncDecl(false, f)
			g.Printf("\n")
		}
		g.Outdent()
		g.Printf(")\n\n")
	}
}

func (g *ObjcWrapper) GenInterfaces() {
	g.Printf("//File is generated by gobind. Do not edit.\n\n")
	g.Printf("package ObjC\n\n")
	g.Printf("// Used to silence this package not used errors\n")
	g.Printf("const Dummy = 0\n\n")
	for _, n := range g.types {
		g.genInterface(n)
	}
}

func (g *ObjcWrapper) genInterface(n *objc.Named) {
	g.Printf("type %s interface {\n", n.Module+"_"+n.GoName)
	g.Indent()
	// Methods
	for _, f := range n.AllMethods {
		if !g.isFuncSupported(f) {
			continue
		}
		g.Printf(f.GoName)
		g.genFuncDecl(true, f)
		g.Printf("\n")
	}
	if _, exists := g.supers[n.GoName]; exists {
		g.Printf("Super() %s\n", n.Module+"_"+n.GoName)
	}
	g.Outdent()
	g.Printf("}\n\n")
}

func (g *ObjcWrapper) genFuncDecl(local bool, f *objc.Func) {
	var returnsErr bool
	g.Printf("(")
	for i, p := range f.Params {
		if i == len(f.Params)-1 && g.isErrorType(p.Type) {
			returnsErr = true
			break
		}
		if i > 0 {
			g.Printf(", ")
		}
		g.Printf("%s %s", p.Name, g.goType(p.Type, local))
	}
	g.Printf(")")
	if f.Ret != nil || returnsErr {
		ret := f.Ret
		if ret.Kind == objc.Bool && returnsErr {
			// Skip the bool result and use the error results.
			ret = nil
		}
		if ret != nil {
			g.Printf(" (%s", g.goType(f.Ret, local))
			if returnsErr {
				g.Printf(", error")
			}
			g.Printf(")")
		} else {
			g.Printf(" error")
		}
	}
}

func (g *ObjcWrapper) isFuncSupported(f *objc.Func) bool {
	for i, p := range f.Params {
		if !g.isSupported(p.Type) {
			if i < len(f.Params)-1 || !g.isErrorType(p.Type) {
				return false
			}
		}
	}
	if f.Ret != nil {
		return g.isSupported(f.Ret)
	}
	return true
}

func (g *ObjcWrapper) isErrorType(t *objc.Type) bool {
	// Must be a NSError ** type
	return t.Kind == objc.Class && t.Indirect && t.Name == "NSError"
}

func (g *ObjcWrapper) isSupported(t *objc.Type) bool {
	if t.Indirect {
		return false
	}
	switch t.Kind {
	case objc.Unknown:
		return false
	case objc.Protocol:
		// TODO: support inout parameters.
		return !strings.HasSuffix(t.Decl, " *")
	case objc.Class:
		return t.Name != "SEL" && t.Name != "void"
	default:
		return true
	}
}

func (g *ObjcWrapper) cgoType(t *objc.Type) string {
	switch t.Kind {
	case objc.Uint:
		return "C.ulong"
	case objc.Ushort:
		return "C.ushort"
	case objc.Uchar:
		return "C.uchar"
	default:
		return "C." + g.cType(t)
	}
}

func (g *ObjcWrapper) cType(t *objc.Type) string {
	switch t.Kind {
	case objc.Protocol, objc.Class:
		return "int"
	case objc.String:
		return "nstring"
	case objc.Data:
		return "nbyteslice"
	case objc.Int:
		return "long"
	case objc.Uint:
		return "unsigned long"
	case objc.Short:
		return "short"
	case objc.Ushort:
		return "unsigned short"
	case objc.Bool:
		return "char"
	case objc.Char:
		return "char"
	case objc.Uchar:
		return "unsigned char"
	case objc.Float:
		return "float"
	case objc.Double:
		return "double"
	default:
		panic("invalid kind")
	}
}

func (g *ObjcWrapper) objcType(t *objc.Type) string {
	return t.Decl
}

func (g *ObjcWrapper) lookupImported(t *objc.Type) *objc.Named {
	var mangled string
	switch t.Kind {
	case objc.Class:
		mangled = t.Name + "C"
	case objc.Protocol:
		mangled = t.Name + "P"
	default:
		panic("invalid type kind")
	}
	if n, exists := g.imported[mangled]; exists {
		return n
	}
	return g.imported[t.Name]
}

func (g *ObjcWrapper) goType(t *objc.Type, local bool) string {
	switch t.Kind {
	case objc.String:
		return "string"
	case objc.Data:
		return "[]byte"
	case objc.Int:
		return "int"
	case objc.Uint:
		return "uint"
	case objc.Short:
		return "int16"
	case objc.Ushort:
		return "uint16"
	case objc.Bool:
		return "bool"
	case objc.Char:
		return "byte"
	case objc.Float:
		return "float32"
	case objc.Double:
		return "float64"
	case objc.Protocol, objc.Class:
		var n *objc.Named
		n = g.lookupImported(t)
		name := n.Module + "_" + n.GoName
		if !local {
			name = "ObjC." + name
		}
		return name
	default:
		panic("invalid kind")
	}
}
