// File is generated by gobind. Do not edit.

package Java

// Used to silence this package not used errors
const Dummy = 0

type Java_lang_Float interface {
}

type Java_lang_Object interface {
}

type Java_lang_Runnable interface {
}

type Java_lang_Character interface {
}

type Java_lang_Character_Subset interface {
}

// File is generated by gobind. Do not edit.

package gomobile_bind

/*
#include <stdlib.h> // for free()
#include <jni.h>
#include "seq.h"
#include "classes.h"
*/
import "C"

import (
	"Java"
	_seq "golang.org/x/mobile/bind/seq"
)

import "Java/java/lang/Float"
import "Java/java/lang/Object"
import "Java/java/lang/Runnable"
import "Java/java/lang/Character"
import "Java/java/lang/Character/Subset"
import "unsafe"

import "reflect"

import "fmt"

type proxy interface { Bind_proxy_refnum__() int32 }

// Suppress unused package error

var _ = _seq.FromRefNum
const _ = Java.Dummy

//export initClasses
func initClasses() {
	C.init_proxies()
	init_java_lang_Float()
	init_java_lang_Object()
	init_java_lang_Runnable()
	init_java_lang_Character()
	init_java_lang_Character_Subset()
}

var class_java_lang_Float C.jclass

func init_java_lang_Float() {
	cls := C.CString("java/lang/Float")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_Float = clazz
	Float.Cast = func(v interface{}) Java.Java_lang_Float {
		t := reflect.TypeOf((*proxy_class_java_lang_Float)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_Float)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_Float) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.Float"))
		}
		return cv
	}
}

type proxy_class_java_lang_Float _seq.Ref

func (p *proxy_class_java_lang_Float) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_lang_Object C.jclass

func init_java_lang_Object() {
	cls := C.CString("java/lang/Object")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_Object = clazz
	Object.Cast = func(v interface{}) Java.Java_lang_Object {
		t := reflect.TypeOf((*proxy_class_java_lang_Object)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_Object)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_Object) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.Object"))
		}
		return cv
	}
}

type proxy_class_java_lang_Object _seq.Ref

func (p *proxy_class_java_lang_Object) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_lang_Runnable C.jclass

func init_java_lang_Runnable() {
	cls := C.CString("java/lang/Runnable")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_Runnable = clazz
	Runnable.Cast = func(v interface{}) Java.Java_lang_Runnable {
		t := reflect.TypeOf((*proxy_class_java_lang_Runnable)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_Runnable)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_Runnable) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.Runnable"))
		}
		return cv
	}
}

type proxy_class_java_lang_Runnable _seq.Ref

func (p *proxy_class_java_lang_Runnable) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_lang_Character C.jclass

func init_java_lang_Character() {
	cls := C.CString("java/lang/Character")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_Character = clazz
	Character.Cast = func(v interface{}) Java.Java_lang_Character {
		t := reflect.TypeOf((*proxy_class_java_lang_Character)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_Character)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_Character) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.Character"))
		}
		return cv
	}
}

type proxy_class_java_lang_Character _seq.Ref

func (p *proxy_class_java_lang_Character) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

var class_java_lang_Character_Subset C.jclass

func init_java_lang_Character_Subset() {
	cls := C.CString("java/lang/Character$Subset")
	clazz := C.go_seq_find_class(cls)
	C.free(unsafe.Pointer(cls))
	if clazz == nil {
		return
	}
	class_java_lang_Character_Subset = clazz
	Subset.Cast = func(v interface{}) Java.Java_lang_Character_Subset {
		t := reflect.TypeOf((*proxy_class_java_lang_Character_Subset)(nil))
		cv := reflect.ValueOf(v).Convert(t).Interface().(*proxy_class_java_lang_Character_Subset)
		ref := C.jint(_seq.ToRefNum(cv))
		if C.go_seq_isinstanceof(ref, class_java_lang_Character_Subset) != 1 {
			panic(fmt.Errorf("%T is not an instance of %s", v, "java.lang.Character.Subset"))
		}
		return cv
	}
}

type proxy_class_java_lang_Character_Subset _seq.Ref

func (p *proxy_class_java_lang_Character_Subset) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

// Package gomobile_bind is an autogenerated binder stub for package java.
//   gobind -lang=go java
//
// File is generated by gobind. Do not edit.
package gomobile_bind

/*
#include <stdlib.h>
#include <stdint.h>
#include "seq.h"
#include "java.h"

*/
import "C"

import (
	_seq "golang.org/x/mobile/bind/seq"
)

// suppress the error if seq ends up unused
var _ = _seq.FromRefNum

type proxyjava_F _seq.Ref

func (p *proxyjava_F) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

type proxyjava_O _seq.Ref

func (p *proxyjava_O) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

type proxyjava_R _seq.Ref

func (p *proxyjava_R) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }

type proxyjava_S _seq.Ref

func (p *proxyjava_S) Bind_proxy_refnum__() int32 { return (*_seq.Ref)(p).Bind_IncNum() }
