// Code generated by protoc-gen-go_temporal. DO NOT EDIT.
// versions:
//
//	protoc-gen-go_temporal dev (latest)
//	protoc (unknown)
//
// source: example/mutex/v1/mutex.proto
package mutexv1

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	expression "github.com/cludden/protoc-gen-go-temporal/pkg/expression"
	helpers "github.com/cludden/protoc-gen-go-temporal/pkg/helpers"
	scheme "github.com/cludden/protoc-gen-go-temporal/pkg/scheme"
	testutil "github.com/cludden/protoc-gen-go-temporal/pkg/testutil"
	uuid "github.com/google/uuid"
	gohomedir "github.com/mitchellh/go-homedir"
	v2 "github.com/urfave/cli/v2"
	enumsv1 "go.temporal.io/api/enums/v1"
	serviceerror "go.temporal.io/api/serviceerror"
	activity "go.temporal.io/sdk/activity"
	client "go.temporal.io/sdk/client"
	converter "go.temporal.io/sdk/converter"
	temporal "go.temporal.io/sdk/temporal"
	testsuite "go.temporal.io/sdk/testsuite"
	worker "go.temporal.io/sdk/worker"
	workflow "go.temporal.io/sdk/workflow"
	protojson "google.golang.org/protobuf/encoding/protojson"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	durationpb "google.golang.org/protobuf/types/known/durationpb"
	"log/slog"
	"os"
	"sort"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

// ExampleTaskQueue is the default task-queue for a example.mutex.v1.Example worker
var ExampleTaskQueue = "mutex"

// example.mutex.v1.Example workflow names
const (
	MutexWorkflowName                   = "mutex.v1.Mutex"
	SampleWorkflowWithMutexWorkflowName = "example.mutex.v1.Example.SampleWorkflowWithMutex"
)

// example.mutex.v1.Example workflow id expressions
var (
	MutexIdexpression                   = expression.MustParseExpression("mutex:${! resourceId }")
	SampleWorkflowWithMutexIdexpression = expression.MustParseExpression("SampleWorkflow1WithMutex_${! uuid_v4() }")
)

// example.mutex.v1.Example activity names
const (
	MutexActivityName = "example.mutex.v1.Example.Mutex"
)

// example.mutex.v1.Example signal names
const (
	ReleaseLockSignalName = "mutex.v1.ReleaseLock"
)

// example.mutex.v1.Example update names
const (
	AcquireLockUpdateName = "mutex.v1.AcquireLock"
)

// ExampleClient describes a client for a(n) example.mutex.v1.Example worker
type ExampleClient interface {
	// Mutex is a workflow that manages concurrent access to a resource
	// identified by `resource_id`.
	Mutex(ctx context.Context, req *MutexInput, opts ...*MutexOptions) error

	// MutexAsync starts a(n) mutex.v1.Mutex workflow and returns a handle to the workflow run
	MutexAsync(ctx context.Context, req *MutexInput, opts ...*MutexOptions) (MutexRun, error)

	// GetMutex retrieves a handle to an existing mutex.v1.Mutex workflow execution
	GetMutex(ctx context.Context, workflowID string, runID string) MutexRun

	// MutexWithAcquireLock executes a(n) mutex.v1.AcquireLock update on a(n) mutex.v1.Mutex workflow, starting it if necessary, and blocks until update completion
	MutexWithAcquireLock(ctx context.Context, req *MutexInput, update *AcquireLockInput, opts ...*MutexWithAcquireLockOptions) (*AcquireLockOutput, MutexRun, error)
	// MutexWithAcquireLockAsync starts a(n) mutex.v1.AcquireLock update on a(n) mutex.v1.Mutex workflow, starting it if necessary, and returns a handle to the update execution
	MutexWithAcquireLockAsync(ctx context.Context, req *MutexInput, update *AcquireLockInput, opts ...*MutexWithAcquireLockOptions) (AcquireLockHandle, MutexRun, error)
	// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
	// use the Mutex service.
	SampleWorkflowWithMutex(ctx context.Context, req *SampleWorkflowWithMutexInput, opts ...*SampleWorkflowWithMutexOptions) error

	// SampleWorkflowWithMutexAsync starts a(n) example.mutex.v1.Example.SampleWorkflowWithMutex workflow and returns a handle to the workflow run
	SampleWorkflowWithMutexAsync(ctx context.Context, req *SampleWorkflowWithMutexInput, opts ...*SampleWorkflowWithMutexOptions) (SampleWorkflowWithMutexRun, error)

	// GetSampleWorkflowWithMutex retrieves a handle to an existing example.mutex.v1.Example.SampleWorkflowWithMutex workflow execution
	GetSampleWorkflowWithMutex(ctx context.Context, workflowID string, runID string) SampleWorkflowWithMutexRun

	// CancelWorkflow requests cancellation of an existing workflow execution
	CancelWorkflow(ctx context.Context, workflowID string, runID string) error

	// TerminateWorkflow an existing workflow execution
	TerminateWorkflow(ctx context.Context, workflowID string, runID string, reason string, details ...interface{}) error

	// ReleaseLock releases a lock on a resource identified by `lease_id`.
	ReleaseLock(ctx context.Context, workflowID string, runID string, signal *ReleaseLockInput) error

	// AcquireLock requests a lock on a resource identified by `resource_id`
	// and blocks until the lock is acquired, returning a `lease_id` that
	// can be used to release the lock.
	AcquireLock(ctx context.Context, workflowID string, runID string, req *AcquireLockInput, opts ...*AcquireLockOptions) (*AcquireLockOutput, error)

	// AcquireLockAsync starts a(n) mutex.v1.AcquireLock update and returns a handle to the workflow update
	AcquireLockAsync(ctx context.Context, workflowID string, runID string, req *AcquireLockInput, opts ...*AcquireLockOptions) (AcquireLockHandle, error)

	// GetAcquireLock retrieves a handle to an existing mutex.v1.AcquireLock update
	GetAcquireLock(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (AcquireLockHandle, error)
}

// exampleClient implements a temporal client for a example.mutex.v1.Example service
type exampleClient struct {
	client client.Client
	log    *slog.Logger
}

// NewExampleClient initializes a new example.mutex.v1.Example client
func NewExampleClient(c client.Client, options ...*exampleClientOptions) ExampleClient {
	var cfg *exampleClientOptions
	if len(options) > 0 {
		cfg = options[0]
	} else {
		cfg = NewExampleClientOptions()
	}
	return &exampleClient{
		client: c,
		log:    cfg.getLogger(),
	}
}

// NewExampleClientWithOptions initializes a new Example client with the given options
func NewExampleClientWithOptions(c client.Client, opts client.Options, options ...*exampleClientOptions) (ExampleClient, error) {
	var err error
	c, err = client.NewClientFromExisting(c, opts)
	if err != nil {
		return nil, fmt.Errorf("error initializing client with options: %w", err)
	}
	var cfg *exampleClientOptions
	if len(options) > 0 {
		cfg = options[0]
	} else {
		cfg = NewExampleClientOptions()
	}
	return &exampleClient{
		client: c,
		log:    cfg.getLogger(),
	}, nil
}

// exampleClientOptions describes optional runtime configuration for a ExampleClient
type exampleClientOptions struct {
	log *slog.Logger
}

// NewExampleClientOptions initializes a new exampleClientOptions value
func NewExampleClientOptions() *exampleClientOptions {
	return &exampleClientOptions{}
}

// WithLogger can be used to override the default logger
func (opts *exampleClientOptions) WithLogger(l *slog.Logger) *exampleClientOptions {
	if l != nil {
		opts.log = l
	}
	return opts
}

// getLogger returns the configured logger, or the default logger
func (opts *exampleClientOptions) getLogger() *slog.Logger {
	if opts != nil && opts.log != nil {
		return opts.log
	}
	return slog.Default()
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func (c *exampleClient) Mutex(ctx context.Context, req *MutexInput, options ...*MutexOptions) error {
	run, err := c.MutexAsync(ctx, req, options...)
	if err != nil {
		return err
	}
	return run.Get(ctx)
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func (c *exampleClient) MutexAsync(ctx context.Context, req *MutexInput, options ...*MutexOptions) (MutexRun, error) {
	var o *MutexOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexOptions()
	}
	opts, err := o.Build(req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing client.StartWorkflowOptions: %w", err)
	}
	run, err := c.client.ExecuteWorkflow(ctx, opts, MutexWorkflowName, req)
	if err != nil {
		return nil, err
	}
	if run == nil {
		return nil, errors.New("execute workflow returned nil run")
	}
	return &mutexRun{
		client: c,
		run:    run,
	}, nil
}

// GetMutex fetches an existing mutex.v1.Mutex execution
func (c *exampleClient) GetMutex(ctx context.Context, workflowID string, runID string) MutexRun {
	return &mutexRun{
		client: c,
		run:    c.client.GetWorkflow(ctx, workflowID, runID),
	}
}

// MutexWithAcquireLockOptions is the options for a mutex.v1.Mutex workflow with a mutex.v1.AcquireLock update
type MutexWithAcquireLockOptions struct {
	options         client.UpdateWithStartWorkflowOptions
	workflowOptions *MutexOptions
	updateOptions   *AcquireLockOptions
}

// NewMutexWithAcquireLockOptions initializes a new MutexWithAcquireLockOptions value
func NewMutexWithAcquireLockOptions() *MutexWithAcquireLockOptions {
	return &MutexWithAcquireLockOptions{}
}

// Build transforms MutexWithAcquireLockOptions into valid client.UpdateWithStartWorkflowOptions
func (o *MutexWithAcquireLockOptions) Build(ctx context.Context, op func(client.StartWorkflowOptions) client.WithStartWorkflowOperation, input *MutexInput, update *AcquireLockInput) (options client.UpdateWithStartWorkflowOptions, err error) {
	options = o.options
	if o.workflowOptions == nil {
		o.workflowOptions = NewMutexOptions()
	}
	swo, err := o.workflowOptions.Build(input.ProtoReflect())
	if err != nil {
		return options, err
	}
	if swo.WorkflowIDConflictPolicy == enumsv1.WORKFLOW_ID_CONFLICT_POLICY_UNSPECIFIED {
		swo.WorkflowIDConflictPolicy = enumsv1.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING
	}
	options.StartWorkflowOperation = op(swo)
	if o.updateOptions == nil {
		o.updateOptions = NewAcquireLockOptions()
	}
	uo, err := o.updateOptions.Build(swo.ID, "", update)
	if err != nil {
		return options, err
	}
	options.UpdateOptions = *uo
	return options, nil
}

// WithUpdateWithStartWorkflowOptions sets the UpdateWithStartWorkflowOptions
func (o *MutexWithAcquireLockOptions) WithUpdateWithStartWorkflowOptions(options client.UpdateWithStartWorkflowOptions) *MutexWithAcquireLockOptions {
	o.options = options
	return o
}

// WithMutexOptions sets the WithMutexOptions
func (o *MutexWithAcquireLockOptions) WithMutexOptions(options *MutexOptions) *MutexWithAcquireLockOptions {
	o.workflowOptions = options
	return o
}

// WithAcquireLockOptions sets the AcquireLockOptions
func (o *MutexWithAcquireLockOptions) WithAcquireLockOptions(options *AcquireLockOptions) *MutexWithAcquireLockOptions {
	o.updateOptions = options
	return o
}

// MutexWithAcquireLock starts a(n) mutex.v1.Mutex workflow and executes a(n) mutex.v1.AcquireLock update in a transaction
func (c *exampleClient) MutexWithAcquireLock(ctx context.Context, req *MutexInput, update *AcquireLockInput, options ...*MutexWithAcquireLockOptions) (*AcquireLockOutput, MutexRun, error) {
	updateHandle, run, err := c.MutexWithAcquireLockAsync(ctx, req, update, options...)
	if err != nil {
		return nil, run, err
	}
	out, err := updateHandle.Get(ctx)
	if err != nil {
		return nil, run, err
	}
	return out, run, nil
}

// MutexWithAcquireLockAsync starts a(n) mutex.v1.Mutex workflow and executes a(n) mutex.v1.AcquireLock update in a transaction
func (c *exampleClient) MutexWithAcquireLockAsync(ctx context.Context, req *MutexInput, update *AcquireLockInput, options ...*MutexWithAcquireLockOptions) (AcquireLockHandle, MutexRun, error) {
	var o *MutexWithAcquireLockOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexWithAcquireLockOptions()
	}
	opts, err := o.Build(ctx, func(swo client.StartWorkflowOptions) client.WithStartWorkflowOperation {
		return c.client.NewWithStartWorkflowOperation(swo, MutexWorkflowName, req)
	}, req, update)
	if err != nil {
		return nil, nil, fmt.Errorf("error initializing UpdateWorkflowWithOptions: %w", err)
	}
	handle, err := c.client.UpdateWithStartWorkflow(ctx, opts)
	if err != nil {
		return nil, nil, err
	}
	return &acquireLockHandle{
		client: c,
		handle: handle,
	}, c.GetMutex(ctx, handle.WorkflowID(), handle.RunID()), nil
}

// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
// use the Mutex service.
func (c *exampleClient) SampleWorkflowWithMutex(ctx context.Context, req *SampleWorkflowWithMutexInput, options ...*SampleWorkflowWithMutexOptions) error {
	run, err := c.SampleWorkflowWithMutexAsync(ctx, req, options...)
	if err != nil {
		return err
	}
	return run.Get(ctx)
}

// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
// use the Mutex service.
func (c *exampleClient) SampleWorkflowWithMutexAsync(ctx context.Context, req *SampleWorkflowWithMutexInput, options ...*SampleWorkflowWithMutexOptions) (SampleWorkflowWithMutexRun, error) {
	var o *SampleWorkflowWithMutexOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewSampleWorkflowWithMutexOptions()
	}
	opts, err := o.Build(req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing client.StartWorkflowOptions: %w", err)
	}
	run, err := c.client.ExecuteWorkflow(ctx, opts, SampleWorkflowWithMutexWorkflowName, req)
	if err != nil {
		return nil, err
	}
	if run == nil {
		return nil, errors.New("execute workflow returned nil run")
	}
	return &sampleWorkflowWithMutexRun{
		client: c,
		run:    run,
	}, nil
}

