[#77] protogen: Initial implementation
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
a28ceb251a
commit
adb7c602d7
115 changed files with 36376 additions and 20397 deletions
124
util/protogen/internalgengo/proto_stable_compat.go
Normal file
124
util/protogen/internalgengo/proto_stable_compat.go
Normal file
|
@ -0,0 +1,124 @@
|
|||
package internalgengo
|
||||
|
||||
import (
|
||||
"google.golang.org/protobuf/compiler/protogen"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
var protowirePackage = protogen.GoImportPath("google.golang.org/protobuf/encoding/protowire")
|
||||
|
||||
func emitStableSize(g *protogen.GeneratedFile, msg *protogen.Message) {
|
||||
fs := sortFields(msg.Fields)
|
||||
|
||||
g.P("// StableSize returns the size of x in protobuf format.")
|
||||
g.P("//")
|
||||
g.P("// Structures with the same field values have the same binary size.")
|
||||
g.P("func (x *", msg.GoIdent.GoName, ") StableSize() (size int) {")
|
||||
g.P("if x == nil { return 0 }")
|
||||
if len(fs) != 0 {
|
||||
for _, f := range fs {
|
||||
if f.Desc.IsList() && marshalers[f.Desc.Kind()].RepeatedDouble && !(f.Desc.Kind() == protoreflect.Uint64Kind && !f.Desc.IsPacked()) {
|
||||
g.P("var n int")
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, f := range fs {
|
||||
emitFieldSize(g, f)
|
||||
}
|
||||
}
|
||||
g.P("return size")
|
||||
g.P("}\n")
|
||||
}
|
||||
|
||||
func emitSignatureMethods(g *protogen.GeneratedFile, msg *protogen.Message) {
|
||||
// SignedDataSize implementation (only for requests and responses).
|
||||
g.P("// ReadSignedData fills buf with signed data of x.")
|
||||
g.P("// If buffer length is less than x.SignedDataSize(), new buffer is allocated.")
|
||||
g.P("//")
|
||||
g.P("// Returns any error encountered which did not allow writing the data completely.")
|
||||
g.P("// Otherwise, returns the buffer in which the data is written.")
|
||||
g.P("//")
|
||||
g.P("// Structures with the same field values have the same signed data.")
|
||||
g.P("func (x *", msg.GoIdent.GoName, ") SignedDataSize() int {")
|
||||
g.P("return x.GetBody().StableSize()")
|
||||
g.P("}\n")
|
||||
|
||||
// ReadSignedData implementation (only for requests and responses).
|
||||
g.P("// SignedDataSize returns size of the request signed data in bytes.")
|
||||
g.P("//")
|
||||
g.P("// Structures with the same field values have the same signed data size.")
|
||||
g.P("func (x *", msg.GoIdent.GoName, ") ReadSignedData(buf []byte) ([]byte, error) {")
|
||||
g.P("return x.GetBody().MarshalProtobuf(buf), nil")
|
||||
g.P("}\n")
|
||||
}
|
||||
|
||||
func emitFieldSize(g *protogen.GeneratedFile, f *protogen.Field) {
|
||||
m := marshalers[f.Desc.Kind()]
|
||||
if m.Prefix == "" {
|
||||
g.P("// FIXME missing field marshaler: ", f.GoName, " of type ", f.Desc.Kind().String())
|
||||
g.P(`panic("unimplemented")`)
|
||||
return
|
||||
}
|
||||
|
||||
name := castFieldName(f)
|
||||
if f.Oneof != nil {
|
||||
name = "x." + f.Oneof.GoName
|
||||
g.P("if inner, ok := ", name, ".(*", f.GoIdent.GoName, "); ok {")
|
||||
defer g.P("}")
|
||||
name = "inner." + f.GoName
|
||||
}
|
||||
|
||||
switch {
|
||||
case f.Desc.IsList() && (f.Desc.Kind() == protoreflect.MessageKind || f.Desc.Kind() == protoreflect.Uint64Kind && !f.Desc.IsPacked()):
|
||||
g.P("for i := range ", name, "{")
|
||||
if f.Desc.Kind() == protoreflect.MessageKind {
|
||||
g.P("size += ", protoPackage.Ident("NestedStructureSize"), "(", f.Desc.Number(), ", ", name, "[i])")
|
||||
} else {
|
||||
if f.Desc.Kind() != protoreflect.Uint64Kind {
|
||||
panic("only uint64 unpacked primitive is supported")
|
||||
}
|
||||
|
||||
g.P("size += ", protowirePackage.Ident("SizeGroup"), "(",
|
||||
protowirePackage.Ident("Number"), "(", f.Desc.Number(), "), ",
|
||||
protowirePackage.Ident("SizeVarint"), "(", name, "[i]))")
|
||||
}
|
||||
g.P("}")
|
||||
|
||||
case f.Desc.IsList():
|
||||
if m.RepeatedDouble {
|
||||
g.P("n, _ = ", protoPackage.Ident("Repeated"+m.Prefix+"Size"), "(", f.Desc.Number(), ", ", name, ")")
|
||||
g.P("size += n")
|
||||
} else {
|
||||
g.P("size += ", protoPackage.Ident("Repeated"+m.Prefix+"Size"), "(", f.Desc.Number(), ", ", name, ")")
|
||||
}
|
||||
default:
|
||||
g.P("size += ", protoPackage.Ident(m.Prefix+"Size"), "(", f.Desc.Number(), ", ", name, ")")
|
||||
}
|
||||
}
|
||||
|
||||
type marshalerDesc struct {
|
||||
Prefix string
|
||||
RepeatedDouble bool
|
||||
}
|
||||
|
||||
// Unused kinds are commented.
|
||||
var marshalers = map[protoreflect.Kind]marshalerDesc{
|
||||
protoreflect.BoolKind: {Prefix: "Bool"},
|
||||
protoreflect.EnumKind: {Prefix: "Enum"},
|
||||
protoreflect.Int32Kind: {Prefix: "Int32", RepeatedDouble: true},
|
||||
// protoreflect.Sint32Kind: "",
|
||||
protoreflect.Uint32Kind: {Prefix: "UInt32", RepeatedDouble: true},
|
||||
protoreflect.Int64Kind: {Prefix: "Int64", RepeatedDouble: true},
|
||||
// protoreflect.Sint64Kind: "",
|
||||
protoreflect.Uint64Kind: {Prefix: "UInt64", RepeatedDouble: true},
|
||||
// protoreflect.Sfixed32Kind: "",
|
||||
protoreflect.Fixed32Kind: {Prefix: "Fixed32", RepeatedDouble: true},
|
||||
// protoreflect.FloatKind: "",
|
||||
// protoreflect.Sfixed64Kind: "",
|
||||
protoreflect.Fixed64Kind: {Prefix: "Fixed64", RepeatedDouble: true},
|
||||
protoreflect.DoubleKind: {Prefix: "Float64"},
|
||||
protoreflect.StringKind: {Prefix: "String"},
|
||||
protoreflect.BytesKind: {Prefix: "Bytes"},
|
||||
protoreflect.MessageKind: {Prefix: "NestedStructure"},
|
||||
// protoreflect.GroupKind: "",
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue