generating sql methods, reading/writing associative containers
This commit is contained in:
parent
7f92d11514
commit
c1128ec7c4
|
@ -1,6 +1,18 @@
|
|||
<?php
|
||||
namespace metagen_go;
|
||||
|
||||
use Exception;
|
||||
use mtgMetaInfo;
|
||||
use mtgMetaInfoUnit;
|
||||
use mtgMetaEnum;
|
||||
use mtgMetaStruct;
|
||||
use mtgMetaField;
|
||||
use mtgMetaRPC;
|
||||
use mtgType;
|
||||
use mtgTypeRef;
|
||||
use mtgBuiltinType;
|
||||
use mtgArrType;
|
||||
use Twig\{TwigTest, TwigFilter, TwigFunction};
|
||||
|
||||
function get_twig(array $inc_path = [])
|
||||
{
|
||||
|
@ -8,13 +20,15 @@ function get_twig(array $inc_path = [])
|
|||
$loader = new \Twig\Loader\FilesystemLoader($inc_path);
|
||||
|
||||
$twig = new \Twig\Environment($loader, [
|
||||
'debug' => true,
|
||||
'autoescape' => false,
|
||||
'strict_variables' => true]
|
||||
);
|
||||
'debug' => true,
|
||||
'autoescape' => false,
|
||||
'strict_variables' => true,
|
||||
]);
|
||||
$twig->addExtension(new \Twig\Extension\DebugExtension());
|
||||
|
||||
_add_twig_support($twig);
|
||||
addTwigTests($twig);
|
||||
addTwigFilters($twig);
|
||||
addTwigFunctions($twig);
|
||||
|
||||
return $twig;
|
||||
}
|
||||
|
@ -22,117 +36,317 @@ function get_twig(array $inc_path = [])
|
|||
function supported_tokens()
|
||||
{
|
||||
return [
|
||||
'POD',
|
||||
'table',
|
||||
'table_pkey',
|
||||
'table_json_kv',
|
||||
|
||||
'root',
|
||||
'bitfields',
|
||||
'diffable',
|
||||
'diff_removed',
|
||||
|
||||
'alias',
|
||||
'default',
|
||||
'optional',
|
||||
'bitfields',
|
||||
'cloneable',
|
||||
'virtual',
|
||||
|
||||
'table',
|
||||
'id',
|
||||
'owner',
|
||||
'pkey',
|
||||
|
||||
'statist',
|
||||
'statist_skip',
|
||||
'statist_alias',
|
||||
];
|
||||
}
|
||||
|
||||
function _add_twig_support(\Twig\Environment $twig)
|
||||
function addTwigTests(\Twig\Environment $twig)
|
||||
{
|
||||
$twig->addTest(new \Twig\TwigTest('instanceof',
|
||||
function($obj, $class)
|
||||
{
|
||||
return (new \ReflectionClass($class))->isInstance($obj);
|
||||
$twig->addTest(new TwigTest(
|
||||
'metaenum',
|
||||
fn(mtgMetaInfoUnit $u): bool => $u->object instanceof mtgMetaEnum,
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'metastruct',
|
||||
fn(mtgMetaInfoUnit $u): bool => $u->object instanceof mtgMetaStruct,
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'metarpc',
|
||||
fn(mtgMetaInfoUnit $u): bool => $u->object instanceof mtgMetaRPC,
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'enum',
|
||||
fn(mtgType $t): bool => $t instanceof mtgMetaEnum,
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'struct',
|
||||
fn(mtgType $t): bool => $t instanceof mtgMetaStruct,
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'array',
|
||||
fn(mtgType $t): bool => $t instanceof mtgArrType,
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'builtin',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType,
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'numeric',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isNumeric(),
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'int',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isInt(),
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'uint',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isUint(),
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'bool',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isBool(),
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'float',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isFloat(),
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'double',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isDouble(),
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'string',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isString(),
|
||||
));
|
||||
$twig->addTest(new TwigTest(
|
||||
'blob',
|
||||
fn(mtgType $t): bool => $t instanceof mtgBuiltinType && $t->isBlob(),
|
||||
));
|
||||
|
||||
$twig->addTest(new TwigTest(
|
||||
'instanceof',
|
||||
fn($obj, $class): bool => (new \ReflectionClass($class))->isInstance($obj),
|
||||
));
|
||||
}
|
||||
|
||||
function addTwigFilters(\Twig\Environment $twig)
|
||||
{
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'go_type',
|
||||
fn(mtgType $t): string => goType($t),
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'ucfirst',
|
||||
fn(string $str): string => ucfirst($str),
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'lcfirst',
|
||||
fn(string $str): string => lcfirst($str),
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'camel',
|
||||
fn(string $str): string => snake2camel($str),
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'quote',
|
||||
fn(string $str, string $char = '`'): string => "{$char}{$str}{$char}"
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'sql_where',
|
||||
function(array $fields): string {
|
||||
$exprs = [];
|
||||
foreach ($fields as $field) {
|
||||
$fieldName = $field->getName();
|
||||
$exprs[] = "`{$fieldName}` = ?";
|
||||
}
|
||||
return implode(' AND ', $exprs);
|
||||
}
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('Error',
|
||||
function($e)
|
||||
{
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'alias',
|
||||
function(mtgMetaField $field): string {
|
||||
if ($field->hasToken('alias')) {
|
||||
return $field->getToken('alias');
|
||||
}
|
||||
return $field->getName();
|
||||
}
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'fname',
|
||||
fn(mtgMetaField $field): string => snake2camel($field->getName())
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'varname',
|
||||
fn(mtgMetaField $field): string => lcfirst(snake2camel($field->getName()))
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'builtin_type_suffix',
|
||||
fn (mtgBuiltinType $type): string => builtinTypeMethodSuffix($type),
|
||||
));
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'default_val',
|
||||
fn(mtgMetaField $field) => defaultValue($field)
|
||||
));
|
||||
|
||||
$twig->addFilter(new TwigFilter(
|
||||
'rpc_invert',
|
||||
fn(string $name): string => rpc_invert($name),
|
||||
));
|
||||
}
|
||||
|
||||
function addTwigFunctions(\Twig\Environment $twig)
|
||||
{
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'Error',
|
||||
function(string $e) {
|
||||
throw new Exception($e);
|
||||
}
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('has_token',
|
||||
function($o, $token)
|
||||
{
|
||||
return $o->hasToken($token);
|
||||
}
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'has_token',
|
||||
fn($o, string $token): bool => $o->hasToken($token),
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('has_token_in_parent',
|
||||
function($o, $token)
|
||||
{
|
||||
return $o->hasTokenInParent($token);
|
||||
}
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'has_token_in_parent',
|
||||
fn(mtgMetaStruct $s, string $token): bool => $s->hasTokenInParent($token),
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('token',
|
||||
function($o, $name)
|
||||
{
|
||||
return $o->getToken($name);
|
||||
}
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'token',
|
||||
fn($o, string $name) => $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;
|
||||
}
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'token_or',
|
||||
fn($o, string $name, $v) => $o->hasToken($name) ? $o->getToken($name) : $v,
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('get_all_fields',
|
||||
function($o)
|
||||
{
|
||||
return \mtg_get_all_fields($o);
|
||||
}
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'get_all_fields',
|
||||
fn(mtgMetaStruct $s): array => \mtg_get_all_fields($s),
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('count_optional',
|
||||
function($os)
|
||||
{
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'count_optional',
|
||||
function($os) {
|
||||
$opts = 0;
|
||||
foreach($os as $o)
|
||||
if($o->hasToken('optional'))
|
||||
++$opts;
|
||||
return $opts;
|
||||
}
|
||||
));
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'arr_fill',
|
||||
fn($value, int $count): array => array_fill(0, $count, $value)
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('field_reset',
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'table_pkey',
|
||||
function(mtgMetaStruct $struct): array {
|
||||
$pkey = explode(',', $struct->getToken('table_pkey'));
|
||||
$fields = [];
|
||||
foreach ($pkey as $fieldName) {
|
||||
$fields[] = $struct->getField($fieldName);
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
));
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'table_fields',
|
||||
function(mtgMetaStruct $struct): array {
|
||||
$pkey = explode(',', $struct->getToken('table_pkey'));
|
||||
return array_filter(
|
||||
$struct->getFields(),
|
||||
fn(mtgMetaField $field): bool => !in_array($field->getName(), $pkey),
|
||||
);
|
||||
}
|
||||
));
|
||||
$twig->addFunction(new TwigFunction(
|
||||
'meta_field',
|
||||
function (string $str) use ($twig): mtgMetaField {
|
||||
$meta = $twig->getGlobals()['meta'];
|
||||
return parseMetaField($str, $meta);
|
||||
}
|
||||
));
|
||||
|
||||
$twig->addFunction(new TwigFunction('field_reset',
|
||||
function($name, $type, $tokens)
|
||||
{
|
||||
return field_reset($name, $type, $tokens);
|
||||
}
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('buf2var',
|
||||
$twig->addFunction(new TwigFunction('buf2var',
|
||||
function($name, $fname, $type, $buf, $tokens, $is_ptr)
|
||||
{
|
||||
return buf2var($name, $fname, $type, $buf, $tokens, $is_ptr);
|
||||
}
|
||||
));
|
||||
$twig->addFunction(new \Twig\TwigFunction('var2buf',
|
||||
$twig->addFunction(new TwigFunction('var2buf',
|
||||
function($name, $fname, $type, $buf, $tokens, $is_ptr)
|
||||
{
|
||||
return var2buf($name, $fname, $type, $buf, $tokens, $is_ptr);
|
||||
}
|
||||
));
|
||||
$twig->addFilter(new \Twig\TwigFilter('rpc_invert',
|
||||
function($name)
|
||||
{
|
||||
return rpc_invert($name);
|
||||
}
|
||||
|
||||
function snake2camel(string $str): string
|
||||
{
|
||||
return str_replace('_', '', ucwords($str, '_'));
|
||||
}
|
||||
|
||||
function goType(mtgType $type, array $tokens = []): string
|
||||
{
|
||||
if ($type instanceof mtgMetaEnum) {
|
||||
return $type->getName();
|
||||
} else if ($type instanceof mtgMetaStruct) {
|
||||
return $type->getName();
|
||||
} else if ($type instanceof mtgBuiltinType) {
|
||||
if ($type->isFloat()) {
|
||||
return 'float32';
|
||||
} else if ($type->isDouble()) {
|
||||
return 'float64';
|
||||
} else if ($type->isBlob()) {
|
||||
return '[]byte';
|
||||
} else {
|
||||
return $type->getName();
|
||||
}
|
||||
));
|
||||
$twig->addFilter(new \Twig\TwigFilter('go_type',
|
||||
function($type, $tokens)
|
||||
{
|
||||
return go_type($type, $tokens);
|
||||
} else if ($type instanceof mtgArrType) {
|
||||
$native = goType($type->getValue());
|
||||
return "[]$native";
|
||||
} else {
|
||||
throw new Exception("Unknown type '$type'");
|
||||
}
|
||||
}
|
||||
|
||||
function builtinTypeMethodSuffix(mtgBuiltinType $type): string
|
||||
{
|
||||
if ($type->isBlob()) {
|
||||
return 'Bytes';
|
||||
}
|
||||
return ucfirst(goType($type));
|
||||
}
|
||||
|
||||
function defaultValue(mtgMetaField $field)
|
||||
{
|
||||
$type = $field->getType();
|
||||
$tokens = $field->getTokens();
|
||||
$default = $field->getToken('default');
|
||||
|
||||
if ($type instanceof mtgBuiltinType) {
|
||||
if ($type->isNumeric()) {
|
||||
return $default ?? 0;
|
||||
} else if ($type->isString()) {
|
||||
return $default ?? '""';
|
||||
} else if($type->isBool()) {
|
||||
return $default ?? 'false';
|
||||
} else if($type->isBlob()) {
|
||||
return $default ?? 'nil';
|
||||
} else {
|
||||
throw new Exception("Unknown type '$type'");
|
||||
}
|
||||
));
|
||||
$twig->addFilter(new \Twig\TwigFilter('ucfirst',
|
||||
function($str)
|
||||
{
|
||||
return ucfirst($str);
|
||||
}
|
||||
));
|
||||
} else if($type instanceof mtgMetaEnum) {
|
||||
return $default ? goType($type, $tokens)."_".trim($tokens['default'], '"') : 0;
|
||||
} else {
|
||||
throw new Exception("Unknown type '$type'");
|
||||
}
|
||||
}
|
||||
|
||||
function parseMetaField(string $str, mtgMetaInfo $meta): mtgMetaField
|
||||
{
|
||||
list($name, $type) = explode('|', $str);
|
||||
return new mtgMetaField($name, new mtgTypeRef(new mtgBuiltinType($type), $meta));
|
||||
}
|
||||
|
||||
function go_type(\mtgType $type, array $tokens = array())
|
||||
|
@ -177,7 +391,7 @@ function go_type(\mtgType $type, array $tokens = array())
|
|||
throw new Exception("Unknown type '$type'");
|
||||
}
|
||||
|
||||
function builtin_type_prefix(\mtgBuiltinType $type)
|
||||
function builtin_type_prefix(mtgBuiltinType $type)
|
||||
{
|
||||
switch($type->getName())
|
||||
{
|
||||
|
@ -214,11 +428,11 @@ function builtin_type_prefix(\mtgBuiltinType $type)
|
|||
}
|
||||
}
|
||||
|
||||
function field_reset($name, \mtgType $type, array $tokens)
|
||||
function field_reset($name, mtgType $type, array $tokens)
|
||||
{
|
||||
$str = '';
|
||||
|
||||
if($type instanceof \mtgBuiltinType)
|
||||
if($type instanceof mtgBuiltinType)
|
||||
{
|
||||
if($type->isNumeric())
|
||||
{
|
||||
|
@ -251,23 +465,23 @@ function field_reset($name, \mtgType $type, array $tokens)
|
|||
else
|
||||
throw new Exception("Unknown type '$type'");
|
||||
}
|
||||
else if($type instanceof \mtgArrType)
|
||||
else if($type instanceof mtgArrType)
|
||||
{
|
||||
$str = "if self.$name == nil { \nself.$name = make(".go_type($type, $tokens).",0) \n}\n ";
|
||||
$str = "if self.$name == nil { \nself.$name = make(".goType($type, $tokens).",0) \n}\n ";
|
||||
$str .= "self.$name = self.{$name}[0:0]";
|
||||
}
|
||||
else if($type instanceof \mtgMetaEnum)
|
||||
else if($type instanceof mtgMetaEnum)
|
||||
{
|
||||
if(array_key_exists('default', $tokens))
|
||||
$str = "self.$name = ".go_type($type, $tokens)."_".trim($tokens['default'], '"');
|
||||
$str = "self.$name = ".goType($type, $tokens)."_".trim($tokens['default'], '"');
|
||||
else
|
||||
$str = "self.$name = 0";
|
||||
}
|
||||
else if($type instanceof \mtgMetaStruct)
|
||||
else if($type instanceof mtgMetaStruct)
|
||||
{
|
||||
$is_virtual = array_key_exists("virtual", $tokens);
|
||||
if($is_virtual)
|
||||
$str .= "self.$name = New".ltrim(go_type($type, $tokens),'I')."() ";
|
||||
$str .= "self.$name = New".ltrim(goType($type, $tokens),'I')."() ";
|
||||
else
|
||||
$str .= "self.$name.Reset()";
|
||||
}
|
||||
|
@ -276,30 +490,30 @@ function field_reset($name, \mtgType $type, array $tokens)
|
|||
return $str;
|
||||
}
|
||||
|
||||
function buf2var($name, $fname, \mtgType $type, $buf, array $tokens = array(), $is_ptr = false)
|
||||
function buf2var($name, $fname, mtgType $type, $buf, array $tokens = array(), $is_ptr = false)
|
||||
{
|
||||
$str = '';
|
||||
|
||||
if($type instanceof \mtgBuiltinType)
|
||||
if($type instanceof mtgBuiltinType)
|
||||
{
|
||||
$str .= _read_op($tokens, $buf.'.Read'.builtin_type_prefix($type).'(&'.$fname.', "'.$name.'")');
|
||||
}
|
||||
else if($type instanceof \mtgMetaEnum)
|
||||
else if($type instanceof mtgMetaEnum)
|
||||
{
|
||||
$str .= _read_op($tokens, "{$buf}.ReadI32((*int32)(&{$fname}), \"$name\")");
|
||||
$str .= "\n if !{$fname}.IsValid() { return errors.Errorf(\"Bad enum value %d for $name\", $fname) }";
|
||||
}
|
||||
else if($type instanceof \mtgMetaStruct)
|
||||
else if($type instanceof mtgMetaStruct)
|
||||
{
|
||||
if(array_key_exists('virtual', $tokens))
|
||||
$str .= "if v, err := meta.ReadStructGeneric($buf, CreateById, \"{$name}\"); err != nil { return err } else { {$fname} = v.(I{$type}) }";
|
||||
else
|
||||
$str .= _read_op($tokens, "meta.ReadStruct($buf, ".($is_ptr?"":"&")."$fname, \"$name\")");
|
||||
}
|
||||
else if($type instanceof \mtgArrType)
|
||||
else if($type instanceof mtgArrType)
|
||||
{
|
||||
$is_virtual = array_key_exists("virtual", $tokens);
|
||||
$native_type = go_type($type->getValue(), $tokens);
|
||||
$native_type = goType($type->getValue(), $tokens);
|
||||
$offset = "\n ";
|
||||
$str .= "/*[]{$name}*/";
|
||||
$str .= $offset . _read_op($tokens, "{$buf}.BeginContainer(\"$name\")");
|
||||
|
@ -308,14 +522,14 @@ function buf2var($name, $fname, \mtgType $type, $buf, array $tokens = array(), $
|
|||
$str .= $offset . "_{$name}_size, err := {$buf}.GetContainerSize()";
|
||||
$str .= $offset . "if err != nil { return err }";
|
||||
|
||||
$need_new = !$is_virtual && $type->getValue() instanceof \mtgMetaStruct;
|
||||
$need_new = !$is_virtual && $type->getValue() instanceof mtgMetaStruct;
|
||||
|
||||
$str .= $offset . "for ; _{$name}_size > 0; _{$name}_size-- {";
|
||||
$offset = "\n ";
|
||||
$str .= $offset . "var tmp_{$name} {$native_type}";
|
||||
|
||||
$str .= $offset . buf2var("", "tmp_{$name}", $type->getValue(), $buf, $tokens, $is_virtual);
|
||||
$str .= $offset . "{$fname} = append({$fname}, ".($need_new?"&":"")."tmp_{$name})";
|
||||
$str .= $offset . "{$fname} = append({$fname}, tmp_{$name})";
|
||||
|
||||
$offset = "\n ";
|
||||
$str .= $offset . "}";
|
||||
|
@ -328,26 +542,26 @@ function buf2var($name, $fname, \mtgType $type, $buf, array $tokens = array(), $
|
|||
return $str;
|
||||
}
|
||||
|
||||
function var2buf($name, $fname, \mtgType $type, $buf, array $tokens = array(), $is_ptr = false)
|
||||
function var2buf($name, $fname, mtgType $type, $buf, array $tokens = array(), $is_ptr = false)
|
||||
{
|
||||
$str = '';
|
||||
|
||||
if($type instanceof \mtgBuiltinType)
|
||||
if($type instanceof mtgBuiltinType)
|
||||
{
|
||||
$str .= _write_op("{$buf}.Write".builtin_type_prefix($type)."($fname, \"$name\")")."\n";
|
||||
}
|
||||
else if($type instanceof \mtgMetaEnum)
|
||||
else if($type instanceof mtgMetaEnum)
|
||||
{
|
||||
$str .= _write_op("{$buf}.WriteI32(int32($fname), \"$name\")");
|
||||
}
|
||||
else if($type instanceof \mtgMetaStruct)
|
||||
else if($type instanceof mtgMetaStruct)
|
||||
{
|
||||
if(array_key_exists('virtual', $tokens))
|
||||
$str .= _write_op("meta.WriteStructGeneric($buf, ".($is_ptr?"":"&")."$fname, \"$name\")");
|
||||
else
|
||||
$str .= _write_op("meta.WriteStruct($buf, ".($is_ptr?"":"&")."$fname, \"$name\")");
|
||||
$str .= _write_op("meta.WriteStruct($buf, &$fname, \"$name\")");
|
||||
}
|
||||
else if($type instanceof \mtgArrType)
|
||||
else if($type instanceof mtgArrType)
|
||||
{
|
||||
$str .= "{$buf}.BeginContainer(\"{$name}\")\n";
|
||||
$str .= " for _, v := range({$fname}) {\n";
|
||||
|
|
|
@ -1,54 +1,90 @@
|
|||
package {{package}}
|
||||
package {{ package }}
|
||||
//THIS FILE IS GENERATED AUTOMATICALLY, DO NOT TOUCH IT!
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"github.com/pkg/errors"
|
||||
"git.bit5.ru/backend/meta"
|
||||
"context"
|
||||
"database/sql"
|
||||
"sort"
|
||||
|
||||
"git.bit5.ru/backend/meta"
|
||||
"git.bit5.ru/gomodules/metadb"
|
||||
"github.com/doug-martin/goqu/v9"
|
||||
"github.com/doug-martin/goqu/v9/exp"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
//supress *imported but not used* warnings
|
||||
var _ = fmt.Printf
|
||||
var _ = sort.SearchInts
|
||||
{% import "macros_enum.twig" as enum_macros %}
|
||||
{% import "macros_struct.twig" as struct_macros %}
|
||||
{% import "macros_rpc.twig" as rpc_macros %}
|
||||
|
||||
{%- import "macro.twig" as macro -%}
|
||||
{% set enums = meta.getunits|filter(u => u is metaenum) %}
|
||||
{% set structs = meta.getunits|filter(u => u is metastruct) %}
|
||||
{% set rpcs = meta.getunits|filter(u => u is metarpc) %}
|
||||
|
||||
{{ macro.decl_units(meta) }}
|
||||
{% for u in enums %}
|
||||
{{ enum_macros.enum(u.object) }}
|
||||
{% endfor %}
|
||||
|
||||
func CreateById(classId uint32) (meta.IMetaStruct, error) {
|
||||
{% for u in structs %}
|
||||
{{ struct_macros.struct(u.object) }}
|
||||
{% endfor %}
|
||||
|
||||
func CreateById(classId uint32) (meta.Struct, error) {
|
||||
switch classId {
|
||||
|
||||
{%- for u in meta.getunits ~%}
|
||||
{%- if u.object is instanceof('\\mtgMetaStruct')~%}
|
||||
case {{u.object.classid}}: { return New{{u.object.name}}(), nil }
|
||||
{%- endif ~%}
|
||||
{%- endfor ~%}
|
||||
|
||||
default : return nil, errors.Errorf("Can't find struct for class id %d", classId)
|
||||
{% for u in structs %}
|
||||
case {{ u.object.classid }}:
|
||||
return New{{ u.object.name }}(), nil
|
||||
{% endfor %}
|
||||
default:
|
||||
return nil, errors.Errorf("Can't find struct for class id %d", classId)
|
||||
}
|
||||
}
|
||||
func CreateByName(name string) (meta.IMetaStruct, error) {
|
||||
|
||||
func CreateByName(name string) (meta.Struct, error) {
|
||||
switch name {
|
||||
|
||||
{%- for u in meta.getunits ~%}
|
||||
{%- if u.object is instanceof('\\mtgMetaStruct')~%}
|
||||
case "{{u.object.name}}": { return New{{u.object.name}}(), nil }
|
||||
{%- endif ~%}
|
||||
{%- endfor ~%}
|
||||
|
||||
default : return nil, errors.Errorf("Can't find struct for name %s", name)
|
||||
{% for u in structs %}
|
||||
case "{{ u.object.name }}":
|
||||
return New{{ u.object.name }}(), nil
|
||||
{% endfor %}
|
||||
default:
|
||||
return nil, errors.Errorf("Can't find struct for name %s", name)
|
||||
}
|
||||
}
|
||||
func CreateRPC(code uint32)(meta.IRPC, error) {
|
||||
|
||||
{% for u in rpcs %}
|
||||
{{ rpc_macros.rpc(u.object) }}
|
||||
{% endfor %}
|
||||
|
||||
func CreateRPC(code uint32) (Rpc, error) {
|
||||
switch code {
|
||||
|
||||
{%- for u in meta.getunits ~%}
|
||||
{%- if u.object is instanceof('\\mtgMetaRPC')~%}
|
||||
case {{u.object.code}}: { return New{{u.object.name}}(), nil }
|
||||
{%- endif ~%}
|
||||
{%- endfor ~%}
|
||||
default: return nil, errors.Errorf("Can't find rpc for code %d", code)
|
||||
{%~ for u in rpcs %}
|
||||
{%- set name = u.object.name|lower|camel|replace({'Rpc': ''}) ~ 'Rpc' %}
|
||||
case {{ u.object.code }}:
|
||||
return &{{ name }}{}, nil
|
||||
{%~ endfor %}
|
||||
default:
|
||||
return nil, errors.Errorf("Can't find rpc for code %d", code)
|
||||
}
|
||||
}
|
||||
|
||||
type RpcHandler interface {
|
||||
{%~ for u in rpcs %}
|
||||
{%- set name = u.object.name|lower|camel|replace({'Rpc': ''}) %}
|
||||
{{ name }}({{ name ~ 'Rpc' }}) error
|
||||
{%~ endfor %}
|
||||
}
|
||||
|
||||
type Rpc interface {
|
||||
Code() uint32
|
||||
Name() string
|
||||
|
||||
Error() (int32, string)
|
||||
SetError(int32, string)
|
||||
|
||||
Execute(RpcHandler) error
|
||||
|
||||
ReadRequest(meta.Reader) error
|
||||
WriteResponse(meta.Writer) error
|
||||
}
|
||||
|
||||
type CreateRpcFunc func(uint32) (Rpc, error)
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
{% macro enum(o) %}
|
||||
{% set values_var = '_' ~ o.name ~ '_values' %}
|
||||
{% set map_var = '_' ~ o.name ~ '_map' %}
|
||||
|
||||
type {{o.name}} int32
|
||||
|
||||
const (
|
||||
{%~ for k,v in o.values %}
|
||||
{{o.name}}_{{k}} {{o.name}} = {{v}}
|
||||
{%~ endfor %}
|
||||
)
|
||||
|
||||
var {{ values_var }} = []int{
|
||||
{%- for v in o.values|sort -%}
|
||||
{{v}},
|
||||
{%- endfor -%}
|
||||
}
|
||||
|
||||
var {{ map_var }} map[string]{{o.name}}
|
||||
func init() {
|
||||
{{ map_var }} = map[string]{{o.name}}{
|
||||
{%- for k,v in o.values -%}
|
||||
"{{k}}": {{v}},
|
||||
{%- endfor -%}
|
||||
}
|
||||
}
|
||||
|
||||
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 {{o.values|first}}
|
||||
}
|
||||
|
||||
func (enum *{{o.name}}) IsValid() bool {
|
||||
return sort.SearchInts({{ values_var }}, int(*enum)) != -1
|
||||
}
|
||||
|
||||
func {{o.name}}_GetNameByValue(value int) string {
|
||||
for name, num := range {{ map_var }} {
|
||||
if value == int(num) {
|
||||
return name
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func New{{o.name}}ByName(name string) ({{o.name}}, error) {
|
||||
if v, ok := {{ map_var }}[name]; ok {
|
||||
return v, nil
|
||||
}
|
||||
return 0, errors.Errorf("Wrong name of {{o.name}}: '%s'", name)
|
||||
}
|
||||
{% endmacro enum %}
|
|
@ -0,0 +1,70 @@
|
|||
{% macro rpc(r) %}
|
||||
{% import "macros_struct.twig" as struct_macros %}
|
||||
|
||||
{% set prefix = r.name|lower|camel|replace({'Rpc': ''}) %}
|
||||
{% set name = prefix ~ 'Rpc' %}
|
||||
{% set req_name = prefix ~ 'Request' %}
|
||||
{% set rsp_name = prefix ~ 'Response' %}
|
||||
|
||||
type {{ name }} struct {
|
||||
req {{ req_name }}
|
||||
rsp {{ rsp_name }}
|
||||
|
||||
errCode int32
|
||||
errMsg string
|
||||
}
|
||||
|
||||
func (rpc {{ name }}) Name() string {
|
||||
return "{{ name }}"
|
||||
}
|
||||
|
||||
func (rpc {{ name }}) Code() uint32 {
|
||||
return {{ r.code }}
|
||||
}
|
||||
|
||||
func (rpc *{{ name }}) SetError(code int32, msg string) {
|
||||
rpc.errCode = code
|
||||
rpc.errMsg = msg
|
||||
}
|
||||
|
||||
func (rpc {{ name }}) Error() (int32, string) {
|
||||
return rpc.errCode, rpc.errMsg
|
||||
}
|
||||
|
||||
func (rpc {{ name }}) Execute(h RpcHandler) error {
|
||||
return h.{{ prefix }}(rpc)
|
||||
}
|
||||
|
||||
func (rpc {{ name }}) Request() {{ req_name }} {
|
||||
return rpc.req
|
||||
}
|
||||
|
||||
func (rpc *{{ name }}) SetResponse(rsp {{ rsp_name }}) {
|
||||
rpc.rsp = rsp
|
||||
}
|
||||
|
||||
func (rpc *{{ name }}) ReadRequest(reader meta.Reader) error {
|
||||
return rpc.req.Read(reader)
|
||||
}
|
||||
|
||||
func (rpc *{{ name }}) WriteResponse(writer meta.Writer) error {
|
||||
return rpc.rsp.Write(writer)
|
||||
}
|
||||
|
||||
type {{ req_name }} struct {
|
||||
{%~ for f in r.req.fields %}
|
||||
{{ f|fname }} {{ f.type|go_type }} `json:"{{ f|alias }}" msgpack:"{{ f|alias }}"`
|
||||
{%~ endfor %}
|
||||
}
|
||||
|
||||
{{ struct_macros.struct_required_fields(req_name, r.req.fields)}}
|
||||
{{ struct_macros.meta_read(r.req, req_name) }}
|
||||
|
||||
type {{ rsp_name }} struct {
|
||||
{%~ for f in r.rsp.fields %}
|
||||
{{ f|fname }} {{ f.type|go_type }} `json:"{{ f|alias }}" msgpack:"{{ f|alias }}"`
|
||||
{%~ endfor %}
|
||||
}
|
||||
|
||||
{{ struct_macros.meta_write(r.rsp, rsp_name) }}
|
||||
{% endmacro rpc %}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue