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:
Adam Van Ymeren
2025-06-27 20:03:37 -07:00
committed by GitHub
parent 0952df0244
commit 7a04f298d2
19264 changed files with 1539697 additions and 84 deletions
+218
View File
@@ -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
}