// 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(gobindPreamble)
	// 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.Uchar, 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(gobindPreamble)
	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(gobindPreamble)
	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.Uchar, 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.Uchar, 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.Uchar, 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.Uchar, 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(gobindPreamble)
	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(gobindPreamble)
	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.Uchar:
		return "uint8"
	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")
	}
}
