// 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, false)\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, true)\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")
	}
}
