Protobuf: protoc-gen-go: XXX_ fields break code back compatibility

Created on 15 May 2018  路  4Comments  路  Source: golang/protobuf

having []byte XXX_ fields in generated code prevents those structs to be able to be compared by value.

package main

import (
    "fmt"
)

type Hash struct {
    XXX_NoUnkeyedLiteral struct{} `json:"-"`
    XXX_unrecognized     []byte   `json:"-"`
    XXX_sizecache        int32    `json:"-"`
}

func main() {
    fmt.Println(Hash{} == Hash{})
}

This breaks an existent code.

Another argument to the issue #276

Even if the []byte field will be removed, those third-party states being embed into the structs makes it pointless.

Most helpful comment

@dsnet Then I would say that an update to the proto3 spec broke it.

First (many moons ago) when proto2 was introduced, Optional Fields were all the rage and unrecognized fields just sit quietly in reserved by them "slots". Then proto3 came in, and put it as "optional is no more - everything is optional" (and broke separation of "not supplied" and "default" by the way). Now, by introducing XXX_ mess it pretty much went back, just storing unrecognized fields under XXX_. Again, breaking perfectly normal code that was comparing proto.Timestamp, and other simple generated structs.

proto generated code in the current form is unusable for anything but storage - with no comparison, simple, small, and fast common structures used between different components neither not small nor fast anymore.

All 4 comments

This breakage is really unfortunate, but it's a consequence of Go protobufs being compliant with the updated proto3 specification. See https://github.com/golang/protobuf/issues/594#issuecomment-386303295.

Another argument to the issue #276

This is orthogonal to #276, which is about removing XXX fields from the exported API. The implementation will still require unexported fields of some form, some of which may still be incomparable.

Just to add more on what these changes broke.

1) Generated types can NOT be used as map keys.
2) New generated code does not import go packages for imported proto types, so it just does not compile.

@dsnet Then I would say that an update to the proto3 spec broke it.

First (many moons ago) when proto2 was introduced, Optional Fields were all the rage and unrecognized fields just sit quietly in reserved by them "slots". Then proto3 came in, and put it as "optional is no more - everything is optional" (and broke separation of "not supplied" and "default" by the way). Now, by introducing XXX_ mess it pretty much went back, just storing unrecognized fields under XXX_. Again, breaking perfectly normal code that was comparing proto.Timestamp, and other simple generated structs.

proto generated code in the current form is unusable for anything but storage - with no comparison, simple, small, and fast common structures used between different components neither not small nor fast anymore.

Please see my comment here (https://github.com/golang/protobuf/issues/594#issuecomment-409009380).

Was this page helpful?
0 / 5 - 0 ratings