Description
Hi. Recently I generated golang code and discovered that it didn't compile. The problem seems quite severe - no <set>
element can be correctly generated. But it's actually quite easy to fix.
Schema:
<set name="OrderFlags" encodingType="uint64">
<choice name="SomeVal">0</choice>
...
</set>
Generated code:
type OrderFlags [64]bool
type OrderFlagsChoiceValue uint8
type OrderFlagsChoiceValues struct{
SomeVal OrderFlagsChoiceValue
...
var OrderFlagsChoice = OrderFlagsChoiceValues{uint64(0), uint64(1) ...}
Now, this has no chance of being compiled because uint64
cannot be converted into OrderFlagsChoiceValue
since in golang those are different types. The last line therefore raises an error. I suspect that the intention was to generate something like this:
var OrderFlagsChoice = OrderFlagsChoiceValues{OrderFlagsChoiceValue(0), OrderFlagsChoiceValue(1) ...}
Or just the numbers as golang considers numbers to be "untyped".
Aside from the main issue: I have a question about the implementation. Since the generated code does not work anyway, could we replace it with something more efficient? If you have a look at the implementation of the Encode()
and Decode()
methods, you will quickly spot that the algorithm iterates 64 times over the array to generate just one set element. For a low level protocol such a SBE this operation seems to be way more costly than any other element of SBE. Instead you could just use standard binary operations.
Rough proposal:
type OrderFlags uint64
type OrderFlagsChoiceValues struct {
SomeVal OrderFlags
....
var OrderFlagsChoice = OrderFlagsChoiceValues{
SomeVal = 1 << 0,
...
// example use
msg.OrderFlags = proto.OrderFlagsChoice.SomeVal | proto.OrderFlagsChoice.SomeOtherVal
// check if set
if ((msg.OrderFlags & proto.OrderFlagsChoice.SomeVal) != 0){
Even move golangish
version and probably a bit faster (but less consistent with other generated code):
type OrderFlags uint64
const OrderFlagsSomeVal OrderFlags = 1 << 0
....
msg.OrderFlags = proto.OrderFlagsSomeVal | proto.OrderFlagsSomeOtherVal
This way encoding and decoding becomes just a direct write of 8 bytes .