// 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
	DIRECTIONALITY_LEFT_TO_RIGHT_ISOLATE = 19
	DIRECTIONALITY_RIGHT_TO_LEFT_ISOLATE = 20
	DIRECTIONALITY_FIRST_STRONG_ISOLATE = 21
	DIRECTIONALITY_POP_DIRECTIONAL_ISOLATE = 22
	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
}
