// Copyright 2014 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.

/*
Gobind generates language bindings that make it possible to call Go
functions from Java and Objective-C.

Typically gobind is not used directly. Instead, a binding is
generated and automatically packaged for Android or iOS by
`gomobile bind`. For more details on installing and using the gomobile
tool, see https://golang.org/x/mobile/cmd/gomobile.

Binding Go

Gobind generates target language (Java or Objective-C) bindings for
each exported symbol in a Go package. The Go package you choose to
bind defines a cross-language interface.

Bindings require additional Go code be generated, so using gobind
manually requires calling it twice, first with -lang=<target>, where
target is either java or objc, and again with -lang=go. The generated
package can then be _ imported into a Go program, typically built
with -buildmode=c-archive for iOS or -buildmode=c-shared for Android.
These details are handled by the `gomobile bind` command.

Passing Go objects to target languages

Consider a type for counting:

	package mypkg

	type Counter struct {
		Value int
	}

	func (c *Counter) Inc() { c.Value++ }

	func NewCounter() *Counter { return &Counter{ 5 } }

In Java, the generated bindings are,

	public abstract class Mypkg {
		public static native Counter newCounter();
	}

and

	public final class Counter {
		public Counter() { ... }

		public final long getValue();
		public final void setValue(long v);
		public void inc();

	}

The package-level function newCounter can be called like so:

	Counter c = Mypkg.newCounter()

For convenience, functions on the form NewT(...) *T are converted to constructors for T:

	Counter c = new Counter()

Both forms returns a Java Counter, which is a proxy for a Go *Counter. Calling the inc, getValue and
setValue methods will call the Go implementations of these methods.

Similarly, the same Go package will generate the Objective-C interface

	@class GoMypkgCounter;

	@interface GoMypkgCounter : NSObject {
	}

	@property(strong, readonly) id ref;
	- (void)inc;
	- (int64_t)value;
	- (void)setValue:(int64_t)v;
	@end

	FOUNDATION_EXPORT GoMypkgCounter* GoMypkgNewCounter();

The equivalent of calling newCounter in Go is GoMypkgNewCounter in Objective-C.
The returned GoMypkgCounter* holds a reference to an underlying Go
*Counter.

Passing target language objects to Go

For a Go interface:

	package myfmt

	type Printer interface {
		Print(s string)
	}

	func PrintHello(p Printer) {
		p.Print("Hello, World!")
	}

gobind generates a Java interface that can be used to implement a Printer:

	public abstract class Myfmt {
		public static void printHello(Printer p0);
	}

and

	public interface Printer {
		public void print(String s);
	}

You can implement Printer, and pass it to Go using the printHello
package function:

	public class SysPrint implements Printer {
		public void print(String s) {
			System.out.println(s);
		}
	}

The Java implementation can be used like so:

	Printer printer = new SysPrint();
	Myfmt.printHello(printer);


For Objective-C binding, gobind generates a protocol that declares
methods corresponding to Go interface's methods.

	@protocol GoMyfmtPrinter
	- (void)Print:(NSString*)s;
	@end

	FOUNDATION_EXPORT void GoMyfmtPrintHello(id<GoMyfmtPrinter> p0);

Any Objective-C classes conforming to the GoMyfmtPrinter protocol can be
passed to Go using the GoMyfmtPrintHello function:

	@interface SysPrint : NSObject<GoMyfmtPrinter> {
	}
	@end

	@implementation SysPrint {
	}
	- (void)Print:(NSString*)s {
		NSLog("%@", s);
	}
	@end

The Objective-C implementation can be used like so:

	SysPrint* printer = [[SysPrint alloc] init];
	GoMyfmtPrintHello(printer);


Type restrictions

At present, only a subset of Go types are supported.

All exported symbols in the package must have types that are supported.
Supported types include:

	- Signed integer and floating point types.

	- String and boolean types.

	- Byte slice types. Note that byte slices are passed by reference,
	  and support mutation.

	- Any function type all of whose parameters and results have
	  supported types. Functions must return either no results,
	  one result, or two results where the type of the second is
	  the built-in 'error' type.

	- Any interface type, all of whose exported methods have
	  supported function types.

	- Any struct type, all of whose exported methods have
	  supported function types and all of whose exported fields
	  have supported types.

Unexported symbols have no effect on the cross-language interface, and
as such are not restricted.

The set of supported types will eventually be expanded to cover more
Go types, but this is a work in progress.

Exceptions and panics are not yet supported. If either pass a language
boundary, the program will exit.


Reverse bindings

Gobind also supports accessing API from Java or Objective C from Go.
Similar to how Cgo supports the magic "C" import, gobind recognizes
import statements that start with "Java/" or "ObjC/". For example,
to import java.lang.System and call the static method currentTimeMillis:

	import "Java/java/lang/System"

	t := System.CurrentTimeMillis()

Similarly, to import NSDate and call the static method [NSDate date]:

	import "ObjC/Foundation/NSDate

	d := NSDate.Date()

Gobind also supports specifying particular classes, interfaces or
protocols a particular Go struct should extend or implement. For example,
to create an Android Activity subclass MainActivity:

	import "Java/android/app/Activity"

	type MainActivity struct {
		app.Activity
	}

Gobind also recognizes Java interfaces as well as Objective C classes and
protocols the same way.

For more details on binding the the native API, see the design proposals,
https://golang.org/issues/16876 (Java) and https://golang.org/issues/17102
(Objective C).

Avoid reference cycles

The language bindings maintain a reference to each object that has been
proxied. When a proxy object becomes unreachable, its finalizer reports
this fact to the object's native side, so that the reference can be
removed, potentially allowing the object to be reclaimed by its native
garbage collector.  The mechanism is symmetric.

However, it is possible to create a reference cycle between Go and
objects in target languages, via proxies, meaning objects cannot be
collected. This causes a memory leak.

For example, in Java: if a Go object G holds a reference to the Go
proxy of a Java object J, and J holds a reference to the Java proxy
of G, then the language bindings on each side must keep G and J live
even if they are otherwise unreachable.

We recommend that implementations of foreign interfaces do not hold
references to proxies of objects. That is: if you implement a Go
interface in Java, do not store an instance of Seq.Object inside it.

Further reading

Examples can be found in http://golang.org/x/mobile/example.

Design doc: http://golang.org/s/gobind
*/
package main // import "golang.org/x/mobile/cmd/gobind"
