// Handle special tags that get converted to the kind and remote endpoint
// fields, and throw the rest of the tags into a map that becomes the Zipkin
// Tags field.
// nolint: gocyclo
192289
func processJaegerTags(s *jThrift.Span) (*string, *trace.Endpoint, map[string]string) {
	var kind *string
	var remote *trace.Endpoint
	tags := make(map[string]string, len(s.Tags))

	ensureRemote := func() {
		if remote == nil {
			remote = &trace.Endpoint{}
		}
	}

	for i := range s.Tags {
		switch s.Tags[i].Key {
		case string(ext.PeerHostIPv4):
			ip := convertPeerIPv4(s.Tags[i])
			if ip == "" {
				continue
			}
			ensureRemote()
			remote.Ipv4 = pointer.String(ip)
		// ipv6 host is always string
		case string(ext.PeerHostIPv6):
			if s.Tags[i].VStr != nil {
				ensureRemote()
				remote.Ipv6 = s.Tags[i].VStr
			}
		case string(ext.PeerPort):
			port := convertPeerPort(s.Tags[i])
			if port == 0 {
				continue
			}
			ensureRemote()
			remote.Port = &port
		case string(ext.PeerService):
			ensureRemote()
			remote.ServiceName = s.Tags[i].VStr
		case string(ext.SpanKind):
			kind = convertKind(s.Tags[i])
		default:
			val := tagValueToString(s.Tags[i])
			if val != "" {
				tags[s.Tags[i].Key] = val
			}
		}
	}
	return kind, remote, tags
}
536119
func tagsToMapCloudWatch(ts []*cloudwatch.Tag) map[string]string {
	result := make(map[string]string)
	for _, t := range ts {
		if !tagIgnoredCloudWatch(t) {
			result[*t.Key] = *t.Value
		}
	}

	return result
}
482046
func tagsToMapRDS(ts []*rds.Tag) map[string]string {
	result := make(map[string]string)
	for _, t := range ts {
		if !tagIgnoredRDS(t) {
			result[*t.Key] = *t.Value
		}
	}

	return result
}
1143371
func tagsToMapKinesisFirehose(ts []*firehose.Tag) map[string]string {
	result := make(map[string]string)
	for _, t := range ts {
		if !tagIgnoredKinesisFirehose(t) {
			result[aws.StringValue(t.Key)] = aws.StringValue(t.Value)
		}
	}

	return result
}
1167826
func tagsToMapDS(ts []*directoryservice.Tag) map[string]string {
	result := make(map[string]string)
	for _, t := range ts {
		if !tagIgnoredDS(t) {
			result[*t.Key] = *t.Value
		}
	}

	return result
}
340982
func tagsFromMapDX(m map[string]interface{}) []*directconnect.Tag {
	result := make([]*directconnect.Tag, 0, len(m))
	for k, v := range m {
		t := &directconnect.Tag{
			Key:   aws.String(k),
			Value: aws.String(v.(string)),
		}
		if !tagIgnoredDX(t) {
			result = append(result, t)
		}
	}

	return result
}
351912
func tagsToMapBeanstalk(ts []*elasticbeanstalk.Tag) map[string]string {
	result := make(map[string]string)
	for _, t := range ts {
		if !tagIgnoredBeanstalk(t) {
			result[*t.Key] = *t.Value
		}
	}

	return result
}
82339
func tagsToMapECS(tags []*ecs.Tag) map[string]string {
	tagMap := make(map[string]string)
	for _, tag := range tags {
		if !tagIgnoredECS(tag) {
			tagMap[aws.StringValue(tag.Key)] = aws.StringValue(tag.Value)
		}
	}

	return tagMap
}
130352
func (r *Route) Tag(value interface{}) *Route {
	if len(r.routes) > 0 {
		// this route is a composite one (a path with multiple methods)
		for _, route := range r.routes {
			route.Tag(value)
		}
		return r
	}
	if r.tags == nil {
		r.tags = []interface{}{}
	}
	r.tags = append(r.tags, value)
	return r
}
1167575
func (a *Wrapper) RouteTags() {
	if _, y := a.Controller.(Initer); !y {
		a.Module.Core.Logger().Infof(`%T is no method Init(echo.Context)error, skiped.`, a.Controller)
		return
	}
	t := reflect.TypeOf(a.Controller)
	e := t.Elem()
	v := reflect.ValueOf(a.Controller)
	ctlPath := e.PkgPath() + `.(*` + e.Name() + `).`
	//github.com/webx-top/{Project}/app/{Module}/controller.(*Index).

	var ctl string
	if a.Module.URLConvert != nil {
		ctl = a.Module.URLConvert(e.Name())
	} else {
		ctl = e.Name()
	}
	a.ControllerName = ctl
	for i := 0; i < e.NumField(); i++ {
		f := e.Field(i)
		if !a.Module.Application.MapperCheck(f.Type) {
			continue
		}
		name := strings.Title(f.Name)
		m := v.MethodByName(name)
		if !m.IsValid() && !a.hasMain {
			m = v.MethodByName(`Main`)
			if !m.IsValid() {
				continue
			}
			a.hasMain = true
		}
		/*
			支持的tag:
			1. webx - 路由规则
			2. memo - 注释说明
			webx标签内容支持以下格式：
			1、只指定http请求方式，如`webx:"POST|GET"`
			2、只指定路由规则，如`webx:"index"`
			3、只指定扩展名规则，如`webx:".JSON|XML"`
			4、指定以上全部规则，如`webx:"GET|POST.JSON|XML index"`
			注: 当路径规则以波浪线"~"开头时，表示该规则加在app下，否则加在controller下
		*/
		tag := e.Field(i).Tag
		tagv := tag.Get(a.Module.RouteTagName)
		var methods, extends []string
		var p, w string
		if len(tagv) > 0 {
			tags := strings.Split(tagv, ` `)
			length := len(tags)
			if length >= 2 { //`webx:"GET|POST /index"`
				w = tags[0]
				p = tags[1]
			} else if length == 1 {
				if !routeTagRegex.MatchString(tags[0]) {
					//非全大写字母时，判断为网址规则
					p = tags[0]
				} else { //`webx:"GET|POST"`
					w = tags[0]
				}
			}
		}
		if len(p) == 0 {
			if a.Module.URLConvert != nil {
				p = `/` + a.Module.URLConvert(name)
			} else {
				p = `/` + name
			}
		}
		var ppath string
		if p[0] == '~' {
			p = p[1:]
			if p[0] != '/' {
				p = `/` + p
			}
			ppath = p
		} else {
			if p[0] != '/' {
				p = `/` + p
			}
			ppath = `/` + ctl + p
		}
		var met, ext string
		if len(w) > 0 {
			me := strings.Split(w, `.`)
			met = me[0]
			if len(me) > 1 {
				ext = me[1]
			}
		}
		if len(met) > 0 {
			methods = strings.Split(met, `|`)
		}
		if len(ext) > 0 {
			ext = strings.ToLower(ext)
			extends = strings.Split(ext, `|`)
		}
		k := ctlPath + name + `-fm`
		u := a.Module.Application.URLBuilder.SetExtensions(k, extends)
		h := NewHandler(func(ctx echo.Context) error {
			return a.execute(ctx, k, e, u, name)
		}, k)
		switch len(methods) {
		case 0:
			methods = append(methods, `GET`)
			methods = append(methods, `POST`)
		case 1:
			if methods[0] == `ANY` {
				a.addRouter(ctl, ppath, h)
				continue
			}
		}
		a.addRouter(ctl, ppath, h, methods...)
	}
}
989749
func IndexTagHandler(ctx *tagContext) error {
	if len(ctx.params) > 0 {
		ctx.indexNames[ctx.params[0]] = core.IndexType
	} else {
		ctx.isIndex = true
	}
	return nil
}
1203655
func Tags(tags map[string]string) TracerOption {
	return func(o *tracerOptions) {
		for k, v := range tags {
			o.tags[k] = v
		}
	}
}
965405
func tagsFromMapCloudWatchEvents(m map[string]interface{}) []*events.Tag {
	var result []*events.Tag
	for k, v := range m {
		t := &events.Tag{
			Key:   aws.String(k),
			Value: aws.String(v.(string)),
		}
		if !tagIgnoredCloudWatchEvents(t) {
			result = append(result, t)
		}
	}

	return result
}
1340993
func tagsToMapDax(ts []*dax.Tag) map[string]string {
	result := make(map[string]string)
	for _, t := range ts {
		if !tagIgnoredDax(t) {
			result[*t.Key] = *t.Value
		}
	}

	return result
}
639468
func tagsFromMapECR(m map[string]interface{}) []*ecr.Tag {
	result := make([]*ecr.Tag, 0, len(m))
	for k, v := range m {
		t := &ecr.Tag{
			Key:   aws.String(k),
			Value: aws.String(v.(string)),
		}
		if !tagIgnoredECR(t) {
			result = append(result, t)
		}
	}

	return result
}
593097
func tagsFromMapDocDB(m map[string]interface{}) []*docdb.Tag {
	result := make([]*docdb.Tag, 0, len(m))
	for k, v := range m {
		t := &docdb.Tag{
			Key:   aws.String(k),
			Value: aws.String(v.(string)),
		}
		if !tagIgnoredDocDB(t) {
			result = append(result, t)
		}
	}

	return result
}
996694
func SortTags(tags map[string]string) [][]string {
	keys := make([]string, len(tags))
	result := make([][]string, len(tags))
	i := 0
	for k := range tags {
		keys[i] = k
		i++
	}
	sort.Strings(keys)
	for i, k := range keys {
		result[i] = []string{k, tags[k]}
	}
	return result
}