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: engine.go
    path of file: ./repos/buildkit/sourcepolicy
    
    the code of the file until where you have to start completion: package sourcepolicy

import (
	"context"

	"github.com/moby/buildkit/solver/pb"
	spb "github.com/moby/buildkit/sourcepolicy/pb"
	"github.com/moby/buildkit/util/bklog"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)

var (
	// ErrSourceDenied is returned by the policy engine when a source is denied by the policy.
	ErrSourceDenied = errors.New("source denied by policy")

	// ErrTooManyOps is returned by the policy engine when there are too many converts for a single source op.
	ErrTooManyOps = errors.New("too many operations")
)

// Engine is the source policy engine.
// It is responsible for evaluating a source policy against a source operation.
// Create one with `NewEngine`
//
// Rule matching is delegated to the `Matcher` interface.
// Mutation
    
func (e *Engine) evaluatePolicy(ctx context.Context, pol *spb.Policy, srcOp *pb.SourceOp) (retMut bool, retErr error) {
	ident := srcOp.GetIdentifier()

	ctx = bklog.WithLogger(ctx, bklog.G(ctx).WithField("ref", ident))
	defer func() {
		if retMut || retErr != nil {
			bklog.G(ctx).WithFields(
				logrus.Fields{
					"mutated":       retMut,
					"updated":       srcOp.GetIdentifier(),
					logrus.ErrorKey: retErr,
				}).Debug("Evaluated source policy")
		}
	}()

	var deny bool
	for _, rule := range pol.Rules {
		selector := e.selectorCache(rule.Selector)
		matched, err := match(ctx, selector, ident, srcOp.Attrs)
		if err != nil {
			return false, errors.Wrap(err, "error matching source policy")
		}
		if !matched {
			continue
		}

		switch rule.Action {
		case spb.PolicyAction_ALLOW:
			deny = false
		case spb.PolicyAction_DENY:
			deny = true
		case spb.PolicyAction_CONVERT:
			mut, err := mutate(ctx, srcOp, rule, selector, ident)
			if err != nil || mut {
				return mut, errors.Wrap(err, "error mutating source policy")
			}
		default:
			return false, errors.Errorf("source policy: rule %s %s: unknown type %q", rule.Action, rule.Selector.Identifier, ident)
		}
	}

	if deny {
		return false, errors.Wrapf(ErrSourceDenied, "source %q denied by policy", ident)
	}
	return false, nil
}