Skip to content

Commit

Permalink
chore(internal/protoveneer): generate support functions (#10416)
Browse files Browse the repository at this point in the history
Generate the support functions along with the rest of the code,
instead of requiring a separate package.
  • Loading branch information
jba authored Jun 24, 2024
1 parent eba8727 commit 9eb4d2a
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 87 deletions.
2 changes: 0 additions & 2 deletions internal/protoveneer/cmd/protoveneer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import (
type config struct {
Package string
ProtoImportPath string `yaml:"protoImportPath"`
// Import path for the support package needed by the generated code.
SupportImportPath string `yaml:"supportImportPath"`

// The types to process. Only these types and the types they depend
// on will be output.
Expand Down
28 changes: 20 additions & 8 deletions internal/protoveneer/cmd/protoveneer/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,18 @@ func (identityConverter) genTransformTo() string { return "" }
// A derefConverter converts between T in the veneer and *T in the proto.
type derefConverter struct{}

func (derefConverter) genFrom(arg string) string { return fmt.Sprintf("support.DerefOrZero(%s)", arg) }
func (derefConverter) genTo(arg string) string { return fmt.Sprintf("support.AddrOrNil(%s)", arg) }
func (derefConverter) genTransformFrom() string { panic("can't handle deref slices") }
func (derefConverter) genTransformTo() string { panic("can't handle deref slices") }
func (derefConverter) genFrom(arg string) string {
needSupport("pvDerefOrZero")
return fmt.Sprintf("pvDerefOrZero(%s)", arg)
}

func (derefConverter) genTo(arg string) string {
needSupport("pvAddrOrNil")
return fmt.Sprintf("pvAddrOrNil(%s)", arg)
}

func (derefConverter) genTransformFrom() string { panic("can't handle deref slices") }
func (derefConverter) genTransformTo() string { panic("can't handle deref slices") }

type enumConverter struct {
protoName, veneerName string
Expand Down Expand Up @@ -105,14 +113,16 @@ type sliceConverter struct {

func (c sliceConverter) genFrom(arg string) string {
if fn := c.eltConverter.genTransformFrom(); fn != "" {
return fmt.Sprintf("support.TransformSlice(%s, %s)", arg, fn)
needSupport("pvTransformSlice")
return fmt.Sprintf("pvTransformSlice(%s, %s)", arg, fn)
}
return c.eltConverter.genFrom(arg)
}

func (c sliceConverter) genTo(arg string) string {
if fn := c.eltConverter.genTransformTo(); fn != "" {
return fmt.Sprintf("support.TransformSlice(%s, %s)", arg, fn)
needSupport("pvTransformSlice")
return fmt.Sprintf("pvTransformSlice(%s, %s)", arg, fn)
}
return c.eltConverter.genTo(arg)
}
Expand All @@ -132,14 +142,16 @@ type mapConverter struct {

func (c mapConverter) genFrom(arg string) string {
if fn := c.valueConverter.genTransformFrom(); fn != "" {
return fmt.Sprintf("support.TransformMapValues(%s, %s)", arg, fn)
needSupport("pvTransformMapValues")
return fmt.Sprintf("pvTransformMapValues(%s, %s)", arg, fn)
}
return c.valueConverter.genFrom(arg)
}

func (c mapConverter) genTo(arg string) string {
if fn := c.valueConverter.genTransformTo(); fn != "" {
return fmt.Sprintf("support.TransformMapValues(%s, %s)", arg, fn)
needSupport("pvTransformMapValues")
return fmt.Sprintf("pvTransformMapValues(%s, %s)", arg, fn)
}
return c.valueConverter.genTo(arg)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package support provides support functions for protoveneer.
// Package support provides support functions for protoveneer. The protoveneer binary
// embeds it and extracts the needed functions when generating code.
//
// This package should not be imported. It is written as an ordinary Go package so
// it can be edited and tested with standard tools.
//
// The symbols begin with "pv" to reduce the chance of collision when the generated
// code is combined with user-written code in the same package.
package support

import (
Expand All @@ -29,9 +36,9 @@ import (
"google.golang.org/protobuf/types/known/timestamppb"
)

// TransformSlice applies f to each element of from and returns
// pvTransformSlice applies f to each element of from and returns
// a new slice with the results.
func TransformSlice[From, To any](from []From, f func(From) To) []To {
func pvTransformSlice[From, To any](from []From, f func(From) To) []To {
if from == nil {
return nil
}
Expand All @@ -42,9 +49,9 @@ func TransformSlice[From, To any](from []From, f func(From) To) []To {
return to
}

// TransformMapValues applies f to each value of from, returning a new map.
// pvTransformMapValues applies f to each value of from, returning a new map.
// It does not change the keys.
func TransformMapValues[K comparable, VFrom, VTo any](from map[K]VFrom, f func(VFrom) VTo) map[K]VTo {
func pvTransformMapValues[K comparable, VFrom, VTo any](from map[K]VFrom, f func(VFrom) VTo) map[K]VTo {
if from == nil {
return nil
}
Expand All @@ -55,37 +62,37 @@ func TransformMapValues[K comparable, VFrom, VTo any](from map[K]VFrom, f func(V
return to
}

// AddrOrNil returns nil if x is the zero value for T,
// pvAddrOrNil returns nil if x is the zero value for T,
// or &x otherwise.
func AddrOrNil[T comparable](x T) *T {
func pvAddrOrNil[T comparable](x T) *T {
var z T
if x == z {
return nil
}
return &x
}

// DerefOrZero returns the zero value for T if x is nil,
// pvDerefOrZero returns the zero value for T if x is nil,
// or *x otherwise.
func DerefOrZero[T any](x *T) T {
func pvDerefOrZero[T any](x *T) T {
if x == nil {
var z T
return z
}
return *x
}

// CivilDateToProto converts a civil.Date to a date.Date.
func CivilDateToProto(d civil.Date) *date.Date {
// pvCivilDateToProto converts a civil.Date to a date.Date.
func pvCivilDateToProto(d civil.Date) *date.Date {
return &date.Date{
Year: int32(d.Year),
Month: int32(d.Month),
Day: int32(d.Day),
}
}

// CivilDateFromProto converts a date.Date to a civil.Date.
func CivilDateFromProto(p *date.Date) civil.Date {
// pvCivilDateFromProto converts a date.Date to a civil.Date.
func pvCivilDateFromProto(p *date.Date) civil.Date {
if p == nil {
return civil.Date{}
}
Expand All @@ -96,8 +103,8 @@ func CivilDateFromProto(p *date.Date) civil.Date {
}
}

// MapToStructPB converts a map into a structpb.Struct.
func MapToStructPB(m map[string]any) *structpb.Struct {
// pvMapToStructPB converts a map into a structpb.Struct.
func pvMapToStructPB(m map[string]any) *structpb.Struct {
if m == nil {
return nil
}
Expand All @@ -108,40 +115,40 @@ func MapToStructPB(m map[string]any) *structpb.Struct {
return s
}

// MapFromStructPB converts a structpb.Struct to a map.
func MapFromStructPB(p *structpb.Struct) map[string]any {
// pvMapFromStructPB converts a structpb.Struct to a map.
func pvMapFromStructPB(p *structpb.Struct) map[string]any {
if p == nil {
return nil
}
return p.AsMap()
}

// TimeToProto converts a time.Time into a Timestamp.
func TimeToProto(t time.Time) *timestamppb.Timestamp {
// pvTimeToProto converts a time.Time into a Timestamp.
func pvTimeToProto(t time.Time) *timestamppb.Timestamp {
if t.IsZero() {
return nil
}
return timestamppb.New(t)
}

// TimeFromProto converts a Timestamp into a time.Time.
func TimeFromProto(ts *timestamppb.Timestamp) time.Time {
// pvTimeFromProto converts a Timestamp into a time.Time.
func pvTimeFromProto(ts *timestamppb.Timestamp) time.Time {
if ts == nil {
return time.Time{}
}
return ts.AsTime()
}

// APIErrorToProto converts an APIError to a proto Status.
func APIErrorToProto(ae *apierror.APIError) *spb.Status {
// pvAPIErrorToProto converts an APIError to a proto Status.
func pvAPIErrorToProto(ae *apierror.APIError) *spb.Status {
if ae == nil {
return nil
}
return ae.GRPCStatus().Proto()
}

// APIErrorFromProto converts a proto Status to an APIError.
func APIErrorFromProto(s *spb.Status) *apierror.APIError {
// pvAPIErrorFromProto converts a proto Status to an APIError.
func pvAPIErrorFromProto(s *spb.Status) *apierror.APIError {
err := gstatus.ErrorProto(s)
aerr, ok := apierror.ParseError(err, true)
if !ok {
Expand All @@ -151,8 +158,8 @@ func APIErrorFromProto(s *spb.Status) *apierror.APIError {
return aerr
}

// DurationFromProto converts a Duration proto to a time.Duration.
func DurationFromProto(d *durationpb.Duration) time.Duration {
// pvDurationFromProto converts a Duration proto to a time.Duration.
func pvDurationFromProto(d *durationpb.Duration) time.Duration {
if d == nil {
return 0
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ import (

func TestTransformMapValues(t *testing.T) {
var from map[string]int
got := TransformMapValues(from, strconv.Itoa)
got := pvTransformMapValues(from, strconv.Itoa)
if got != nil {
t.Fatalf("got %v, want nil", got)
}
from = map[string]int{"one": 1, "two": 2}
got = TransformMapValues(from, strconv.Itoa)
got = pvTransformMapValues(from, strconv.Itoa)
want := map[string]string{"one": "1", "two": "2"}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
Expand All @@ -57,7 +57,7 @@ func TestAPIError(t *testing.T) {
Details: []*anypb.Any{pbany},
}

ae := APIErrorFromProto(s)
ae := pvAPIErrorFromProto(s)
if ae == nil {
t.Fatal("got nil")
}
Expand All @@ -72,7 +72,7 @@ func TestAPIError(t *testing.T) {
t.Errorf("got %q, want %q", g, reason)
}

gps := APIErrorToProto(ae)
gps := pvAPIErrorToProto(ae)
if !cmp.Equal(gps, s, cmpopts.IgnoreUnexported(spb.Status{}, anypb.Any{})) {
t.Errorf("\ngot %s\nwant %s", gps, s)
}
Expand Down
Loading

0 comments on commit 9eb4d2a

Please sign in to comment.