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: control.go
    path of file: ./repos/steampipe/pkg/control/controldisplay
    
    the code of the file until where you have to start completion: package controldisplay

import (
	"fmt"
	"strings"

	"github.com/spf13/viper"
	typehelpers "github.com/turbot/go-kit/types"
	"github.com/turbot/steampipe/pkg/constants"
	"github.com/turbot/steampipe/pkg/control/controlexecute"
)

type ControlRenderer struct {
	run               *controlexecute.ControlRun
	parent            *GroupRenderer
	maxFailedControls int
	maxTotalControls  int
	// screen width
	width          int
	colorGenerator *controlexecute.DimensionColorGenerator
	lastChild      bool
}

func NewControlRenderer(run *controlexecute.ControlRun, parent *GroupRenderer) *ControlRenderer {
	r := &ControlRenderer{
		run:               run,
		parent:            parent,
		maxFailedControls: parent.maxFailedControls,
		maxTotalControls:  parent.maxTotalControls,
		colorGenerator:    parent.resultTree.DimensionColorGenerator,
		width:             parent.width,
	}
	r.lastChild = r.isLastChild()
	return r
}

// are we the last child of our parent?
// this affects the tree rendering
func (r ControlRenderer) isLastChild() bool {
	if r.parent.group == nil || r.parent.group.GroupItem == nil {
		return true
	}
	siblings := r.parent.group.GroupItem.GetChildren()
	return r.run.Control.Name() == siblings[len(siblings)-1].Name()
}

// get the indent inherited from our parent
// - this will depend on whether we are our parents last child
func (r ControlRenderer) parentIndent() string {
	if r.lastChild {
		return r.parent.lastChildIndent()
	}
	return r.parent.childIndent()
}

// indent before first result
func (r ControlRenderer) preResultIndent() string {
	// when we do not have any rows, do not add a '|' to indent
	if viper.GetBool(constants.ArgDryRun) || len(r.run.Rows) == 0 {
		return r.parentIndent()
	}
	return r.parentIndent() + "| "
}

// indent before first res
    
func (r ControlRenderer) Render() string {
	var controlStrings []string
	// use group heading renderer to render the control title and counts
	controlHeadingRenderer := NewGroupHeadingRenderer(typehelpers.SafeString(r.run.Control.Title),
		r.run.Summary.FailedCount(),
		r.run.Summary.TotalCount(),
		r.maxFailedControls,
		r.maxTotalControls,
		r.width,
		r.parent.childGroupIndent())

	// set the severity on the heading renderer
	controlHeadingRenderer.severity = typehelpers.SafeString(r.run.Control.Severity)

	// get formatted indents
	formattedPostResultIndent := fmt.Sprintf("%s", ControlColors.Indent(r.postResultIndent()))
	formattedPreResultIndent := fmt.Sprintf("%s", ControlColors.Indent(r.preResultIndent()))

	controlStrings = append(controlStrings,
		controlHeadingRenderer.Render(),
		// newline after control heading
		formattedPreResultIndent)

	// if the control is in error, render an error
	if r.run.GetError() != nil {
		errorRenderer := NewErrorRenderer(r.run.GetError(), r.width, r.parentIndent())
		controlStrings = append(controlStrings,
			errorRenderer.Render(),
			// newline after error
			formattedPostResultIndent)
	}

	// now render the results (if any)
	var resultStrings []string
	for _, row := range r.run.Rows {
		resultRenderer := NewResultRenderer(
			row.Status,
			row.Reason,
			row.Dimensions,
			r.colorGenerator,
			r.width,
			r.resultIndent())
		// the result renderer may not render the result - in quiet mode only failures are rendered
		if resultString := resultRenderer.Render(); resultString != "" {
			resultStrings = append(resultStrings, resultString)
		}
	}

	// newline after results
	if len(resultStrings) > 0 {
		controlStrings = append(controlStrings, resultStrings...)
		if len(r.run.Rows) > 0 || r.run.GetError() != nil {
			controlStrings = append(controlStrings, formattedPostResultIndent)
		}
	}

	return strings.Join(controlStrings, "\n")
}