// GetSampleWorkflowWithMutex fetches an existing example.mutex.v1.Example.SampleWorkflowWithMutex execution
func (c *exampleClient) GetSampleWorkflowWithMutex(ctx context.Context, workflowID string, runID string) SampleWorkflowWithMutexRun {
	return &sampleWorkflowWithMutexRun{
		client: c,
		run:    c.client.GetWorkflow(ctx, workflowID, runID),
	}
}

// CancelWorkflow requests cancellation of an existing workflow execution
func (c *exampleClient) CancelWorkflow(ctx context.Context, workflowID string, runID string) error {
	return c.client.CancelWorkflow(ctx, workflowID, runID)
}

// TerminateWorkflow terminates an existing workflow execution
func (c *exampleClient) TerminateWorkflow(ctx context.Context, workflowID string, runID string, reason string, details ...interface{}) error {
	return c.client.TerminateWorkflow(ctx, workflowID, runID, reason, details...)
}

// ReleaseLock releases a lock on a resource identified by `lease_id`.
func (c *exampleClient) ReleaseLock(ctx context.Context, workflowID string, runID string, signal *ReleaseLockInput) error {
	return c.client.SignalWorkflow(ctx, workflowID, runID, ReleaseLockSignalName, signal)
}

// AcquireLock requests a lock on a resource identified by `resource_id`
// and blocks until the lock is acquired, returning a `lease_id` that
// can be used to release the lock.
func (c *exampleClient) AcquireLock(ctx context.Context, workflowID string, runID string, req *AcquireLockInput, opts ...*AcquireLockOptions) (*AcquireLockOutput, error) {
	// initialize update options
	o := NewAcquireLockOptions()
	if len(opts) > 0 && opts[0].Options != nil {
		o = opts[0]
	}

	// call sync update with WorkflowUpdateStageCompleted wait policy
	handle, err := c.AcquireLockAsync(ctx, workflowID, runID, req, o.WithWaitPolicy(client.WorkflowUpdateStageCompleted))
	if err != nil {
		return nil, err
	}

	// block on update completion
	return handle.Get(ctx)
}

// AcquireLock requests a lock on a resource identified by `resource_id`
// and blocks until the lock is acquired, returning a `lease_id` that
// can be used to release the lock.
func (c *exampleClient) AcquireLockAsync(ctx context.Context, workflowID string, runID string, req *AcquireLockInput, opts ...*AcquireLockOptions) (AcquireLockHandle, error) {
	// initialize update options
	var o *AcquireLockOptions
	if len(opts) > 0 && opts[0] != nil {
		o = opts[0]
	} else {
		o = NewAcquireLockOptions()
	}

	// build UpdateWorkflowOptions
	options, err := o.Build(workflowID, runID, req)
	if err != nil {
		return nil, fmt.Errorf("error initializing UpdateWorkflowWithOptions: %w", err)
	}

	// update workflow
	handle, err := c.client.UpdateWorkflow(ctx, *options)
	if err != nil {
		return nil, err
	}
	return &acquireLockHandle{client: c, handle: handle}, nil
}

// GetAcquireLock retrieves a handle to an existing mutex.v1.AcquireLock update
func (c *exampleClient) GetAcquireLock(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (AcquireLockHandle, error) {
	return &acquireLockHandle{
		client: c,
		handle: c.client.GetWorkflowUpdateHandle(req),
	}, nil
}

// MutexOptions provides configuration for a mutex.v1.Mutex workflow operation
type MutexOptions struct {
	options                  client.StartWorkflowOptions
	executionTimeout         *time.Duration
	id                       *string
	idReusePolicy            enumsv1.WorkflowIdReusePolicy
	retryPolicy              *temporal.RetryPolicy
	runTimeout               *time.Duration
	searchAttributes         map[string]any
	taskQueue                *string
	taskTimeout              *time.Duration
	workflowIdConflictPolicy enumsv1.WorkflowIdConflictPolicy
}

// NewMutexOptions initializes a new MutexOptions value
func NewMutexOptions() *MutexOptions {
	return &MutexOptions{}
}

// Build initializes a new go.temporal.io/sdk/client.StartWorkflowOptions value with defaults and overrides applied
func (o *MutexOptions) Build(req protoreflect.Message) (client.StartWorkflowOptions, error) {
	opts := o.options
	if v := o.id; v != nil {
		opts.ID = *v
	} else if opts.ID == "" {
		id, err := expression.EvalExpression(MutexIdexpression, req)
		if err != nil {
			return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", MutexWorkflowName, err)
		}
		opts.ID = id
	}
	if v := o.idReusePolicy; v != enumsv1.WORKFLOW_ID_REUSE_POLICY_UNSPECIFIED {
		opts.WorkflowIDReusePolicy = v
	}
	if v := o.workflowIdConflictPolicy; v != enumsv1.WORKFLOW_ID_CONFLICT_POLICY_UNSPECIFIED {
		opts.WorkflowIDConflictPolicy = v
	}
	if v := o.taskQueue; v != nil {
		opts.TaskQueue = *v
	} else if opts.TaskQueue == "" {
		opts.TaskQueue = ExampleTaskQueue
	}
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	} else if opts.RetryPolicy == nil {
		opts.RetryPolicy = &temporal.RetryPolicy{
			InitialInterval:    1000000000,
			MaximumInterval:    60000000000,
			BackoffCoefficient: 2.0,
			MaximumAttempts:    int32(5),
		}
	}
	if v := o.searchAttributes; v != nil {
		opts.SearchAttributes = o.searchAttributes
	}
	if v := o.executionTimeout; v != nil {
		opts.WorkflowExecutionTimeout = *v
	}
	if v := o.runTimeout; v != nil {
		opts.WorkflowRunTimeout = *v
	}
	if v := o.taskTimeout; v != nil {
		opts.WorkflowTaskTimeout = *v
	}
	return opts, nil
}

// WithStartWorkflowOptions sets the initial go.temporal.io/sdk/client.StartWorkflowOptions
func (o *MutexOptions) WithStartWorkflowOptions(options client.StartWorkflowOptions) *MutexOptions {
	o.options = options
	return o
}

// WithExecutionTimeout sets the WorkflowExecutionTimeout value
func (o *MutexOptions) WithExecutionTimeout(d time.Duration) *MutexOptions {
	o.executionTimeout = &d
	return o
}

// WithID sets the ID value
func (o *MutexOptions) WithID(id string) *MutexOptions {
	o.id = &id
	return o
}

// WithIDReusePolicy sets the WorkflowIDReusePolicy value
func (o *MutexOptions) WithIDReusePolicy(policy enumsv1.WorkflowIdReusePolicy) *MutexOptions {
	o.idReusePolicy = policy
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *MutexOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *MutexOptions {
	o.retryPolicy = policy
	return o
}

// WithRunTimeout sets the WorkflowRunTimeout value
func (o *MutexOptions) WithRunTimeout(d time.Duration) *MutexOptions {
	o.runTimeout = &d
	return o
}

// WithSearchAttributes sets the SearchAttributes value
func (o *MutexOptions) WithSearchAttributes(sa map[string]any) *MutexOptions {
	o.searchAttributes = sa
	return o
}

// WithTaskTimeout sets the WorkflowTaskTimeout value
func (o *MutexOptions) WithTaskTimeout(d time.Duration) *MutexOptions {
	o.taskTimeout = &d
	return o
}

// WithTaskQueue sets the TaskQueue value
func (o *MutexOptions) WithTaskQueue(tq string) *MutexOptions {
	o.taskQueue = &tq
	return o
}

// WithWorkflowIdConflictPolicy sets the WorkflowIdConflictPolicy value
func (o *MutexOptions) WithWorkflowIdConflictPolicy(policy enumsv1.WorkflowIdConflictPolicy) *MutexOptions {
	o.workflowIdConflictPolicy = policy
	return o
}

// MutexRun describes a(n) mutex.v1.Mutex workflow run
type MutexRun interface {
	// ID returns the workflow ID
	ID() string

	// RunID returns the workflow instance ID
	RunID() string

	// Run returns the inner client.WorkflowRun
	Run() client.WorkflowRun

	// Get blocks until the workflow is complete and returns the result
	Get(ctx context.Context) error

	// Cancel requests cancellation of a workflow in execution, returning an error if applicable
	Cancel(ctx context.Context) error

	// Terminate terminates a workflow in execution, returning an error if applicable
	Terminate(ctx context.Context, reason string, details ...interface{}) error

	// ReleaseLock releases a lock on a resource identified by `lease_id`.
	ReleaseLock(ctx context.Context, req *ReleaseLockInput) error

	// AcquireLock requests a lock on a resource identified by `resource_id`
	// and blocks until the lock is acquired, returning a `lease_id` that
	// can be used to release the lock.
	AcquireLock(ctx context.Context, req *AcquireLockInput, opts ...*AcquireLockOptions) (*AcquireLockOutput, error)

	// AcquireLock requests a lock on a resource identified by `resource_id`
	// and blocks until the lock is acquired, returning a `lease_id` that
	// can be used to release the lock.
	AcquireLockAsync(ctx context.Context, req *AcquireLockInput, opts ...*AcquireLockOptions) (AcquireLockHandle, error)
}

// mutexRun provides an internal implementation of a(n) MutexRunRun
type mutexRun struct {
	client *exampleClient
	run    client.WorkflowRun
}

// ID returns the workflow ID
func (r *mutexRun) ID() string {
	return r.run.GetID()
}

// Run returns the inner client.WorkflowRun
func (r *mutexRun) Run() client.WorkflowRun {
	return r.run
}

// RunID returns the execution ID
func (r *mutexRun) RunID() string {
	return r.run.GetRunID()
}

// Cancel requests cancellation of a workflow in execution, returning an error if applicable
func (r *mutexRun) Cancel(ctx context.Context) error {
	return r.client.CancelWorkflow(ctx, r.ID(), r.RunID())
}

// Get blocks until the workflow is complete, returning the result if applicable
func (r *mutexRun) Get(ctx context.Context) error {
	return r.run.Get(ctx, nil)
}

// Terminate terminates a workflow in execution, returning an error if applicable
func (r *mutexRun) Terminate(ctx context.Context, reason string, details ...interface{}) error {
	return r.client.TerminateWorkflow(ctx, r.ID(), r.RunID(), reason, details...)
}

// ReleaseLock releases a lock on a resource identified by `lease_id`.
func (r *mutexRun) ReleaseLock(ctx context.Context, req *ReleaseLockInput) error {
	return r.client.ReleaseLock(ctx, r.ID(), "", req)
}

// AcquireLock requests a lock on a resource identified by `resource_id`
// and blocks until the lock is acquired, returning a `lease_id` that
// can be used to release the lock.
func (r *mutexRun) AcquireLock(ctx context.Context, req *AcquireLockInput, opts ...*AcquireLockOptions) (*AcquireLockOutput, error) {
	return r.client.AcquireLock(ctx, r.ID(), r.RunID(), req, opts...)
}

// AcquireLock requests a lock on a resource identified by `resource_id`
// and blocks until the lock is acquired, returning a `lease_id` that
// can be used to release the lock.
func (r *mutexRun) AcquireLockAsync(ctx context.Context, req *AcquireLockInput, opts ...*AcquireLockOptions) (AcquireLockHandle, error) {
	return r.client.AcquireLockAsync(ctx, r.ID(), r.RunID(), req, opts...)
}

// SampleWorkflowWithMutexOptions provides configuration for a example.mutex.v1.Example.SampleWorkflowWithMutex workflow operation
type SampleWorkflowWithMutexOptions struct {
	options                  client.StartWorkflowOptions
	executionTimeout         *time.Duration
	id                       *string
	idReusePolicy            enumsv1.WorkflowIdReusePolicy
	retryPolicy              *temporal.RetryPolicy
	runTimeout               *time.Duration
	searchAttributes         map[string]any
	taskQueue                *string
	taskTimeout              *time.Duration
	workflowIdConflictPolicy enumsv1.WorkflowIdConflictPolicy
}

// NewSampleWorkflowWithMutexOptions initializes a new SampleWorkflowWithMutexOptions value
func NewSampleWorkflowWithMutexOptions() *SampleWorkflowWithMutexOptions {
	return &SampleWorkflowWithMutexOptions{}
}

// Build initializes a new go.temporal.io/sdk/client.StartWorkflowOptions value with defaults and overrides applied
func (o *SampleWorkflowWithMutexOptions) Build(req protoreflect.Message) (client.StartWorkflowOptions, error) {
	opts := o.options
	if v := o.id; v != nil {
		opts.ID = *v
	} else if opts.ID == "" {
		id, err := expression.EvalExpression(SampleWorkflowWithMutexIdexpression, req)
		if err != nil {
			return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", SampleWorkflowWithMutexWorkflowName, err)
		}
		opts.ID = id
	}
	if v := o.idReusePolicy; v != enumsv1.WORKFLOW_ID_REUSE_POLICY_UNSPECIFIED {
		opts.WorkflowIDReusePolicy = v
	}
	if v := o.workflowIdConflictPolicy; v != enumsv1.WORKFLOW_ID_CONFLICT_POLICY_UNSPECIFIED {
		opts.WorkflowIDConflictPolicy = v
	}
	if v := o.taskQueue; v != nil {
		opts.TaskQueue = *v
	} else if opts.TaskQueue == "" {
		opts.TaskQueue = ExampleTaskQueue
	}
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	}
	if v := o.searchAttributes; v != nil {
		opts.SearchAttributes = o.searchAttributes
	}
	if v := o.executionTimeout; v != nil {
		opts.WorkflowExecutionTimeout = *v
	}
	if v := o.runTimeout; v != nil {
		opts.WorkflowRunTimeout = *v
	}
	if v := o.taskTimeout; v != nil {
		opts.WorkflowTaskTimeout = *v
	}
	return opts, nil
}

