github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/pkg/protoc/syntaxutil.go (about)

     1  package protoc
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/bazelbuild/bazel-gazelle/rule"
     7  	"github.com/bazelbuild/buildtools/build"
     8  )
     9  
    10  func MakeStringListDict(in map[string][]string) build.Expr {
    11  	items := make([]*build.KeyValueExpr, 0)
    12  	keys := make([]string, 0)
    13  	for k := range in {
    14  		keys = append(keys, k)
    15  	}
    16  	sort.Strings(keys)
    17  	for _, key := range keys {
    18  		values := in[key]
    19  		sort.Strings(values)
    20  		value := &build.ListExpr{List: make([]build.Expr, len(values))}
    21  		for i, val := range values {
    22  			value.List[i] = &build.StringExpr{Value: val}
    23  		}
    24  		items = append(items, &build.KeyValueExpr{
    25  			Key:   &build.StringExpr{Value: key},
    26  			Value: value,
    27  		})
    28  	}
    29  	return &build.DictExpr{List: items}
    30  }
    31  
    32  func MakeStringDict(in map[string]string) build.Expr {
    33  	dict := &build.DictExpr{}
    34  	keys := make([]string, 0)
    35  	for k := range in {
    36  		keys = append(keys, k)
    37  	}
    38  	sort.Strings(keys)
    39  	for _, key := range keys {
    40  		value := in[key]
    41  		dict.List = append(dict.List, &build.KeyValueExpr{
    42  			Key:   &build.StringExpr{Value: key},
    43  			Value: &build.StringExpr{Value: value},
    44  		})
    45  	}
    46  	return dict
    47  }
    48  
    49  // GetKeptFileRuleAttrString returns the value of the rule attribute IFF the
    50  // backing File rule attribute has a '# keep' comment on it.
    51  func GetKeptFileRuleAttrString(file *rule.File, r *rule.Rule, name string) string {
    52  	if file == nil {
    53  		return ""
    54  	}
    55  	assign := getRuleAssignExpr(file.File, r.Kind(), r.Name(), name)
    56  	if assign == nil {
    57  		return ""
    58  	}
    59  	if !rule.ShouldKeep(assign) {
    60  		return ""
    61  	}
    62  	str, ok := assign.RHS.(*build.StringExpr)
    63  	if !ok {
    64  		return ""
    65  	}
    66  	return str.Value
    67  }
    68  
    69  // getRuleAssignExpr seeks through the file looking for call expressions having
    70  // the given kind and rule name.  If found, the assignment expression having the
    71  // given name is returned.  Otherwise, return nil.
    72  func getRuleAssignExpr(file *build.File, kind string, name string, attrName string) *build.AssignExpr {
    73  	if file == nil {
    74  		return nil
    75  	}
    76  	for _, stmt := range file.Stmt {
    77  		call, ok := stmt.(*build.CallExpr)
    78  		if !ok {
    79  			continue
    80  		}
    81  		ident, ok := call.X.(*build.Ident)
    82  		if !ok {
    83  			continue
    84  		}
    85  		if ident.Name != kind {
    86  			continue
    87  		}
    88  		var ruleName string
    89  		var want *build.AssignExpr
    90  		for _, arg := range call.List {
    91  			attr, ok := arg.(*build.AssignExpr)
    92  			if !ok {
    93  				continue
    94  			}
    95  			key := attr.LHS.(*build.Ident)
    96  			switch key.Name {
    97  			case "name":
    98  				str, ok := attr.RHS.(*build.StringExpr)
    99  				if ok {
   100  					ruleName = str.Value
   101  				}
   102  			case attrName:
   103  				want = attr
   104  			}
   105  		}
   106  		if ruleName != name {
   107  			continue
   108  		}
   109  		return want
   110  	}
   111  	return nil
   112  }