github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/pkg/protoc/protoc_configuration.go (about) 1 package protoc 2 3 import ( 4 "path" 5 "strings" 6 ) 7 8 // ProtocConfiguration represents the complete configuration and source 9 // mappings. 10 type ProtocConfiguration struct { 11 // PackageConfig parent 12 PackageConfig *PackageConfig 13 // The config for the p 14 LanguageConfig *LanguageConfig 15 // the workspace relative path of the BUILD file where this rule is being 16 // generated. 17 Rel string 18 // the prefix for the rule (e.g. 'java') 19 Prefix string 20 // the library thar holds the proto files 21 Library ProtoLibrary 22 // the configuration for the plugins 23 Plugins []*PluginConfiguration 24 // The merged set of Source files for the compilations 25 Outputs []string 26 // The merged set of imports for the compilations 27 Imports []string 28 // The generated source mappings 29 Mappings map[string]string 30 } 31 32 func newProtocConfiguration(pc *PackageConfig, lc *LanguageConfig, workDir, rel, prefix string, lib ProtoLibrary, plugins []*PluginConfiguration) *ProtocConfiguration { 33 srcs, mappings := mergeSources(workDir, rel, plugins, lib.StripImportPrefix()) 34 35 return &ProtocConfiguration{ 36 PackageConfig: pc, 37 LanguageConfig: lc, 38 Rel: rel, 39 Prefix: prefix, 40 Library: lib, 41 Plugins: plugins, 42 Outputs: srcs, 43 Mappings: mappings, 44 } 45 } 46 47 func (c *ProtocConfiguration) GetPluginConfiguration(implementationName string) *PluginConfiguration { 48 for _, plugin := range c.Plugins { 49 if plugin.Config.Implementation == implementationName { 50 return plugin 51 } 52 } 53 return nil 54 } 55 56 func (c *ProtocConfiguration) GetPluginOutputs(implementationName string) []string { 57 plugin := c.GetPluginConfiguration(implementationName) 58 if plugin == nil { 59 return nil 60 } 61 return plugin.Outputs 62 } 63 64 // mergeSources computes the source files that are generated by the rule and any 65 // necessary mappings. 66 func mergeSources(workDir, rel string, plugins []*PluginConfiguration, stripImportPrefix string) ([]string, map[string]string) { 67 srcs := make([]string, 0) 68 mappings := make(map[string]string) 69 70 // if the stripImportPrefix is defined and "absolute" (starting with a 71 // slash), this means it is relative to the repository root. 72 // https://github.com/bazelbuild/bazel/issues/3867#issuecomment-441971525 73 prefix := strings.TrimPrefix(stripImportPrefix, "/") 74 75 for _, plugin := range plugins { 76 77 // if plugin provided mappings for us, use those preferentially 78 if len(plugin.Mappings) > 0 { 79 srcs = append(srcs, plugin.Outputs...) 80 81 for k, v := range plugin.Mappings { 82 mappings[k] = v 83 } 84 continue 85 } 86 87 // otherwise, fallback to baseline method 88 for _, filename := range plugin.Outputs { 89 if prefix != "" { 90 filename = strings.TrimPrefix(filename, prefix) 91 } 92 dir := path.Dir(filename) 93 if dir == "." && rel == "" { 94 dir = rel 95 } 96 if dir == rel { 97 // no mapping required, just add to the srcs list 98 srcs = append(srcs, strings.TrimPrefix(filename, rel+"/")) 99 } else { 100 // add the basename only to the srcs list and add a mapping. 101 base := path.Base(filename) 102 mappings[base] = filename 103 srcs = append(srcs, base) 104 } 105 } 106 } 107 108 return srcs, mappings 109 }