// WithStartWorkflowOptions sets the initial go.temporal.io/sdk/client.StartWorkflowOptions
func (o *SampleWorkflowWithMutexOptions) WithStartWorkflowOptions(options client.StartWorkflowOptions) *SampleWorkflowWithMutexOptions {
	o.options = options
	return o
}

// WithExecutionTimeout sets the WorkflowExecutionTimeout value
func (o *SampleWorkflowWithMutexOptions) WithExecutionTimeout(d time.Duration) *SampleWorkflowWithMutexOptions {
	o.executionTimeout = &d
	return o
}

// WithID sets the ID value
func (o *SampleWorkflowWithMutexOptions) WithID(id string) *SampleWorkflowWithMutexOptions {
	o.id = &id
	return o
}

// WithIDReusePolicy sets the WorkflowIDReusePolicy value
func (o *SampleWorkflowWithMutexOptions) WithIDReusePolicy(policy enumsv1.WorkflowIdReusePolicy) *SampleWorkflowWithMutexOptions {
	o.idReusePolicy = policy
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *SampleWorkflowWithMutexOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *SampleWorkflowWithMutexOptions {
	o.retryPolicy = policy
	return o
}

// WithRunTimeout sets the WorkflowRunTimeout value
func (o *SampleWorkflowWithMutexOptions) WithRunTimeout(d time.Duration) *SampleWorkflowWithMutexOptions {
	o.runTimeout = &d
	return o
}

// WithSearchAttributes sets the SearchAttributes value
func (o *SampleWorkflowWithMutexOptions) WithSearchAttributes(sa map[string]any) *SampleWorkflowWithMutexOptions {
	o.searchAttributes = sa
	return o
}

// WithTaskTimeout sets the WorkflowTaskTimeout value
func (o *SampleWorkflowWithMutexOptions) WithTaskTimeout(d time.Duration) *SampleWorkflowWithMutexOptions {
	o.taskTimeout = &d
	return o
}

// WithTaskQueue sets the TaskQueue value
func (o *SampleWorkflowWithMutexOptions) WithTaskQueue(tq string) *SampleWorkflowWithMutexOptions {
	o.taskQueue = &tq
	return o
}

// WithWorkflowIdConflictPolicy sets the WorkflowIdConflictPolicy value
func (o *SampleWorkflowWithMutexOptions) WithWorkflowIdConflictPolicy(policy enumsv1.WorkflowIdConflictPolicy) *SampleWorkflowWithMutexOptions {
	o.workflowIdConflictPolicy = policy
	return o
}

// SampleWorkflowWithMutexRun describes a(n) example.mutex.v1.Example.SampleWorkflowWithMutex workflow run
type SampleWorkflowWithMutexRun interface {
	// ID returns the workflow ID
	ID() string

	// RunID returns the workflow instance ID
	RunID() string

	// Run returns the inner client.WorkflowRun
	Run() client.WorkflowRun

	// Get blocks until the workflow is complete and returns the result
	Get(ctx context.Context) error

	// Cancel requests cancellation of a workflow in execution, returning an error if applicable
	Cancel(ctx context.Context) error

	// Terminate terminates a workflow in execution, returning an error if applicable
	Terminate(ctx context.Context, reason string, details ...interface{}) error
}

// sampleWorkflowWithMutexRun provides an internal implementation of a(n) SampleWorkflowWithMutexRunRun
type sampleWorkflowWithMutexRun struct {
	client *exampleClient
	run    client.WorkflowRun
}

// ID returns the workflow ID
func (r *sampleWorkflowWithMutexRun) ID() string {
	return r.run.GetID()
}

// Run returns the inner client.WorkflowRun
func (r *sampleWorkflowWithMutexRun) Run() client.WorkflowRun {
	return r.run
}

// RunID returns the execution ID
func (r *sampleWorkflowWithMutexRun) RunID() string {
	return r.run.GetRunID()
}

// Cancel requests cancellation of a workflow in execution, returning an error if applicable
func (r *sampleWorkflowWithMutexRun) Cancel(ctx context.Context) error {
	return r.client.CancelWorkflow(ctx, r.ID(), r.RunID())
}

// Get blocks until the workflow is complete, returning the result if applicable
func (r *sampleWorkflowWithMutexRun) Get(ctx context.Context) error {
	return r.run.Get(ctx, nil)
}

// Terminate terminates a workflow in execution, returning an error if applicable
func (r *sampleWorkflowWithMutexRun) Terminate(ctx context.Context, reason string, details ...interface{}) error {
	return r.client.TerminateWorkflow(ctx, r.ID(), r.RunID(), reason, details...)
}

// AcquireLockHandle describes a(n) mutex.v1.AcquireLock update handle
type AcquireLockHandle interface {
	// WorkflowID returns the workflow ID
	WorkflowID() string
	// RunID returns the workflow instance ID
	RunID() string
	// UpdateID returns the update ID
	UpdateID() string
	// Get blocks until the workflow is complete and returns the result
	Get(ctx context.Context) (*AcquireLockOutput, error)
}

// acquireLockHandle provides an internal implementation of a(n) AcquireLockHandle
type acquireLockHandle struct {
	client *exampleClient
	handle client.WorkflowUpdateHandle
}

// WorkflowID returns the workflow ID
func (h *acquireLockHandle) WorkflowID() string {
	return h.handle.WorkflowID()
}

// RunID returns the execution ID
func (h *acquireLockHandle) RunID() string {
	return h.handle.RunID()
}

// UpdateID returns the update ID
func (h *acquireLockHandle) UpdateID() string {
	return h.handle.UpdateID()
}

// Get blocks until the update wait policy is met, returning the result if applicable
func (h *acquireLockHandle) Get(ctx context.Context) (*AcquireLockOutput, error) {
	var resp AcquireLockOutput
	var err error
	doneCh := make(chan struct{})
	gctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	go func() {
		for {
			var deadlineExceeded *serviceerror.DeadlineExceeded
			if err = h.handle.Get(gctx, &resp); err != nil && ctx.Err() == nil && (errors.As(err, &deadlineExceeded) || strings.Contains(err.Error(), context.DeadlineExceeded.Error())) {
				continue
			}
			break
		}
		close(doneCh)
	}()

	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case <-doneCh:
		if err != nil {
			return nil, err
		}
		return &resp, nil
	}
}

// AcquireLockOptions provides configuration for a mutex.v1.AcquireLock update operation
type AcquireLockOptions struct {
	Options    *client.UpdateWorkflowOptions
	id         *string
	waitPolicy client.WorkflowUpdateStage
}

// NewAcquireLockOptions initializes a new AcquireLockOptions value
func NewAcquireLockOptions() *AcquireLockOptions {
	return &AcquireLockOptions{Options: &client.UpdateWorkflowOptions{}}
}

// Build initializes a new client.UpdateWorkflowOptions with defaults and overrides applied
func (o *AcquireLockOptions) Build(workflowID string, runID string, req *AcquireLockInput) (opts *client.UpdateWorkflowOptions, err error) {
	// use user-provided UpdateWorkflowOptions if exists
	if o.Options != nil {
		opts = o.Options
	} else {
		opts = &client.UpdateWorkflowOptions{}
	}

	// set constants
	opts.Args = []any{req}
	opts.RunID = runID
	opts.UpdateName = AcquireLockUpdateName
	opts.WorkflowID = workflowID

	// set UpdateID
	if v := o.id; v != nil {
		opts.UpdateID = *v
	}

	// set WaitPolicy
	if v := o.waitPolicy; v != client.WorkflowUpdateStageUnspecified {
		opts.WaitForStage = v
	} else if opts.WaitForStage == client.WorkflowUpdateStageUnspecified {
		opts.WaitForStage = client.WorkflowUpdateStageAccepted
	}
	return opts, nil
}

// WithUpdateID sets the UpdateID
func (o *AcquireLockOptions) WithUpdateID(id string) *AcquireLockOptions {
	o.id = &id
	return o
}

// WithUpdateWorkflowOptions sets the initial client.UpdateWorkflowOptions
func (o *AcquireLockOptions) WithUpdateWorkflowOptions(options client.UpdateWorkflowOptions) *AcquireLockOptions {
	o.Options = &options
	return o
}

// WithWaitPolicy sets the WaitPolicy
func (o *AcquireLockOptions) WithWaitPolicy(policy client.WorkflowUpdateStage) *AcquireLockOptions {
	o.waitPolicy = policy
	return o
}

// Reference to generated workflow functions
var (
	// exampleRegistrationMutex is a mutex for registering example.mutex.v1.Example workflows
	exampleRegistrationMutex sync.Mutex
	// Mutex is a workflow that manages concurrent access to a resource
	// identified by `resource_id`.
	MutexFunction func(workflow.Context, *MutexInput) error
	// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
	// use the Mutex service.
	SampleWorkflowWithMutexFunction func(workflow.Context, *SampleWorkflowWithMutexInput) error
)

// ExampleWorkflowFunctions describes a mockable dependency for inlining workflows within other workflows
type (
	// ExampleWorkflowFunctions describes a mockable dependency for inlining workflows within other workflows
	ExampleWorkflowFunctions interface {
		// Mutex is a workflow that manages concurrent access to a resource
		// identified by `resource_id`.
		Mutex(workflow.Context, *MutexInput) error
		// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
		// use the Mutex service.
		SampleWorkflowWithMutex(workflow.Context, *SampleWorkflowWithMutexInput) error
	}
	// exampleWorkflowFunctions provides an internal ExampleWorkflowFunctions implementation
	exampleWorkflowFunctions struct{}
)

