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: caddyfile.go
    path of file: ./repos/caddy/modules/caddyhttp/fileserver
    
    the code of the file until where you have to start completion: // Copyright 2015 Matthew Holt and The Caddy Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fileserver

import (
	"path/filepath"
	"strings"

	"github.com/caddyserver/caddy/v2"
	"github.com/caddyserver/caddy/v2/caddyconfig"
	"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
	"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
	"github.com/caddyserver/caddy/v2/modules/caddyhttp"
	"github.com/caddyserver/caddy/v2/modules/caddyhttp/encode"
	"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
)

func init() {
	httpcaddyfile.RegisterHandlerDirective("file_server", parseCaddyfile)
	httpcaddyfile.RegisterDirective("try_files", parseTryFiles)
}

// parseCaddyfile parses the file_server directive.
// See UnmarshalCaddyfile for the syntax.
func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
	fsrv := new(FileServer)
	err := fsrv.UnmarshalCaddyfile(h.Dispenser)
	if err != nil {
		return fsrv, err
	}
	err = fsrv.FinalizeUnmarshalCaddyfile(h)
	if err != nil {
		return nil, err
	}
	return fsrv, err
}

// UnmarshalCaddyfile parses the file_server directive. It enables
// the static file server and configures it with this syntax:
//
//	file_server [<matcher>] [browse] {
//	    fs            <filesystem>
//	    root          <path>
//	    hide          <files...>
//	    index         <files..
    
func parseTryFiles(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) {
	if !h.Next() {
		return nil, h.ArgErr()
	}

	tryFiles := h.RemainingArgs()
	if len(tryFiles) == 0 {
		return nil, h.ArgErr()
	}

	// parse out the optional try policy
	var tryPolicy string
	for h.NextBlock(0) {
		switch h.Val() {
		case "policy":
			if tryPolicy != "" {
				return nil, h.Err("try policy already configured")
			}
			if !h.NextArg() {
				return nil, h.ArgErr()
			}
			tryPolicy = h.Val()

			switch tryPolicy {
			case tryPolicyFirstExist, tryPolicyLargestSize, tryPolicySmallestSize, tryPolicyMostRecentlyMod:
			default:
				return nil, h.Errf("unrecognized try policy: %s", tryPolicy)
			}
		}
	}

	// makeRoute returns a route that tries the files listed in try
	// and then rewrites to the matched file; userQueryString is
	// appended to the rewrite rule.
	makeRoute := func(try []string, userQueryString string) []httpcaddyfile.ConfigValue {
		handler := rewrite.Rewrite{
			URI: "{http.matchers.file.relative}" + userQueryString,
		}
		matcherSet := caddy.ModuleMap{
			"file": h.JSON(MatchFile{TryFiles: try, TryPolicy: tryPolicy}),
		}
		return h.NewRoute(matcherSet, handler)
	}

	var result []httpcaddyfile.ConfigValue

	// if there are query strings in the list, we have to split into
	// a separate route for each item with a query string, because
	// the rewrite is different for that item
	try := make([]string, 0, len(tryFiles))
	for _, item := range tryFiles {
		if idx := strings.Index(item, "?"); idx >= 0 {
			if len(try) > 0 {
				result = append(result, makeRoute(try, "")...)
				try = []string{}
			}
			result = append(result, makeRoute([]string{item[:idx]}, item[idx:])...)
			continue
		}
		// accumulate consecutive non-query-string parameters
		try = append(try, item)
	}
	if len(try) > 0 {
		result = append(result, makeRoute(try, "")...)
	}

	// ensure that multiple routes (possible if rewrite targets
	// have query strings, for example) are grouped together
	// so only the first matching rewrite is performed (#2891)
	h.GroupRoutes(result)

	return result, nil
}