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: object.go
    path of file: ./repos/terraform/internal/command/jsonformat/differ
    
    the code of the file until where you have to start completion: // Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package differ

import (
	"github.com/zclconf/go-cty/cty"

	"github.com/hashicorp/terraform/internal/command/jsonformat/collections"
	"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
	"github.com/hashicorp/terraform/internal/command/jsonformat/computed/renderers"
	"github.com/hashicorp/terraform/internal/command/jsonformat/structured"
	"github.com/hashicorp/terraform/internal/command/jsonprovider"
	"github.com/hashicorp/terraform/internal/plans"
)

func computeAttributeDiffAsObject(change structured.Change, attributes map[string]cty.Type) computed.Diff {
	attributeDiffs, action := processObject(change, attributes, func(value structured.Change, ctype cty.Type) computed.Diff {
		return ComputeDiffForType(value, ctype)
	})
	return computed.NewDiff(renderers.Object(attributeDiffs), action, change.Repl
    
func processObject[T any](v structured.Change, attributes map[string]T, computeDiff func(structured.Change, T) computed.Diff) (map[string]computed.Diff, plans.Action) {
	attributeDiffs := make(map[string]computed.Diff)
	mapValue := v.AsMap()

	currentAction := v.GetDefaultActionForIteration()
	for key, attribute := range attributes {
		attributeValue := mapValue.GetChild(key)

		if !attributeValue.RelevantAttributes.MatchesPartial() {
			// Mark non-relevant attributes as unchanged.
			attributeValue = attributeValue.AsNoOp()
		}

		// We always assume changes to object are implicit.
		attributeValue.BeforeExplicit = false
		attributeValue.AfterExplicit = false

		attributeDiff := computeDiff(attributeValue, attribute)
		if attributeDiff.Action == plans.NoOp && attributeValue.Before == nil && attributeValue.After == nil {
			// We skip attributes of objects that are null both before and
			// after. We don't even count these as unchanged attributes.
			continue
		}
		attributeDiffs[key] = attributeDiff
		currentAction = collections.CompareActions(currentAction, attributeDiff.Action)
	}

	return attributeDiffs, currentAction
}