// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by starcgen. DO NOT EDIT.
// File: passert.shims.go

package passert

import (
	"context"
	"fmt"
	"io"
	"reflect"

	// Library imports
	"github.com/apache/beam/sdks/go/pkg/beam/core/runtime"
	"github.com/apache/beam/sdks/go/pkg/beam/core/runtime/exec"
	"github.com/apache/beam/sdks/go/pkg/beam/core/typex"
	"github.com/apache/beam/sdks/go/pkg/beam/core/util/reflectx"
)

func init() {
	runtime.RegisterType(reflect.TypeOf((*diffFn)(nil)).Elem())
	runtime.RegisterType(reflect.TypeOf((*failFn)(nil)).Elem())
	runtime.RegisterType(reflect.TypeOf((*failGBKFn)(nil)).Elem())
	runtime.RegisterType(reflect.TypeOf((*failKVFn)(nil)).Elem())
	runtime.RegisterType(reflect.TypeOf((*hashFn)(nil)).Elem())
	runtime.RegisterType(reflect.TypeOf((*sumFn)(nil)).Elem())
	reflectx.RegisterStructWrapper(reflect.TypeOf((*diffFn)(nil)).Elem(), wrapMakerDiffFn)
	reflectx.RegisterStructWrapper(reflect.TypeOf((*failFn)(nil)).Elem(), wrapMakerFailFn)
	reflectx.RegisterStructWrapper(reflect.TypeOf((*failGBKFn)(nil)).Elem(), wrapMakerFailGBKFn)
	reflectx.RegisterStructWrapper(reflect.TypeOf((*failKVFn)(nil)).Elem(), wrapMakerFailKVFn)
	reflectx.RegisterStructWrapper(reflect.TypeOf((*hashFn)(nil)).Elem(), wrapMakerHashFn)
	reflectx.RegisterStructWrapper(reflect.TypeOf((*sumFn)(nil)).Elem(), wrapMakerSumFn)
	reflectx.RegisterFunc(reflect.TypeOf((*func(int, func(*int) bool) error)(nil)).Elem(), funcMakerIntIterIntГError)
	reflectx.RegisterFunc(reflect.TypeOf((*func(int, func(*string) bool) error)(nil)).Elem(), funcMakerIntIterStringГError)
	reflectx.RegisterFunc(reflect.TypeOf((*func([]byte, func(*typex.T) bool, func(*typex.T) bool, func(t typex.T), func(t typex.T), func(t typex.T)) error)(nil)).Elem(), funcMakerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError)
	reflectx.RegisterFunc(reflect.TypeOf((*func(typex.X, func(*typex.Y) bool) error)(nil)).Elem(), funcMakerTypex۰XIterTypex۰YГError)
	reflectx.RegisterFunc(reflect.TypeOf((*func(typex.X, typex.Y) error)(nil)).Elem(), funcMakerTypex۰XTypex۰YГError)
	reflectx.RegisterFunc(reflect.TypeOf((*func(typex.X) error)(nil)).Elem(), funcMakerTypex۰XГError)
	exec.RegisterEmitter(reflect.TypeOf((*func(typex.T))(nil)).Elem(), emitMakerTypex۰T)
	exec.RegisterInput(reflect.TypeOf((*func(*int) bool)(nil)).Elem(), iterMakerInt)
	exec.RegisterInput(reflect.TypeOf((*func(*string) bool)(nil)).Elem(), iterMakerString)
	exec.RegisterInput(reflect.TypeOf((*func(*typex.T) bool)(nil)).Elem(), iterMakerTypex۰T)
	exec.RegisterInput(reflect.TypeOf((*func(*typex.Y) bool)(nil)).Elem(), iterMakerTypex۰Y)
}

func wrapMakerDiffFn(fn interface{}) map[string]reflectx.Func {
	dfn := fn.(*diffFn)
	return map[string]reflectx.Func{
		"ProcessElement": reflectx.MakeFunc(func(a0 []byte, a1 func(*typex.T) bool, a2 func(*typex.T) bool, a3 func(t typex.T), a4 func(t typex.T), a5 func(t typex.T)) error {
			return dfn.ProcessElement(a0, a1, a2, a3, a4, a5)
		}),
	}
}

func wrapMakerFailFn(fn interface{}) map[string]reflectx.Func {
	dfn := fn.(*failFn)
	return map[string]reflectx.Func{
		"ProcessElement": reflectx.MakeFunc(func(a0 typex.X) error { return dfn.ProcessElement(a0) }),
	}
}

func wrapMakerFailGBKFn(fn interface{}) map[string]reflectx.Func {
	dfn := fn.(*failGBKFn)
	return map[string]reflectx.Func{
		"ProcessElement": reflectx.MakeFunc(func(a0 typex.X, a1 func(*typex.Y) bool) error { return dfn.ProcessElement(a0, a1) }),
	}
}

func wrapMakerFailKVFn(fn interface{}) map[string]reflectx.Func {
	dfn := fn.(*failKVFn)
	return map[string]reflectx.Func{
		"ProcessElement": reflectx.MakeFunc(func(a0 typex.X, a1 typex.Y) error { return dfn.ProcessElement(a0, a1) }),
	}
}

