// 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 main

/*
#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 uintptr(clazz) == 0 {
		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 uintptr(clazz) == 0 {
		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 uintptr(clazz) == 0 {
		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 uintptr(clazz) == 0 {
		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 uintptr(clazz) == 0 {
		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 uintptr(clazz) == 0 {
		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 main is an autogenerated binder stub for package java.
//   gobind -lang=go java
//
// File is generated by gobind. Do not edit.
package main

/*
#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
}
