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
+165
View File
@@ -0,0 +1,165 @@
package gen
import (
"strings"
)
type constructorMapping struct {
// Name is go name of interface or struct.
Name string
// Constructor is go name of mapped constructor.
// May be empty.
Constructor string
// Concrete is flag which is true when Name address a struct, not interface.
Concrete bool
// MapperName is name of mapper which created this sub.
MapperName string
// Fields is slice of field mappings from this struct to target.
Fields []fieldPair
}
// interfaceDef represents generic interface, type which has multiple constructors.
type interfaceDef struct {
// Name of interface.
Name string
// RawType is raw type from TL schema.
RawType string
// Fields, common for every constructor.
SharedFields map[string][]fieldDef
// Sub interfaces of this TL class.
// Need to create As${sub.MapperName}() ${sub.Name} mappers.
Mappings []constructorMapping
// Constructors of interface.
Constructors []structDef
Func string
Namespace []string
BaseName string
URL string
}
func interfaceHasOneSuffix(suffixes ...string) func(s structDef) bool {
return func(s structDef) bool {
for _, suffix := range suffixes {
if strings.HasSuffix(s.Name, suffix) {
return true
}
}
return false
}
}
func makeMapping(def *interfaceDef, name string, emptyFilter func(s structDef) bool) {
var (
// Fields, common for every non-empty constructor.
nonEmptyFields []fieldDef
// Non-empty constructors.
nonEmptyConstructors []structDef
// Index of optional empty constructor.
emptyIdx = -1
)
for _, s := range def.Constructors {
if emptyFilter(s) {
emptyIdx = len(def.Constructors)
} else {
nonEmptyFields = intersectFields(nonEmptyFields, s.Fields)
nonEmptyConstructors = append(nonEmptyConstructors, s)
}
}
// If have at least one empty constructor.
hasEmpty := emptyIdx >= 0
// If all non-empty constructors have common fields.
nonEmptyHasCommonFields := len(nonEmptyFields) > 0
if hasEmpty && nonEmptyHasCommonFields && len(nonEmptyConstructors) > 0 {
def.SharedFields[name] = nonEmptyFields
// If there are only one non-empty constructor, so we use concrete type.
concrete := len(nonEmptyConstructors) < 2
goName := name + strings.TrimSuffix(def.Name, "Class")
if concrete {
goName = nonEmptyConstructors[0].Name
}
mapping := constructorMapping{
Name: goName,
Concrete: concrete,
MapperName: name,
}
def.Mappings = append(def.Mappings, mapping)
}
}
func (g *Generator) collectMappings(def *interfaceDef) {
for _, s := range g.structs {
// Filter constructors from same Class and empty constructors.
if s.Interface == def.Name || len(s.Fields) < 1 {
continue
}
for _, constructor := range def.Constructors {
// Filter constructors which have not similar name.
if !strings.HasPrefix(s.Name, "Input") || !strings.Contains(s.Name, constructor.Name) {
continue
}
mapping, ok := mappableFields(constructor, s)
// Filter constructors which we can't fill completely.
if !ok {
continue
}
def.Mappings = append(def.Mappings, mapping)
}
}
emptyAnnotations := []struct {
name string
filter func(s structDef) bool
}{
{"NotEmpty", interfaceHasOneSuffix("Empty")},
{"Modified", interfaceHasOneSuffix("NotModified")},
{"Available", interfaceHasOneSuffix("Unavailable")},
{"NotForbidden", interfaceHasOneSuffix("Forbidden")},
{"Full", interfaceHasOneSuffix("Empty", "NotModified", "Forbidden")},
}
for _, annotation := range emptyAnnotations {
// Full annotation is necessary only if there are more than two empty annotations.
if annotation.name == "Full" && len(def.SharedFields) <= 2 {
continue
}
makeMapping(def, annotation.name, annotation.filter)
}
}
func (g *Generator) makeInterfaces() {
// Make interfaces for classes.
for _, c := range g.classes {
if c.Singular {
continue
}
def := interfaceDef{
Name: c.Name,
Namespace: c.Namespace,
Func: c.Func,
BaseName: c.BaseName,
RawType: c.RawType,
SharedFields: map[string][]fieldDef{},
URL: g.docURL("type", c.RawType),
}
for _, s := range g.structs {
if s.Interface != def.Name {
continue
}
def.SharedFields["Common"] = intersectFields(def.SharedFields["Common"], s.Fields)
def.Constructors = append(def.Constructors, s)
}
g.collectMappings(&def)
g.interfaces = append(g.interfaces, def)
g.mappings[def.Name] = append(g.mappings[def.Name], def.Mappings...)
}
}