// Copyright 2017 Istio 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.

// THIS FILE IS AUTOMATICALLY GENERATED.

package template

import (
	"context"
	"errors"
	"fmt"
	"net"
	"strings"

	"github.com/gogo/protobuf/proto"
	"github.com/golang/glog"

	"istio.io/api/mixer/v1/config/descriptor"
	adptTmpl "istio.io/api/mixer/v1/template"
	"istio.io/istio/mixer/pkg/adapter"
	"istio.io/istio/mixer/pkg/attribute"
	"istio.io/istio/mixer/pkg/config/proto"
	"istio.io/istio/mixer/pkg/expr"
	"istio.io/istio/mixer/pkg/template"

	"istio.io/istio/mixer/adapter/kubernetesenv/template"

	"istio.io/istio/mixer/adapter/servicecontrol/template/servicecontrolreport"

	"istio.io/istio/mixer/template/apikey"

	"istio.io/istio/mixer/template/checknothing"

	"istio.io/istio/mixer/template/listentry"

	"istio.io/istio/mixer/template/logentry"

	"istio.io/istio/mixer/template/metric"

	"istio.io/istio/mixer/template/quota"

	"istio.io/istio/mixer/template/reportnothing"

	"istio.io/istio/mixer/template/tracespan"

	"time"
)

// Add void usages for some imports so that go linter does not complain in case the imports does not get used in the
// below codegen.
var (
	_ net.IP
	_ istio_mixer_v1_config.AttributeManifest
	_ = strings.Reader{}
)

type (
	getFn         func(name string) (value interface{}, found bool)
	namesFn       func() []string
	doneFn        func()
	debugStringFn func() string
	wrapperAttr   struct {
		get         getFn
		names       namesFn
		done        doneFn
		debugString debugStringFn
	}
)

func newWrapperAttrBag(get getFn, names namesFn, done doneFn, debugString debugStringFn) attribute.Bag {
	return &wrapperAttr{
		debugString: debugString,
		done:        done,
		get:         get,
		names:       names,
	}
}

// Get returns an attribute value.
func (w *wrapperAttr) Get(name string) (value interface{}, found bool) {
	return w.get(name)
}

// Names returns the names of all the attributes known to this bag.
func (w *wrapperAttr) Names() []string {
	return w.names()
}

// Done indicates the bag can be reclaimed.
func (w *wrapperAttr) Done() {
	w.done()
}

// DebugString provides a dump of an attribute Bag that avoids affecting the
// calculation of referenced attributes.
func (w *wrapperAttr) DebugString() string {
	return w.debugString()
}

