commit f54fcebd8cf36921b37cc30c1348d48576002dea Author: Pavel Shevaev Date: Thu Dec 8 11:40:55 2022 +0300 First commit diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..0c8eb65 --- /dev/null +++ b/composer.json @@ -0,0 +1,15 @@ +{ + "name": "bit/metagen_go", + "version" : "v0.0.1", + "description": "Go codgen support from meta descriptions", + "homepage": "https://git.bit5.ru/bit/metagen_go", + "require": { + "php": ">=7.4", + "twig/twig" : "v3.4.3" + }, + "autoload": { + "files": [ + "src/codegen.inc.php" + ] + } +} diff --git a/src/codegen.inc.php b/src/codegen.inc.php new file mode 100644 index 0000000..ad34706 --- /dev/null +++ b/src/codegen.inc.php @@ -0,0 +1,83 @@ + true, + 'autoescape' => false, + 'strict_variables' => true] + ); + $twig->addExtension(new \Twig\Extension\DebugExtension()); + + _add_twig_support($twig); + + return $twig; +} + +function supported_tokens() +{ + return [ + 'POD', + 'default', + 'optional', + 'bitfields', + 'cloneable', + 'virtual', + + 'table', + 'id', + 'owner', + 'pkey', + + 'statist', + 'statist_skip', + ]; +} + +function _add_twig_support(\Twig\Environment $twig) +{ + $twig->addTest(new \Twig\TwigTest('instanceof', + function($obj, $class) + { + return (new \ReflectionClass($class))->isInstance($obj); + } + )); + $twig->addFunction(new \Twig\TwigFunction('Error', + function($e) + { + throw new Exception($e); + } + )); + $twig->addFunction(new \Twig\TwigFunction('has_token', + function($o, $token) + { + return $o->hasToken($token); + } + )); + $twig->addFunction(new \Twig\TwigFunction('has_token_in_parent', + function($o, $token) + { + return $o->hasTokenInParent($token); + } + )); + $twig->addFunction(new \Twig\TwigFunction('token', + function($o, $name) + { + return $o->getToken($name); + } + )); + $twig->addFunction(new \Twig\TwigFunction('token_or', + function($o, $name, $v) + { + if($o->hasToken($name)) + return $o->getToken($name); + else + return $v; + } + )); +} diff --git a/tpl/codegen_bundle.twig b/tpl/codegen_bundle.twig new file mode 100644 index 0000000..cbe6590 --- /dev/null +++ b/tpl/codegen_bundle.twig @@ -0,0 +1,37 @@ +package {{package}} +//THIS FILE IS GENERATED AUTOMATICALLY, DO NOT TOUCH IT! + +import ( + "fmt" + "sort" + "github.com/pkg/errors" + "git.bit5.ru/backend/meta" +) + +//supress *imported but not used* warnings +var _ = fmt.Printf +var _ = sort.SearchInts + +{%- import "macro.twig" as macro -%} + +{{ macro.decl_units(meta) }} + +func CreateById(classId uint32) (meta.IMetaStruct, error) { + switch classId { + %create_struct_by_crc28% + default : return nil, errors.Errorf("Can't find struct for class id %d", classId) + } +} +func CreateByName(name string) (meta.IMetaStruct, error) { + switch name { + %create_struct_by_name% + default : return nil, errors.Errorf("Can't find struct for name %s", name) + } +} +func CreateRPC(code uint32)(meta.IRPC, error) { + switch code { +%create_rpc_by_code% + default: return nil, errors.Errorf("Can't find rpc for code %d", code) + } +} + diff --git a/tpl/macro.twig b/tpl/macro.twig new file mode 100644 index 0000000..6d1c060 --- /dev/null +++ b/tpl/macro.twig @@ -0,0 +1,74 @@ +{% macro decl_units(meta) %} + {%- for u in meta.getunits ~%} + {%- if u.object is instanceof('\\mtgMetaStruct') ~%} + {{ _self.decl_struct(u.object) }} + {%- elseif u.object is instanceof('\\mtgMetaEnum') ~%} + {{ _self.decl_enum(u.object) }} + {%- elseif u.object is instanceof('\\mtgMetaRPC') ~%} + {{ _self.decl_rpc(u.object) }} + {%- endif ~%} + {%- endfor ~%} +{% endmacro %} + +{% macro decl_struct(o) %} +{% endmacro %} + +{% macro decl_enum(o) %} + +const ( +{{_self.enum_consts(o)}} +) +type {{o.name}} int32 +var _{{o.name}}_values []int = []int{ {{_self.enum_values_list(o)}} } +var _{{o.name}}_map map[string]{{o.name}} +func init() { +_{{o.name}}_map = map[string]{{o.name}}{ {{_self.enum_values_map(o)}} } +} +func (*{{o.name}}) CLASS_ID() uint32 { + return {{o.classid}} +} +func (*{{o.name}}) CLASS_NAME() string { + return "{{o.name}}" +} +func (*{{o.name}}) DEFAULT_VALUE() int32 { + return %default_enum_value% +} +func (self *{{o.name}}) IsValid() bool { + return sort.SearchInts(_{{o.name}}_values, int(*self)) != -1 +} +func {{o.name}}_GetNameByValue(value int) string { + for name, num := range _{{o.name}}_map { + if value == int(num) { + return name + } + } + return "" +} +func New{{o.name}}ByName(name string) ({{o.name}}, error) { + if v, ok := _{{o.name}}_map[name]; ok == true { + return v, nil + } + return 0, errors.Errorf("Wrong name of {{o.name}}: '%s'", name) +} +{% endmacro %} + +{% macro enum_values_list(o) %} +{%- for v in o.values -%} +{{v}}, +{%- endfor ~%} +{% endmacro %} + +{% macro enum_values_map(o) %} +{%- for k,v in o.values -%} +"{{k}}" : {{v}}, +{%- endfor ~%} +{% endmacro %} + +{% macro enum_consts(o) %} +{%- for k,v in o.values ~%} +{{o.name}}_{{k}} {{o.name}} = {{v}} +{%- endfor ~%} +{% endmacro %} + +{% macro decl_rpc(o) %} +{% endmacro %}