func wrapMakerHashFn(fn interface{}) map[string]reflectx.Func {
	dfn := fn.(*hashFn)
	return map[string]reflectx.Func{
		"ProcessElement": reflectx.MakeFunc(func(a0 int, a1 func(*string) bool) error { return dfn.ProcessElement(a0, a1) }),
	}
}

func wrapMakerSumFn(fn interface{}) map[string]reflectx.Func {
	dfn := fn.(*sumFn)
	return map[string]reflectx.Func{
		"ProcessElement": reflectx.MakeFunc(func(a0 int, a1 func(*int) bool) error { return dfn.ProcessElement(a0, a1) }),
	}
}

type callerIntIterIntГError struct {
	fn func(int, func(*int) bool) error
}

func funcMakerIntIterIntГError(fn interface{}) reflectx.Func {
	f := fn.(func(int, func(*int) bool) error)
	return &callerIntIterIntГError{fn: f}
}

func (c *callerIntIterIntГError) Name() string {
	return reflectx.FunctionName(c.fn)
}

func (c *callerIntIterIntГError) Type() reflect.Type {
	return reflect.TypeOf(c.fn)
}

func (c *callerIntIterIntГError) Call(args []interface{}) []interface{} {
	out0 := c.fn(args[0].(int), args[1].(func(*int) bool))
	return []interface{}{out0}
}

func (c *callerIntIterIntГError) Call2x1(arg0, arg1 interface{}) interface{} {
	return c.fn(arg0.(int), arg1.(func(*int) bool))
}

type callerIntIterStringГError struct {
	fn func(int, func(*string) bool) error
}

func funcMakerIntIterStringГError(fn interface{}) reflectx.Func {
	f := fn.(func(int, func(*string) bool) error)
	return &callerIntIterStringГError{fn: f}
}

func (c *callerIntIterStringГError) Name() string {
	return reflectx.FunctionName(c.fn)
}

func (c *callerIntIterStringГError) Type() reflect.Type {
	return reflect.TypeOf(c.fn)
}

func (c *callerIntIterStringГError) Call(args []interface{}) []interface{} {
	out0 := c.fn(args[0].(int), args[1].(func(*string) bool))
	return []interface{}{out0}
}

func (c *callerIntIterStringГError) Call2x1(arg0, arg1 interface{}) interface{} {
	return c.fn(arg0.(int), arg1.(func(*string) bool))
}

type callerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError struct {
	fn func([]byte, func(*typex.T) bool, func(*typex.T) bool, func(t typex.T), func(t typex.T), func(t typex.T)) error
}

func funcMakerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError(fn interface{}) reflectx.Func {
	f := fn.(func([]byte, func(*typex.T) bool, func(*typex.T) bool, func(t typex.T), func(t typex.T), func(t typex.T)) error)
	return &callerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError{fn: f}
}

func (c *callerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError) Name() string {
	return reflectx.FunctionName(c.fn)
}

func (c *callerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError) Type() reflect.Type {
	return reflect.TypeOf(c.fn)
}

func (c *callerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError) Call(args []interface{}) []interface{} {
	out0 := c.fn(args[0].([]byte), args[1].(func(*typex.T) bool), args[2].(func(*typex.T) bool), args[3].(func(t typex.T)), args[4].(func(t typex.T)), args[5].(func(t typex.T)))
	return []interface{}{out0}
}

func (c *callerSliceOfByteIterTypex۰TIterTypex۰TEmitTypex۰TEmitTypex۰TEmitTypex۰TГError) Call6x1(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) interface{} {
	return c.fn(arg0.([]byte), arg1.(func(*typex.T) bool), arg2.(func(*typex.T) bool), arg3.(func(t typex.T)), arg4.(func(t typex.T)), arg5.(func(t typex.T)))
}

type callerTypex۰XIterTypex۰YГError struct {
	fn func(typex.X, func(*typex.Y) bool) error
}

func funcMakerTypex۰XIterTypex۰YГError(fn interface{}) reflectx.Func {
	f := fn.(func(typex.X, func(*typex.Y) bool) error)
	return &callerTypex۰XIterTypex۰YГError{fn: f}
}

func (c *callerTypex۰XIterTypex۰YГError) Name() string {
	return reflectx.FunctionName(c.fn)
}

func (c *callerTypex۰XIterTypex۰YГError) Type() reflect.Type {
	return reflect.TypeOf(c.fn)
}

func (c *callerTypex۰XIterTypex۰YГError) Call(args []interface{}) []interface{} {
	out0 := c.fn(args[0].(typex.X), args[1].(func(*typex.Y) bool))
	return []interface{}{out0}
}

func (c *callerTypex۰XIterTypex۰YГError) Call2x1(arg0, arg1 interface{}) interface{} {
	return c.fn(arg0.(typex.X), arg1.(func(*typex.Y) bool))
}

type callerTypex۰XTypex۰YГError struct {
	fn func(typex.X, typex.Y) error
}

