You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: transformer.go
    path of file: ./repos/flyte/flytepropeller/pkg/controller/nodes/task
    
    the code of the file until where you have to start completion: package task

import (
	"time"

	"google.golang.org/protobuf/types/known/timestamppb"

	"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/core"
	"github.com/flyteorg/flyte/flyteidl/gen/pb-go/flyteidl/event"
	pluginCore "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/core"
	flytek8sConfig "github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/flytek8s/config"
	"github.com/flyteorg/flyte/flyteplugins/go/tasks/pluginmachinery/io"
	"github.com/flyt
    
func ToTaskExecutionEvent(input ToTaskExecutionEventInputs) (*event.TaskExecutionEvent, error) {
	// Transitions to a new phase

	var occurredAt *timestamppb.Timestamp
	if i := input.Info.Info(); i != nil && i.OccurredAt != nil {
		occurredAt = timestamppb.New(*i.OccurredAt)
	} else {
		occurredAt = timestamppb.New(input.OccurredAt)
	}

	reportedAt := timestamppb.Now()
	if i := input.Info.Info(); i != nil && i.ReportedAt != nil {
		occurredAt = timestamppb.New(*i.ReportedAt)
	}

	taskExecID := input.TaskExecContext.TaskExecutionMetadata().GetTaskExecutionID().GetID()
	nodeExecutionID, err := getParentNodeExecIDForTask(&taskExecID, input.ExecContext)
	if err != nil {
		return nil, err
	}

	metadata := &event.TaskExecutionMetadata{
		GeneratedName:    input.TaskExecContext.TaskExecutionMetadata().GetTaskExecutionID().GetGeneratedName(),
		PluginIdentifier: input.PluginID,
		ResourcePoolInfo: input.ResourcePoolInfo,
	}

	if input.Info.Info() != nil && input.Info.Info().ExternalResources != nil {
		externalResources := input.Info.Info().ExternalResources

		metadata.ExternalResources = make([]*event.ExternalResourceInfo, len(externalResources))
		for idx, e := range input.Info.Info().ExternalResources {
			phase := ToTaskEventPhase(e.Phase)
			metadata.ExternalResources[idx] = &event.ExternalResourceInfo{
				ExternalId:   e.ExternalID,
				CacheStatus:  e.CacheStatus,
				Index:        e.Index,
				Logs:         e.Logs,
				RetryAttempt: e.RetryAttempt,
				Phase:        phase,
			}
		}
	}

	var reasons []*event.EventReason
	if len(input.Info.Reason()) > 0 {
		reasons = append(reasons, &event.EventReason{
			Reason:     input.Info.Reason(),
			OccurredAt: occurredAt,
		})
	}
	for _, reasonInfo := range input.Info.Info().AdditionalReasons {
		reasons = append(reasons, &event.EventReason{
			Reason:     reasonInfo.Reason,
			OccurredAt: timestamppb.New(*reasonInfo.OccurredAt),
		})
	}
	tev := &event.TaskExecutionEvent{
		TaskId:                taskExecID.TaskId,
		ParentNodeExecutionId: nodeExecutionID,
		RetryAttempt:          taskExecID.RetryAttempt,
		Phase:                 ToTaskEventPhase(input.Info.Phase()),
		PhaseVersion:          input.Info.Version(),
		ProducerId:            input.ClusterID,
		OccurredAt:            occurredAt,
		TaskType:              input.TaskType,
		Reasons:               reasons,
		Metadata:              metadata,
		EventVersion:          taskExecutionEventVersion,
		ReportedAt:            reportedAt,
	}
	if !flytek8sConfig.GetK8sPluginConfig().SendObjectEvents {
		// For back compat with old versions of flyteadmin, populate the deprecated reason field.
		// Setting SendObjectEvents to true assumes that flyteadmin is using the new reasons field.
		tev.Reason = input.Info.Reason()
	}

	if input.Info.Phase().IsSuccess() && input.OutputWriter != nil {
		if input.OutputWriter.GetOutputPath() != "" {
			tev.OutputResult = &event.TaskExecutionEvent_OutputUri{OutputUri: input.OutputWriter.GetOutputPath().String()}
		}
	}

	if input.Info.Phase().IsFailure() && input.Info.Err() != nil {
		tev.OutputResult = &event.TaskExecutionEvent_Error{
			Error: input.Info.Err(),
		}
	}

	if input.Info.Info() != nil {
		tev.Logs = input.Info.Info().Logs
		tev.CustomInfo = input.Info.Info().CustomInfo
	}

	if input.NodeExecutionMetadata.IsInterruptible() {
		tev.Metadata.InstanceClass = event.TaskExecutionMetadata_INTERRUPTIBLE
	} else {
		tev.Metadata.InstanceClass = event.TaskExecutionMetadata_DEFAULT
	}
	if input.EventConfig.RawOutputPolicy == config.RawOutputPolicyInline {
		tev.InputValue = &event.TaskExecutionEvent_InputData{
			InputData: input.Inputs,
		}
	} else {
		tev.InputValue = &event.TaskExecutionEvent_InputUri{
			InputUri: input.InputReader.GetInputPath().String(),
		}
	}

	return tev, nil
}