well_known.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package shared
  2. import (
  3. "github.com/envoyproxy/protoc-gen-validate/validate"
  4. "github.com/lyft/protoc-gen-star"
  5. )
  6. type WellKnown string
  7. const (
  8. Email WellKnown = "email"
  9. Hostname WellKnown = "hostname"
  10. UUID WellKnown = "uuid"
  11. )
  12. func FileNeeds(f pgs.File, wk WellKnown) bool {
  13. for _, msg := range f.Messages() {
  14. needed := Needs(msg, wk)
  15. if needed {
  16. return true
  17. }
  18. }
  19. return false
  20. }
  21. // Needs returns true if a well-known string validator is needed for this
  22. // message.
  23. func Needs(m pgs.Message, wk WellKnown) bool {
  24. for _, f := range m.Fields() {
  25. var rules validate.FieldRules
  26. if _, err := f.Extension(validate.E_Rules, &rules); err != nil {
  27. continue
  28. }
  29. switch {
  30. case f.Type().IsRepeated() && f.Type().Element().ProtoType() == pgs.StringT:
  31. if strRulesNeeds(rules.GetRepeated().GetItems().GetString_(), wk) {
  32. return true
  33. }
  34. case f.Type().IsMap():
  35. if f.Type().Key().ProtoType() == pgs.StringT &&
  36. strRulesNeeds(rules.GetMap().GetKeys().GetString_(), wk) {
  37. return true
  38. }
  39. if f.Type().Element().ProtoType() == pgs.StringT &&
  40. strRulesNeeds(rules.GetMap().GetValues().GetString_(), wk) {
  41. return true
  42. }
  43. case f.Type().ProtoType() == pgs.StringT:
  44. if strRulesNeeds(rules.GetString_(), wk) {
  45. return true
  46. }
  47. case f.Type().ProtoType() == pgs.MessageT && f.Type().IsEmbed() && f.Type().Embed().WellKnownType() == pgs.StringValueWKT:
  48. if strRulesNeeds(rules.GetString_(), wk) {
  49. return true
  50. }
  51. }
  52. }
  53. return false
  54. }
  55. func strRulesNeeds(rules *validate.StringRules, wk WellKnown) bool {
  56. switch wk {
  57. case Email:
  58. if rules.GetEmail() {
  59. return true
  60. }
  61. case Hostname:
  62. if rules.GetEmail() || rules.GetHostname() || rules.GetAddress() {
  63. return true
  64. }
  65. case UUID:
  66. if rules.GetUuid() {
  67. return true
  68. }
  69. }
  70. return false
  71. }