k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/generators/rules/idl_tag.go (about)

     1  package rules
     2  
     3  import (
     4  	"k8s.io/gengo/v2"
     5  	"k8s.io/gengo/v2/types"
     6  )
     7  
     8  const ListTypeIDLTag = "listType"
     9  
    10  // ListTypeMissing implements APIRule interface.
    11  // A list type is required for inlined list.
    12  type ListTypeMissing struct{}
    13  
    14  // Name returns the name of APIRule
    15  func (l *ListTypeMissing) Name() string {
    16  	return "list_type_missing"
    17  }
    18  
    19  // Validate evaluates API rule on type t and returns a list of field names in
    20  // the type that violate the rule. Empty field name [""] implies the entire
    21  // type violates the rule.
    22  func (l *ListTypeMissing) Validate(t *types.Type) ([]string, error) {
    23  	fields := make([]string, 0)
    24  
    25  	switch t.Kind {
    26  	case types.Struct:
    27  		for _, m := range t.Members {
    28  			hasListType := gengo.ExtractCommentTags("+", m.CommentLines)[ListTypeIDLTag] != nil
    29  
    30  			if m.Name == "Items" && m.Type.Kind == types.Slice && hasNamedMember(t, "ListMeta") {
    31  				if hasListType {
    32  					fields = append(fields, m.Name)
    33  				}
    34  				continue
    35  			}
    36  
    37  			// All slice fields must have a list-type tag except []byte
    38  			if m.Type.Kind == types.Slice && m.Type.Elem != types.Byte && !hasListType {
    39  				fields = append(fields, m.Name)
    40  				continue
    41  			}
    42  		}
    43  	}
    44  
    45  	return fields, nil
    46  }
    47  
    48  func hasNamedMember(t *types.Type, name string) bool {
    49  	for _, m := range t.Members {
    50  		if m.Name == name {
    51  			return true
    52  		}
    53  	}
    54  	return false
    55  }