func NewExampleWorkflowFunctions() ExampleWorkflowFunctions {
	return &exampleWorkflowFunctions{}
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func (f *exampleWorkflowFunctions) Mutex(ctx workflow.Context, req *MutexInput) error {
	if MutexFunction == nil {
		return errors.New("Mutex requires workflow registration via RegisterExampleWorkflows or RegisterMutexWorkflow")
	}
	return MutexFunction(ctx, req)
}

// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
// use the Mutex service.
func (f *exampleWorkflowFunctions) SampleWorkflowWithMutex(ctx workflow.Context, req *SampleWorkflowWithMutexInput) error {
	if SampleWorkflowWithMutexFunction == nil {
		return errors.New("SampleWorkflowWithMutex requires workflow registration via RegisterExampleWorkflows or RegisterSampleWorkflowWithMutexWorkflow")
	}
	return SampleWorkflowWithMutexFunction(ctx, req)
}

// ExampleWorkflows provides methods for initializing new example.mutex.v1.Example workflow values
type ExampleWorkflows interface {
	// Mutex is a workflow that manages concurrent access to a resource
	// identified by `resource_id`.
	Mutex(ctx workflow.Context, input *MutexWorkflowInput) (MutexWorkflow, error)

	// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
	// use the Mutex service.
	SampleWorkflowWithMutex(ctx workflow.Context, input *SampleWorkflowWithMutexWorkflowInput) (SampleWorkflowWithMutexWorkflow, error)
}

// RegisterExampleWorkflows registers example.mutex.v1.Example workflows with the given worker
func RegisterExampleWorkflows(r worker.WorkflowRegistry, workflows ExampleWorkflows) {
	RegisterMutexWorkflow(r, workflows.Mutex)
	RegisterSampleWorkflowWithMutexWorkflow(r, workflows.SampleWorkflowWithMutex)
}

// RegisterMutexWorkflow registers a example.mutex.v1.Example.Mutex workflow with the given worker
func RegisterMutexWorkflow(r worker.WorkflowRegistry, wf func(workflow.Context, *MutexWorkflowInput) (MutexWorkflow, error)) {
	exampleRegistrationMutex.Lock()
	defer exampleRegistrationMutex.Unlock()
	MutexFunction = buildMutex(wf)
	r.RegisterWorkflowWithOptions(MutexFunction, workflow.RegisterOptions{Name: MutexWorkflowName})
}

// buildMutex converts a Mutex workflow struct into a valid workflow function
func buildMutex(ctor func(workflow.Context, *MutexWorkflowInput) (MutexWorkflow, error)) func(workflow.Context, *MutexInput) error {
	return func(ctx workflow.Context, req *MutexInput) error {
		input := &MutexWorkflowInput{
			Req: req,
			ReleaseLock: &ReleaseLockSignal{
				Channel: workflow.GetSignalChannel(ctx, ReleaseLockSignalName),
			},
		}
		wf, err := ctor(ctx, input)
		if err != nil {
			return err
		}
		if initializable, ok := wf.(helpers.Initializable); ok {
			if err := initializable.Initialize(ctx); err != nil {
				return err
			}
		}
		{
			opts := workflow.UpdateHandlerOptions{}
			if err := workflow.SetUpdateHandlerWithOptions(ctx, AcquireLockUpdateName, wf.AcquireLock, opts); err != nil {
				return err
			}
		}
		return wf.Execute(ctx)
	}
}

// MutexWorkflowInput describes the input to a(n) mutex.v1.Mutex workflow constructor
type MutexWorkflowInput struct {
	Req         *MutexInput
	ReleaseLock *ReleaseLockSignal
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
//
// workflow details: (name: "mutex.v1.Mutex", id: "mutex:${! resourceId }")
type MutexWorkflow interface {
	// Execute defines the entrypoint to a(n) mutex.v1.Mutex workflow
	Execute(ctx workflow.Context) error

	// AcquireLock requests a lock on a resource identified by `resource_id`
	// and blocks until the lock is acquired, returning a `lease_id` that
	// can be used to release the lock.
	AcquireLock(workflow.Context, *AcquireLockInput) (*AcquireLockOutput, error)
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func MutexChild(ctx workflow.Context, req *MutexInput, options ...*MutexChildOptions) error {
	childRun, err := MutexChildAsync(ctx, req, options...)
	if err != nil {
		return err
	}
	return childRun.Get(ctx)
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func MutexChildAsync(ctx workflow.Context, req *MutexInput, options ...*MutexChildOptions) (*MutexChildRun, error) {
	var o *MutexChildOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexChildOptions()
	}
	opts, err := o.Build(ctx, req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing workflow.ChildWorkflowOptions: %w", err)
	}
	ctx = workflow.WithChildOptions(ctx, opts)
	if o.dc != nil {
		ctx = workflow.WithDataConverter(ctx, o.dc)
	}
	return &MutexChildRun{Future: workflow.ExecuteChildWorkflow(ctx, MutexWorkflowName, req)}, nil
}

// MutexChildOptions provides configuration for a child mutex.v1.Mutex workflow operation
type MutexChildOptions struct {
	options                  workflow.ChildWorkflowOptions
	executionTimeout         *time.Duration
	id                       *string
	idReusePolicy            enumsv1.WorkflowIdReusePolicy
	retryPolicy              *temporal.RetryPolicy
	runTimeout               *time.Duration
	searchAttributes         map[string]any
	taskQueue                *string
	taskTimeout              *time.Duration
	workflowIdConflictPolicy enumsv1.WorkflowIdConflictPolicy
	dc                       converter.DataConverter
	parentClosePolicy        enumsv1.ParentClosePolicy
	waitForCancellation      *bool
}

// NewMutexChildOptions initializes a new MutexChildOptions value
func NewMutexChildOptions() *MutexChildOptions {
	return &MutexChildOptions{}
}

// Build initializes a new go.temporal.io/sdk/workflow.ChildWorkflowOptions value with defaults and overrides applied
func (o *MutexChildOptions) Build(ctx workflow.Context, req protoreflect.Message) (workflow.ChildWorkflowOptions, error) {
	opts := o.options
	if v := o.id; v != nil {
		opts.WorkflowID = *v
	} else if opts.WorkflowID == "" {
		// wrap expression evaluation in local activity
		// more info: https://cludden.github.io/protoc-gen-go-temporal/docs/guides/patches#pv_64-expression-evaluation-local-activity
		if workflow.GetVersion(ctx, "cludden_protoc-gen-go-temporal_64_expression-evaluation-local-activity", workflow.DefaultVersion, 1) == 1 {
			lao := workflow.GetLocalActivityOptions(ctx)
			lao.ScheduleToCloseTimeout = time.Second * 10
			if err := workflow.ExecuteLocalActivity(workflow.WithLocalActivityOptions(ctx, lao), func(ctx context.Context) (string, error) {
				id, err := expression.EvalExpression(MutexIdexpression, req)
				if err != nil {
					return "", fmt.Errorf("error evaluating id expression for %q workflow: %w", MutexWorkflowName, err)
				}
				return id, nil
			}).Get(ctx, &opts.WorkflowID); err != nil {
				return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", MutexWorkflowName, err)
			}
		} else {
			id, err := expression.EvalExpression(MutexIdexpression, req)
			if err != nil {
				return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", MutexWorkflowName, err)
			}
			opts.WorkflowID = id
		}
	}
	if v := o.idReusePolicy; v != enumsv1.WORKFLOW_ID_REUSE_POLICY_UNSPECIFIED {
		opts.WorkflowIDReusePolicy = v
	}
	if v := o.taskQueue; v != nil {
		opts.TaskQueue = *v
	} else if opts.TaskQueue == "" {
		opts.TaskQueue = ExampleTaskQueue
	}
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	} else if opts.RetryPolicy == nil {
		opts.RetryPolicy = &temporal.RetryPolicy{
			InitialInterval:    1000000000,
			MaximumInterval:    60000000000,
			BackoffCoefficient: 2.0,
			MaximumAttempts:    int32(5),
		}
	}
	if v := o.searchAttributes; v != nil {
		opts.SearchAttributes = o.searchAttributes
	}
	if v := o.executionTimeout; v != nil {
		opts.WorkflowExecutionTimeout = *v
	}
	if v := o.runTimeout; v != nil {
		opts.WorkflowRunTimeout = *v
	}
	if v := o.taskTimeout; v != nil {
		opts.WorkflowTaskTimeout = *v
	}
	if v := o.parentClosePolicy; v != enumsv1.PARENT_CLOSE_POLICY_UNSPECIFIED {
		opts.ParentClosePolicy = v
	}
	if v := o.waitForCancellation; v != nil {
		opts.WaitForCancellation = *v
	}
	return opts, nil
}

// WithChildWorkflowOptions sets the initial go.temporal.io/sdk/workflow.ChildWorkflowOptions
func (o *MutexChildOptions) WithChildWorkflowOptions(options workflow.ChildWorkflowOptions) *MutexChildOptions {
	o.options = options
	return o
}

// WithDataConverter registers a DataConverter for the child workflow
func (o *MutexChildOptions) WithDataConverter(dc converter.DataConverter) *MutexChildOptions {
	o.dc = dc
	return o
}

// WithExecutionTimeout sets the WorkflowExecutionTimeout value
func (o *MutexChildOptions) WithExecutionTimeout(d time.Duration) *MutexChildOptions {
	o.executionTimeout = &d
	return o
}

// WithID sets the WorkflowID value
func (o *MutexChildOptions) WithID(id string) *MutexChildOptions {
	o.id = &id
	return o
}

// WithIDReusePolicy sets the WorkflowIDReusePolicy value
func (o *MutexChildOptions) WithIDReusePolicy(policy enumsv1.WorkflowIdReusePolicy) *MutexChildOptions {
	o.idReusePolicy = policy
	return o
}

// WithParentClosePolicy sets the WorkflowIDReusePolicy value
func (o *MutexChildOptions) WithParentClosePolicy(policy enumsv1.ParentClosePolicy) *MutexChildOptions {
	o.parentClosePolicy = policy
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *MutexChildOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *MutexChildOptions {
	o.retryPolicy = policy
	return o
}

// WithRunTimeout sets the WorkflowRunTimeout value
func (o *MutexChildOptions) WithRunTimeout(d time.Duration) *MutexChildOptions {
	o.runTimeout = &d
	return o
}

// WithSearchAttributes sets the SearchAttributes value
func (o *MutexChildOptions) WithSearchAttributes(sa map[string]any) *MutexChildOptions {
	o.searchAttributes = sa
	return o
}

// WithTaskTimeout sets the WorkflowTaskTimeout value
func (o *MutexChildOptions) WithTaskTimeout(d time.Duration) *MutexChildOptions {
	o.taskTimeout = &d
	return o
}

// WithTaskQueue sets the TaskQueue value
func (o *MutexChildOptions) WithTaskQueue(tq string) *MutexChildOptions {
	o.taskQueue = &tq
	return o
}

// WithWaitForCancellation sets the WaitForCancellation value
func (o *MutexChildOptions) WithWaitForCancellation(wait bool) *MutexChildOptions {
	o.waitForCancellation = &wait
	return o
}

// WithWorkflowIdConflictPolicy sets the WorkflowIdConflictPolicy value
func (o *MutexChildOptions) WithWorkflowIdConflictPolicy(policy enumsv1.WorkflowIdConflictPolicy) *MutexChildOptions {
	o.workflowIdConflictPolicy = policy
	return o
}

// MutexChildRun describes a child Mutex workflow run
type MutexChildRun struct {
	Future workflow.ChildWorkflowFuture
}

// Get blocks until the workflow is completed, returning the response value
func (r *MutexChildRun) Get(ctx workflow.Context) error {
	if err := r.Future.Get(ctx, nil); err != nil {
		return err
	}
	return nil
}

// Select adds this completion to the selector. Callback can be nil.
func (r *MutexChildRun) Select(sel workflow.Selector, fn func(*MutexChildRun)) workflow.Selector {
	return sel.AddFuture(r.Future, func(workflow.Future) {
		if fn != nil {
			fn(r)
		}
	})
}

// SelectStart adds waiting for start to the selector. Callback can be nil.
func (r *MutexChildRun) SelectStart(sel workflow.Selector, fn func(*MutexChildRun)) workflow.Selector {
	return sel.AddFuture(r.Future.GetChildWorkflowExecution(), func(workflow.Future) {
		if fn != nil {
			fn(r)
		}
	})
}

// WaitStart waits for the child workflow to start
func (r *MutexChildRun) WaitStart(ctx workflow.Context) (*workflow.Execution, error) {
	var exec workflow.Execution
	if err := r.Future.GetChildWorkflowExecution().Get(ctx, &exec); err != nil {
		return nil, err
	}
	return &exec, nil
}

// ReleaseLock sends a(n) "mutex.v1.ReleaseLock" signal request to the child workflow
func (r *MutexChildRun) ReleaseLock(ctx workflow.Context, input *ReleaseLockInput) error {
	return r.ReleaseLockAsync(ctx, input).Get(ctx, nil)
}

// ReleaseLockAsync sends a(n) "mutex.v1.ReleaseLock" signal request to the child workflow
func (r *MutexChildRun) ReleaseLockAsync(ctx workflow.Context, input *ReleaseLockInput) workflow.Future {
	return r.Future.SignalChildWorkflow(ctx, ReleaseLockSignalName, input)
}

// RegisterSampleWorkflowWithMutexWorkflow registers a example.mutex.v1.Example.SampleWorkflowWithMutex workflow with the given worker
func RegisterSampleWorkflowWithMutexWorkflow(r worker.WorkflowRegistry, wf func(workflow.Context, *SampleWorkflowWithMutexWorkflowInput) (SampleWorkflowWithMutexWorkflow, error)) {
	exampleRegistrationMutex.Lock()
	defer exampleRegistrationMutex.Unlock()
	SampleWorkflowWithMutexFunction = buildSampleWorkflowWithMutex(wf)
	r.RegisterWorkflowWithOptions(SampleWorkflowWithMutexFunction, workflow.RegisterOptions{Name: SampleWorkflowWithMutexWorkflowName})
}

// buildSampleWorkflowWithMutex converts a SampleWorkflowWithMutex workflow struct into a valid workflow function
func buildSampleWorkflowWithMutex(ctor func(workflow.Context, *SampleWorkflowWithMutexWorkflowInput) (SampleWorkflowWithMutexWorkflow, error)) func(workflow.Context, *SampleWorkflowWithMutexInput) error {
	return func(ctx workflow.Context, req *SampleWorkflowWithMutexInput) error {
		input := &SampleWorkflowWithMutexWorkflowInput{
			Req: req,
		}
		wf, err := ctor(ctx, input)
		if err != nil {
			return err
		}
		if initializable, ok := wf.(helpers.Initializable); ok {
			if err := initializable.Initialize(ctx); err != nil {
				return err
			}
		}
		return wf.Execute(ctx)
	}
}

// SampleWorkflowWithMutexWorkflowInput describes the input to a(n) example.mutex.v1.Example.SampleWorkflowWithMutex workflow constructor
type SampleWorkflowWithMutexWorkflowInput struct {
	Req *SampleWorkflowWithMutexInput
}

// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
// use the Mutex service.
//
// workflow details: (name: "example.mutex.v1.Example.SampleWorkflowWithMutex", id: "SampleWorkflow1WithMutex_${! uuid_v4() }")
type SampleWorkflowWithMutexWorkflow interface {
	// Execute defines the entrypoint to a(n) example.mutex.v1.Example.SampleWorkflowWithMutex workflow
	Execute(ctx workflow.Context) error
}

// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
// use the Mutex service.
func SampleWorkflowWithMutexChild(ctx workflow.Context, req *SampleWorkflowWithMutexInput, options ...*SampleWorkflowWithMutexChildOptions) error {
	childRun, err := SampleWorkflowWithMutexChildAsync(ctx, req, options...)
	if err != nil {
		return err
	}
	return childRun.Get(ctx)
}

// SampleWorkflowWithMutex is a sample workflow that demonstrates how to
// use the Mutex service.
func SampleWorkflowWithMutexChildAsync(ctx workflow.Context, req *SampleWorkflowWithMutexInput, options ...*SampleWorkflowWithMutexChildOptions) (*SampleWorkflowWithMutexChildRun, error) {
	var o *SampleWorkflowWithMutexChildOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewSampleWorkflowWithMutexChildOptions()
	}
	opts, err := o.Build(ctx, req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing workflow.ChildWorkflowOptions: %w", err)
	}
	ctx = workflow.WithChildOptions(ctx, opts)
	if o.dc != nil {
		ctx = workflow.WithDataConverter(ctx, o.dc)
	}
	return &SampleWorkflowWithMutexChildRun{Future: workflow.ExecuteChildWorkflow(ctx, SampleWorkflowWithMutexWorkflowName, req)}, nil
}

// SampleWorkflowWithMutexChildOptions provides configuration for a child example.mutex.v1.Example.SampleWorkflowWithMutex workflow operation
type SampleWorkflowWithMutexChildOptions struct {
	options                  workflow.ChildWorkflowOptions
	executionTimeout         *time.Duration
	id                       *string
	idReusePolicy            enumsv1.WorkflowIdReusePolicy
	retryPolicy              *temporal.RetryPolicy
	runTimeout               *time.Duration
	searchAttributes         map[string]any
	taskQueue                *string
	taskTimeout              *time.Duration
	workflowIdConflictPolicy enumsv1.WorkflowIdConflictPolicy
	dc                       converter.DataConverter
	parentClosePolicy        enumsv1.ParentClosePolicy
	waitForCancellation      *bool
}

// NewSampleWorkflowWithMutexChildOptions initializes a new SampleWorkflowWithMutexChildOptions value
func NewSampleWorkflowWithMutexChildOptions() *SampleWorkflowWithMutexChildOptions {
	return &SampleWorkflowWithMutexChildOptions{}
}

// Build initializes a new go.temporal.io/sdk/workflow.ChildWorkflowOptions value with defaults and overrides applied
func (o *SampleWorkflowWithMutexChildOptions) Build(ctx workflow.Context, req protoreflect.Message) (workflow.ChildWorkflowOptions, error) {
	opts := o.options
	if v := o.id; v != nil {
		opts.WorkflowID = *v
	} else if opts.WorkflowID == "" {
		// wrap expression evaluation in local activity
		// more info: https://cludden.github.io/protoc-gen-go-temporal/docs/guides/patches#pv_64-expression-evaluation-local-activity
		if workflow.GetVersion(ctx, "cludden_protoc-gen-go-temporal_64_expression-evaluation-local-activity", workflow.DefaultVersion, 1) == 1 {
			lao := workflow.GetLocalActivityOptions(ctx)
			lao.ScheduleToCloseTimeout = time.Second * 10
			if err := workflow.ExecuteLocalActivity(workflow.WithLocalActivityOptions(ctx, lao), func(ctx context.Context) (string, error) {
				id, err := expression.EvalExpression(SampleWorkflowWithMutexIdexpression, req)
				if err != nil {
					return "", fmt.Errorf("error evaluating id expression for %q workflow: %w", SampleWorkflowWithMutexWorkflowName, err)
				}
				return id, nil
			}).Get(ctx, &opts.WorkflowID); err != nil {
				return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", SampleWorkflowWithMutexWorkflowName, err)
			}
		} else {
			id, err := expression.EvalExpression(SampleWorkflowWithMutexIdexpression, req)
			if err != nil {
				return opts, fmt.Errorf("error evaluating id expression for %q workflow: %w", SampleWorkflowWithMutexWorkflowName, err)
			}
			opts.WorkflowID = id
		}
	}
	if v := o.idReusePolicy; v != enumsv1.WORKFLOW_ID_REUSE_POLICY_UNSPECIFIED {
		opts.WorkflowIDReusePolicy = v
	}
	if v := o.taskQueue; v != nil {
		opts.TaskQueue = *v
	} else if opts.TaskQueue == "" {
		opts.TaskQueue = ExampleTaskQueue
	}
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	}
	if v := o.searchAttributes; v != nil {
		opts.SearchAttributes = o.searchAttributes
	}
	if v := o.executionTimeout; v != nil {
		opts.WorkflowExecutionTimeout = *v
	}
	if v := o.runTimeout; v != nil {
		opts.WorkflowRunTimeout = *v
	}
	if v := o.taskTimeout; v != nil {
		opts.WorkflowTaskTimeout = *v
	}
	if v := o.parentClosePolicy; v != enumsv1.PARENT_CLOSE_POLICY_UNSPECIFIED {
		opts.ParentClosePolicy = v
	}
	if v := o.waitForCancellation; v != nil {
		opts.WaitForCancellation = *v
	}
	return opts, nil
}

// WithChildWorkflowOptions sets the initial go.temporal.io/sdk/workflow.ChildWorkflowOptions
func (o *SampleWorkflowWithMutexChildOptions) WithChildWorkflowOptions(options workflow.ChildWorkflowOptions) *SampleWorkflowWithMutexChildOptions {
	o.options = options
	return o
}

// WithDataConverter registers a DataConverter for the child workflow
func (o *SampleWorkflowWithMutexChildOptions) WithDataConverter(dc converter.DataConverter) *SampleWorkflowWithMutexChildOptions {
	o.dc = dc
	return o
}

// WithExecutionTimeout sets the WorkflowExecutionTimeout value
func (o *SampleWorkflowWithMutexChildOptions) WithExecutionTimeout(d time.Duration) *SampleWorkflowWithMutexChildOptions {
	o.executionTimeout = &d
	return o
}

// WithID sets the WorkflowID value
func (o *SampleWorkflowWithMutexChildOptions) WithID(id string) *SampleWorkflowWithMutexChildOptions {
	o.id = &id
	return o
}

// WithIDReusePolicy sets the WorkflowIDReusePolicy value
func (o *SampleWorkflowWithMutexChildOptions) WithIDReusePolicy(policy enumsv1.WorkflowIdReusePolicy) *SampleWorkflowWithMutexChildOptions {
	o.idReusePolicy = policy
	return o
}

// WithParentClosePolicy sets the WorkflowIDReusePolicy value
func (o *SampleWorkflowWithMutexChildOptions) WithParentClosePolicy(policy enumsv1.ParentClosePolicy) *SampleWorkflowWithMutexChildOptions {
	o.parentClosePolicy = policy
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *SampleWorkflowWithMutexChildOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *SampleWorkflowWithMutexChildOptions {
	o.retryPolicy = policy
	return o
}

// WithRunTimeout sets the WorkflowRunTimeout value
func (o *SampleWorkflowWithMutexChildOptions) WithRunTimeout(d time.Duration) *SampleWorkflowWithMutexChildOptions {
	o.runTimeout = &d
	return o
}

// WithSearchAttributes sets the SearchAttributes value
func (o *SampleWorkflowWithMutexChildOptions) WithSearchAttributes(sa map[string]any) *SampleWorkflowWithMutexChildOptions {
	o.searchAttributes = sa
	return o
}

// WithTaskTimeout sets the WorkflowTaskTimeout value
func (o *SampleWorkflowWithMutexChildOptions) WithTaskTimeout(d time.Duration) *SampleWorkflowWithMutexChildOptions {
	o.taskTimeout = &d
	return o
}

// WithTaskQueue sets the TaskQueue value
func (o *SampleWorkflowWithMutexChildOptions) WithTaskQueue(tq string) *SampleWorkflowWithMutexChildOptions {
	o.taskQueue = &tq
	return o
}

// WithWaitForCancellation sets the WaitForCancellation value
func (o *SampleWorkflowWithMutexChildOptions) WithWaitForCancellation(wait bool) *SampleWorkflowWithMutexChildOptions {
	o.waitForCancellation = &wait
	return o
}

// WithWorkflowIdConflictPolicy sets the WorkflowIdConflictPolicy value
func (o *SampleWorkflowWithMutexChildOptions) WithWorkflowIdConflictPolicy(policy enumsv1.WorkflowIdConflictPolicy) *SampleWorkflowWithMutexChildOptions {
	o.workflowIdConflictPolicy = policy
	return o
}

// SampleWorkflowWithMutexChildRun describes a child SampleWorkflowWithMutex workflow run
type SampleWorkflowWithMutexChildRun struct {
	Future workflow.ChildWorkflowFuture
}

// Get blocks until the workflow is completed, returning the response value
func (r *SampleWorkflowWithMutexChildRun) Get(ctx workflow.Context) error {
	if err := r.Future.Get(ctx, nil); err != nil {
		return err
	}
	return nil
}

// Select adds this completion to the selector. Callback can be nil.
func (r *SampleWorkflowWithMutexChildRun) Select(sel workflow.Selector, fn func(*SampleWorkflowWithMutexChildRun)) workflow.Selector {
	return sel.AddFuture(r.Future, func(workflow.Future) {
		if fn != nil {
			fn(r)
		}
	})
}

// SelectStart adds waiting for start to the selector. Callback can be nil.
func (r *SampleWorkflowWithMutexChildRun) SelectStart(sel workflow.Selector, fn func(*SampleWorkflowWithMutexChildRun)) workflow.Selector {
	return sel.AddFuture(r.Future.GetChildWorkflowExecution(), func(workflow.Future) {
		if fn != nil {
			fn(r)
		}
	})
}

// WaitStart waits for the child workflow to start
func (r *SampleWorkflowWithMutexChildRun) WaitStart(ctx workflow.Context) (*workflow.Execution, error) {
	var exec workflow.Execution
	if err := r.Future.GetChildWorkflowExecution().Get(ctx, &exec); err != nil {
		return nil, err
	}
	return &exec, nil
}

// ReleaseLockSignal describes a(n) example.mutex.v1.Example.ReleaseLock signal
type ReleaseLockSignal struct {
	Channel workflow.ReceiveChannel
}

// NewReleaseLockSignal initializes a new mutex.v1.ReleaseLock signal wrapper
func NewReleaseLockSignal(ctx workflow.Context) *ReleaseLockSignal {
	return &ReleaseLockSignal{Channel: workflow.GetSignalChannel(ctx, ReleaseLockSignalName)}
}

// Receive blocks until a(n) example.mutex.v1.Example.ReleaseLock signal is received
func (s *ReleaseLockSignal) Receive(ctx workflow.Context) (*ReleaseLockInput, bool) {
	var resp ReleaseLockInput
	more := s.Channel.Receive(ctx, &resp)
	return &resp, more
}

// ReceiveAsync checks for a example.mutex.v1.Example.ReleaseLock signal without blocking
func (s *ReleaseLockSignal) ReceiveAsync() *ReleaseLockInput {
	var resp ReleaseLockInput
	if ok := s.Channel.ReceiveAsync(&resp); !ok {
		return nil
	}
	return &resp
}

// ReceiveWithTimeout blocks until a(n) example.mutex.v1.Example.ReleaseLock signal is received or timeout expires.
// Returns more value of false when Channel is closed.
// Returns ok value of false when no value was found in the channel for the duration of timeout or the ctx was canceled.
// resp will be nil if ok is false.
func (s *ReleaseLockSignal) ReceiveWithTimeout(ctx workflow.Context, timeout time.Duration) (resp *ReleaseLockInput, ok bool, more bool) {
	resp = &ReleaseLockInput{}
	if ok, more = s.Channel.ReceiveWithTimeout(ctx, timeout, &resp); !ok {
		return nil, false, more
	}
	return
}

// Select checks for a(n) example.mutex.v1.Example.ReleaseLock signal without blocking
func (s *ReleaseLockSignal) Select(sel workflow.Selector, fn func(*ReleaseLockInput)) workflow.Selector {
	return sel.AddReceive(s.Channel, func(workflow.ReceiveChannel, bool) {
		req := s.ReceiveAsync()
		if fn != nil {
			fn(req)
		}
	})
}

// ReleaseLock releases a lock on a resource identified by `lease_id`.
func ReleaseLockExternal(ctx workflow.Context, workflowID string, runID string, req *ReleaseLockInput) error {
	return ReleaseLockExternalAsync(ctx, workflowID, runID, req).Get(ctx, nil)
}

// ReleaseLock releases a lock on a resource identified by `lease_id`.
func ReleaseLockExternalAsync(ctx workflow.Context, workflowID string, runID string, req *ReleaseLockInput) workflow.Future {
	return workflow.SignalExternalWorkflow(ctx, workflowID, runID, ReleaseLockSignalName, req)
}

// ExampleActivities describes available worker activities
type ExampleActivities interface {
	// Mutex is a workflow that manages concurrent access to a resource
	// identified by `resource_id`.
	Mutex(ctx context.Context, req *MutexInput) error
}

// RegisterExampleActivities registers activities with a worker
func RegisterExampleActivities(r worker.ActivityRegistry, activities ExampleActivities) {
	RegisterMutexActivity(r, activities.Mutex)
}

// RegisterMutexActivity registers a example.mutex.v1.Example.Mutex activity
func RegisterMutexActivity(r worker.ActivityRegistry, fn func(context.Context, *MutexInput) error) {
	r.RegisterActivityWithOptions(fn, activity.RegisterOptions{
		Name: MutexActivityName,
	})
}

// MutexFuture describes a(n) example.mutex.v1.Example.Mutex activity execution
type MutexFuture struct {
	Future workflow.Future
}

// Get blocks on the activity's completion, returning the response
func (f *MutexFuture) Get(ctx workflow.Context) error {
	return f.Future.Get(ctx, nil)
}

// Select adds the activity's completion to the selector, callback can be nil
func (f *MutexFuture) Select(sel workflow.Selector, fn func(*MutexFuture)) workflow.Selector {
	return sel.AddFuture(f.Future, func(workflow.Future) {
		if fn != nil {
			fn(f)
		}
	})
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func Mutex(ctx workflow.Context, req *MutexInput, options ...*MutexActivityOptions) error {
	return MutexAsync(ctx, req, options...).Get(ctx)
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func MutexAsync(ctx workflow.Context, req *MutexInput, options ...*MutexActivityOptions) *MutexFuture {
	var o *MutexActivityOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexActivityOptions()
	}
	var err error
	if ctx, err = o.Build(ctx); err != nil {
		errF, errS := workflow.NewFuture(ctx)
		errS.SetError(err)
		return &MutexFuture{Future: errF}
	}
	activity := MutexActivityName
	if o.dc != nil {
		ctx = workflow.WithDataConverter(ctx, o.dc)
	}
	future := &MutexFuture{Future: workflow.ExecuteActivity(ctx, activity, req)}
	return future
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func MutexLocal(ctx workflow.Context, req *MutexInput, options ...*MutexLocalActivityOptions) error {
	return MutexLocalAsync(ctx, req, options...).Get(ctx)
}

// Mutex is a workflow that manages concurrent access to a resource
// identified by `resource_id`.
func MutexLocalAsync(ctx workflow.Context, req *MutexInput, options ...*MutexLocalActivityOptions) *MutexFuture {
	var o *MutexLocalActivityOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexLocalActivityOptions()
	}
	var err error
	if ctx, err = o.Build(ctx); err != nil {
		errF, errS := workflow.NewFuture(ctx)
		errS.SetError(err)
		return &MutexFuture{Future: errF}
	}
	var activity any
	if o.fn != nil {
		activity = o.fn
	} else {
		activity = MutexActivityName
	}
	if o.dc != nil {
		ctx = workflow.WithDataConverter(ctx, o.dc)
	}
	future := &MutexFuture{Future: workflow.ExecuteLocalActivity(ctx, activity, req)}
	return future
}

// MutexActivityOptions provides configuration for a(n) example.mutex.v1.Example.Mutex activity
type MutexActivityOptions struct {
	options                workflow.ActivityOptions
	retryPolicy            *temporal.RetryPolicy
	scheduleToCloseTimeout *time.Duration
	startToCloseTimeout    *time.Duration
	dc                     converter.DataConverter
	heartbeatTimeout       *time.Duration
	scheduleToStartTimeout *time.Duration
	taskQueue              *string
	waitForCancellation    *bool
}

// NewMutexActivityOptions initializes a new MutexActivityOptions value
func NewMutexActivityOptions() *MutexActivityOptions {
	return &MutexActivityOptions{}
}

// Build initializes a workflow.Context with appropriate ActivityOptions values derived from schema defaults and any user-defined overrides
func (o *MutexActivityOptions) Build(ctx workflow.Context) (workflow.Context, error) {
	opts := o.options
	if v := o.heartbeatTimeout; v != nil {
		opts.HeartbeatTimeout = *v
	}
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	}
	if v := o.scheduleToCloseTimeout; v != nil {
		opts.ScheduleToCloseTimeout = *v
	}
	if v := o.scheduleToStartTimeout; v != nil {
		opts.ScheduleToStartTimeout = *v
	}
	if v := o.startToCloseTimeout; v != nil {
		opts.StartToCloseTimeout = *v
	} else if opts.StartToCloseTimeout == 0 {
		opts.StartToCloseTimeout = 10000000000 // 10 seconds
	}
	if v := o.taskQueue; v != nil {
		opts.TaskQueue = *v
	} else if opts.TaskQueue == "" {
		opts.TaskQueue = ExampleTaskQueue
	}
	if v := o.waitForCancellation; v != nil {
		opts.WaitForCancellation = *v
	}
	return workflow.WithActivityOptions(ctx, opts), nil
}

// WithActivityOptions specifies an initial ActivityOptions value to which defaults will be applied
func (o *MutexActivityOptions) WithActivityOptions(options workflow.ActivityOptions) *MutexActivityOptions {
	o.options = options
	return o
}

// WithDataConverter registers a DataConverter for the (local) activity
func (o *MutexActivityOptions) WithDataConverter(dc converter.DataConverter) *MutexActivityOptions {
	o.dc = dc
	return o
}

// WithHeartbeatTimeout sets the HeartbeatTimeout value
func (o *MutexActivityOptions) WithHeartbeatTimeout(d time.Duration) *MutexActivityOptions {
	o.heartbeatTimeout = &d
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *MutexActivityOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *MutexActivityOptions {
	o.retryPolicy = policy
	return o
}

// WithScheduleToCloseTimeout sets the ScheduleToCloseTimeout value
func (o *MutexActivityOptions) WithScheduleToCloseTimeout(d time.Duration) *MutexActivityOptions {
	o.scheduleToCloseTimeout = &d
	return o
}

// WithScheduleToStartTimeout sets the ScheduleToStartTimeout value
func (o *MutexActivityOptions) WithScheduleToStartTimeout(d time.Duration) *MutexActivityOptions {
	o.scheduleToStartTimeout = &d
	return o
}

// WithStartToCloseTimeout sets the StartToCloseTimeout value
func (o *MutexActivityOptions) WithStartToCloseTimeout(d time.Duration) *MutexActivityOptions {
	o.startToCloseTimeout = &d
	return o
}

// WithTaskQueue sets the TaskQueue value
func (o *MutexActivityOptions) WithTaskQueue(tq string) *MutexActivityOptions {
	o.taskQueue = &tq
	return o
}

// WithWaitForCancellation sets the WaitForCancellation value
func (o *MutexActivityOptions) WithWaitForCancellation(wait bool) *MutexActivityOptions {
	o.waitForCancellation = &wait
	return o
}

// MutexLocalActivityOptions provides configuration for a(n) example.mutex.v1.Example.Mutex activity
type MutexLocalActivityOptions struct {
	options                workflow.LocalActivityOptions
	retryPolicy            *temporal.RetryPolicy
	scheduleToCloseTimeout *time.Duration
	startToCloseTimeout    *time.Duration
	dc                     converter.DataConverter
	fn                     func(context.Context, *MutexInput) error
}

// NewMutexLocalActivityOptions initializes a new MutexLocalActivityOptions value
func NewMutexLocalActivityOptions() *MutexLocalActivityOptions {
	return &MutexLocalActivityOptions{}
}

// Build initializes a workflow.Context with appropriate LocalActivityOptions values derived from schema defaults and any user-defined overrides
func (o *MutexLocalActivityOptions) Build(ctx workflow.Context) (workflow.Context, error) {
	opts := o.options
	if v := o.retryPolicy; v != nil {
		opts.RetryPolicy = v
	}
	if v := o.scheduleToCloseTimeout; v != nil {
		opts.ScheduleToCloseTimeout = *v
	}
	if v := o.startToCloseTimeout; v != nil {
		opts.StartToCloseTimeout = *v
	} else if opts.StartToCloseTimeout == 0 {
		opts.StartToCloseTimeout = 10000000000 // 10 seconds
	}
	return workflow.WithLocalActivityOptions(ctx, opts), nil
}

// Local specifies a custom example.mutex.v1.Example.Mutex implementation
func (o *MutexLocalActivityOptions) Local(fn func(context.Context, *MutexInput) error) *MutexLocalActivityOptions {
	o.fn = fn
	return o
}

// WithLocalActivityOptions specifies an initial LocalActivityOptions value to which defaults will be applied
func (o *MutexLocalActivityOptions) WithLocalActivityOptions(options workflow.LocalActivityOptions) *MutexLocalActivityOptions {
	o.options = options
	return o
}

// WithDataConverter registers a DataConverter for the (local) activity
func (o *MutexLocalActivityOptions) WithDataConverter(dc converter.DataConverter) *MutexLocalActivityOptions {
	o.dc = dc
	return o
}

// WithRetryPolicy sets the RetryPolicy value
func (o *MutexLocalActivityOptions) WithRetryPolicy(policy *temporal.RetryPolicy) *MutexLocalActivityOptions {
	o.retryPolicy = policy
	return o
}

// WithScheduleToCloseTimeout sets the ScheduleToCloseTimeout value
func (o *MutexLocalActivityOptions) WithScheduleToCloseTimeout(d time.Duration) *MutexLocalActivityOptions {
	o.scheduleToCloseTimeout = &d
	return o
}

// WithStartToCloseTimeout sets the StartToCloseTimeout value
func (o *MutexLocalActivityOptions) WithStartToCloseTimeout(d time.Duration) *MutexLocalActivityOptions {
	o.startToCloseTimeout = &d
	return o
}

// TestClient provides a testsuite-compatible Client
type TestExampleClient struct {
	env       *testsuite.TestWorkflowEnvironment
	workflows ExampleWorkflows
}

var _ ExampleClient = &TestExampleClient{}

// NewTestExampleClient initializes a new TestExampleClient value
func NewTestExampleClient(env *testsuite.TestWorkflowEnvironment, workflows ExampleWorkflows, activities ExampleActivities) *TestExampleClient {
	if workflows != nil {
		RegisterExampleWorkflows(env, workflows)
	}
	if activities != nil {
		RegisterExampleActivities(env, activities)
	}
	return &TestExampleClient{env, workflows}
}

// Mutex executes a(n) mutex.v1.Mutex workflow in the test environment
func (c *TestExampleClient) Mutex(ctx context.Context, req *MutexInput, opts ...*MutexOptions) error {
	run, err := c.MutexAsync(ctx, req, opts...)
	if err != nil {
		return err
	}
	return run.Get(ctx)
}

// MutexAsync executes a(n) mutex.v1.Mutex workflow in the test environment
func (c *TestExampleClient) MutexAsync(ctx context.Context, req *MutexInput, options ...*MutexOptions) (MutexRun, error) {
	var o *MutexOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexOptions()
	}
	opts, err := o.Build(req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing client.StartWorkflowOptions: %w", err)
	}
	return &testMutexRun{client: c, env: c.env, opts: &opts, req: req, workflows: c.workflows}, nil
}

// GetMutex is a noop
func (c *TestExampleClient) GetMutex(ctx context.Context, workflowID string, runID string) MutexRun {
	return &testMutexRun{env: c.env, workflows: c.workflows}
}

// MutexWithAcquireLock executes a(n) mutex.v1.Mutex workflow and a(n) mutex.v1.AcquireLock update in the test environment
func (c *TestExampleClient) MutexWithAcquireLock(ctx context.Context, input *MutexInput, update *AcquireLockInput, options ...*MutexWithAcquireLockOptions) (*AcquireLockOutput, MutexRun, error) {
	var o *MutexWithAcquireLockOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexWithAcquireLockOptions()
	}
	handle, run, err := c.MutexWithAcquireLockAsync(ctx, input, update, o)
	if err != nil {
		return nil, run, err
	}
	run.Get(ctx)
	out, err := handle.Get(ctx)
	if err != nil {
		return nil, run, err
	}
	return out, run, nil
}

// MutexWithAcquireLockAsync executes a(n) mutex.v1.Mutex workflow and a(n) mutex.v1.AcquireLock update in the test environment
func (c *TestExampleClient) MutexWithAcquireLockAsync(ctx context.Context, input *MutexInput, update *AcquireLockInput, options ...*MutexWithAcquireLockOptions) (AcquireLockHandle, MutexRun, error) {
	var o *MutexWithAcquireLockOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewMutexWithAcquireLockOptions()
	}
	if o.workflowOptions == nil {
		o.workflowOptions = NewMutexOptions()
	}
	swo, err := o.workflowOptions.Build(input.ProtoReflect())
	if err != nil {
		return nil, nil, fmt.Errorf("error initializing workflowOptions: %w", err)
	}
	if o.updateOptions == nil {
		o.updateOptions = NewAcquireLockOptions()
	}
	uo, err := o.updateOptions.Build(swo.ID, "", update)
	if err != nil {
		return nil, nil, fmt.Errorf("error initializing updateOptions: %w", err)
	}
	run, err := c.MutexAsync(ctx, input)
	if err != nil {
		return nil, nil, err
	}
	uc := testutil.NewUpdateCallbacks()
	c.env.RegisterDelayedCallback(func() {
		c.env.UpdateWorkflow(AcquireLockUpdateName, uo.UpdateID, uc, update)
	}, 0)
	return &testAcquireLockHandle{
		callbacks:  uc,
		env:        c.env,
		opts:       uo,
		req:        update,
		runID:      "",
		workflowID: swo.ID,
	}, run, nil
}

