-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
internal/impl: implement support for non-pointer message fields #1142
Comments
This project only provides backwards compatibility for messages generated by
This project does not have support for the "non-nullable" feature in On the user end, the problem should be addressed by calling In the distant future, if the maintainers of |
We’re currently using a number of Google Cloud APIs, which are migrating to the new v2 API, and currently have a hack in our
The fact that this module (
That’s actually…not true. The panic here proves that. Option 1 above would be significantly easier if the Go protobuf library added support for these features, most of which are already present in other languages’ protobuf libraries:
|
In this case, distant == indefinite. The maintainers of GoGo Protobuf are no longer able to maintain the project: gogo/protobuf#691 |
It was a typo. I meant to say it does not have support. |
It is unlikely that we provide support for those features. See https://developers.google.com/protocol-buffers/docs/reference/go/faq#new-feature. Philosophically, this project prioritizes adherence to the wider protobuf ecosystem and deliberately does not treat Go as a special snowflake that gets to have many special features that the other language implementation does not have. I understand this stance is contrary to what some Go users would prefer, but that is how it is. |
Fair enough. However, #52 and #555 seem like a bare minimum of interacting well in the Go ecosystem, not "special" features. Please reconsider your stance here. It appears extremely hard-line and closed-minded to state that the project philosophically disagrees with adding anything specific to Go. |
I would strongly encourage you reconsider your choice of language (“special snowflake”) right now. It does more harm than good, and actively discourages folks from wanting to contribute, much less participate here. |
I understand, but there are other factors at play. If protobufs were a technology invented by the Go project, we would have more freedom in choosing our stance on things. However, that is not the case. Go protobufs happens to be implemented by members of members of the Go team, but the overall direction of the project fundamentally is determined by the primary protobuf project. No amount of convincing will change this since it is not something we have power to decide. |
I understand you feel you have no power to change the decision of the protobuf team. I think you missed the point about your language (not Go) choices in the discussion above. |
I don't really understand what this sentence means. |
One thing, however, is entirely within your power: add hooks to I’ve already forked The argument put forth here is specious. Language-specific implementation details have nothing to do with the protocol interop, but rather conforming to the language ecosystem a developer chooses to work in. By all means, don’t add |
Didn't think I'd have to point out why, but OK. The term is, unfortunately, now politicized and often used in derogatory sense, which seems inconsistent with the Go code of conduct. |
That is not the stance of the protobuf project. They care about consistency even in the generated API that most target languages use. You are free to disagree. I should also note that features like #52 and #555 require something to be specified in the .proto file, which is pretty clearly in the territory that the protobuf project cares about.
Two thoughts:
Thanks for pointing that out. I was not aware of the etymology of the term (hence my confusion about what your sentence meant) which are very unfortunate and sad. My intention with the phrase is to simply indicate something "unique and specialized" (not in a derogatory sense) based on the popular science fact that every snowflake is unique. |
As a contributor to Swift Protobuf, I will happily disagree. This implementation has several ergonomic features that improve its usability by doing more than the least-common-denominator API.
Can you promote the quasi-internal |
Examples? A glance over |
Here’s a quick example that cribs some internal code from The body of the file is copied from the main Adding a I’m trying to avoid folks needing to fork this repo to get egonomic Go output from |
The approach taken in https://gist.github.com/ydnar/327d33e4c9fa54f08b6d7f0e31880bf7 seems functionally equivalent to hooks in that it imposes maintainability problems down the line. The Also, I think an example that implements #52 would have been more compelling since |
|
Heck, just fixing the But to your core argument of “maintainability costs:” the choice of this team to not use the Go module |
Let's think this through. Users want to avoid forking Above, @ydnar's gist forks Consider promoting at least portions of Take as an example I'll stop here before trying to construct an example for #555 or writing code for the above suggestion to get your response. |
And just for clarity, |
This issue has ranged around a bit, but as I understand it, the feature request is to support generated messages produced by the gogoprotobuf fork of the code generator. The compatibility guarantee for the Go protobuf implementation states:
While we only guarantee support for generated code produced by a Unfortunately, we are unable to provide support for generated code not produced by a version of We do support any type that implements the The gogoprotobuf project includes forks of both I realize this isn't going to make gogoprotobuf users happy, but we simply don't have the ability to provide any reasonable level of support for non-standard generated code. |
I agree that this issue has meandered, but the current title
Completely understand this stance. In fact, I don't believe those discussing this issue are requesting compatibility with gogoprotobuf, rather they are asking for this generator to support several specific ergonomic features that cannot be implemented by creating a supplementary generator (a la Speaking for myself, I would be happy to no longer be a gogoprotobuf user if certain ergonomic needs were able to be met by using Regarding other topics covered in the discussion here, perhaps new issues should be created to address the unacceptable parts of #52 and #555 and offer modified proposals that don't introduce changes to
|
To further clarify what we’re asking for: We want to be able to implement a subset of what GoGo Protobuf provides without having to fork the entire protobuf-go repo and The |
The OP of this issue is about supporting generated messages produced by gogoproto's fork of the code generator. I think that rather than trying to repurpose this issue, it'll be clearer to create new ones for any specific generator feature requests. For the specific case of representing |
The original request was to remove a panic stemming from an assumption that a non-basic typed field is a pointer. The message in question is a proto3, not proto2, and this was for an internal API where the value was represented as a The Go Given that idiomatic Go suggests that the zero value of a struct should be useful where possible, and that Go is garbage-collected, reducing the number of pointers (and allocs) is a reasonable goal. Especially if the use case doesn’t need to discriminate between the (non-)presence of a field and the zero value. |
I see. The protobuf code generator has never created Unfortunately, as I said above, we are unable to provide support for generated code not produced by a version of |
Okay—how about a hook in Ultimately, if your answer is just “fork the repo if you want those features,” then just say so, close #52 and #555, and get rid of the TODO in |
We are heavily leaning towards that option. There's not really a good way to expose hooks in a way that will not be regularly broken by changes to the internal implementation of the generator. I should note that I was the one who proposed #555, and I personally have some interest in seeing it provided. However, I also understand the reasons not to provide it. We're not holding back on features to be rude or deliberately cause users pain. Engineering is about trade-offs. Every feature has benefits and costs; they must be evaluated.
If we decide that we definitely will not do #52 and #555, we will remove that TODO. |
I note that the first question on #555 that appears not to have been answered is from @neild:
Are extension options more generally palatable? We've established that the protobuf team are not interested in additions to |
In some ways yes, and in other ways no. Consider the following message MyMessage {
// With options declared in descriptor.proto.
optional int32 my_field1 [cpp_name = "custom_name", java_name = "custom_name", ruby_name = "custom_name", go_name = "custom_name", python_name = "custom_name"];
// With options declared as extensions to descriptor.proto.
optional int32 my_field2 [(cpp.name) = "custom_name", (java.name) = "custom_name", (ruby.name) = "custom_name", (go.name) = "custom_name", (python.name) = "custom_name"];
} The concern about allowing name overrides is the proliferation of similar options in all languages and the readability detriments it brings to the .proto source files. It seems that the same concern occurs regardless of whether the option is a declared option in |
I think the usability costs for engineers working with generated types outweighs minor complexity in the proto files. The lack of go_tags alone requires any user of this library to build parallel adapter structs if struct tags are needed. |
Generating better names will in many cases eliminate the need to use an option, if one were available, to change the struct field name. That would reduce the problem of .proto file readability. |
Closing: The initial issue here is about supporting generated code not produced by |
We’re in the process of migrating from
github.com/golang/protobuf
to the v2 API (google.golang.org/protobuf
) and hit a panic when usingproto.Equal
to compare protos.We traced the issue to a use of
(reflect.Value).IsNil()
here: https://github.com/protocolbuffers/protobuf-go/blob/1f5b6fe64530cac2061a3d315b7e44966b1a200b/internal/impl/message_reflect_field.go#L386-L392(reflect.Value).IsNil()
panics when the underlying value is not a pointer type (e.g. struct pointer, channel, slice, map, etc.).It looks like v2’s internal API assumes that all non-scalar values are pointers, which in this case is not true—we’re using GoGo Protobuf’s feature of non-nullable fields in most of our messages, primarily
time.Time
values and occasional struct value where we don’t want the additional GC load.We forked this and replaced the
IsNil
call withIsZero
, which in this use case works correctly. Suggestion: swap out calls toIsNil
with calls toIsZero
to prevent this runtime panic and work correctly with legacy v1 protos.Additionally, it looks like this package reimplements
IsZero
to some extent here: https://github.com/protocolbuffers/protobuf-go/blob/1f5b6fe64530cac2061a3d315b7e44966b1a200b/internal/descfmt/stringer.go#L224-L243Thanks!
The text was updated successfully, but these errors were encountered: