Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protoc-gen-go: support generating standard Go types in place of well-known-types #414

Open
jhump opened this issue Aug 16, 2017 · 10 comments
Labels
generator-proto-option involves generators respecting a proto option to control generated source output proposal proposal-hold
Milestone

Comments

@jhump
Copy link
Contributor

jhump commented Aug 16, 2017

This is quite similar in spirit to protocolbuffers/protobuf#2055 (which is for the Java protobuf codegen and runtime).

Protos would be easier to integrate with Go libraries that rely on struct reflection (serialization, ORM, etc) if struct fields used standard Go types in place of some of the well-known types:

  • google.protobuf.Timestamp -> time.Time
  • google.protobuf.Duration -> time.Duration
  • google.protobuf.Int32Value -> *int32
  • google.protobuf.Int64Value -> *int64
  • google.protobuf.UInt32Value -> *uint32
  • google.protobuf.UInt64Value -> *uint64
  • google.protobuf.FloatValue -> *float32
  • google.protobuf.DoubleValue -> *float64
  • google.protobuf.BoolValue -> *bool
  • google.protobuf.StringValue -> *string
  • google.protobuf.BytesValue -> []byte

(For the lattermost one, we could distinguish a missing/default value from a BytesValue message that contained an empty Value field by assuming nil means absent and otherwise empty slice is a message with an empty value.)

Other solutions we've had to use to work around this (mostly the timestamp and duration ones):

  • Creating a parallel struct that mirrors the generated proto, but with the above type swaps. Implement adapter methods to translate between the proto and the parallel type. While this can be done via codegen, we find ourselves doing it by hand more often than not.
  • If the library allows customized representation (via a Marshaler or Saver sort of interface), write a reflection-based library that will recursively apply the transformations to a proto when generating the marshaled/saved form.
  • Use JSON as a go-between. The JSON format for well-known-types matches the type expectations pretty well, so marshalling the proto to JSON and then to map[string]interface{} often does the trick. Timestamps are not converted correctly, but for libraries that are applying the data to a schema, they can typically handle parsing the string, without any extra effort, for fields where a timestamp value is expected.

Since it would impact compatibility, it could be an opt-in flag that changes the output of codegen. The runtime library could probably be updated to accommodate without any compatibility issues (e.g. could just examine the type of a field to make decisions or, if it's more efficient, could encode more bits into the struct tag so that the library knows what to do without extra reflection steps).

@dsnet dsnet added the proposal label Dec 6, 2017
@dsnet dsnet changed the title Option to use standard Go types in place of well-known-types proposal: protoc-gen-go: support generating standard Go types in place of well-known-types Feb 13, 2018
@dsnet
Copy link
Member

dsnet commented Mar 8, 2018

Just wanted to note that it would have to be *time.Duration in order to preserve the fact that proto has a distinction between the zero duration and an unset duration.

@dsnet dsnet added the generator-proto-option involves generators respecting a proto option to control generated source output label Mar 10, 2018
@sanjaypsmc
Copy link

Hi, is there any update on this? Are there third-party options? If I wanted to implement it myself, what would the level of effort look like and would that necessitate a fork? Since this has been outstanding for nearly a year, it'd be great to get a comment from a maintainer on how much of a priority it is and whether there's a timeline in place. Thanks!

@dsnet
Copy link
Member

dsnet commented Aug 2, 2018

This proposal is on hold until reflection work is finished (see #364) as generating native Go types will need to inter-operate with proto reflection in a reasonable way.

@johanbrandhorst
Copy link
Member

@sanjaypsmc gogo/protobuf has supported timestamp and duration for a while, but using gogo over golang/protobuf is not a choice without other consequences. At this point you might just want to wait until the work in #364 has been completed.

@dsnet dsnet changed the title proposal: protoc-gen-go: support generating standard Go types in place of well-known-types protoc-gen-go: support generating standard Go types in place of well-known-types Mar 4, 2020
@nwparker
Copy link

nwparker commented Apr 9, 2020

Hey, now that work on #364 is complete, is it reasonable to see work started back on this item? Or are there additional blockers?

@tgulacsi
Copy link

tgulacsi commented Nov 7, 2021

This would be very nice!
Till that, can we add database/sql.Scanner, database/sql/driver.Valuer, proper MarshalJSON, UnmarshalJSON, MarshalText, UnmarshalText to these WKTs?
It's only a handful of lines (github.com/UNO-SOFT/knownpb/timestamppb for example), and would alleviate the grudge induced by sed-ing the generated files' imports (https://github.com/UNO-SOFT/knownpb/blob/main/replace_timestamp.sh)...

Shall I open a new issue for this?

@baryluk
Copy link

baryluk commented May 12, 2022

Is there any recent work on this? Most interested in Duration and Time

@james-lawrence
Copy link

this is a very much needed improvement. the way golang protobufs handles these types is incredibly painful for interop.

@hariso
Copy link

hariso commented Mar 22, 2023

+1 from me as well. I'm interested in time.Time. Are there any plans to support slices and maps as well?

@mesmerx
Copy link

mesmerx commented May 10, 2024

+1 to not let it die, time.Time will be a world savior for all my work, with it i can set all database schema with protos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generator-proto-option involves generators respecting a proto option to control generated source output proposal proposal-hold
Projects
None yet
Development

No branches or pull requests

10 participants