// SampleWorkflowWithMutex executes a(n) example.mutex.v1.Example.SampleWorkflowWithMutex workflow in the test environment
func (c *TestExampleClient) SampleWorkflowWithMutex(ctx context.Context, req *SampleWorkflowWithMutexInput, opts ...*SampleWorkflowWithMutexOptions) error {
	run, err := c.SampleWorkflowWithMutexAsync(ctx, req, opts...)
	if err != nil {
		return err
	}
	return run.Get(ctx)
}

// SampleWorkflowWithMutexAsync executes a(n) example.mutex.v1.Example.SampleWorkflowWithMutex workflow in the test environment
func (c *TestExampleClient) SampleWorkflowWithMutexAsync(ctx context.Context, req *SampleWorkflowWithMutexInput, options ...*SampleWorkflowWithMutexOptions) (SampleWorkflowWithMutexRun, error) {
	var o *SampleWorkflowWithMutexOptions
	if len(options) > 0 && options[0] != nil {
		o = options[0]
	} else {
		o = NewSampleWorkflowWithMutexOptions()
	}
	opts, err := o.Build(req.ProtoReflect())
	if err != nil {
		return nil, fmt.Errorf("error initializing client.StartWorkflowOptions: %w", err)
	}
	return &testSampleWorkflowWithMutexRun{client: c, env: c.env, opts: &opts, req: req, workflows: c.workflows}, nil
}

