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

package Float

import "Java"

const _ = Java.Dummy

const (
	MAX_VALUE = 3.4028235E38
	MIN_NORMAL = 1.17549435E-38
	MIN_VALUE = 1.4E-45
	MAX_EXPONENT = 127
	MIN_EXPONENT = -126
	SIZE = 32
	BYTES = 4
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Float proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Float.
	Cast func(v interface{}) Java.Java_lang_Float
)

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

package lang

import "Java"

const _ = Java.Dummy

type Float Java.Java_lang_Float
type Long Java.Java_lang_Long
type Object Java.Java_lang_Object
type Runnable Java.Java_lang_Runnable
type Character Java.Java_lang_Character
// File is generated by gobind. Do not edit.

package Long

import "Java"

const _ = Java.Dummy

const (
	MIN_VALUE = -9223372036854775808
	MAX_VALUE = 9223372036854775807
	SIZE = 64
	BYTES = 8
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Long proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Long.
	Cast func(v interface{}) Java.Java_lang_Long
)

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

package Object

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Object proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Object.
	Cast func(v interface{}) Java.Java_lang_Object
)

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

package Runnable

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Runnable proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Runnable.
	Cast func(v interface{}) Java.Java_lang_Runnable
)

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

package Character

import "Java"

const _ = Java.Dummy

type Subset Java.Java_lang_Character_Subset
const (
	MIN_RADIX = 2
	MAX_RADIX = 36
	UNASSIGNED = 0
	UPPERCASE_LETTER = 1
	LOWERCASE_LETTER = 2
	TITLECASE_LETTER = 3
	MODIFIER_LETTER = 4
	OTHER_LETTER = 5
	NON_SPACING_MARK = 6
	ENCLOSING_MARK = 7
	COMBINING_SPACING_MARK = 8
	DECIMAL_DIGIT_NUMBER = 9
	LETTER_NUMBER = 10
	OTHER_NUMBER = 11
	SPACE_SEPARATOR = 12
	LINE_SEPARATOR = 13
	PARAGRAPH_SEPARATOR = 14
	CONTROL = 15
	FORMAT = 16
	PRIVATE_USE = 18
	SURROGATE = 19
	DASH_PUNCTUATION = 20
	START_PUNCTUATION = 21
	END_PUNCTUATION = 22
	CONNECTOR_PUNCTUATION = 23
	OTHER_PUNCTUATION = 24
	MATH_SYMBOL = 25
	CURRENCY_SYMBOL = 26
	MODIFIER_SYMBOL = 27
	OTHER_SYMBOL = 28
	INITIAL_QUOTE_PUNCTUATION = 29
	FINAL_QUOTE_PUNCTUATION = 30
	DIRECTIONALITY_UNDEFINED = -1
	DIRECTIONALITY_LEFT_TO_RIGHT = 0
	DIRECTIONALITY_RIGHT_TO_LEFT = 1
	DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2
	DIRECTIONALITY_EUROPEAN_NUMBER = 3
	DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4
	DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5
	DIRECTIONALITY_ARABIC_NUMBER = 6
	DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7
	DIRECTIONALITY_NONSPACING_MARK = 8
	DIRECTIONALITY_BOUNDARY_NEUTRAL = 9
	DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10
	DIRECTIONALITY_SEGMENT_SEPARATOR = 11
	DIRECTIONALITY_WHITESPACE = 12
	DIRECTIONALITY_OTHER_NEUTRALS = 13
	DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14
	DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15
	DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16
	DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17
	DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18
	MIN_SUPPLEMENTARY_CODE_POINT = 65536
	MIN_CODE_POINT = 0
	MAX_CODE_POINT = 1114111
	SIZE = 16
	BYTES = 2
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Character proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Character.
	Cast func(v interface{}) Java.Java_lang_Character
)

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

package Subset

import "Java"

const _ = Java.Dummy

const (
)

var (
	// Cast takes a proxy for a Java object and converts it to a java.lang.Character.Subset proxy.
	// Cast panics if the argument is not a proxy or if the underlying object does
	// not extend or implement java.lang.Character.Subset.
	Cast func(v interface{}) Java.Java_lang_Character_Subset
)

// 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 {
	ToString() string
}

type Java_lang_Long interface {
	ToString() string
}

type Java_lang_Object interface {
	ToString() string
}

type Java_lang_Runnable interface {
}

type Java_lang_Character interface {
	ToString() string
}

type Java_lang_Character_Subset interface {
	ToString() string
}

// 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/Long"
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_Long()
	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() }

func (p *proxy_class_java_lang_Float) ToString() string {
	res := C.cproxy_java_lang_Float_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

var class_java_lang_Long C.jclass

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

type proxy_class_java_lang_Long _seq.Ref

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

func (p *proxy_class_java_lang_Long) ToString() string {
	res := C.cproxy_java_lang_Long_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

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() }

func (p *proxy_class_java_lang_Object) ToString() string {
	res := C.cproxy_java_lang_Object_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

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() }

func (p *proxy_class_java_lang_Character) ToString() string {
	res := C.cproxy_java_lang_Character_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

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() }

func (p *proxy_class_java_lang_Character_Subset) ToString() string {
	res := C.cproxy_java_lang_Character_Subset_toString(C.jint(p.Bind_proxy_refnum__()))
	_res := decodeString(res.res)
	var _exc error
	_exc_ref := _seq.FromRefNum(int32(res.exc))
	if _exc_ref != nil {
		if res.exc < 0 { // go object
			_exc = _exc_ref.Get().(error)
		} else { // foreign object
			_exc = (*proxy_error)(_exc_ref)
		}
	}
	if (_exc != nil) { panic(_exc) }
	return _res
}

// 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"
	"java"
)

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

//export proxyjava_F_ToString
func proxyjava_F_ToString(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(java.F)
	res_0 := v.ToString()
	_res_0 := encodeString(res_0)
	return _res_0
}

type proxyjava_F _seq.Ref

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

func (p *proxyjava_F) ToString() string {
	res := C.cproxyjava_F_ToString(C.int32_t(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

//export proxyjava_L_ToString
func proxyjava_L_ToString(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(java.L)
	res_0 := v.ToString()
	_res_0 := encodeString(res_0)
	return _res_0
}

type proxyjava_L _seq.Ref

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

func (p *proxyjava_L) ToString() string {
	res := C.cproxyjava_L_ToString(C.int32_t(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

//export proxyjava_O_ToString
func proxyjava_O_ToString(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(java.O)
	res_0 := v.ToString()
	_res_0 := encodeString(res_0)
	return _res_0
}

type proxyjava_O _seq.Ref

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

func (p *proxyjava_O) ToString() string {
	res := C.cproxyjava_O_ToString(C.int32_t(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}

type proxyjava_R _seq.Ref

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

//export proxyjava_S_ToString
func proxyjava_S_ToString(refnum C.int32_t) C.nstring {
	ref := _seq.FromRefNum(int32(refnum))
	v := ref.Get().(java.S)
	res_0 := v.ToString()
	_res_0 := encodeString(res_0)
	return _res_0
}

type proxyjava_S _seq.Ref

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

func (p *proxyjava_S) ToString() string {
	res := C.cproxyjava_S_ToString(C.int32_t(p.Bind_proxy_refnum__()))
	_res := decodeString(res)
	return _res
}
