You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kratos/tool/protobuf/pkg/generator/helper.go

137 lines
3.5 KiB

package generator
import (
"reflect"
"strings"
"github.com/bilibili/kratos/tool/protobuf/pkg/extensions/gogoproto"
"github.com/bilibili/kratos/tool/protobuf/pkg/tag"
"github.com/bilibili/kratos/tool/protobuf/pkg/typemap"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
)
// GetJSONFieldName get name from gogoproto.jsontag
// else the original name
func GetJSONFieldName(field *descriptor.FieldDescriptorProto) string {
if field == nil {
return ""
}
if field.Options != nil {
v, err := proto.GetExtension(field.Options, gogoproto.E_Jsontag)
if err == nil && v.(*string) != nil {
ret := *(v.(*string))
i := strings.Index(ret, ",")
if i != -1 {
ret = ret[:i]
}
return ret
}
}
return field.GetName()
}
// GetFormOrJSONName get name from form tag, then json tag
// then original name
func GetFormOrJSONName(field *descriptor.FieldDescriptorProto) string {
if field == nil {
return ""
}
tags := tag.GetMoreTags(field)
if tags != nil {
tag := reflect.StructTag(*tags)
fName := tag.Get("form")
if fName != "" {
i := strings.Index(fName, ",")
if i != -1 {
fName = fName[:i]
}
return fName
}
}
return GetJSONFieldName(field)
}
// IsScalar Is this field a scalar numeric type?
func IsScalar(field *descriptor.FieldDescriptorProto) bool {
if field.Type == nil {
return false
}
switch *field.Type {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
descriptor.FieldDescriptorProto_TYPE_FLOAT,
descriptor.FieldDescriptorProto_TYPE_INT64,
descriptor.FieldDescriptorProto_TYPE_UINT64,
descriptor.FieldDescriptorProto_TYPE_INT32,
descriptor.FieldDescriptorProto_TYPE_FIXED64,
descriptor.FieldDescriptorProto_TYPE_FIXED32,
descriptor.FieldDescriptorProto_TYPE_BOOL,
descriptor.FieldDescriptorProto_TYPE_UINT32,
descriptor.FieldDescriptorProto_TYPE_ENUM,
descriptor.FieldDescriptorProto_TYPE_SFIXED32,
descriptor.FieldDescriptorProto_TYPE_SFIXED64,
descriptor.FieldDescriptorProto_TYPE_SINT32,
descriptor.FieldDescriptorProto_TYPE_SINT64,
descriptor.FieldDescriptorProto_TYPE_BYTES,
descriptor.FieldDescriptorProto_TYPE_STRING:
return true
default:
return false
}
}
// IsMap is protocol buffer map
func IsMap(field *descriptor.FieldDescriptorProto, reg *typemap.Registry) bool {
if field.GetType() != descriptor.FieldDescriptorProto_TYPE_MESSAGE {
return false
}
md := reg.MessageDefinition(field.GetTypeName())
if md == nil || !md.Descriptor.GetOptions().GetMapEntry() {
return false
}
return true
}
// IsRepeated Is this field repeated?
func IsRepeated(field *descriptor.FieldDescriptorProto) bool {
return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
}
// GetFieldRequired is field required?
// eg. validate="required"
func GetFieldRequired(
f *descriptor.FieldDescriptorProto,
reg *typemap.Registry,
md *typemap.MessageDefinition,
) bool {
fComment, _ := reg.FieldComments(md, f)
var tags []reflect.StructTag
{
//get required info from gogoproto.moretags
moretags := tag.GetMoreTags(f)
if moretags != nil {
tags = []reflect.StructTag{reflect.StructTag(*moretags)}
}
}
if len(tags) == 0 {
tags = tag.GetTagsInComment(fComment.Leading)
}
validateTag := tag.GetTagValue("validate", tags)
var validateRules []string
if validateTag != "" {
validateRules = strings.Split(validateTag, ",")
}
required := false
for _, rule := range validateRules {
if rule == "required" {
required = true
}
}
return required
}
func MakeIndentStr(i int) string {
return strings.Repeat(" ", i)
}