go-tdlib/codegen/tdlib.go

488 lines
10 KiB
Go
Raw Normal View History

2018-08-30 14:55:42 +00:00
package codegen
import (
2018-10-23 12:49:10 +00:00
"github.com/zelenin/go-tdlib/tlparser"
"log"
"strings"
2018-08-30 14:55:42 +00:00
)
type tdlibFunction struct {
2018-10-23 12:49:10 +00:00
name string
schema *tlparser.Schema
2018-08-30 14:55:42 +00:00
}
func TdlibFunction(name string, schema *tlparser.Schema) *tdlibFunction {
2018-10-23 12:49:10 +00:00
return &tdlibFunction{
name: name,
schema: schema,
}
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunction) ToGoName() string {
2018-10-23 12:49:10 +00:00
return firstUpper(entity.name)
2018-08-30 14:55:42 +00:00
}
type tdlibFunctionReturn struct {
2018-10-23 12:49:10 +00:00
name string
schema *tlparser.Schema
2018-08-30 14:55:42 +00:00
}
func TdlibFunctionReturn(name string, schema *tlparser.Schema) *tdlibFunctionReturn {
2018-10-23 12:49:10 +00:00
return &tdlibFunctionReturn{
name: name,
schema: schema,
}
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionReturn) IsType() bool {
2018-10-23 12:49:10 +00:00
return isType(entity.name, func(entity *tlparser.Type) string {
return entity.Class
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionReturn) GetType() *tdlibType {
2018-10-23 12:49:10 +00:00
return getType(entity.name, func(entity *tlparser.Type) string {
return entity.Class
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionReturn) IsClass() bool {
2018-10-23 12:49:10 +00:00
return isClass(entity.name, func(entity *tlparser.Class) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionReturn) GetClass() *tdlibClass {
2018-10-23 12:49:10 +00:00
return getClass(entity.name, func(entity *tlparser.Class) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionReturn) ToGoReturn() string {
2018-10-23 12:49:10 +00:00
if strings.HasPrefix(entity.name, "vector<") {
log.Fatal("vectors are not supported")
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
if entity.IsClass() {
return entity.GetClass().ToGoType()
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
if entity.GetType().IsInternal() {
return entity.GetType().ToGoType()
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return "*" + entity.GetType().ToGoType()
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionReturn) ToGoType() string {
2018-10-23 12:49:10 +00:00
if strings.HasPrefix(entity.name, "vector<") {
log.Fatal("vectors are not supported")
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
if entity.IsClass() {
return entity.GetClass().ToGoType()
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return entity.GetType().ToGoType()
2018-08-30 14:55:42 +00:00
}
type tdlibFunctionProperty struct {
2018-10-23 12:49:10 +00:00
name string
propertyType string
schema *tlparser.Schema
2018-08-30 14:55:42 +00:00
}
func TdlibFunctionProperty(name string, propertyType string, schema *tlparser.Schema) *tdlibFunctionProperty {
2018-10-23 12:49:10 +00:00
return &tdlibFunctionProperty{
name: name,
propertyType: propertyType,
schema: schema,
}
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionProperty) GetPrimitive() string {
2018-10-23 12:49:10 +00:00
primitive := entity.propertyType
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
for strings.HasPrefix(primitive, "vector<") {
primitive = strings.TrimSuffix(strings.TrimPrefix(primitive, "vector<"), ">")
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return primitive
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionProperty) IsType() bool {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return isType(primitive, func(entity *tlparser.Type) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionProperty) GetType() *tdlibType {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return getType(primitive, func(entity *tlparser.Type) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionProperty) IsClass() bool {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return isClass(primitive, func(entity *tlparser.Class) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionProperty) GetClass() *tdlibClass {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return getClass(primitive, func(entity *tlparser.Class) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionProperty) ToGoName() string {
2018-10-23 12:49:10 +00:00
name := firstLower(underscoreToCamelCase(entity.name))
if name == "type" {
name += "Param"
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return name
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibFunctionProperty) ToGoType() string {
2018-10-23 12:49:10 +00:00
tdlibType := entity.propertyType
goType := ""
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
for strings.HasPrefix(tdlibType, "vector<") {
goType = goType + "[]"
tdlibType = strings.TrimSuffix(strings.TrimPrefix(tdlibType, "vector<"), ">")
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
if entity.IsClass() {
return goType + entity.GetClass().ToGoType()
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
if entity.GetType().IsInternal() {
return goType + entity.GetType().ToGoType()
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return goType + "*" + entity.GetType().ToGoType()
2018-08-30 14:55:42 +00:00
}
type tdlibType struct {
2018-10-23 12:49:10 +00:00
name string
schema *tlparser.Schema
2018-08-30 14:55:42 +00:00
}
func TdlibType(name string, schema *tlparser.Schema) *tdlibType {
2018-10-23 12:49:10 +00:00
return &tdlibType{
name: name,
schema: schema,
}
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) IsInternal() bool {
2018-10-23 12:49:10 +00:00
switch entity.name {
case "double":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "string":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "int32":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "int53":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "int64":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "bytes":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "boolFalse":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "boolTrue":
return true
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "vector<t>":
return true
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return false
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) GetType() *tlparser.Type {
2018-10-23 12:49:10 +00:00
name := normalizeEntityName(entity.name)
for _, typ := range entity.schema.Types {
if typ.Name == name {
return typ
}
}
return nil
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) ToGoType() string {
2018-10-23 12:49:10 +00:00
if strings.HasPrefix(entity.name, "vector<") {
log.Fatal("vectors are not supported")
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
switch entity.name {
case "double":
return "float64"
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "string":
return "string"
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "int32":
return "int32"
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "int53":
return "int64"
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "int64":
return "JsonInt64"
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "bytes":
return "[]byte"
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "boolFalse":
return "bool"
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
case "boolTrue":
return "bool"
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return firstUpper(entity.name)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) ToType() string {
2018-10-23 12:49:10 +00:00
return entity.ToGoType() + "Type"
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) HasClass() bool {
2018-10-23 12:49:10 +00:00
className := entity.GetType().Class
for _, class := range entity.schema.Classes {
if class.Name == className {
return true
}
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return false
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) GetClass() *tlparser.Class {
2018-10-23 12:49:10 +00:00
className := entity.GetType().Class
for _, class := range entity.schema.Classes {
if class.Name == className {
return class
}
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return nil
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) HasClassProperties() bool {
2018-10-23 12:49:10 +00:00
for _, prop := range entity.GetType().Properties {
tdlibTypeProperty := TdlibTypeProperty(prop.Name, prop.Type, entity.schema)
if tdlibTypeProperty.IsClass() && !tdlibTypeProperty.IsList() {
return true
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return false
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) IsList() bool {
2018-10-23 12:49:10 +00:00
return strings.HasPrefix(entity.name, "vector<")
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) ToClassConst() string {
2018-10-23 12:49:10 +00:00
if entity.HasClass() {
return "Class" + TdlibClass(entity.GetType().Class, entity.schema).ToGoType()
}
return "Class" + entity.ToGoType()
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibType) ToTypeConst() string {
2018-10-23 12:49:10 +00:00
return "Type" + entity.ToGoType()
2018-08-30 14:55:42 +00:00
}
type tdlibClass struct {
2018-10-23 12:49:10 +00:00
name string
schema *tlparser.Schema
2018-08-30 14:55:42 +00:00
}
func TdlibClass(name string, schema *tlparser.Schema) *tdlibClass {
2018-10-23 12:49:10 +00:00
return &tdlibClass{
name: name,
schema: schema,
}
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibClass) ToGoType() string {
2018-10-23 12:49:10 +00:00
return firstUpper(entity.name)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibClass) ToType() string {
2018-10-23 12:49:10 +00:00
return entity.ToGoType() + "Type"
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibClass) GetSubTypes() []*tdlibType {
2018-10-23 12:49:10 +00:00
types := []*tdlibType{}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
for _, t := range entity.schema.Types {
if t.Class == entity.name {
types = append(types, TdlibType(t.Name, entity.schema))
}
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return types
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibClass) ToClassConst() string {
2018-10-23 12:49:10 +00:00
return "Class" + entity.ToGoType()
2018-08-30 14:55:42 +00:00
}
type tdlibTypeProperty struct {
2018-10-23 12:49:10 +00:00
name string
propertyType string
schema *tlparser.Schema
2018-08-30 14:55:42 +00:00
}
func TdlibTypeProperty(name string, propertyType string, schema *tlparser.Schema) *tdlibTypeProperty {
2018-10-23 12:49:10 +00:00
return &tdlibTypeProperty{
name: name,
propertyType: propertyType,
schema: schema,
}
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) IsList() bool {
2018-10-23 12:49:10 +00:00
return strings.HasPrefix(entity.propertyType, "vector<")
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) GetPrimitive() string {
2018-10-23 12:49:10 +00:00
primitive := entity.propertyType
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
for strings.HasPrefix(primitive, "vector<") {
primitive = strings.TrimSuffix(strings.TrimPrefix(primitive, "vector<"), ">")
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return primitive
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) IsType() bool {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return isType(primitive, func(entity *tlparser.Type) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) GetType() *tdlibType {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return getType(primitive, func(entity *tlparser.Type) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) IsClass() bool {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return isClass(primitive, func(entity *tlparser.Class) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) GetClass() *tdlibClass {
2018-10-23 12:49:10 +00:00
primitive := entity.GetPrimitive()
return getClass(primitive, func(entity *tlparser.Class) string {
return entity.Name
}, entity.schema)
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) ToGoName() string {
2018-10-23 12:49:10 +00:00
return firstUpper(underscoreToCamelCase(entity.name))
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) ToGoFunctionPropertyName() string {
2018-10-23 12:49:10 +00:00
name := firstLower(underscoreToCamelCase(entity.name))
if name == "type" {
name += "Param"
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return name
2018-08-30 14:55:42 +00:00
}
func (entity *tdlibTypeProperty) ToGoType() string {
2018-10-23 12:49:10 +00:00
tdlibType := entity.propertyType
goType := ""
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
for strings.HasPrefix(tdlibType, "vector<") {
goType = goType + "[]"
tdlibType = strings.TrimSuffix(strings.TrimPrefix(tdlibType, "vector<"), ">")
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
if entity.IsClass() {
return goType + entity.GetClass().ToGoType()
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
if entity.GetType().IsInternal() {
return goType + entity.GetType().ToGoType()
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return goType + "*" + entity.GetType().ToGoType()
2018-08-30 14:55:42 +00:00
}
func isType(name string, field func(entity *tlparser.Type) string, schema *tlparser.Schema) bool {
2018-10-23 12:49:10 +00:00
name = normalizeEntityName(name)
for _, entity := range schema.Types {
if name == field(entity) {
return true
}
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return false
2018-08-30 14:55:42 +00:00
}
func getType(name string, field func(entity *tlparser.Type) string, schema *tlparser.Schema) *tdlibType {
2018-10-23 12:49:10 +00:00
name = normalizeEntityName(name)
for _, entity := range schema.Types {
if name == field(entity) {
return TdlibType(entity.Name, schema)
}
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return nil
2018-08-30 14:55:42 +00:00
}
func isClass(name string, field func(entity *tlparser.Class) string, schema *tlparser.Schema) bool {
2018-10-23 12:49:10 +00:00
name = normalizeEntityName(name)
for _, entity := range schema.Classes {
if name == field(entity) {
return true
}
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return false
2018-08-30 14:55:42 +00:00
}
func getClass(name string, field func(entity *tlparser.Class) string, schema *tlparser.Schema) *tdlibClass {
2018-10-23 12:49:10 +00:00
name = normalizeEntityName(name)
for _, entity := range schema.Classes {
if name == field(entity) {
return TdlibClass(entity.Name, schema)
}
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return nil
2018-08-30 14:55:42 +00:00
}
func normalizeEntityName(name string) string {
2018-10-23 12:49:10 +00:00
if name == "Bool" {
name = "boolFalse"
}
2018-08-30 14:55:42 +00:00
2018-10-23 12:49:10 +00:00
return name
2018-08-30 14:55:42 +00:00
}