move gotd fork into repo. (#111)
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
package gen
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-faster/errors"
|
||||
|
||||
"github.com/gotd/tl"
|
||||
)
|
||||
|
||||
const flagsType = "bin.Fields"
|
||||
|
||||
// fieldDef represents structDef field.
|
||||
type fieldDef struct {
|
||||
// Name of field. Should be in camel case.
|
||||
Name string
|
||||
// Comment for field. Currently only one-line.
|
||||
Comment []string
|
||||
// Type is go type for field.
|
||||
Type string
|
||||
// Func is name for bin.* functions, e.g. String will render
|
||||
// to bin.Buffer.String and bin.Buffer.PutString.
|
||||
Func string
|
||||
// Encoder denotes whether fieldDef implements bin.Encoder and bin.Decoder.
|
||||
Encoder bool
|
||||
// RawName is raw name from TL Schema.
|
||||
RawName string
|
||||
// RawType is type from TL Schema.
|
||||
RawType string
|
||||
// BareVector denotes whether fieldDef TL type is a bare vector.
|
||||
BareVector bool
|
||||
// Vector denotes whether fieldDef TL type is vector.
|
||||
Vector bool
|
||||
// DoubleVector denotes whether fieldDef TL type is vector of vectors.
|
||||
DoubleVector bool
|
||||
// Slice denotes whether slice should be used for this field.
|
||||
Slice bool
|
||||
// DoubleSlice denotes whether double slicing should be used, e.g. [][]bytes.
|
||||
DoubleSlice bool
|
||||
// BareEncoder denotes whether field type should use bare encoder.
|
||||
BareEncoder bool
|
||||
// Interface is name of interface type if field type is constructor.
|
||||
Interface string
|
||||
// InterfaceFunc is encoding func postfix if Interface is set.
|
||||
InterfaceFunc string
|
||||
// Conditional denotes whether fieldDef is conditional.
|
||||
Conditional bool
|
||||
// ConditionalField if name of bitset param.
|
||||
ConditionalField string
|
||||
// ConditionalIndex is fieldDef bit in ConditionalField.
|
||||
ConditionalIndex int
|
||||
// ConditionalBool denotes whether value is fully encoded in ConditionalField as bit.
|
||||
ConditionalBool bool
|
||||
// Links from documentation
|
||||
Links []string
|
||||
}
|
||||
|
||||
type fieldPair struct {
|
||||
L, R fieldDef
|
||||
}
|
||||
|
||||
func (f fieldDef) String() string {
|
||||
b := strings.Builder{}
|
||||
b.Grow(len(f.Name) + len(f.Type) + 16)
|
||||
b.WriteString(f.Name)
|
||||
b.WriteByte(' ')
|
||||
|
||||
switch {
|
||||
case f.Slice || f.Vector:
|
||||
b.WriteString("[]")
|
||||
case f.DoubleSlice || f.DoubleVector:
|
||||
b.WriteString("[][]")
|
||||
}
|
||||
b.WriteString(f.Type)
|
||||
switch {
|
||||
case f.Conditional:
|
||||
b.WriteString("?")
|
||||
case f.ConditionalBool:
|
||||
b.WriteString("?true")
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (f fieldDef) SameType(b fieldDef) bool {
|
||||
return f.Type == b.Type &&
|
||||
f.Func == b.Func &&
|
||||
f.Vector == b.Vector &&
|
||||
f.DoubleVector == b.DoubleVector &&
|
||||
f.Slice == b.Slice &&
|
||||
f.DoubleSlice == b.DoubleSlice
|
||||
}
|
||||
|
||||
func (f fieldDef) EqualAsField(b fieldDef) bool {
|
||||
return f.Name == b.Name &&
|
||||
f.SameType(b) &&
|
||||
f.Interface == b.Interface &&
|
||||
f.InterfaceFunc == b.InterfaceFunc &&
|
||||
f.Conditional == b.Conditional &&
|
||||
f.ConditionalBool == b.ConditionalBool
|
||||
}
|
||||
|
||||
// nolint:gocognit,gocyclo
|
||||
//
|
||||
// TODO(ernado) Split into multiple sections: base type, encoder and conditional.
|
||||
func (g *Generator) makeField(param tl.Parameter, annotations []tl.Annotation) (fieldDef, error) {
|
||||
const bareVectorName = "vector"
|
||||
|
||||
f := fieldDef{
|
||||
Name: pascal(param.Name),
|
||||
RawName: param.Name,
|
||||
RawType: param.Type.String(),
|
||||
}
|
||||
// Unwrapping up to 2 levels of vectors.
|
||||
baseType := param.Type
|
||||
for _, a := range annotations {
|
||||
if a.Name == param.Name {
|
||||
if a.Value != "" {
|
||||
f.Comment = []string{a.Value}
|
||||
}
|
||||
}
|
||||
}
|
||||
if baseType.Name == bareVectorName || baseType.Name == "Vector" {
|
||||
f.BareVector = baseType.Name == bareVectorName
|
||||
baseType = *baseType.GenericArg
|
||||
f.Vector = true
|
||||
f.Slice = true
|
||||
f.BareVector = f.BareVector || baseType.Percent
|
||||
}
|
||||
if baseType.Name == bareVectorName || baseType.Name == "Vector" {
|
||||
baseType = *baseType.GenericArg
|
||||
f.DoubleSlice = true
|
||||
f.DoubleVector = true
|
||||
}
|
||||
if param.Flags {
|
||||
f.Type = flagsType
|
||||
}
|
||||
f.Type = baseType.Name
|
||||
switch baseType.Name {
|
||||
case "int":
|
||||
f.Func = "Int"
|
||||
case "int32":
|
||||
f.Func = "Int32"
|
||||
case "int128":
|
||||
f.Func = "Int128"
|
||||
f.Type = "bin.Int128"
|
||||
case "int256":
|
||||
f.Func = "Int256"
|
||||
f.Type = "bin.Int256"
|
||||
case "double":
|
||||
f.Func = "Double"
|
||||
f.Type = "float64"
|
||||
case "int53":
|
||||
f.Func = "Int53"
|
||||
f.Type = "int64"
|
||||
case "long", "int64":
|
||||
f.Func = "Long"
|
||||
f.Type = "int64"
|
||||
case "string":
|
||||
f.Func = "String"
|
||||
case "Bool", "bool", "true", "false":
|
||||
f.Func = "Bool"
|
||||
f.Type = "bool"
|
||||
case "bytes":
|
||||
f.Func = "Bytes"
|
||||
f.Type = "byte"
|
||||
if f.Slice {
|
||||
f.DoubleSlice = true
|
||||
}
|
||||
f.Slice = true
|
||||
default:
|
||||
f.Encoder = true
|
||||
f.BareEncoder = f.BareVector
|
||||
|
||||
if param.Flags {
|
||||
f.Type = flagsType
|
||||
break
|
||||
}
|
||||
|
||||
if baseType.Bare {
|
||||
// Using exact go type for bare types.
|
||||
tn := strings.TrimPrefix(baseType.String(), "%")
|
||||
t, ok := g.types[tn]
|
||||
if !ok {
|
||||
return fieldDef{}, errors.Errorf("types[%s] not found", baseType)
|
||||
}
|
||||
f.Type = t.Name
|
||||
} else {
|
||||
// Type is generic.
|
||||
t, ok := g.classes[baseType.String()]
|
||||
if param.Type.GenericRef {
|
||||
ok = true
|
||||
t.RawType = param.Type.Name
|
||||
t.Name = "bin.Object"
|
||||
}
|
||||
if !ok {
|
||||
return fieldDef{}, errors.Errorf("classes[%s] not found", baseType)
|
||||
}
|
||||
f.Type = t.Name
|
||||
if !baseType.Percent && t.Singular && !param.Type.GenericRef {
|
||||
f.BareEncoder = false
|
||||
}
|
||||
if !t.Singular && !param.Type.GenericRef {
|
||||
f.Interface = t.Name
|
||||
f.InterfaceFunc = t.Func
|
||||
}
|
||||
}
|
||||
}
|
||||
if flag := param.Flag; flag != nil {
|
||||
f.Conditional = true
|
||||
f.ConditionalIndex = flag.Index
|
||||
f.ConditionalField = pascal(flag.Name)
|
||||
if f.Type == "bool" && !f.Vector && baseType.Name == "true" {
|
||||
f.ConditionalBool = true
|
||||
}
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
Reference in New Issue
Block a user