// GetSampleWorkflowWithMutex is a noop
func (c *TestExampleClient) GetSampleWorkflowWithMutex(ctx context.Context, workflowID string, runID string) SampleWorkflowWithMutexRun {
	return &testSampleWorkflowWithMutexRun{env: c.env, workflows: c.workflows}
}

// CancelWorkflow requests cancellation of an existing workflow execution
func (c *TestExampleClient) CancelWorkflow(ctx context.Context, workflowID string, runID string) error {
	c.env.CancelWorkflow()
	return nil
}

// TerminateWorkflow terminates an existing workflow execution
func (c *TestExampleClient) TerminateWorkflow(ctx context.Context, workflowID string, runID string, reason string, details ...interface{}) error {
	return c.CancelWorkflow(ctx, workflowID, runID)
}

// ReleaseLock executes a mutex.v1.ReleaseLock signal
func (c *TestExampleClient) ReleaseLock(ctx context.Context, workflowID string, runID string, req *ReleaseLockInput) error {
	c.env.SignalWorkflow(ReleaseLockSignalName, req)
	return nil
}

// AcquireLock executes a(n) mutex.v1.AcquireLock update in the test environment
func (c *TestExampleClient) AcquireLock(ctx context.Context, workflowID string, runID string, req *AcquireLockInput, opts ...*AcquireLockOptions) (*AcquireLockOutput, error) {
	options := NewAcquireLockOptions()
	if len(opts) > 0 && opts[0].Options != nil {
		options = opts[0]
	}
	options.Options.WaitForStage = client.WorkflowUpdateStageCompleted
	handle, err := c.AcquireLockAsync(ctx, workflowID, runID, req, options)
	if err != nil {
		return nil, err
	}
	return handle.Get(ctx)
}

