Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions module/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//templates",
"//templates/shared",
"//templates/java",
"//validate",
"@com_github_lyft_protoc_gen_star//:protoc-gen-star",
Expand Down
40 changes: 27 additions & 13 deletions module/validate.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package module

import (
"strings"

"github.com/envoyproxy/protoc-gen-validate/templates"
"github.com/envoyproxy/protoc-gen-validate/templates/java"
"github.com/envoyproxy/protoc-gen-validate/templates/shared"
pgs "github.com/lyft/protoc-gen-star"
pgsgo "github.com/lyft/protoc-gen-star/lang/go"
"strings"
)

const (
validatorName = "validator"
langParam = "lang"
moduleParam = "module"
validatorName = "validator"
langParam = "lang"
langPluginParam = "lang-plugin"
moduleParam = "module"
)

type Module struct {
Expand All @@ -29,13 +32,8 @@ func (m *Module) InitContext(ctx pgs.BuildContext) {
func (m *Module) Name() string { return validatorName }

func (m *Module) Execute(targets map[string]pgs.File, pkgs map[string]pgs.Package) []pgs.Artifact {
lang := m.Parameters().Str(langParam)
m.Assert(lang != "", "`lang` parameter must be set")
module := m.Parameters().Str(moduleParam)

// Process file-level templates
tpls := templates.Template(m.Parameters())[lang]
m.Assert(tpls != nil, "could not find templates for `lang`: ", lang)
plugin := m.resolveTemplate()

for _, f := range targets {
m.Push(f.Name().String())
Expand All @@ -44,16 +42,16 @@ func (m *Module) Execute(targets map[string]pgs.File, pkgs map[string]pgs.Packag
m.CheckRules(msg)
}

for _, tpl := range tpls {
out := templates.FilePathFor(tpl)(f, m.ctx, tpl)
for _, tpl := range plugin.Templates {
out := plugin.PathFunction(f, m.ctx, tpl)

// A nil path means no output should be generated for this file - as controlled by
// implementation-specific FilePathFor implementations.
// Ex: Don't generate Java validators for files that don't reference PGV.
if out != nil {
outPath := strings.TrimLeft(strings.ReplaceAll(out.String(), module, ""), "/")

if opts := f.Descriptor().GetOptions(); opts != nil && opts.GetJavaMultipleFiles() && lang == "java" {
if opts := f.Descriptor().GetOptions(); opts != nil && opts.GetJavaMultipleFiles() && plugin.Name == "java" {
// TODO: Only Java supports multiple file generation. If more languages add multiple file generation
// support, the implementation should be made more inderect.
for _, msg := range f.Messages() {
Expand All @@ -71,4 +69,20 @@ func (m *Module) Execute(targets map[string]pgs.File, pkgs map[string]pgs.Packag
return m.Artifacts()
}

func (m *Module) resolveTemplate() *shared.TemplatePlugin {
lang := m.Parameters().Str(langParam)
langPlugin := m.Parameters().Str(langPluginParam)
m.Assert(lang != "" || langPlugin != "", "`lang` parameter or `lang-plugin` must be set")

if lang != "" {
plugin := templates.MakeTemplateForLang(m.Parameters(), lang)
m.Assert(plugin != nil, "could not find templates for `lang`: ", lang)
return plugin
}

plugin, err := templates.MakeTemplateFromPlugin(langPlugin, m.Parameters())
m.Assert(err == nil, err)
return plugin
}

var _ pgs.Module = (*Module)(nil)
1 change: 1 addition & 0 deletions templates/cc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ go_library(
"msg.go",
"none.go",
"num.go",
"plugin.go",
"register.go",
"repeated.go",
"string.go",
Expand Down
21 changes: 21 additions & 0 deletions templates/cc/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cc

import (
"text/template"

"github.com/envoyproxy/protoc-gen-validate/templates/shared"
pgs "github.com/lyft/protoc-gen-star"
)

const PluginName = "cc"

func MakePlugin(params pgs.Parameters) *shared.TemplatePlugin {
return &shared.TemplatePlugin{
Templates: []*template.Template{
shared.MakeTemplate("h", registerHeader, params),
shared.MakeTemplate("cc", registerModule, params),
},
PathFunction: ccFilePath,
Name: PluginName,
}
}
6 changes: 3 additions & 3 deletions templates/cc/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)

func RegisterModule(tpl *template.Template, params pgs.Parameters) {
func registerModule(tpl *template.Template, params pgs.Parameters) {
fns := CCFuncs{pgsgo.InitContext(params)}

tpl.Funcs(map[string]interface{}{
Expand Down Expand Up @@ -91,7 +91,7 @@ func RegisterModule(tpl *template.Template, params pgs.Parameters) {
template.Must(tpl.New("wrapper").Parse(wrapperTpl))
}

func RegisterHeader(tpl *template.Template, params pgs.Parameters) {
func registerHeader(tpl *template.Template, params pgs.Parameters) {
fns := CCFuncs{pgsgo.InitContext(params)}

tpl.Funcs(map[string]interface{}{
Expand All @@ -107,7 +107,7 @@ func RegisterHeader(tpl *template.Template, params pgs.Parameters) {
// TODO(rodaine): break pgsgo dependency here (with equivalent pgscc subpackage)
type CCFuncs struct{ pgsgo.Context }

func CcFilePath(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath {
func ccFilePath(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath {
out := pgs.FilePath(f.Name().String())
out = out.SetExt(".pb.validate." + tpl.Name())
return &out
Expand Down
3 changes: 3 additions & 0 deletions templates/go/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ go_library(
"duration.go",
"file.go",
"message.go",
"plugin.go",
"register.go",
"required.go",
"timestamp.go",
],
importpath = "github.com/envoyproxy/protoc-gen-validate/templates/go",
visibility = ["//visibility:public"],
deps = [
"//templates/shared",
"//templates/goshared",
"@com_github_lyft_protoc_gen_star//:protoc-gen-star",
"@com_github_lyft_protoc_gen_star//lang/go",
],
)

Expand Down
23 changes: 23 additions & 0 deletions templates/go/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package golang

import (
"text/template"

"github.com/envoyproxy/protoc-gen-validate/templates/shared"
pgs "github.com/lyft/protoc-gen-star"
pgsgo "github.com/lyft/protoc-gen-star/lang/go"
)

const PluginName = "go"

func MakePlugin(params pgs.Parameters) *shared.TemplatePlugin {
return &shared.TemplatePlugin{
Templates: []*template.Template{shared.MakeTemplate("go", register, params)},
PathFunction: func(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath {
out := ctx.OutputPath(f)
out = out.SetExt(".validate." + tpl.Name())
return &out
},
Name: PluginName,
}
}
4 changes: 2 additions & 2 deletions templates/go/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package golang
import (
"text/template"

"github.com/lyft/protoc-gen-star"
"github.com/envoyproxy/protoc-gen-validate/templates/goshared"
pgs "github.com/lyft/protoc-gen-star"
)

func Register(tpl *template.Template, params pgs.Parameters) {
func register(tpl *template.Template, params pgs.Parameters) {
goshared.Register(tpl, params)
template.Must(tpl.Parse(fileTpl))
template.Must(tpl.New("required").Parse(requiredTpl))
Expand Down
1 change: 1 addition & 0 deletions templates/java/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ go_library(
"none.go",
"num.go",
"oneof.go",
"plugin.go",
"register.go",
"repeated.go",
"required.go",
Expand Down
18 changes: 18 additions & 0 deletions templates/java/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package java

import (
"text/template"

"github.com/envoyproxy/protoc-gen-validate/templates/shared"
pgs "github.com/lyft/protoc-gen-star"
)

const PluginName = "java"

func MakePlugin(params pgs.Parameters) *shared.TemplatePlugin {
return &shared.TemplatePlugin{
Templates: []*template.Template{shared.MakeTemplate("java", register, params)},
PathFunction: javaFilePath,
Name: PluginName,
}
}
6 changes: 3 additions & 3 deletions templates/java/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)

func RegisterIndex(tpl *template.Template, params pgs.Parameters) {
func registerIndex(tpl *template.Template, params pgs.Parameters) {
fns := javaFuncs{pgsgo.InitContext(params)}

tpl.Funcs(map[string]interface{}{
Expand All @@ -28,7 +28,7 @@ func RegisterIndex(tpl *template.Template, params pgs.Parameters) {
})
}

func Register(tpl *template.Template, params pgs.Parameters) {
func register(tpl *template.Template, params pgs.Parameters) {
fns := javaFuncs{pgsgo.InitContext(params)}

tpl.Funcs(map[string]interface{}{
Expand Down Expand Up @@ -117,7 +117,7 @@ func Register(tpl *template.Template, params pgs.Parameters) {

type javaFuncs struct{ pgsgo.Context }

func JavaFilePath(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath {
func javaFilePath(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath {
// Don't generate validators for files that don't import PGV
if !importsPvg(f) {
return nil
Expand Down
61 changes: 30 additions & 31 deletions templates/pkg.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,46 @@
package templates

import (
"text/template"
"errors"
"plugin"

"github.com/lyft/protoc-gen-star"
"github.com/lyft/protoc-gen-star/lang/go"
"github.com/envoyproxy/protoc-gen-validate/templates/cc"
"github.com/envoyproxy/protoc-gen-validate/templates/go"
golang "github.com/envoyproxy/protoc-gen-validate/templates/go"
"github.com/envoyproxy/protoc-gen-validate/templates/java"
"github.com/envoyproxy/protoc-gen-validate/templates/shared"
pgs "github.com/lyft/protoc-gen-star"
)

type RegisterFn func(tpl *template.Template, params pgs.Parameters)
type FilePathFn func(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath
type makePluginFn func(params pgs.Parameters) *shared.TemplatePlugin

func makeTemplate(ext string, fn RegisterFn, params pgs.Parameters) *template.Template {
tpl := template.New(ext)
shared.RegisterFunctions(tpl, params)
fn(tpl, params)
return tpl
func MakeTemplateForLang(params pgs.Parameters, lang string) *shared.TemplatePlugin {
switch lang {
case cc.PluginName:
return cc.MakePlugin(params)
case golang.PluginName:
return golang.MakePlugin(params)
case java.PluginName:
return java.MakePlugin(params)
default:
return nil
}
}

func Template(params pgs.Parameters) map[string][]*template.Template {
return map[string][]*template.Template{
"cc": {makeTemplate("h", cc.RegisterHeader, params), makeTemplate("cc", cc.RegisterModule, params)},
"go": {makeTemplate("go", golang.Register, params)},
"java": {makeTemplate("java", java.Register, params)},
func MakeTemplateFromPlugin(path string, params pgs.Parameters) (*shared.TemplatePlugin, error) {
plug, err := plugin.Open(path)
if err != nil {
return nil, err
}
}

func FilePathFor(tpl *template.Template) FilePathFn {
switch tpl.Name() {
case "h":
return cc.CcFilePath
case "cc":
return cc.CcFilePath
case "java":
return java.JavaFilePath
default:
return func(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath {
out := ctx.OutputPath(f)
out = out.SetExt(".validate." + tpl.Name())
return &out
}
symPlugin, err := plug.Lookup("Plugin")
if err != nil {
return nil, err
}

makePlugin, ok := symPlugin.(makePluginFn)
if !ok {
return nil, errors.New("loaded object has an incorrect type, expected: *TemplatePlugin")
}

return makePlugin(params), nil
}
2 changes: 2 additions & 0 deletions templates/shared/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ go_library(
"disabled.go",
"functions.go",
"reflection.go",
"template.go",
"well_known.go",
],
importpath = "github.com/envoyproxy/protoc-gen-validate/templates/shared",
visibility = ["//visibility:public"],
deps = [
"//validate",
"@com_github_lyft_protoc_gen_star//:protoc-gen-star",
"@com_github_lyft_protoc_gen_star//lang/go",
"@org_golang_google_protobuf//proto",
],
)
Expand Down
24 changes: 24 additions & 0 deletions templates/shared/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package shared

import (
"text/template"

pgs "github.com/lyft/protoc-gen-star"
pgsgo "github.com/lyft/protoc-gen-star/lang/go"
)

type RegisterFn func(tpl *template.Template, params pgs.Parameters)
type FilePathFn func(f pgs.File, ctx pgsgo.Context, tpl *template.Template) *pgs.FilePath

type TemplatePlugin struct {
Templates []*template.Template
PathFunction FilePathFn
Name string
}

func MakeTemplate(ext string, fn RegisterFn, params pgs.Parameters) *template.Template {
tpl := template.New(ext)
RegisterFunctions(tpl, params)
fn(tpl, params)
return tpl
}
1 change: 1 addition & 0 deletions validate/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ go_proto_library(
name = "validate_go_proto",
importpath = "github.com/envoyproxy/protoc-gen-validate/validate",
proto = ":validate_proto",
gc_goopts = ["-trimpath=$(BINDIR)=>."],
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an important change for go plugins to work. see more info about this on: bazel-contrib/rules_go#2994

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the rules_go fix is now merged!

)

cc_library(
Expand Down