var (
	SupportedTmplInfo = map[string]template.Info{

		adapter_template_kubernetes.TemplateName: {
			Name:               adapter_template_kubernetes.TemplateName,
			Impl:               "adapter.template.kubernetes",
			CtrCfg:             &adapter_template_kubernetes.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_ATTRIBUTE_GENERATOR,
			BldrInterfaceName:  adapter_template_kubernetes.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: adapter_template_kubernetes.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(adapter_template_kubernetes.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(adapter_template_kubernetes.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *adapter_template_kubernetes.InstanceParam,
					path string) (proto.Message, error)

				_ = BuildTemplate

				BuildTemplate = func(param *adapter_template_kubernetes.InstanceParam,
					path string) (proto.Message, error) {

					if param == nil {
						return nil, nil
					}

					var err error = nil

					if param.SourceUid == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"SourceUid")
					}
					if t, e := tEvalFn(param.SourceUid); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"SourceUid", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"SourceUid", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.SourceIp == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"SourceIp")
					}
					if t, e := tEvalFn(param.SourceIp); e != nil || t != istio_mixer_v1_config_descriptor.IP_ADDRESS {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"SourceIp", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"SourceIp", t, istio_mixer_v1_config_descriptor.IP_ADDRESS)
					}

					if param.DestinationUid == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"DestinationUid")
					}
					if t, e := tEvalFn(param.DestinationUid); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"DestinationUid", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"DestinationUid", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.DestinationIp == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"DestinationIp")
					}
					if t, e := tEvalFn(param.DestinationIp); e != nil || t != istio_mixer_v1_config_descriptor.IP_ADDRESS {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"DestinationIp", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"DestinationIp", t, istio_mixer_v1_config_descriptor.IP_ADDRESS)
					}

					if param.OriginUid == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"OriginUid")
					}
					if t, e := tEvalFn(param.OriginUid); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"OriginUid", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"OriginUid", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.OriginIp == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"OriginIp")
					}
					if t, e := tEvalFn(param.OriginIp); e != nil || t != istio_mixer_v1_config_descriptor.IP_ADDRESS {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"OriginIp", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"OriginIp", t, istio_mixer_v1_config_descriptor.IP_ADDRESS)
					}

					return nil, err

				}

				instParam := cp.(*adapter_template_kubernetes.InstanceParam)

				const fullOutName = "adapter_template_kubernetes.output."
				for attr, exp := range instParam.AttributeBindings {
					expr := strings.Replace(exp, "$out.", fullOutName, -1)
					t1, err := tEvalFn(expr)
					if err != nil {
						return nil, fmt.Errorf("error evaluating AttributeBinding expression '%s' for attribute '%s': %v", expr, attr, err)
					}
					t2, err := tEvalFn(attr)
					if err != nil {
						return nil, fmt.Errorf("error evaluating AttributeBinding expression for attribute key '%s': %v", attr, err)
					}
					if t1 != t2 {
						return nil, fmt.Errorf(
							"error evaluating AttributeBinding: type '%v' for attribute '%s' does not match type '%s' for expression '%s'",
							t2, attr, t1, expr)
					}
				}

				return BuildTemplate(instParam, "")
			},

			AttributeManifests: []*istio_mixer_v1_config.AttributeManifest{
				{
					Attributes: map[string]*istio_mixer_v1_config.AttributeManifest_AttributeInfo{

						"adapter_template_kubernetes.output.source_pod_ip": {
							ValueType: istio_mixer_v1_config_descriptor.IP_ADDRESS,
						},

						"adapter_template_kubernetes.output.source_pod_name": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.source_labels": {
							ValueType: istio_mixer_v1_config_descriptor.STRING_MAP,
						},

						"adapter_template_kubernetes.output.source_namespace": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.source_service": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.source_service_account_name": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.source_host_ip": {
							ValueType: istio_mixer_v1_config_descriptor.IP_ADDRESS,
						},

						"adapter_template_kubernetes.output.destination_pod_ip": {
							ValueType: istio_mixer_v1_config_descriptor.IP_ADDRESS,
						},

						"adapter_template_kubernetes.output.destination_pod_name": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.destination_labels": {
							ValueType: istio_mixer_v1_config_descriptor.STRING_MAP,
						},

						"adapter_template_kubernetes.output.destination_namespace": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.destination_service": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.destination_service_account_name": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.destination_host_ip": {
							ValueType: istio_mixer_v1_config_descriptor.IP_ADDRESS,
						},

						"adapter_template_kubernetes.output.origin_pod_ip": {
							ValueType: istio_mixer_v1_config_descriptor.IP_ADDRESS,
						},

						"adapter_template_kubernetes.output.origin_pod_name": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.origin_labels": {
							ValueType: istio_mixer_v1_config_descriptor.STRING_MAP,
						},

						"adapter_template_kubernetes.output.origin_namespace": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.origin_service": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.origin_service_account_name": {
							ValueType: istio_mixer_v1_config_descriptor.STRING,
						},

						"adapter_template_kubernetes.output.origin_host_ip": {
							ValueType: istio_mixer_v1_config_descriptor.IP_ADDRESS,
						},
					},
				},
			},

			ProcessGenAttrs: func(ctx context.Context, instName string, inst proto.Message, attrs attribute.Bag,
				mapper expr.Evaluator, handler adapter.Handler) (*attribute.MutableBag, error) {

				var BuildTemplate func(instName string,
					param *adapter_template_kubernetes.InstanceParam, path string) (
					*adapter_template_kubernetes.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *adapter_template_kubernetes.InstanceParam, path string) (
					*adapter_template_kubernetes.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					SourceUid, err := mapper.Eval(param.SourceUid, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"SourceUid", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					SourceIp, err := mapper.Eval(param.SourceIp, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"SourceIp", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					DestinationUid, err := mapper.Eval(param.DestinationUid, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"DestinationUid", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					DestinationIp, err := mapper.Eval(param.DestinationIp, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"DestinationIp", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					OriginUid, err := mapper.Eval(param.OriginUid, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"OriginUid", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					OriginIp, err := mapper.Eval(param.OriginIp, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"OriginIp", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &adapter_template_kubernetes.Instance{

						Name: instName,

						SourceUid: SourceUid.(string),

						SourceIp: net.IP(SourceIp.([]uint8)),

						DestinationUid: DestinationUid.(string),

						DestinationIp: net.IP(DestinationIp.([]uint8)),

						OriginUid: OriginUid.(string),

						OriginIp: net.IP(OriginIp.([]uint8)),
					}, nil
				}

				instParam := inst.(*adapter_template_kubernetes.InstanceParam)
				instance, err := BuildTemplate(instName, instParam, "")
				if err != nil {
					return nil, err

				}

				out, err := handler.(adapter_template_kubernetes.Handler).GenerateKubernetesAttributes(ctx, instance)
				if err != nil {
					return nil, err
				}
				abag := attrs
				const fullOutName = "adapter_template_kubernetes.output."
				if out == nil {
					glog.Info(fmt.Sprintf("Preprocess adapter returned nil output for instance name '%s'", instName))
				} else {
					abag = newWrapperAttrBag(
						func(name string) (value interface{}, found bool) {
							field := strings.TrimPrefix(name, fullOutName)
							if len(field) != len(name) {
								switch field {

								case "source_pod_ip":

									return []uint8(out.SourcePodIp), true

								case "source_pod_name":

									return out.SourcePodName, true

								case "source_labels":

									return out.SourceLabels, true

								case "source_namespace":

									return out.SourceNamespace, true

								case "source_service":

									return out.SourceService, true

								case "source_service_account_name":

									return out.SourceServiceAccountName, true

								case "source_host_ip":

									return []uint8(out.SourceHostIp), true

								case "destination_pod_ip":

									return []uint8(out.DestinationPodIp), true

								case "destination_pod_name":

									return out.DestinationPodName, true

								case "destination_labels":

									return out.DestinationLabels, true

								case "destination_namespace":

									return out.DestinationNamespace, true

								case "destination_service":

									return out.DestinationService, true

								case "destination_service_account_name":

									return out.DestinationServiceAccountName, true

								case "destination_host_ip":

									return []uint8(out.DestinationHostIp), true

								case "origin_pod_ip":

									return []uint8(out.OriginPodIp), true

								case "origin_pod_name":

									return out.OriginPodName, true

								case "origin_labels":

									return out.OriginLabels, true

								case "origin_namespace":

									return out.OriginNamespace, true

								case "origin_service":

									return out.OriginService, true

								case "origin_service_account_name":

									return out.OriginServiceAccountName, true

								case "origin_host_ip":

									return []uint8(out.OriginHostIp), true

								default:
									return nil, false
								}

							}
							return attrs.Get(name)
						},
						func() []string { return attrs.Names() },
						func() { attrs.Done() },
						func() string { return attrs.DebugString() },
					)
				}
				resultBag := attribute.GetMutableBag(nil)
				for attrName, outExpr := range instParam.AttributeBindings {
					ex := strings.Replace(outExpr, "$out.", fullOutName, -1)
					val, err := mapper.Eval(ex, abag)
					if err != nil {
						return nil, err
					}
					switch v := val.(type) {
					case net.IP:
						// conversion to []byte necessary based on current IP_ADDRESS handling within Mixer
						// TODO: remove
						glog.V(4).Info("converting net.IP to []byte")
						if v4 := v.To4(); v4 != nil {
							resultBag.Set(attrName, []byte(v4))
							continue
						}
						resultBag.Set(attrName, []byte(v.To16()))
					default:
						resultBag.Set(attrName, val)
					}
				}
				return resultBag, nil

			},
		},

		servicecontrolreport.TemplateName: {
			Name:               servicecontrolreport.TemplateName,
			Impl:               "servicecontrolreport",
			CtrCfg:             &servicecontrolreport.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_REPORT,
			BldrInterfaceName:  servicecontrolreport.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: servicecontrolreport.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(servicecontrolreport.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(servicecontrolreport.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *servicecontrolreport.InstanceParam,
					path string) (*servicecontrolreport.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *servicecontrolreport.InstanceParam,
					path string) (*servicecontrolreport.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &servicecontrolreport.Type{}

					var err error = nil

					if param.ApiVersion == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiVersion")
					}
					if t, e := tEvalFn(param.ApiVersion); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiVersion", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiVersion", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ApiOperation == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiOperation")
					}
					if t, e := tEvalFn(param.ApiOperation); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiOperation", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiOperation", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ApiProtocol == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiProtocol")
					}
					if t, e := tEvalFn(param.ApiProtocol); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiProtocol", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiProtocol", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ApiService == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiService")
					}
					if t, e := tEvalFn(param.ApiService); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiService", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiService", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ApiKey == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiKey")
					}
					if t, e := tEvalFn(param.ApiKey); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiKey", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiKey", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.RequestTime == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"RequestTime")
					}
					if t, e := tEvalFn(param.RequestTime); e != nil || t != istio_mixer_v1_config_descriptor.TIMESTAMP {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"RequestTime", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"RequestTime", t, istio_mixer_v1_config_descriptor.TIMESTAMP)
					}

					if param.RequestMethod == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"RequestMethod")
					}
					if t, e := tEvalFn(param.RequestMethod); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"RequestMethod", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"RequestMethod", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.RequestPath == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"RequestPath")
					}
					if t, e := tEvalFn(param.RequestPath); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"RequestPath", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"RequestPath", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.RequestBytes == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"RequestBytes")
					}
					if t, e := tEvalFn(param.RequestBytes); e != nil || t != istio_mixer_v1_config_descriptor.INT64 {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"RequestBytes", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"RequestBytes", t, istio_mixer_v1_config_descriptor.INT64)
					}

					if param.ResponseTime == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ResponseTime")
					}
					if t, e := tEvalFn(param.ResponseTime); e != nil || t != istio_mixer_v1_config_descriptor.TIMESTAMP {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ResponseTime", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ResponseTime", t, istio_mixer_v1_config_descriptor.TIMESTAMP)
					}

					if param.ResponseCode == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ResponseCode")
					}
					if t, e := tEvalFn(param.ResponseCode); e != nil || t != istio_mixer_v1_config_descriptor.INT64 {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ResponseCode", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ResponseCode", t, istio_mixer_v1_config_descriptor.INT64)
					}

					if param.ResponseBytes == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ResponseBytes")
					}
					if t, e := tEvalFn(param.ResponseBytes); e != nil || t != istio_mixer_v1_config_descriptor.INT64 {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ResponseBytes", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ResponseBytes", t, istio_mixer_v1_config_descriptor.INT64)
					}

					if param.ResponseLatency == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ResponseLatency")
					}
					if t, e := tEvalFn(param.ResponseLatency); e != nil || t != istio_mixer_v1_config_descriptor.DURATION {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ResponseLatency", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ResponseLatency", t, istio_mixer_v1_config_descriptor.DURATION)
					}

					return infrdType, err

				}

				instParam := cp.(*servicecontrolreport.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(servicecontrolreport.HandlerBuilder)
				castedTypes := make(map[string]*servicecontrolreport.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*servicecontrolreport.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetServicecontrolReportTypes(castedTypes)
			},

			ProcessReport: func(ctx context.Context, insts map[string]proto.Message, attrs attribute.Bag, mapper expr.Evaluator, handler adapter.Handler) error {

				var BuildTemplate func(instName string,
					param *servicecontrolreport.InstanceParam, path string) (
					*servicecontrolreport.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *servicecontrolreport.InstanceParam, path string) (
					*servicecontrolreport.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					ApiVersion, err := mapper.Eval(param.ApiVersion, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiVersion", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ApiOperation, err := mapper.Eval(param.ApiOperation, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiOperation", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ApiProtocol, err := mapper.Eval(param.ApiProtocol, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiProtocol", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ApiService, err := mapper.Eval(param.ApiService, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiService", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ApiKey, err := mapper.Eval(param.ApiKey, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiKey", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					RequestTime, err := mapper.Eval(param.RequestTime, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"RequestTime", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					RequestMethod, err := mapper.Eval(param.RequestMethod, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"RequestMethod", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					RequestPath, err := mapper.Eval(param.RequestPath, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"RequestPath", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					RequestBytes, err := mapper.Eval(param.RequestBytes, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"RequestBytes", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ResponseTime, err := mapper.Eval(param.ResponseTime, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ResponseTime", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ResponseCode, err := mapper.Eval(param.ResponseCode, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ResponseCode", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ResponseBytes, err := mapper.Eval(param.ResponseBytes, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ResponseBytes", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ResponseLatency, err := mapper.Eval(param.ResponseLatency, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ResponseLatency", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &servicecontrolreport.Instance{

						Name: instName,

						ApiVersion: ApiVersion.(string),

						ApiOperation: ApiOperation.(string),

						ApiProtocol: ApiProtocol.(string),

						ApiService: ApiService.(string),

						ApiKey: ApiKey.(string),

						RequestTime: RequestTime.(time.Time),

						RequestMethod: RequestMethod.(string),

						RequestPath: RequestPath.(string),

						RequestBytes: RequestBytes.(int64),

						ResponseTime: ResponseTime.(time.Time),

						ResponseCode: ResponseCode.(int64),

						ResponseBytes: ResponseBytes.(int64),

						ResponseLatency: ResponseLatency.(time.Duration),
					}, nil
				}

				var instances []*servicecontrolreport.Instance
				for instName, inst := range insts {
					instance, err := BuildTemplate(instName, inst.(*servicecontrolreport.InstanceParam), "")
					if err != nil {
						return err
					}
					instances = append(instances, instance)
				}

				if err := handler.(servicecontrolreport.Handler).HandleServicecontrolReport(ctx, instances); err != nil {
					return fmt.Errorf("failed to report all values: %v", err)
				}
				return nil
			},
		},

		apikey.TemplateName: {
			Name:               apikey.TemplateName,
			Impl:               "apikey",
			CtrCfg:             &apikey.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_CHECK,
			BldrInterfaceName:  apikey.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: apikey.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(apikey.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(apikey.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *apikey.InstanceParam,
					path string) (*apikey.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *apikey.InstanceParam,
					path string) (*apikey.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &apikey.Type{}

					var err error = nil

					if param.Api == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"Api")
					}
					if t, e := tEvalFn(param.Api); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"Api", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"Api", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ApiVersion == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiVersion")
					}
					if t, e := tEvalFn(param.ApiVersion); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiVersion", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiVersion", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ApiOperation == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiOperation")
					}
					if t, e := tEvalFn(param.ApiOperation); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiOperation", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiOperation", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ApiKey == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ApiKey")
					}
					if t, e := tEvalFn(param.ApiKey); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ApiKey", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ApiKey", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.Timestamp == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"Timestamp")
					}
					if t, e := tEvalFn(param.Timestamp); e != nil || t != istio_mixer_v1_config_descriptor.TIMESTAMP {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"Timestamp", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"Timestamp", t, istio_mixer_v1_config_descriptor.TIMESTAMP)
					}

					return infrdType, err

				}

				instParam := cp.(*apikey.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(apikey.HandlerBuilder)
				castedTypes := make(map[string]*apikey.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*apikey.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetApiKeyTypes(castedTypes)
			},

			ProcessCheck: func(ctx context.Context, instName string, inst proto.Message, attrs attribute.Bag,
				mapper expr.Evaluator, handler adapter.Handler) (adapter.CheckResult, error) {

				var BuildTemplate func(instName string,
					param *apikey.InstanceParam, path string) (
					*apikey.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *apikey.InstanceParam, path string) (
					*apikey.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					Api, err := mapper.Eval(param.Api, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Api", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ApiVersion, err := mapper.Eval(param.ApiVersion, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiVersion", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ApiOperation, err := mapper.Eval(param.ApiOperation, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiOperation", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ApiKey, err := mapper.Eval(param.ApiKey, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ApiKey", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					Timestamp, err := mapper.Eval(param.Timestamp, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Timestamp", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &apikey.Instance{

						Name: instName,

						Api: Api.(string),

						ApiVersion: ApiVersion.(string),

						ApiOperation: ApiOperation.(string),

						ApiKey: ApiKey.(string),

						Timestamp: Timestamp.(time.Time),
					}, nil
				}

				instParam := inst.(*apikey.InstanceParam)
				instance, err := BuildTemplate(instName, instParam, "")
				if err != nil {

					return adapter.CheckResult{}, err

				}
				return handler.(apikey.Handler).HandleApiKey(ctx, instance)

			},
		},

		checknothing.TemplateName: {
			Name:               checknothing.TemplateName,
			Impl:               "checknothing",
			CtrCfg:             &checknothing.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_CHECK,
			BldrInterfaceName:  checknothing.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: checknothing.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(checknothing.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(checknothing.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *checknothing.InstanceParam,
					path string) (*checknothing.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *checknothing.InstanceParam,
					path string) (*checknothing.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &checknothing.Type{}

					var err error = nil

					return infrdType, err

				}

				instParam := cp.(*checknothing.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(checknothing.HandlerBuilder)
				castedTypes := make(map[string]*checknothing.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*checknothing.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetCheckNothingTypes(castedTypes)
			},

			ProcessCheck: func(ctx context.Context, instName string, inst proto.Message, attrs attribute.Bag,
				mapper expr.Evaluator, handler adapter.Handler) (adapter.CheckResult, error) {

				var BuildTemplate func(instName string,
					param *checknothing.InstanceParam, path string) (
					*checknothing.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *checknothing.InstanceParam, path string) (
					*checknothing.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					_ = param
					return &checknothing.Instance{

						Name: instName,
					}, nil
				}

				instParam := inst.(*checknothing.InstanceParam)
				instance, err := BuildTemplate(instName, instParam, "")
				if err != nil {

					return adapter.CheckResult{}, err

				}
				return handler.(checknothing.Handler).HandleCheckNothing(ctx, instance)

			},
		},

		listentry.TemplateName: {
			Name:               listentry.TemplateName,
			Impl:               "listentry",
			CtrCfg:             &listentry.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_CHECK,
			BldrInterfaceName:  listentry.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: listentry.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(listentry.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(listentry.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *listentry.InstanceParam,
					path string) (*listentry.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *listentry.InstanceParam,
					path string) (*listentry.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &listentry.Type{}

					var err error = nil

					if param.Value == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"Value")
					}
					if t, e := tEvalFn(param.Value); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"Value", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"Value", t, istio_mixer_v1_config_descriptor.STRING)
					}

					return infrdType, err

				}

				instParam := cp.(*listentry.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(listentry.HandlerBuilder)
				castedTypes := make(map[string]*listentry.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*listentry.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetListEntryTypes(castedTypes)
			},

			ProcessCheck: func(ctx context.Context, instName string, inst proto.Message, attrs attribute.Bag,
				mapper expr.Evaluator, handler adapter.Handler) (adapter.CheckResult, error) {

				var BuildTemplate func(instName string,
					param *listentry.InstanceParam, path string) (
					*listentry.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *listentry.InstanceParam, path string) (
					*listentry.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					Value, err := mapper.Eval(param.Value, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Value", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &listentry.Instance{

						Name: instName,

						Value: Value.(string),
					}, nil
				}

				instParam := inst.(*listentry.InstanceParam)
				instance, err := BuildTemplate(instName, instParam, "")
				if err != nil {

					return adapter.CheckResult{}, err

				}
				return handler.(listentry.Handler).HandleListEntry(ctx, instance)

			},
		},

		logentry.TemplateName: {
			Name:               logentry.TemplateName,
			Impl:               "logentry",
			CtrCfg:             &logentry.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_REPORT,
			BldrInterfaceName:  logentry.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: logentry.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(logentry.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(logentry.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *logentry.InstanceParam,
					path string) (*logentry.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *logentry.InstanceParam,
					path string) (*logentry.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &logentry.Type{}

					var err error = nil

					infrdType.Variables = make(map[string]istio_mixer_v1_config_descriptor.ValueType, len(param.Variables))

					for k, v := range param.Variables {

						if infrdType.Variables[k], err = tEvalFn(v); err != nil {

							return nil, fmt.Errorf("failed to evaluate expression for field '%s'; %v", path+"Variables", err)
						}
					}

					if param.Timestamp == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"Timestamp")
					}
					if t, e := tEvalFn(param.Timestamp); e != nil || t != istio_mixer_v1_config_descriptor.TIMESTAMP {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"Timestamp", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"Timestamp", t, istio_mixer_v1_config_descriptor.TIMESTAMP)
					}

					if param.Severity == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"Severity")
					}
					if t, e := tEvalFn(param.Severity); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"Severity", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"Severity", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.MonitoredResourceType == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"MonitoredResourceType")
					}
					if t, e := tEvalFn(param.MonitoredResourceType); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"MonitoredResourceType", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"MonitoredResourceType", t, istio_mixer_v1_config_descriptor.STRING)
					}

					infrdType.MonitoredResourceDimensions = make(map[string]istio_mixer_v1_config_descriptor.ValueType, len(param.MonitoredResourceDimensions))

					for k, v := range param.MonitoredResourceDimensions {

						if infrdType.MonitoredResourceDimensions[k], err = tEvalFn(v); err != nil {

							return nil, fmt.Errorf("failed to evaluate expression for field '%s'; %v", path+"MonitoredResourceDimensions", err)
						}
					}

					return infrdType, err

				}

				instParam := cp.(*logentry.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(logentry.HandlerBuilder)
				castedTypes := make(map[string]*logentry.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*logentry.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetLogEntryTypes(castedTypes)
			},

			ProcessReport: func(ctx context.Context, insts map[string]proto.Message, attrs attribute.Bag, mapper expr.Evaluator, handler adapter.Handler) error {

				var BuildTemplate func(instName string,
					param *logentry.InstanceParam, path string) (
					*logentry.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *logentry.InstanceParam, path string) (
					*logentry.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					Variables, err := template.EvalAll(param.Variables, attrs, mapper)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Variables", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					Timestamp, err := mapper.Eval(param.Timestamp, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Timestamp", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					Severity, err := mapper.Eval(param.Severity, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Severity", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					MonitoredResourceType, err := mapper.Eval(param.MonitoredResourceType, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"MonitoredResourceType", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					MonitoredResourceDimensions, err := template.EvalAll(param.MonitoredResourceDimensions, attrs, mapper)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"MonitoredResourceDimensions", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &logentry.Instance{

						Name: instName,

						Variables: Variables,

						Timestamp: Timestamp.(time.Time),

						Severity: Severity.(string),

						MonitoredResourceType: MonitoredResourceType.(string),

						MonitoredResourceDimensions: MonitoredResourceDimensions,
					}, nil
				}

				var instances []*logentry.Instance
				for instName, inst := range insts {
					instance, err := BuildTemplate(instName, inst.(*logentry.InstanceParam), "")
					if err != nil {
						return err
					}
					instances = append(instances, instance)
				}

				if err := handler.(logentry.Handler).HandleLogEntry(ctx, instances); err != nil {
					return fmt.Errorf("failed to report all values: %v", err)
				}
				return nil
			},
		},

		metric.TemplateName: {
			Name:               metric.TemplateName,
			Impl:               "metric",
			CtrCfg:             &metric.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_REPORT,
			BldrInterfaceName:  metric.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: metric.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(metric.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(metric.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *metric.InstanceParam,
					path string) (*metric.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *metric.InstanceParam,
					path string) (*metric.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &metric.Type{}

					var err error = nil

					if param.Value == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"Value")
					}
					if infrdType.Value, err = tEvalFn(param.Value); err != nil {
						return nil, fmt.Errorf("failed to evaluate expression for field '%s'; %v", path+"Value", err)
					}

					infrdType.Dimensions = make(map[string]istio_mixer_v1_config_descriptor.ValueType, len(param.Dimensions))

					for k, v := range param.Dimensions {

						if infrdType.Dimensions[k], err = tEvalFn(v); err != nil {

							return nil, fmt.Errorf("failed to evaluate expression for field '%s'; %v", path+"Dimensions", err)
						}
					}

					if param.MonitoredResourceType == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"MonitoredResourceType")
					}
					if t, e := tEvalFn(param.MonitoredResourceType); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"MonitoredResourceType", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"MonitoredResourceType", t, istio_mixer_v1_config_descriptor.STRING)
					}

					infrdType.MonitoredResourceDimensions = make(map[string]istio_mixer_v1_config_descriptor.ValueType, len(param.MonitoredResourceDimensions))

					for k, v := range param.MonitoredResourceDimensions {

						if infrdType.MonitoredResourceDimensions[k], err = tEvalFn(v); err != nil {

							return nil, fmt.Errorf("failed to evaluate expression for field '%s'; %v", path+"MonitoredResourceDimensions", err)
						}
					}

					return infrdType, err

				}

				instParam := cp.(*metric.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(metric.HandlerBuilder)
				castedTypes := make(map[string]*metric.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*metric.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetMetricTypes(castedTypes)
			},

			ProcessReport: func(ctx context.Context, insts map[string]proto.Message, attrs attribute.Bag, mapper expr.Evaluator, handler adapter.Handler) error {

				var BuildTemplate func(instName string,
					param *metric.InstanceParam, path string) (
					*metric.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *metric.InstanceParam, path string) (
					*metric.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					Value, err := mapper.Eval(param.Value, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Value", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					Dimensions, err := template.EvalAll(param.Dimensions, attrs, mapper)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Dimensions", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					MonitoredResourceType, err := mapper.Eval(param.MonitoredResourceType, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"MonitoredResourceType", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					MonitoredResourceDimensions, err := template.EvalAll(param.MonitoredResourceDimensions, attrs, mapper)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"MonitoredResourceDimensions", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &metric.Instance{

						Name: instName,

						Value: Value,

						Dimensions: Dimensions,

						MonitoredResourceType: MonitoredResourceType.(string),

						MonitoredResourceDimensions: MonitoredResourceDimensions,
					}, nil
				}

				var instances []*metric.Instance
				for instName, inst := range insts {
					instance, err := BuildTemplate(instName, inst.(*metric.InstanceParam), "")
					if err != nil {
						return err
					}
					instances = append(instances, instance)
				}

				if err := handler.(metric.Handler).HandleMetric(ctx, instances); err != nil {
					return fmt.Errorf("failed to report all values: %v", err)
				}
				return nil
			},
		},

		quota.TemplateName: {
			Name:               quota.TemplateName,
			Impl:               "quota",
			CtrCfg:             &quota.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_QUOTA,
			BldrInterfaceName:  quota.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: quota.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(quota.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(quota.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *quota.InstanceParam,
					path string) (*quota.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *quota.InstanceParam,
					path string) (*quota.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &quota.Type{}

					var err error = nil

					infrdType.Dimensions = make(map[string]istio_mixer_v1_config_descriptor.ValueType, len(param.Dimensions))

					for k, v := range param.Dimensions {

						if infrdType.Dimensions[k], err = tEvalFn(v); err != nil {

							return nil, fmt.Errorf("failed to evaluate expression for field '%s'; %v", path+"Dimensions", err)
						}
					}

					return infrdType, err

				}

				instParam := cp.(*quota.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(quota.HandlerBuilder)
				castedTypes := make(map[string]*quota.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*quota.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetQuotaTypes(castedTypes)
			},

			ProcessQuota: func(ctx context.Context, instName string, inst proto.Message, attrs attribute.Bag,
				mapper expr.Evaluator, handler adapter.Handler, args adapter.QuotaArgs) (adapter.QuotaResult, error) {

				var BuildTemplate func(instName string,
					param *quota.InstanceParam, path string) (
					*quota.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *quota.InstanceParam, path string) (
					*quota.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					Dimensions, err := template.EvalAll(param.Dimensions, attrs, mapper)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"Dimensions", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &quota.Instance{

						Name: instName,

						Dimensions: Dimensions,
					}, nil
				}

				instParam := inst.(*quota.InstanceParam)
				instance, err := BuildTemplate(instName, instParam, "")
				if err != nil {
					return adapter.QuotaResult{}, err

				}
				return handler.(quota.Handler).HandleQuota(ctx, instance, args)

			},
		},

		reportnothing.TemplateName: {
			Name:               reportnothing.TemplateName,
			Impl:               "reportnothing",
			CtrCfg:             &reportnothing.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_REPORT,
			BldrInterfaceName:  reportnothing.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: reportnothing.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(reportnothing.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(reportnothing.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *reportnothing.InstanceParam,
					path string) (*reportnothing.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *reportnothing.InstanceParam,
					path string) (*reportnothing.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &reportnothing.Type{}

					var err error = nil

					return infrdType, err

				}

				instParam := cp.(*reportnothing.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(reportnothing.HandlerBuilder)
				castedTypes := make(map[string]*reportnothing.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*reportnothing.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetReportNothingTypes(castedTypes)
			},

			ProcessReport: func(ctx context.Context, insts map[string]proto.Message, attrs attribute.Bag, mapper expr.Evaluator, handler adapter.Handler) error {

				var BuildTemplate func(instName string,
					param *reportnothing.InstanceParam, path string) (
					*reportnothing.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *reportnothing.InstanceParam, path string) (
					*reportnothing.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					_ = param
					return &reportnothing.Instance{

						Name: instName,
					}, nil
				}

				var instances []*reportnothing.Instance
				for instName, inst := range insts {
					instance, err := BuildTemplate(instName, inst.(*reportnothing.InstanceParam), "")
					if err != nil {
						return err
					}
					instances = append(instances, instance)
				}

				if err := handler.(reportnothing.Handler).HandleReportNothing(ctx, instances); err != nil {
					return fmt.Errorf("failed to report all values: %v", err)
				}
				return nil
			},
		},

		tracespan.TemplateName: {
			Name:               tracespan.TemplateName,
			Impl:               "tracespan",
			CtrCfg:             &tracespan.InstanceParam{},
			Variety:            adptTmpl.TEMPLATE_VARIETY_REPORT,
			BldrInterfaceName:  tracespan.TemplateName + "." + "HandlerBuilder",
			HndlrInterfaceName: tracespan.TemplateName + "." + "Handler",
			BuilderSupportsTemplate: func(hndlrBuilder adapter.HandlerBuilder) bool {
				_, ok := hndlrBuilder.(tracespan.HandlerBuilder)
				return ok
			},
			HandlerSupportsTemplate: func(hndlr adapter.Handler) bool {
				_, ok := hndlr.(tracespan.Handler)
				return ok
			},
			InferType: func(cp proto.Message, tEvalFn template.TypeEvalFn) (proto.Message, error) {

				var BuildTemplate func(param *tracespan.InstanceParam,
					path string) (*tracespan.Type, error)

				_ = BuildTemplate

				BuildTemplate = func(param *tracespan.InstanceParam,
					path string) (*tracespan.Type, error) {

					if param == nil {
						return nil, nil
					}

					infrdType := &tracespan.Type{}

					var err error = nil

					if param.TraceId == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"TraceId")
					}
					if t, e := tEvalFn(param.TraceId); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"TraceId", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"TraceId", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.SpanId == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"SpanId")
					}
					if t, e := tEvalFn(param.SpanId); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"SpanId", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"SpanId", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.ParentSpanId == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"ParentSpanId")
					}
					if t, e := tEvalFn(param.ParentSpanId); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"ParentSpanId", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"ParentSpanId", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.SpanName == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"SpanName")
					}
					if t, e := tEvalFn(param.SpanName); e != nil || t != istio_mixer_v1_config_descriptor.STRING {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"SpanName", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"SpanName", t, istio_mixer_v1_config_descriptor.STRING)
					}

					if param.StartTime == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"StartTime")
					}
					if t, e := tEvalFn(param.StartTime); e != nil || t != istio_mixer_v1_config_descriptor.TIMESTAMP {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"StartTime", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"StartTime", t, istio_mixer_v1_config_descriptor.TIMESTAMP)
					}

					if param.EndTime == "" {
						return nil, fmt.Errorf("expression for field '%s' cannot be empty", path+"EndTime")
					}
					if t, e := tEvalFn(param.EndTime); e != nil || t != istio_mixer_v1_config_descriptor.TIMESTAMP {
						if e != nil {
							return nil, fmt.Errorf("failed to evaluate expression for field '%s': %v", path+"EndTime", e)
						}
						return nil, fmt.Errorf("error type checking for field '%s': Evaluated expression type %v want %v", path+"EndTime", t, istio_mixer_v1_config_descriptor.TIMESTAMP)
					}

					infrdType.SpanTags = make(map[string]istio_mixer_v1_config_descriptor.ValueType, len(param.SpanTags))

					for k, v := range param.SpanTags {

						if infrdType.SpanTags[k], err = tEvalFn(v); err != nil {

							return nil, fmt.Errorf("failed to evaluate expression for field '%s'; %v", path+"SpanTags", err)
						}
					}

					return infrdType, err

				}

				instParam := cp.(*tracespan.InstanceParam)

				return BuildTemplate(instParam, "")
			},

			SetType: func(types map[string]proto.Message, builder adapter.HandlerBuilder) {
				// Mixer framework should have ensured the type safety.
				castedBuilder := builder.(tracespan.HandlerBuilder)
				castedTypes := make(map[string]*tracespan.Type, len(types))
				for k, v := range types {
					// Mixer framework should have ensured the type safety.
					v1 := v.(*tracespan.Type)
					castedTypes[k] = v1
				}
				castedBuilder.SetTraceSpanTypes(castedTypes)
			},

			ProcessReport: func(ctx context.Context, insts map[string]proto.Message, attrs attribute.Bag, mapper expr.Evaluator, handler adapter.Handler) error {

				var BuildTemplate func(instName string,
					param *tracespan.InstanceParam, path string) (
					*tracespan.Instance, error)
				_ = BuildTemplate

				BuildTemplate = func(instName string,
					param *tracespan.InstanceParam, path string) (
					*tracespan.Instance, error) {
					if param == nil {
						return nil, nil
					}
					var err error
					_ = err

					TraceId, err := mapper.Eval(param.TraceId, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"TraceId", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					SpanId, err := mapper.Eval(param.SpanId, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"SpanId", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					ParentSpanId, err := mapper.Eval(param.ParentSpanId, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"ParentSpanId", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					SpanName, err := mapper.Eval(param.SpanName, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"SpanName", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					StartTime, err := mapper.Eval(param.StartTime, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"StartTime", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					EndTime, err := mapper.Eval(param.EndTime, attrs)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"EndTime", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					SpanTags, err := template.EvalAll(param.SpanTags, attrs, mapper)

					if err != nil {
						msg := fmt.Sprintf("failed to evaluate field '%s' for instance '%s': %v", path+"SpanTags", instName, err)
						glog.Error(msg)
						return nil, errors.New(msg)
					}

					_ = param
					return &tracespan.Instance{

						Name: instName,

						TraceId: TraceId.(string),

						SpanId: SpanId.(string),

						ParentSpanId: ParentSpanId.(string),

						SpanName: SpanName.(string),

						StartTime: StartTime.(time.Time),

						EndTime: EndTime.(time.Time),

						SpanTags: SpanTags,
					}, nil
				}

				var instances []*tracespan.Instance
				for instName, inst := range insts {
					instance, err := BuildTemplate(instName, inst.(*tracespan.InstanceParam), "")
					if err != nil {
						return err
					}
					instances = append(instances, instance)
				}

				if err := handler.(tracespan.Handler).HandleTraceSpan(ctx, instances); err != nil {
					return fmt.Errorf("failed to report all values: %v", err)
				}
				return nil
			},
		},
	}
)