// AcquireLockAsync executes a(n) mutex.v1.AcquireLock update in the test environment
func (c *TestExampleClient) AcquireLockAsync(ctx context.Context, workflowID string, runID string, req *AcquireLockInput, opts ...*AcquireLockOptions) (AcquireLockHandle, error) {
	var o *AcquireLockOptions
	if len(opts) > 0 && opts[0] != nil {
		o = opts[0]
	} else {
		o = NewAcquireLockOptions()
	}
	options, err := o.Build(workflowID, runID, req)
	if err != nil {
		return nil, fmt.Errorf("error initializing UpdateWorkflowWithOptions: %w", err)
	}

	if options.UpdateID == "" {
		options.UpdateID = uuid.New().String()
	}

	uc := testutil.NewUpdateCallbacks()
	c.env.UpdateWorkflow(AcquireLockUpdateName, options.UpdateID, uc, req)
	return &testAcquireLockHandle{
		callbacks:  uc,
		env:        c.env,
		opts:       options,
		runID:      runID,
		workflowID: workflowID,
		req:        req,
	}, nil
}

// GetAcquireLock retrieves a handle to an existing mutex.v1.AcquireLock update
func (c *TestExampleClient) GetAcquireLock(ctx context.Context, req client.GetWorkflowUpdateHandleOptions) (AcquireLockHandle, error) {
	return nil, errors.New("unimplemented")
}

var _ AcquireLockHandle = &testAcquireLockHandle{}

// testAcquireLockHandle provides an internal implementation of a(n) AcquireLockHandle
type testAcquireLockHandle struct {
	callbacks  *testutil.UpdateCallbacks
	env        *testsuite.TestWorkflowEnvironment
	opts       *client.UpdateWorkflowOptions
	req        *AcquireLockInput
	runID      string
	workflowID string
}

// Get retrieves a test mutex.v1.AcquireLock update result
func (h *testAcquireLockHandle) Get(ctx context.Context) (*AcquireLockOutput, error) {
	if resp, err := h.callbacks.Get(ctx); err != nil {
		return nil, err
	} else {
		return resp.(*AcquireLockOutput), nil
	}
}

// RunID implementation
func (h *testAcquireLockHandle) RunID() string {
	return h.runID
}

// UpdateID implementation
func (h *testAcquireLockHandle) UpdateID() string {
	if h.opts != nil {
		return h.opts.UpdateID
	}
	return ""
}

// WorkflowID implementation
func (h *testAcquireLockHandle) WorkflowID() string {
	return h.workflowID
}

var _ MutexRun = &testMutexRun{}

// testMutexRun provides convenience methods for interacting with a(n) mutex.v1.Mutex workflow in the test environment
type testMutexRun struct {
	client    *TestExampleClient
	env       *testsuite.TestWorkflowEnvironment
	isStarted atomic.Bool
	opts      *client.StartWorkflowOptions
	req       *MutexInput
	workflows ExampleWorkflows
}

// Cancel requests cancellation of a workflow in execution, returning an error if applicable
func (r *testMutexRun) Cancel(ctx context.Context) error {
	return r.client.CancelWorkflow(ctx, r.ID(), r.RunID())
}

// Get retrieves a test mutex.v1.Mutex workflow result
func (r *testMutexRun) Get(context.Context) error {
	if r.isStarted.CompareAndSwap(false, true) {
		r.env.ExecuteWorkflow(MutexWorkflowName, r.req)
	}
	if !r.env.IsWorkflowCompleted() {
		return errors.New("workflow in progress")
	}
	if err := r.env.GetWorkflowError(); err != nil {
		return err
	}
	return nil
}

// ID returns a test mutex.v1.Mutex workflow run's workflow ID
func (r *testMutexRun) ID() string {
	if r.opts != nil {
		return r.opts.ID
	}
	return ""
}

// Run noop implementation
func (r *testMutexRun) Run() client.WorkflowRun {
	return nil
}

// RunID noop implementation
func (r *testMutexRun) RunID() string {
	return ""
}

// Terminate terminates a workflow in execution, returning an error if applicable
func (r *testMutexRun) Terminate(ctx context.Context, reason string, details ...interface{}) error {
	return r.client.TerminateWorkflow(ctx, r.ID(), r.RunID(), reason, details...)
}

// ReleaseLock executes a mutex.v1.ReleaseLock signal against a test mutex.v1.Mutex workflow
func (r *testMutexRun) ReleaseLock(ctx context.Context, req *ReleaseLockInput) error {
	return r.client.ReleaseLock(ctx, r.ID(), r.RunID(), req)
}

// AcquireLock executes a(n) mutex.v1.AcquireLock update against a test mutex.v1.Mutex workflow
func (r *testMutexRun) AcquireLock(ctx context.Context, req *AcquireLockInput, opts ...*AcquireLockOptions) (*AcquireLockOutput, error) {
	return r.client.AcquireLock(ctx, r.ID(), r.RunID(), req, opts...)
}

// AcquireLockAsync executes a(n) mutex.v1.AcquireLock update against a test mutex.v1.Mutex workflow
func (r *testMutexRun) AcquireLockAsync(ctx context.Context, req *AcquireLockInput, opts ...*AcquireLockOptions) (AcquireLockHandle, error) {
	return r.client.AcquireLockAsync(ctx, r.ID(), r.RunID(), req, opts...)
}

var _ SampleWorkflowWithMutexRun = &testSampleWorkflowWithMutexRun{}

// testSampleWorkflowWithMutexRun provides convenience methods for interacting with a(n) example.mutex.v1.Example.SampleWorkflowWithMutex workflow in the test environment
type testSampleWorkflowWithMutexRun struct {
	client    *TestExampleClient
	env       *testsuite.TestWorkflowEnvironment
	isStarted atomic.Bool
	opts      *client.StartWorkflowOptions
	req       *SampleWorkflowWithMutexInput
	workflows ExampleWorkflows
}

// Cancel requests cancellation of a workflow in execution, returning an error if applicable
func (r *testSampleWorkflowWithMutexRun) Cancel(ctx context.Context) error {
	return r.client.CancelWorkflow(ctx, r.ID(), r.RunID())
}

// Get retrieves a test example.mutex.v1.Example.SampleWorkflowWithMutex workflow result
func (r *testSampleWorkflowWithMutexRun) Get(context.Context) error {
	if r.isStarted.CompareAndSwap(false, true) {
		r.env.ExecuteWorkflow(SampleWorkflowWithMutexWorkflowName, r.req)
	}
	if !r.env.IsWorkflowCompleted() {
		return errors.New("workflow in progress")
	}
	if err := r.env.GetWorkflowError(); err != nil {
		return err
	}
	return nil
}

// ID returns a test example.mutex.v1.Example.SampleWorkflowWithMutex workflow run's workflow ID
func (r *testSampleWorkflowWithMutexRun) ID() string {
	if r.opts != nil {
		return r.opts.ID
	}
	return ""
}

// Run noop implementation
func (r *testSampleWorkflowWithMutexRun) Run() client.WorkflowRun {
	return nil
}

// RunID noop implementation
func (r *testSampleWorkflowWithMutexRun) RunID() string {
	return ""
}

// Terminate terminates a workflow in execution, returning an error if applicable
func (r *testSampleWorkflowWithMutexRun) Terminate(ctx context.Context, reason string, details ...interface{}) error {
	return r.client.TerminateWorkflow(ctx, r.ID(), r.RunID(), reason, details...)
}

// ExampleCliOptions describes runtime configuration for example.mutex.v1.Example cli
type ExampleCliOptions struct {
	after            func(*v2.Context) error
	before           func(*v2.Context) error
	clientForCommand func(*v2.Context) (client.Client, error)
	worker           func(*v2.Context, client.Client) (worker.Worker, error)
}

// NewExampleCliOptions initializes a new ExampleCliOptions value
func NewExampleCliOptions() *ExampleCliOptions {
	return &ExampleCliOptions{}
}

// WithAfter injects a custom After hook to be run after any command invocation
func (opts *ExampleCliOptions) WithAfter(fn func(*v2.Context) error) *ExampleCliOptions {
	opts.after = fn
	return opts
}

// WithBefore injects a custom Before hook to be run prior to any command invocation
func (opts *ExampleCliOptions) WithBefore(fn func(*v2.Context) error) *ExampleCliOptions {
	opts.before = fn
	return opts
}

// WithClient provides a Temporal client factory for use by commands
func (opts *ExampleCliOptions) WithClient(fn func(*v2.Context) (client.Client, error)) *ExampleCliOptions {
	opts.clientForCommand = fn
	return opts
}

// WithWorker provides an method for initializing a worker
func (opts *ExampleCliOptions) WithWorker(fn func(*v2.Context, client.Client) (worker.Worker, error)) *ExampleCliOptions {
	opts.worker = fn
	return opts
}

// NewExampleCli initializes a cli for a(n) example.mutex.v1.Example service
func NewExampleCli(options ...*ExampleCliOptions) (*v2.App, error) {
	commands, err := newExampleCommands(options...)
	if err != nil {
		return nil, fmt.Errorf("error initializing subcommands: %w", err)
	}
	return &v2.App{
		Name:                      "example",
		Commands:                  commands,
		DisableSliceFlagSeparator: true,
	}, nil
}

// NewExampleCliCommand initializes a cli command for a example.mutex.v1.Example service with subcommands for each query, signal, update, and workflow
func NewExampleCliCommand(options ...*ExampleCliOptions) (*v2.Command, error) {
	subcommands, err := newExampleCommands(options...)
	if err != nil {
		return nil, fmt.Errorf("error initializing subcommands: %w", err)
	}
	return &v2.Command{
		Name:        "example",
		Subcommands: subcommands,
	}, nil
}