func funcMakerTypex۰XTypex۰YГError(fn interface{}) reflectx.Func {
	f := fn.(func(typex.X, typex.Y) error)
	return &callerTypex۰XTypex۰YГError{fn: f}
}

func (c *callerTypex۰XTypex۰YГError) Name() string {
	return reflectx.FunctionName(c.fn)
}

func (c *callerTypex۰XTypex۰YГError) Type() reflect.Type {
	return reflect.TypeOf(c.fn)
}

func (c *callerTypex۰XTypex۰YГError) Call(args []interface{}) []interface{} {
	out0 := c.fn(args[0].(typex.X), args[1].(typex.Y))
	return []interface{}{out0}
}

func (c *callerTypex۰XTypex۰YГError) Call2x1(arg0, arg1 interface{}) interface{} {
	return c.fn(arg0.(typex.X), arg1.(typex.Y))
}

type callerTypex۰XГError struct {
	fn func(typex.X) error
}

func funcMakerTypex۰XГError(fn interface{}) reflectx.Func {
	f := fn.(func(typex.X) error)
	return &callerTypex۰XГError{fn: f}
}

func (c *callerTypex۰XГError) Name() string {
	return reflectx.FunctionName(c.fn)
}

func (c *callerTypex۰XГError) Type() reflect.Type {
	return reflect.TypeOf(c.fn)
}

func (c *callerTypex۰XГError) Call(args []interface{}) []interface{} {
	out0 := c.fn(args[0].(typex.X))
	return []interface{}{out0}
}

func (c *callerTypex۰XГError) Call1x1(arg0 interface{}) interface{} {
	return c.fn(arg0.(typex.X))
}

type emitNative struct {
	n  exec.ElementProcessor
	fn interface{}

	ctx   context.Context
	ws    []typex.Window
	et    typex.EventTime
	value exec.FullValue
}

func (e *emitNative) Init(ctx context.Context, ws []typex.Window, et typex.EventTime) error {
	e.ctx = ctx
	e.ws = ws
	e.et = et
	return nil
}

func (e *emitNative) Value() interface{} {
	return e.fn
}

func emitMakerTypex۰T(n exec.ElementProcessor) exec.ReusableEmitter {
	ret := &emitNative{n: n}
	ret.fn = ret.invokeTypex۰T
	return ret
}

func (e *emitNative) invokeTypex۰T(val typex.T) {
	e.value = exec.FullValue{Windows: e.ws, Timestamp: e.et, Elm: val}
	if err := e.n.ProcessElement(e.ctx, &e.value); err != nil {
		panic(err)
	}
}

type iterNative struct {
	s  exec.ReStream
	fn interface{}

	// cur is the "current" stream, if any.
	cur exec.Stream
}

func (v *iterNative) Init() error {
	cur, err := v.s.Open()
	if err != nil {
		return err
	}
	v.cur = cur
	return nil
}

func (v *iterNative) Value() interface{} {
	return v.fn
}

func (v *iterNative) Reset() error {
	if err := v.cur.Close(); err != nil {
		return err
	}
	v.cur = nil
	return nil
}

func iterMakerInt(s exec.ReStream) exec.ReusableInput {
	ret := &iterNative{s: s}
	ret.fn = ret.readInt
	return ret
}

func (v *iterNative) readInt(value *int) bool {
	elm, err := v.cur.Read()
	if err != nil {
		if err == io.EOF {
			return false
		}
		panic(fmt.Sprintf("broken stream: %v", err))
	}
	*value = elm.Elm.(int)
	return true
}

func iterMakerString(s exec.ReStream) exec.ReusableInput {
	ret := &iterNative{s: s}
	ret.fn = ret.readString
	return ret
}

func (v *iterNative) readString(value *string) bool {
	elm, err := v.cur.Read()
	if err != nil {
		if err == io.EOF {
			return false
		}
		panic(fmt.Sprintf("broken stream: %v", err))
	}
	*value = elm.Elm.(string)
	return true
}

func iterMakerTypex۰T(s exec.ReStream) exec.ReusableInput {
	ret := &iterNative{s: s}
	ret.fn = ret.readTypex۰T
	return ret
}

func (v *iterNative) readTypex۰T(value *typex.T) bool {
	elm, err := v.cur.Read()
	if err != nil {
		if err == io.EOF {
			return false
		}
		panic(fmt.Sprintf("broken stream: %v", err))
	}
	*value = elm.Elm.(typex.T)
	return true
}

func iterMakerTypex۰Y(s exec.ReStream) exec.ReusableInput {
	ret := &iterNative{s: s}
	ret.fn = ret.readTypex۰Y
	return ret
}

func (v *iterNative) readTypex۰Y(value *typex.Y) bool {
	elm, err := v.cur.Read()
	if err != nil {
		if err == io.EOF {
			return false
		}
		panic(fmt.Sprintf("broken stream: %v", err))
	}
	*value = elm.Elm.(typex.Y)
	return true
}

// DO NOT MODIFY: GENERATED CODE
