Skip to content

Commit

Permalink
feature: pool paths with wildcard
Browse files Browse the repository at this point in the history
  • Loading branch information
evgfedotov committed Nov 22, 2023
1 parent a8e005f commit 3615d40
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 9 deletions.
4 changes: 3 additions & 1 deletion cmd/protoc-gen-go-vtproto/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ func main() {
var f flag.FlagSet

f.BoolVar(&cfg.AllowEmpty, "allow-empty", false, "allow generation of empty files")
cfg.Poolable = make(generator.ObjectSet)
cfg.Poolable = generator.NewObjectSet()
cfg.PoolableExclude = generator.NewObjectSet()
f.Var(&cfg.Poolable, "pool", "use memory pooling for this object")
f.Var(&cfg.PoolableExclude, "pool-exclude", "do not use memory pooling for this object")
f.BoolVar(&cfg.Wrap, "wrap", false, "generate wrapper types")
f.BoolVar(&cfg.WellKnownTypes, "wkt", true, "generate optimized code for well-known types")
f.StringVar(&features, "features", "all", "list of features to generate (separated by '+')")
Expand Down
7 changes: 5 additions & 2 deletions generator/generatedfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ func (p *GeneratedFile) Ident(path, ident string) string {
}

func (b *GeneratedFile) ShouldPool(message *protogen.Message) bool {
if message == nil {
// Do not generate pool if message is nil or message excluded by external rules
if message == nil || b.Config.PoolableExclude.Contains(message.GoIdent) {
return false
}
if b.Config.Poolable[message.GoIdent] {

if b.Config.Poolable.Contains(message.GoIdent) {
return true
}

ext := proto.GetExtension(message.Desc.Options(), vtproto.E_Mempool)
if mempool, ok := ext.(bool); ok {
return mempool
Expand Down
71 changes: 65 additions & 6 deletions generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,38 @@ type featureHelpers struct {
feature int
}

type ObjectSet map[protogen.GoIdent]bool
type ObjectSet struct {
wildcards map[string]struct{}
mp map[protogen.GoIdent]bool
}

func NewObjectSet() ObjectSet {
return ObjectSet{
mp: map[protogen.GoIdent]bool{},
wildcards: map[string]struct{}{},
}
}

func (o ObjectSet) String() string {
return fmt.Sprintf("%#v", o)
}

func (o ObjectSet) Contains(g protogen.GoIdent) bool {
for wildcard := range o.wildcards {
if Match(wildcard, fmt.Sprintf("%s.%s", string(g.GoImportPath), g.GoName)) {
return true
}
}

return o.mp[g]
}

func (o ObjectSet) Set(s string) error {
if strings.Contains(s, "*") {
o.wildcards[s] = struct{}{}
return nil
}

idx := strings.LastIndexByte(s, '.')
if idx < 0 {
return fmt.Errorf("invalid object name: %q", s)
Expand All @@ -37,15 +62,49 @@ func (o ObjectSet) Set(s string) error {
GoName: s[idx+1:],
}

o[ident] = true
o.mp[ident] = true
return nil
}

func Match(pattern, name string) (matched bool) {
if pattern == "" {
return name == pattern
}

if pattern == "*" {
return true
}
return deepMatchRune([]rune(name), []rune(pattern))

}

func deepMatchRune(str, pattern []rune) bool {
for len(pattern) > 0 {
switch pattern[0] {
default:
if len(str) == 0 || str[0] != pattern[0] {
return false
}
case '*':
return deepMatchRune(str, pattern[1:]) ||
(len(str) > 0 && deepMatchRune(str[1:], pattern))
}

str = str[1:]
pattern = pattern[1:]
}

return len(str) == 0 && len(pattern) == 0
}

type Config struct {
Poolable ObjectSet
Wrap bool
WellKnownTypes bool
AllowEmpty bool
// Poolable rules determines if pool feature generate for particular message
Poolable ObjectSet
// PoolableExclude rules determines if pool feature disabled for particular message
PoolableExclude ObjectSet
Wrap bool
WellKnownTypes bool
AllowEmpty bool
}

type Generator struct {
Expand Down

0 comments on commit 3615d40

Please sign in to comment.