// newExampleCommands initializes (sub)commands for a example.mutex.v1.Example cli or command
func newExampleCommands(options ...*ExampleCliOptions) ([]*v2.Command, error) {
	opts := &ExampleCliOptions{}
	if len(options) > 0 {
		opts = options[0]
	}
	if opts.clientForCommand == nil {
		opts.clientForCommand = func(*v2.Context) (client.Client, error) {
			return client.Dial(client.Options{})
		}
	}
	commands := []*v2.Command{
		{
			Name:                   "release-lock",
			Usage:                  "ReleaseLock releases a lock on a resource identified by `lease_id`.",
			Category:               "SIGNALS",
			UseShortOptionHandling: true,
			Before:                 opts.before,
			After:                  opts.after,
			Flags: []v2.Flag{
				&v2.StringFlag{
					Name:     "workflow-id",
					Usage:    "workflow id",
					Required: true,
					Aliases:  []string{"w"},
				},
				&v2.StringFlag{
					Name:    "run-id",
					Usage:   "run id",
					Aliases: []string{"r"},
				},
				&v2.StringFlag{
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
					Aliases:  []string{"f"},
					Category: "INPUT",
				},
				&v2.StringFlag{
					Name:     "lease-id",
					Usage:    "set the value of the operation's \"LeaseId\" parameter",
					Category: "INPUT",
				},
			},
			Action: func(cmd *v2.Context) error {
				c, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer c.Close()
				client := NewExampleClient(c)
				req, err := UnmarshalCliFlagsToReleaseLockInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling request: %w", err)
				}
				if err := client.ReleaseLock(cmd.Context, cmd.String("workflow-id"), cmd.String("run-id"), req); err != nil {
					return fmt.Errorf("error sending %q signal: %w", ReleaseLockSignalName, err)
				}
				fmt.Println("success")
				return nil
			},
		},
		{
			Name:                   "acquire-lock",
			Usage:                  "AcquireLock requests a lock on a resource identified by `resource_id` and blocks until the lock is acquired, returning a `lease_id` that can be used to release the lock.",
			Category:               "UPDATES",
			UseShortOptionHandling: true,
			Before:                 opts.before,
			After:                  opts.after,
			Flags: []v2.Flag{
				&v2.BoolFlag{
					Name:    "detach",
					Usage:   "run workflow update in the background and print workflow, execution, and udpate id",
					Aliases: []string{"d"},
				},
				&v2.StringFlag{
					Name:     "workflow-id",
					Usage:    "workflow id",
					Required: true,
					Aliases:  []string{"w"},
				},
				&v2.StringFlag{
					Name:    "run-id",
					Usage:   "run id",
					Aliases: []string{"r"},
				},
				&v2.StringFlag{
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
					Aliases:  []string{"f"},
					Category: "INPUT",
				},
				&v2.DurationFlag{
					Name:     "timeout",
					Usage:    "set the value of the operation's \"Timeout\" parameter (e.g. \"3.000000001s\")",
					Category: "INPUT",
				},
			},
			Action: func(cmd *v2.Context) error {
				c, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer c.Close()
				client := NewExampleClient(c)
				req, err := UnmarshalCliFlagsToAcquireLockInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling request: %w", err)
				}
				handle, err := client.AcquireLockAsync(cmd.Context, cmd.String("workflow-id"), cmd.String("run-id"), req)
				if err != nil {
					return fmt.Errorf("error executing %s update: %w", AcquireLockUpdateName, err)
				}
				if cmd.Bool("detach") {
					fmt.Println("success")
					fmt.Printf("workflow id: %s\n", handle.WorkflowID())
					fmt.Printf("run id: %s\n", handle.RunID())
					fmt.Printf("update id: %s\n", handle.UpdateID())
					return nil
				}
				if resp, err := handle.Get(cmd.Context); err != nil {
					return err
				} else {
					b, err := protojson.Marshal(resp)
					if err != nil {
						return fmt.Errorf("error serializing response json: %w", err)
					}
					var out bytes.Buffer
					if err := json.Indent(&out, b, "", "  "); err != nil {
						return fmt.Errorf("error formatting json: %w", err)
					}
					fmt.Println(out.String())
					return nil
				}
			},
		},
		{
			Name:                   "mutex",
			Usage:                  "Mutex is a workflow that manages concurrent access to a resource identified by `resource_id`.",
			Category:               "WORKFLOWS",
			UseShortOptionHandling: true,
			Before:                 opts.before,
			After:                  opts.after,
			Flags: []v2.Flag{
				&v2.BoolFlag{
					Name:    "detach",
					Usage:   "run workflow in the background and print workflow and execution id",
					Aliases: []string{"d"},
				},
				&v2.StringFlag{
					Name:    "task-queue",
					Usage:   "task queue name",
					Aliases: []string{"t"},
					EnvVars: []string{"TEMPORAL_TASK_QUEUE_NAME", "TEMPORAL_TASK_QUEUE", "TASK_QUEUE_NAME", "TASK_QUEUE"},
					Value:   "mutex",
				},
				&v2.StringFlag{
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
					Aliases:  []string{"f"},
					Category: "INPUT",
				},
				&v2.StringFlag{
					Name:     "resource-id",
					Usage:    "set the value of the operation's \"ResourceId\" parameter",
					Category: "INPUT",
				},
			},
			Action: func(cmd *v2.Context) error {
				tc, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer tc.Close()
				c := NewExampleClient(tc)
				req, err := UnmarshalCliFlagsToMutexInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling request: %w", err)
				}
				opts := client.StartWorkflowOptions{}
				if tq := cmd.String("task-queue"); tq != "" {
					opts.TaskQueue = tq
				}
				run, err := c.MutexAsync(cmd.Context, req, NewMutexOptions().WithStartWorkflowOptions(opts))
				if err != nil {
					return fmt.Errorf("error starting %s workflow: %w", MutexWorkflowName, err)
				}
				if cmd.Bool("detach") {
					fmt.Println("success")
					fmt.Printf("workflow id: %s\n", run.ID())
					fmt.Printf("run id: %s\n", run.RunID())
					return nil
				}
				if err := run.Get(cmd.Context); err != nil {
					return err
				} else {
					return nil
				}
			},
		},
		// executes a(n) example.mutex.v1.Example.AcquireLock update on a example.mutex.v1.Example.Mutex workflow, starting it if necessary,
		{
			Action: func(cmd *v2.Context) error {
				c, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer c.Close()
				client := NewExampleClient(c)
				input, err := UnmarshalCliFlagsToMutexInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling input: %w", err)
				}
				update, err := UnmarshalCliFlagsToAcquireLockInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "update-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling update: %w", err)
				}
				handle, _, err := client.MutexWithAcquireLockAsync(cmd.Context, input, update)
				if err != nil {
					return fmt.Errorf("error starting workflow with update: %w", err)
				}
				if cmd.Bool("detach") {
					fmt.Println("success")
					fmt.Printf("workflow id: %s\n", handle.WorkflowID())
					fmt.Printf("run id: %s\n", handle.RunID())
					fmt.Printf("update id: %s\n", handle.UpdateID())
					return nil
				}
				if out, err := handle.Get(cmd.Context); err != nil {
					return err
				} else {
					b, err := protojson.Marshal(out)
					if err != nil {
						return fmt.Errorf("error serializing response json: %w", err)
					}
					var out bytes.Buffer
					if err := json.Indent(&out, b, "", "  "); err != nil {
						return fmt.Errorf("error formatting json: %w", err)
					}
					fmt.Println(out.String())
					return nil
				}
			},
			After:    opts.after,
			Before:   opts.before,
			Category: "WORKFLOWS",
			Flags: []v2.Flag{
				&v2.BoolFlag{
					Aliases: []string{"d"},
					Name:    "detach",
					Usage:   "run workflow update in the background and print workflow, execution, and update id",
				},
				&v2.StringFlag{
					Aliases:  []string{"f"},
					Category: "INPUT",
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
				},
				&v2.StringFlag{
					Name:     "resource-id",
					Usage:    "set the value of the operation's \"ResourceId\" parameter",
					Category: "INPUT",
				},
				&v2.StringFlag{
					Aliases:  []string{"u"},
					Category: "UPDATE",
					Name:     "update-file",
					Usage:    "path to json-formatted update file",
				},
				&v2.DurationFlag{
					Name:     "timeout",
					Usage:    "set the value of the operation's \"Timeout\" parameter (e.g. \"3.000000001s\")",
					Category: "UPDATE",
				},
			},
			Name:                   "mutex-with-acquire-lock",
			Usage:                  "executes a(n) example.mutex.v1.Example.AcquireLock update on a example.mutex.v1.Example.Mutex workflow, starting it if necessary",
			UseShortOptionHandling: true,
		},
		{
			Name:                   "sample-workflow-with-mutex",
			Usage:                  "SampleWorkflowWithMutex is a sample workflow that demonstrates how to use the Mutex service.",
			Category:               "WORKFLOWS",
			UseShortOptionHandling: true,
			Before:                 opts.before,
			After:                  opts.after,
			Flags: []v2.Flag{
				&v2.BoolFlag{
					Name:    "detach",
					Usage:   "run workflow in the background and print workflow and execution id",
					Aliases: []string{"d"},
				},
				&v2.StringFlag{
					Name:    "task-queue",
					Usage:   "task queue name",
					Aliases: []string{"t"},
					EnvVars: []string{"TEMPORAL_TASK_QUEUE_NAME", "TEMPORAL_TASK_QUEUE", "TASK_QUEUE_NAME", "TASK_QUEUE"},
					Value:   "mutex",
				},
				&v2.StringFlag{
					Name:     "input-file",
					Usage:    "path to json-formatted input file",
					Aliases:  []string{"f"},
					Category: "INPUT",
				},
				&v2.StringFlag{
					Name:     "resource-id",
					Usage:    "set the value of the operation's \"ResourceId\" parameter",
					Category: "INPUT",
				},
				&v2.DurationFlag{
					Name:     "sleep",
					Usage:    "set the value of the operation's \"Sleep\" parameter (e.g. \"3.000000001s\")",
					Category: "INPUT",
				},
			},
			Action: func(cmd *v2.Context) error {
				tc, err := opts.clientForCommand(cmd)
				if err != nil {
					return fmt.Errorf("error initializing client for command: %w", err)
				}
				defer tc.Close()
				c := NewExampleClient(tc)
				req, err := UnmarshalCliFlagsToSampleWorkflowWithMutexInput(cmd, helpers.UnmarshalCliFlagsOptions{FromFile: "input-file"})
				if err != nil {
					return fmt.Errorf("error unmarshalling request: %w", err)
				}
				opts := client.StartWorkflowOptions{}
				if tq := cmd.String("task-queue"); tq != "" {
					opts.TaskQueue = tq
				}
				run, err := c.SampleWorkflowWithMutexAsync(cmd.Context, req, NewSampleWorkflowWithMutexOptions().WithStartWorkflowOptions(opts))
				if err != nil {
					return fmt.Errorf("error starting %s workflow: %w", SampleWorkflowWithMutexWorkflowName, err)
				}
				if cmd.Bool("detach") {
					fmt.Println("success")
					fmt.Printf("workflow id: %s\n", run.ID())
					fmt.Printf("run id: %s\n", run.RunID())
					return nil
				}
				if err := run.Get(cmd.Context); err != nil {
					return err
				} else {
					return nil
				}
			},
		},
	}
	if opts.worker != nil {
		commands = append(commands, []*v2.Command{
			{
				Name:                   "worker",
				Usage:                  "runs a example.mutex.v1.Example worker process",
				UseShortOptionHandling: true,
				Before:                 opts.before,
				After:                  opts.after,
				Action: func(cmd *v2.Context) error {
					c, err := opts.clientForCommand(cmd)
					if err != nil {
						return fmt.Errorf("error initializing client for command: %w", err)
					}
					defer c.Close()
					w, err := opts.worker(cmd, c)
					if opts.worker != nil {
						if err != nil {
							return fmt.Errorf("error initializing worker: %w", err)
						}
					}
					if err := w.Start(); err != nil {
						return fmt.Errorf("error starting worker: %w", err)
					}
					defer w.Stop()
					<-cmd.Context.Done()
					return nil
				},
			},
		}...)
	}
	sort.Slice(commands, func(i, j int) bool {
		return commands[i].Name < commands[j].Name
	})
	return commands, nil
}

// UnmarshalCliFlagsToReleaseLockInput unmarshals a ReleaseLockInput from command line flags
func UnmarshalCliFlagsToReleaseLockInput(cmd *v2.Context, options ...helpers.UnmarshalCliFlagsOptions) (*ReleaseLockInput, error) {
	opts := helpers.FlattenUnmarshalCliFlagsOptions(options...)
	var result ReleaseLockInput
	if opts.FromFile != "" && cmd.IsSet(opts.FromFile) {
		f, err := gohomedir.Expand(cmd.String(opts.FromFile))
		if err != nil {
			f = cmd.String(opts.FromFile)
		}
		b, err := os.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", opts.FromFile, err)
		}
		if err := protojson.Unmarshal(b, &result); err != nil {
			return nil, fmt.Errorf("error parsing %s json: %w", opts.FromFile, err)
		}
	}
	if flag := opts.FlagName("lease-id"); cmd.IsSet(flag) {
		value := cmd.String(flag)
		result.LeaseId = value
	}
	return &result, nil
}

// UnmarshalCliFlagsToAcquireLockInput unmarshals a AcquireLockInput from command line flags
func UnmarshalCliFlagsToAcquireLockInput(cmd *v2.Context, options ...helpers.UnmarshalCliFlagsOptions) (*AcquireLockInput, error) {
	opts := helpers.FlattenUnmarshalCliFlagsOptions(options...)
	var result AcquireLockInput
	if opts.FromFile != "" && cmd.IsSet(opts.FromFile) {
		f, err := gohomedir.Expand(cmd.String(opts.FromFile))
		if err != nil {
			f = cmd.String(opts.FromFile)
		}
		b, err := os.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", opts.FromFile, err)
		}
		if err := protojson.Unmarshal(b, &result); err != nil {
			return nil, fmt.Errorf("error parsing %s json: %w", opts.FromFile, err)
		}
	}
	if flag := opts.FlagName("timeout"); cmd.IsSet(flag) {
		value := durationpb.New(cmd.Duration(flag))
		result.Timeout = value
	}
	return &result, nil
}

// UnmarshalCliFlagsToMutexInput unmarshals a MutexInput from command line flags
func UnmarshalCliFlagsToMutexInput(cmd *v2.Context, options ...helpers.UnmarshalCliFlagsOptions) (*MutexInput, error) {
	opts := helpers.FlattenUnmarshalCliFlagsOptions(options...)
	var result MutexInput
	if opts.FromFile != "" && cmd.IsSet(opts.FromFile) {
		f, err := gohomedir.Expand(cmd.String(opts.FromFile))
		if err != nil {
			f = cmd.String(opts.FromFile)
		}
		b, err := os.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", opts.FromFile, err)
		}
		if err := protojson.Unmarshal(b, &result); err != nil {
			return nil, fmt.Errorf("error parsing %s json: %w", opts.FromFile, err)
		}
	}
	if flag := opts.FlagName("resource-id"); cmd.IsSet(flag) {
		value := cmd.String(flag)
		result.ResourceId = value
	}
	return &result, nil
}

// UnmarshalCliFlagsToSampleWorkflowWithMutexInput unmarshals a SampleWorkflowWithMutexInput from command line flags
func UnmarshalCliFlagsToSampleWorkflowWithMutexInput(cmd *v2.Context, options ...helpers.UnmarshalCliFlagsOptions) (*SampleWorkflowWithMutexInput, error) {
	opts := helpers.FlattenUnmarshalCliFlagsOptions(options...)
	var result SampleWorkflowWithMutexInput
	if opts.FromFile != "" && cmd.IsSet(opts.FromFile) {
		f, err := gohomedir.Expand(cmd.String(opts.FromFile))
		if err != nil {
			f = cmd.String(opts.FromFile)
		}
		b, err := os.ReadFile(f)
		if err != nil {
			return nil, fmt.Errorf("error reading %s: %w", opts.FromFile, err)
		}
		if err := protojson.Unmarshal(b, &result); err != nil {
			return nil, fmt.Errorf("error parsing %s json: %w", opts.FromFile, err)
		}
	}
	if flag := opts.FlagName("resource-id"); cmd.IsSet(flag) {
		value := cmd.String(flag)
		result.ResourceId = value
	}
	if flag := opts.FlagName("sleep"); cmd.IsSet(flag) {
		value := durationpb.New(cmd.Duration(flag))
		result.Sleep = value
	}
	return &result, nil
}

// WithExampleSchemeTypes registers all Example protobuf types with the given scheme
func WithExampleSchemeTypes() scheme.Option {
	return func(s *scheme.Scheme) {
		s.RegisterType(File_example_mutex_v1_mutex_proto.Messages().ByName("MutexInput"))
		s.RegisterType(File_example_mutex_v1_mutex_proto.Messages().ByName("ReleaseLockInput"))
		s.RegisterType(File_example_mutex_v1_mutex_proto.Messages().ByName("AcquireLockInput"))
		s.RegisterType(File_example_mutex_v1_mutex_proto.Messages().ByName("AcquireLockOutput"))
		s.RegisterType(File_example_mutex_v1_mutex_proto.Messages().ByName("SampleWorkflowWithMutexInput"))
	}
}
