def _dtype_kind_primitive_read(self, dtype, v): sb = StringBuilder() dtype_name = dtype.get_name() sb.wl("{} = codec.read_{}()".format(v, dtype_name)) return sb.get_string()
def _gen_iface(self): sb = StringBuilder() sb.wl("class Interface(metaclass = ABCMeta):") methods = self._sort_by_name(self._methods) if len(methods) == 0: sb.wl("\tpass") sb.we() else: for method in methods: name = method.get_name() in_struct = method.get_in_struct() args = [field.get_name() for field in in_struct.get_fields()] args.insert(0, "self") argsf = ", ".join(args) sb.wl("\t@abstractmethod") sb.wl("\tdef {}({}):".format(name, argsf)) sb.wl("\t\tpass") sb.we() self._ws(sb.get_string())
def _dtype_kind_primitive_write(self, dtype, v): sb = StringBuilder() dtype_name = dtype.get_name() sb.wl("codec.write_{}({})".format(dtype_name, v)) return sb.get_string()
def _dtype_kind_enum_gen(self, dtype): sb = StringBuilder() dtype_name = dtype.get_name() entries = dtype.get_entries() values = dtype.get_values() classn = self._get_dtype_classn(dtype_name) read_funcn = self._get_enum_read_funcn(dtype_name) write_funcn = self._get_enum_write_funcn(dtype_name) validate_funcn = self._get_enum_validate_funcn(dtype_name) sb.wl("{} = {{".format(classn)) lasti = len(entries) - 1 for (i, (name, value)) in enumerate(entries): sb.wl("\t{}: {}{}".format(name, value, "," if i < lasti else "")) sb.wl("};") sb.we() sb.wl("{} = function(codec)".format(read_funcn)) sb.wl("{") sb.wl("\tvar v = codec.read_i32();") sb.we() sb.wl("\t{}(true, v);".format(validate_funcn)) sb.we() sb.wl("\treturn v;") sb.wl("};") sb.we() sb.wl("{} = function(codec, v)".format(write_funcn)) sb.wl("{") sb.wl("\t{}(false, v);".format(validate_funcn)) sb.we() sb.wl("\tcodec.write_i32(v);") sb.wl("};") sb.we() sb.wl("{} = function(is_read, v)".format(validate_funcn)) sb.wl("{") sb.wl("\tvar msg;") valuesf = ", ".join(values) sb.wl("\tvar values = [{}];".format(valuesf)) sb.we() sb.wl("\tif (values.indexOf(v) == -1) {") sb.wl("\t\tmsg = \"Enum {} unknown value \" + v;".format(dtype_name)) sb.we() sb.wl("\t\tif (is_read)") sb.wl("\t\t\tthrow new myrpc.common.MessageBodyException(msg);") sb.wl("\t\telse") sb.wl("\t\t\tthrow new myrpc.common.MessageEncodeException(msg);") sb.wl("\t}") sb.wl("};") sb.we() return sb.get_string()
def _dtype_kind_enum_gen(self, dtype): sb = StringBuilder() dtype_name = dtype.get_name() entries = dtype.get_entries() values = dtype.get_values() classn = self._get_dtype_classn(dtype_name) read_funcn = self._get_enum_read_funcn(dtype_name) write_funcn = self._get_enum_write_funcn(dtype_name) validate_funcn = self._get_enum_validate_funcn(dtype_name) sb.wl("{} = {{".format(classn)) lasti = len(entries) - 1 for (i, (name, value)) in enumerate(entries): sb.wl("\t{}: {}{}".format(name, value, "," if i < lasti else "")) sb.wl("};") sb.we() sb.wl("{} = function(codec)".format(read_funcn)) sb.wl("{") sb.wl("\tvar v = codec.read_i32();") sb.we() sb.wl("\t{}(true, v);".format(validate_funcn)) sb.we() sb.wl("\treturn v;") sb.wl("};") sb.we() sb.wl("{} = function(codec, v)".format(write_funcn)) sb.wl("{") sb.wl("\t{}(false, v);".format(validate_funcn)) sb.we() sb.wl("\tcodec.write_i32(v);") sb.wl("};") sb.we() sb.wl("{} = function(is_read, v)".format(validate_funcn)) sb.wl("{") sb.wl("\tvar msg;") valuesf = ", ".join(values) sb.wl("\tvar values = [{}];".format(valuesf)) sb.we() sb.wl("\tif (values.indexOf(v) == -1) {") sb.wl("\t\tmsg = \"Enum {} unknown value \" + v;".format(dtype_name)) sb.we() sb.wl("\t\tif (is_read)") sb.wl("\t\t\tthrow new myrpc.common.MessageBodyException(msg);") sb.wl("\t\telse") sb.wl("\t\t\tthrow new myrpc.common.MessageEncodeException(msg);") sb.wl("\t}") sb.wl("};") sb.we() return sb.get_string()
def _wfooter_node(self): self._strip_extra_nl() sb = StringBuilder() sb.wl("})();") self._ws(sb.get_string())
def _dtype_kind_list_read(self, dtype, v): sb = StringBuilder() dtype_name = dtype.get_name() funcn = self._get_list_read_funcn(dtype_name) sb.wl("{} = {}(codec)".format(v, funcn)) return sb.get_string()
def _dtype_kind_list_write(self, dtype, v): sb = StringBuilder() dtype_name = dtype.get_name() funcn = self._get_list_write_funcn(dtype_name) sb.wl("{}(codec, {})".format(funcn, v)) return sb.get_string()
def _wfooter_node(self): self._strip_extra_nl() sb = StringBuilder() sb.wl("})();") self._ws(sb.get_string())
def _dtype_kind_list_gen(self, dtype): sb = StringBuilder() dtype_name = dtype.get_name() elem_dtype = dtype.get_elem_dtype() read_funcn = self._get_list_read_funcn(dtype_name) write_funcn = self._get_list_write_funcn(dtype_name) codec_dtype_classn = self._get_codec_dtype_classn(elem_dtype) sb.wl("{} = function(codec)".format(read_funcn)) sb.wl("{") sb.wl("\tvar linfo;") sb.wl("\tvar llen;") sb.wl("\tvar dtype;") sb.wl("\tvar i;") sb.wl("\tvar elem;") sb.wl("\tvar l = [];") sb.we() sb.wl("\tlinfo = codec.read_list_begin();") sb.wl("\tllen = linfo[0];") sb.wl("\tdtype = linfo[1];") sb.we() sb.wl("\tif (dtype != {})".format(codec_dtype_classn)) sb.wl( "\t\tthrow new myrpc.common.MessageBodyException(\"List {} has unexpected elem data type \" + dtype);" .format(dtype_name)) sb.we() sb.wl("\tfor (i = 0; i < llen; i++) {") s = self._gtm.read_dtype(elem_dtype, "elem") sb.wlsindent("\t\t", s) sb.wl("\t\tl.push(elem);") sb.wl("\t}") sb.we() sb.wl("\tcodec.read_list_end();") sb.we() sb.wl("\treturn l;") sb.wl("};") sb.we() sb.wl("{} = function(codec, l)".format(write_funcn)) sb.wl("{") sb.wl("\tcodec.write_list_begin(l.length, {});".format( codec_dtype_classn)) sb.we() sb.wl("\tl.forEach(function(elem) {") s = self._gtm.write_dtype(elem_dtype, "elem") sb.wlsindent("\t\t", s) sb.wl("\t});") sb.we() sb.wl("\tcodec.write_list_end();") sb.wl("};") sb.we() return sb.get_string()
def _dtype_kind_struct_read(self, dtype, v): sb = StringBuilder() dtype_name = dtype.get_name() classn = self._get_dtype_classn(dtype_name) sb.wl("{} = {}()".format(v, classn)) sb.wl("{}.{}(codec)".format(v, _STRUCT_READ)) return sb.get_string()
def gen_types(self): self._open(_TYPES_FILENAME) # Do target specific namespace creation. if self._target == Target.BROWSER: # Create JavaScript namespace. Types.js should be included first, # before any other generated files. sb = StringBuilder() compl = self._namespace.split(_NS_SEPARATOR) for i in range(len(compl)): current_namespace = compl[i] parent_namespace = "window" if i == 0 else _NS_SEPARATOR.join( compl[:i]) sb.wl("if (!(\"{0}\" in {1})) {1}{2}{0} = {{}};".format( current_namespace, parent_namespace, _NS_SEPARATOR)) sb.we() self._ws(sb.get_string()) elif self._target == Target.NODE: self._wheader_node(("codec/CodecBase", ), True) else: raise InternalException("target {} is unknown".format( self._target)) sb = StringBuilder() sb.wl("{} = {{}};".format(self._dtype_classp)) sb.we() self._ws(sb.get_string()) self._gen_types() self._gen_args_result_seri() if self._target == Target.NODE: self._wfooter_node() self._close()
def _dtype_kind_list_gen(self, dtype): sb = StringBuilder() dtype_name = dtype.get_name() elem_dtype = dtype.get_elem_dtype() read_funcn = self._get_list_read_funcn(dtype_name) write_funcn = self._get_list_write_funcn(dtype_name) codec_dtype_classn = self._get_codec_dtype_classn(elem_dtype) sb.wl("{} = function(codec)".format(read_funcn)) sb.wl("{") sb.wl("\tvar linfo;") sb.wl("\tvar llen;") sb.wl("\tvar dtype;") sb.wl("\tvar i;") sb.wl("\tvar elem;") sb.wl("\tvar l = [];") sb.we() sb.wl("\tlinfo = codec.read_list_begin();") sb.wl("\tllen = linfo[0];") sb.wl("\tdtype = linfo[1];") sb.we() sb.wl("\tif (dtype != {})".format(codec_dtype_classn)) sb.wl("\t\tthrow new myrpc.common.MessageBodyException(\"List {} has unexpected elem data type \" + dtype);".format(dtype_name)) sb.we() sb.wl("\tfor (i = 0; i < llen; i++) {") s = self._gtm.read_dtype(elem_dtype, "elem") sb.wlsindent("\t\t", s) sb.wl("\t\tl.push(elem);") sb.wl("\t}") sb.we() sb.wl("\tcodec.read_list_end();") sb.we() sb.wl("\treturn l;") sb.wl("};") sb.we() sb.wl("{} = function(codec, l)".format(write_funcn)) sb.wl("{") sb.wl("\tcodec.write_list_begin(l.length, {});".format(codec_dtype_classn)) sb.we() sb.wl("\tl.forEach(function(elem) {") s = self._gtm.write_dtype(elem_dtype, "elem") sb.wlsindent("\t\t", s) sb.wl("\t});") sb.we() sb.wl("\tcodec.write_list_end();") sb.wl("};") sb.we() return sb.get_string()
def gen_types(self): self._open(_TYPES_FILENAME) # Do target specific namespace creation. if self._target == Target.BROWSER: # Create JavaScript namespace. Types.js should be included first, # before any other generated files. sb = StringBuilder() compl = self._namespace.split(_NS_SEPARATOR) for i in range(len(compl)): current_namespace = compl[i] parent_namespace = "window" if i == 0 else _NS_SEPARATOR.join(compl[:i]) sb.wl("if (!(\"{0}\" in {1})) {1}{2}{0} = {{}};".format(current_namespace, parent_namespace, _NS_SEPARATOR)) sb.we() self._ws(sb.get_string()) elif self._target == Target.NODE: self._wheader_node(("codec/CodecBase",), True) else: raise InternalException("target {} is unknown".format(self._target)) sb = StringBuilder() sb.wl("{} = {{}};".format(self._dtype_classp)) sb.we() self._ws(sb.get_string()) self._gen_types() self._gen_args_result_seri() if self._target == Target.NODE: self._wfooter_node() self._close()
def _dtype_kind_enum_gen(self, dtype): sb = StringBuilder() dtype_name = dtype.get_name() entries = dtype.get_entries() values = dtype.get_values() classn = self._get_dtype_classn(dtype_name) read_funcn = self._get_enum_read_funcn(dtype_name) write_funcn = self._get_enum_write_funcn(dtype_name) validate_funcn = self._get_enum_validate_funcn(dtype_name) sb.wl("class {}:".format(classn)) if len(entries) == 0: sb.wl("\tpass") else: for (name, value) in entries: sb.wl("\t{} = {}".format(name, value)) sb.we() sb.wl("def {}(codec):".format(read_funcn)) sb.wl("\tv = codec.read_i32()") sb.we() sb.wl("\t{}(True, v)".format(validate_funcn)) sb.we() sb.wl("\treturn v") sb.we() sb.wl("def {}(codec, v):".format(write_funcn)) sb.wl("\t{}(False, v)".format(validate_funcn)) sb.we() sb.wl("\tcodec.write_i32(v)") sb.we() sb.wl("def {}(is_read, v):".format(validate_funcn)) valuesf = ", ".join(values) if len(values) == 1: valuesf += "," sb.wl("\tvalues = ({})".format(valuesf)) sb.we() sb.wl("\tif v not in values:") sb.wl("\t\tmsg = \"Enum {} unknown value {{}}\".format(v)".format(dtype_name)) sb.we() sb.wl("\t\tif is_read:") sb.wl("\t\t\traise myrpc.Common.MessageBodyException(msg)") sb.wl("\t\telse:") sb.wl("\t\t\traise myrpc.Common.MessageEncodeException(msg)") sb.we() return sb.get_string()
def _gen_client(self): sb = StringBuilder() sb.wl("class Client:") sb.wl("\tdef __init__(self, tr, codec):") sb.wl("\t\tself._client = ClientSubr(tr, codec)") sb.we() classn_prefix = "{}.".format(_TYPES_MODULE) methods = self._sort_by_name(self._methods) for method in methods: name = method.get_name() in_struct = method.get_in_struct() args_seri_classn = self._get_args_seri_classn(name, classn_prefix) result_seri_classn = self._get_result_seri_classn(name, classn_prefix) exc_handler_funcn = self._get_exc_handler_funcn(name) in_field_names = [field.get_name() for field in in_struct.get_fields()] args = ["arg_{}".format(in_field_name) for in_field_name in in_field_names] args_self = args.copy() args_self.insert(0, "self") args_selff = ", ".join(args_self) sb.wl("\tdef {}({}):".format(name, args_selff)) sb.wl("\t\targs_seri = {}()".format(args_seri_classn)) for i in range(len(in_field_names)): in_field_name = in_field_names[i] arg = args[i] setter_invoke = self._get_struct_field_setter_invoke("args_seri", in_field_name, arg, _ARGS_RESULT_SERI_SFA) sb.wl("\t\t{}".format(setter_invoke)) sb.we() sb.wl("\t\tresult_seri = {}()".format(result_seri_classn)) sb.we() sb.wl("\t\texc_handler = self.{}".format(exc_handler_funcn)) sb.we() sb.wl("\t\tr = self._client.call(\"{}\", args_seri, result_seri, exc_handler)".format(name)) sb.we() sb.wl("\t\treturn r") sb.we() self._ws(sb.get_string())
def _gen_exc_handler(self): sb = StringBuilder() methods = self._sort_by_name(self._methods) for method in methods: name = method.get_name() excs = method.get_excs() funcn = self._get_exc_handler_funcn(name) sb.wl("{}.prototype.{} = function(codec, name)".format( self._client_classn, funcn)) sb.wl("{") sb.wl("\tvar excmap = {") lasti = len(excs) - 1 for (i, exc) in enumerate(excs): exc_name = exc.get_name() exc_classn = self._get_dtype_classn(exc_name) # Use MYRPC_PREFIX as prefix before exception names. It is # needed because JavaScript objects contain built-in members # (e.g. toString). sb.wl("\t\t\"{}{}\": {}{}".format(MYRPC_PREFIX, exc_name, exc_classn, "," if i < lasti else "")) sb.wl("\t};") sb.wl("\tvar exc_name = \"{}\" + name;".format(MYRPC_PREFIX)) sb.wl("\tvar exc_class;") sb.wl("\tvar exc;") sb.we() sb.wl("\tif (!(exc_name in excmap))") sb.wl( "\t\tthrow new myrpc.common.MessageHeaderException(\"Unknown exception name \" + name);" ) sb.we() sb.wl("\texc_class = excmap[exc_name];") sb.wl("\texc = new exc_class();") sb.wl("\texc.{}(codec);".format(_STRUCT_READ)) sb.we() sb.wl("\treturn exc;") sb.wl("};") sb.we() self._ws(sb.get_string())
def gen_types(self): self._open(_TYPES_FILENAME) # Do not use from ... import ... statement here, since it can # lead to IDL type conflict. sb = StringBuilder() sb.wl("import myrpc.Common") sb.wl("import myrpc.codec.CodecBase") sb.we() self._ws(sb.get_string()) self._gen_types() self._gen_args_result_seri() self._close()
def _gen_exc_handler(self): sb = StringBuilder() methods = self._sort_by_name(self._methods) for method in methods: name = method.get_name() excs = method.get_excs() funcn = self._get_exc_handler_funcn(name) sb.wl("{}.prototype.{} = function(codec, name)".format(self._client_classn, funcn)) sb.wl("{") sb.wl("\tvar excmap = {") lasti = len(excs) - 1 for (i, exc) in enumerate(excs): exc_name = exc.get_name() exc_classn = self._get_dtype_classn(exc_name) # Use MYRPC_PREFIX as prefix before exception names. It is # needed because JavaScript objects contain built-in members # (e.g. toString). sb.wl("\t\t\"{}{}\": {}{}".format(MYRPC_PREFIX, exc_name, exc_classn, "," if i < lasti else "")) sb.wl("\t};") sb.wl("\tvar exc_name = \"{}\" + name;".format(MYRPC_PREFIX)) sb.wl("\tvar exc_class;") sb.wl("\tvar exc;") sb.we() sb.wl("\tif (!(exc_name in excmap))") sb.wl("\t\tthrow new myrpc.common.MessageHeaderException(\"Unknown exception name \" + name);") sb.we() sb.wl("\texc_class = excmap[exc_name];") sb.wl("\texc = new exc_class();") sb.wl("\texc.{}(codec);".format(_STRUCT_READ)) sb.we() sb.wl("\treturn exc;") sb.wl("};") sb.we() self._ws(sb.get_string())
def gen_client(self): self._open(_CLIENT_FILENAME) # Use Types. prefix to reference the types in Types module (to # prevent IDL type conflict). sb = StringBuilder() sb.wl("from myrpc.Common import MessageHeaderException") sb.wl("from myrpc.util.ClientSubr import ClientSubr") sb.we() sb.wl("from {} import {}".format(self._namespace, _TYPES_MODULE)) sb.we() self._ws(sb.get_string()) self._gen_client() self._gen_exc_handler() self._close()
def gen_processor(self): self._open(_PROCESSOR_FILENAME) # Use Types. prefix to reference the types in Types module (to # prevent IDL type conflict). sb = StringBuilder() sb.wl("from abc import ABCMeta, abstractmethod") sb.we() sb.wl("from myrpc.util.ProcessorSubr import HandlerReturn, ProcessorSubr, ProcessorNotFinishedClass") sb.we() sb.wl("from {} import {}".format(self._namespace, _TYPES_MODULE)) sb.we() self._ws(sb.get_string()) self._gen_iface() self._gen_processor() self._close()
def _wheader_node(self, mods, create_ns): sb = StringBuilder() sb.wl("(function() {") sb.wl("var myrpc;") sb.wl("var {};".format(self._namespace)) sb.we() sb.wl("myrpc = require(\"myrpc-runtime\");") for mod in mods: sb.wl("require(\"myrpc-runtime/lib/{}\");".format(mod)) sb.we() sb.wl("{} = {};".format(self._namespace, "{}" if create_ns else "require(\"./{}\")".format(_TYPES_MODULE))) sb.we() sb.wl("module.exports = {};".format(self._namespace)) sb.we() self._ws(sb.get_string())
def _dtype_kind_list_gen(self, dtype): sb = StringBuilder() dtype_name = dtype.get_name() elem_dtype = dtype.get_elem_dtype() read_funcn = self._get_list_read_funcn(dtype_name) write_funcn = self._get_list_write_funcn(dtype_name) codec_dtype_classn = self._get_codec_dtype_classn(elem_dtype) sb.wl("def {}(codec):".format(read_funcn)) sb.wl("\t(llen, dtype) = codec.read_list_begin()") sb.we() sb.wl("\tif dtype != {}:".format(codec_dtype_classn)) sb.wl("\t\traise myrpc.Common.MessageBodyException(\"List {} has unexpected elem data type {{}}\".format(dtype))".format(dtype_name)) sb.we() sb.wl("\tl = []") sb.we() sb.wl("\tfor i in range(llen):") s = self._gtm.read_dtype(elem_dtype, "elem") sb.wlsindent("\t\t", s) sb.wl("\t\tl.append(elem)") sb.we() sb.wl("\tcodec.read_list_end()") sb.we() sb.wl("\treturn l") sb.we() sb.wl("def {}(codec, l):".format(write_funcn)) sb.wl("\tcodec.write_list_begin(len(l), {})".format(codec_dtype_classn)) sb.we() sb.wl("\tfor elem in l:") s = self._gtm.write_dtype(elem_dtype, "elem") sb.wlsindent("\t\t", s) sb.we() sb.wl("\tcodec.write_list_end()") sb.we() return sb.get_string()
def _wheader_node(self, mods, create_ns): sb = StringBuilder() sb.wl("(function() {") sb.wl("var myrpc;") sb.wl("var {};".format(self._namespace)) sb.we() sb.wl("myrpc = require(\"myrpc-runtime\");") for mod in mods: sb.wl("require(\"myrpc-runtime/lib/{}\");".format(mod)) sb.we() sb.wl("{} = {};".format( self._namespace, "{}" if create_ns else "require(\"./{}\")".format(_TYPES_MODULE))) sb.we() sb.wl("module.exports = {};".format(self._namespace)) sb.we() self._ws(sb.get_string())
def _gen_exc_handler(self): sb = StringBuilder() classn_prefix = "{}.".format(_TYPES_MODULE) methods = self._sort_by_name(self._methods) for method in methods: name = method.get_name() excs = method.get_excs() funcn = self._get_exc_handler_funcn(name) sb.wl("\tdef {}(self, codec, name):".format(funcn)) sb.wl("\t\texcmap = {") lasti = len(excs) - 1 for (i, exc) in enumerate(excs): exc_name = exc.get_name() exc_classn = self._get_dtype_classn(exc_name, classn_prefix) sb.wl("\t\t\t\"{}\": {}{}".format(exc_name, exc_classn, "," if i < lasti else "")) sb.wl("\t\t}") sb.we() sb.wl("\t\tif name not in excmap:") sb.wl("\t\t\traise MessageHeaderException(\"Unknown exception name {}\".format(name))") sb.we() sb.wl("\t\texc_class = excmap[name]") sb.wl("\t\texc = exc_class()") sb.wl("\t\texc.{}(codec)".format(_STRUCT_READ)) sb.we() sb.wl("\t\treturn exc") sb.we() self._ws(sb.get_string())
def _gen_client(self): sb = StringBuilder() sb.wl("{} = function(tr, codec)".format(self._client_classn)) sb.wl("{") sb.wl("\tthis._client = new myrpc.util.ClientSubr(tr, codec);") sb.wl("};") sb.we() methods = self._sort_by_name(self._methods) for method in methods: name = method.get_name() in_struct = method.get_in_struct() args_seri_classn = self._get_args_seri_classn(name) result_seri_classn = self._get_result_seri_classn(name) exc_handler_funcn = self._get_exc_handler_funcn(name) in_field_names = [field.get_name() for field in in_struct.get_fields()] args = ["arg_{}".format(in_field_name) for in_field_name in in_field_names] args_oncontinue = args.copy() args_oncontinue.append(_ONCONTINUE) args_oncontinuef = ", ".join(args_oncontinue) sb.wl("{}.prototype.{} = function({})".format(self._client_classn, name, args_oncontinuef)) sb.wl("{") sb.wl("\tvar args_seri;") sb.wl("\tvar result_seri;") sb.wl("\tvar exc_handler;") sb.we() sb.wl("\targs_seri = new {}();".format(args_seri_classn)) for i in range(len(in_field_names)): in_field_name = in_field_names[i] arg = args[i] setter_invoke = self._get_struct_field_setter_invoke("args_seri", in_field_name, arg, _ARGS_RESULT_SERI_SFA) sb.wl("\t{};".format(setter_invoke)) sb.we() sb.wl("\tresult_seri = new {}();".format(result_seri_classn)) sb.we() sb.wl("\texc_handler = myrpc.common.proxy(this.{}, this);".format(exc_handler_funcn)) sb.we() sb.wl("\tthis._client.call(\"{}\", args_seri, result_seri, exc_handler, {}, this);".format(name, _ONCONTINUE)) sb.wl("};") sb.we() sb.wl("{}.prototype.{} = function()".format(self._client_classn, _CONTINUE)) sb.wl("{") sb.wl("\tvar r = this._client.call_continue();") sb.we() sb.wl("\treturn r;") sb.wl("};") sb.we() self._ws(sb.get_string())
def _dtype_kind_struct_write(self, dtype, v): sb = StringBuilder() sb.wl("{}.{}(codec)".format(v, _STRUCT_WRITE)) return sb.get_string()
def _dtype_kind_struct_gen(self, dtype, classn = None, sfa = None): sb = StringBuilder() dtype_name = dtype.get_name() fields = dtype.get_fields() dtype_kind_is_exc = (dtype.get_dtype_kind() == DataTypeKind.EXC) # We have the option to override classname, it is used # during method args_seri/result_seri generation (these are # structs). if classn == None: classn = self._get_dtype_classn(dtype_name) # Do we need to generate validation method? is_validate_needed = False for field in fields: if field.get_req(): is_validate_needed = True break if sfa == None: sfa = self._sfa parent_classn = "(Exception)" if dtype_kind_is_exc else "" sb.wl("class {}{}:".format(classn, parent_classn)) sb.wl("\tdef __init__(self):") if dtype_kind_is_exc: sb.wl("\t\tsuper().__init__()") if len(fields) > 0: sb.we() elif len(fields) == 0: sb.wl("\t\tpass") for field in fields: name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) sb.wl("\t\t{} = None".format(var_name)) sb.we() # Generate setter/getter methods. self._sfa_check_start(dtype_name) for field in fields: name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) getter_name = self._get_struct_field_getter_name(name, sfa) setter_name = self._get_struct_field_setter_name(name, sfa) if getter_name != None: self._sfa_check_name(getter_name) sb.wl("\tdef {}(self):".format(getter_name)) sb.wl("\t\treturn {}".format(var_name)) sb.we() if setter_name != None: self._sfa_check_name(setter_name) sb.wl("\tdef {}(self, {}):".format(setter_name, name)) sb.wl("\t\t{} = {}".format(var_name, name)) sb.we() # Generate serializer, deserializer and validator methods. sb.wl("\tdef {}(self, codec):".format(_STRUCT_READ)) sb.wl("\t\tcodec.read_struct_begin()") sb.we() sb.wl("\t\twhile True:") sb.wl("\t\t\t(fid, dtype) = codec.read_field_begin()") sb.wl("\t\t\terr_dtype = False") sb.wl("\t\t\terr_dup = False") sb.we() sb.wl("\t\t\tif fid == myrpc.codec.CodecBase.FID_STOP:") sb.wl("\t\t\t\tbreak") sb.we() for (i, field) in enumerate(fields): fid = field.get_fid() field_dtype = field.get_dtype() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) codec_dtype_classn = self._get_codec_dtype_classn(field_dtype) sb.wl("\t\t\t{} fid == {}:".format("elif" if i > 0 else "if", fid)) sb.wl("\t\t\t\tif dtype != {}:".format(codec_dtype_classn)) sb.wl("\t\t\t\t\terr_dtype = True") sb.wl("\t\t\t\telif {} != None:".format(var_name)) sb.wl("\t\t\t\t\terr_dup = True") sb.wl("\t\t\t\telse:") s = self._gtm.read_dtype(field_dtype, var_name) sb.wlsindent("\t\t\t\t\t", s) indent = "\t\t\t" if len(fields) > 0: sb.wl("\t\t\telse:") indent += "\t" sb.wl("{}raise myrpc.Common.MessageBodyException(\"Struct {} unknown fid {{}}\".format(fid))".format(indent, dtype_name)) sb.we() sb.wl("\t\t\tif err_dtype:") sb.wl("\t\t\t\traise myrpc.Common.MessageBodyException(\"Struct {} fid {{}} has unexpected data type {{}}\".format(fid, dtype))".format(dtype_name)) sb.wl("\t\t\telif err_dup:") sb.wl("\t\t\t\traise myrpc.Common.MessageBodyException(\"Struct {} fid {{}} is duplicated\".format(fid))".format(dtype_name)) sb.we() sb.wl("\t\t\tcodec.read_field_end()") sb.we() sb.wl("\t\tcodec.read_struct_end()") if is_validate_needed: sb.we() sb.wl("\t\tself.{}(True)".format(_STRUCT_VALIDATE)) sb.we() sb.wl("\tdef {}(self, codec):".format(_STRUCT_WRITE)) if is_validate_needed: sb.wl("\t\tself.{}(False)".format(_STRUCT_VALIDATE)) sb.we() sb.wl("\t\tcodec.write_struct_begin()") sb.we() for field in fields: fid = field.get_fid() req = field.get_req() field_dtype = field.get_dtype() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) codec_dtype_classn = self._get_codec_dtype_classn(field_dtype) indent = "\t\t" if not req: sb.wl("\t\tif {} != None:".format(var_name)) indent += "\t" sb.wl("{}codec.write_field_begin({}, {})".format(indent, fid, codec_dtype_classn)) s = self._gtm.write_dtype(field_dtype, var_name) sb.wlsindent(indent, s) sb.wl("{}codec.write_field_end()".format(indent)) sb.we() sb.wl("\t\tcodec.write_field_stop()") sb.we() sb.wl("\t\tcodec.write_struct_end()") sb.we() if is_validate_needed: sb.wl("\tdef {}(self, is_read):".format(_STRUCT_VALIDATE)) sb.wl("\t\tname = None") sb.we() i = 0 for field in fields: req = field.get_req() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) if req: sb.wl("\t\t{} {} == None:".format("elif" if i > 0 else "if", var_name)) sb.wl("\t\t\tname = \"{}\"".format(name)) i += 1 sb.we() sb.wl("\t\tif name != None:") sb.wl("\t\t\tmsg = \"Struct {} field {{}} is None\".format(name)".format(dtype_name)) sb.we() sb.wl("\t\t\tif is_read:") sb.wl("\t\t\t\traise myrpc.Common.MessageBodyException(msg)") sb.wl("\t\t\telse:") sb.wl("\t\t\t\traise myrpc.Common.MessageEncodeException(msg)") sb.we() return sb.get_string()
def _gen_processor(self): sb = StringBuilder() sb.wl("{} = function(impl)".format(self._processor_classn)) sb.wl("{") sb.wl("\tvar methodmap = {") methods = self._sort_by_name(self._methods) lasti = len(methods) - 1 for (i, method) in enumerate(methods): name = method.get_name() args_seri_classn = self._get_args_seri_classn(name) # Use MYRPC_PREFIX as prefix before exception names. It is # needed because JavaScript objects contain built-in members # (e.g. toString). sb.wl( "\t\t\"{0}{1}\": [{2}, myrpc.common.proxy(this._handle_{1}, this)]{3}" .format(MYRPC_PREFIX, name, args_seri_classn, "," if i < lasti else "")) sb.wl("\t};") sb.we() sb.wl("\tthis._impl = impl;") sb.wl("\tthis._proc = new myrpc.util.ProcessorSubr(methodmap);") sb.wl("};") sb.we() sb.wl("{}.prototype.process_one = function(tr, codec)".format( self._processor_classn)) sb.wl("{") sb.wl("\tvar finished = this._proc.process_one(tr, codec);") sb.we() sb.wl("\treturn finished;") sb.wl("};") sb.we() sb.wl("{}.prototype.call_continue = function(func, user_data)".format( self._processor_classn)) sb.wl("{") sb.wl("\tvar finished = this._proc.call_continue(func, user_data);") sb.we() sb.wl("\treturn finished;") sb.wl("};") sb.we() for method in methods: name = method.get_name() in_struct = method.get_in_struct() excs = method.get_excs() has_result = method.has_result() has_excs = len(excs) > 0 result_seri_classn = self._get_result_seri_classn(name) sb.wl( "{}.prototype._handle_{} = function(args_seri, func, user_data)" .format(self._processor_classn, name)) sb.wl("{") in_field_names = [ field.get_name() for field in in_struct.get_fields() ] args = [ "arg_{}".format(in_field_name) for in_field_name in in_field_names ] argsf = ", ".join(args) for arg in args: sb.wl("\tvar {};".format(arg)) sb.wl("\tvar exc_name = null;") sb.wl("\tvar exc;") sb.wl("\tvar r = null;") sb.wl("\tvar hr;") sb.wl("\tvar result_seri;") sb.we() if len(in_field_names) > 0: sb.wl("\tif (args_seri) {") for i in range(len(in_field_names)): in_field_name = in_field_names[i] arg = "{}".format(args[i]) getter_invoke = self._get_struct_field_getter_invoke( "args_seri", in_field_name, arg, _ARGS_RESULT_SERI_SFA) sb.wl("\t\t{};".format(getter_invoke)) sb.wl("\t}") sb.we() indent = "\t" if has_excs: sb.wl("\ttry {") indent += "\t" # Always check method return value, even if it is declared as void. # If the method would like to do asynchronous execution, then # we have to check for ProcessorNotFinished return value. # Since we are in a try block, be sure that only the called functions # (this._impl.method, func) can throw exceptions. sb.wl("{}r = args_seri ? this._impl.{}({}) : func(user_data);". format(indent, name, argsf)) if has_excs: sb.wl("\t} catch (e) {") for (i, exc) in enumerate(excs): exc_name = exc.get_name() exc_classn = self._get_dtype_classn(exc_name) sb.wl("\t\t{} (e instanceof {}) {{".format( "} else if" if i > 0 else "if", exc_classn)) sb.wl("\t\t\texc_name = \"{}\";".format(exc_name)) sb.wl("\t\t\texc = e;") sb.wl("\t\t} else {") sb.wl("\t\t\tthrow e;") sb.wl("\t\t}") sb.wl("\t}") sb.we() sb.wl("\thr = new myrpc.util.HandlerReturn();") sb.we() sb.wl("\tif (r instanceof myrpc.util.ProcessorNotFinishedClass) {") sb.wl("\t\thr.set_notfinished();") sb.wl("\t} else if (exc_name != null) {") sb.wl("\t\thr.set_exc(exc, exc_name);") sb.wl("\t} else {") sb.wl("\t\tresult_seri = new {}();".format(result_seri_classn)) if has_result: setter_invoke = self._get_struct_field_setter_invoke( "result_seri", RESULT_FIELD_NAME, "r", _ARGS_RESULT_SERI_SFA) sb.wl("\t\t{};".format(setter_invoke)) sb.we() sb.wl("\t\thr.set_result(result_seri);") sb.wl("\t}") sb.we() sb.wl("\treturn hr;") sb.wl("};") sb.we() self._ws(sb.get_string())
def _dtype_kind_struct_gen(self, dtype, classn=None, sfa=None): sb = StringBuilder() dtype_name = dtype.get_name() fields = dtype.get_fields() # We have the option to override classname, it is used # during method args_seri/result_seri generation (these are # structs). if classn == None: classn = self._get_dtype_classn(dtype_name) # Do we need to generate validation method? is_validate_needed = False for field in fields: if field.get_req(): is_validate_needed = True break if sfa == None: sfa = self._sfa sb.wl("{} = function()".format(classn)) sb.wl("{") for field in fields: name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) sb.wl("\t{} = null;".format(var_name)) sb.wl("};") sb.we() # Generate setter/getter methods. self._sfa_check_start(dtype_name) for field in fields: name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) getter_name = self._get_struct_field_getter_name(name, sfa) setter_name = self._get_struct_field_setter_name(name, sfa) if getter_name != None: self._sfa_check_name(getter_name) sb.wl("{}.prototype.{} = function()".format( classn, getter_name)) sb.wl("{") sb.wl("\treturn {};".format(var_name)) sb.wl("};") sb.we() if setter_name != None: self._sfa_check_name(setter_name) sb.wl("{}.prototype.{} = function({})".format( classn, setter_name, name)) sb.wl("{") sb.wl("\t{} = {};".format(var_name, name)) sb.wl("};") sb.we() # Generate serializer, deserializer and validator methods. sb.wl("{}.prototype.{} = function(codec)".format(classn, _STRUCT_READ)) sb.wl("{") sb.wl("\tvar finfo;") sb.wl("\tvar fid;") sb.wl("\tvar dtype;") sb.wl("\tvar err_dtype;") sb.wl("\tvar err_dup;") sb.we() sb.wl("\tcodec.read_struct_begin();") sb.we() sb.wl("\twhile (true) {") sb.wl("\t\tfinfo = codec.read_field_begin();") sb.wl("\t\tfid = finfo[0];") sb.wl("\t\tdtype = finfo[1];") sb.wl("\t\terr_dtype = false;") sb.wl("\t\terr_dup = false;") sb.we() sb.wl("\t\tif (fid == myrpc.codec.FID_STOP)") sb.wl("\t\t\tbreak;") sb.we() sb.wl("\t\tswitch (fid) {") for field in fields: fid = field.get_fid() field_dtype = field.get_dtype() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) codec_dtype_classn = self._get_codec_dtype_classn(field_dtype) sb.wl("\t\t\tcase {}:".format(fid)) sb.wl("\t\t\t\tif (dtype != {}) {{".format(codec_dtype_classn)) sb.wl("\t\t\t\t\terr_dtype = true;") sb.wl("\t\t\t\t}} else if ({} != null) {{".format(var_name)) sb.wl("\t\t\t\t\terr_dup = true;") sb.wl("\t\t\t\t} else {") s = self._gtm.read_dtype(field_dtype, var_name) sb.wlsindent("\t\t\t\t\t", s) sb.wl("\t\t\t\t}") sb.wl("\t\t\t\tbreak;") sb.we() sb.wl("\t\t\tdefault:") sb.wl( "\t\t\t\tthrow new myrpc.common.MessageBodyException(\"Struct {} unknown fid \" + fid);" .format(dtype_name)) sb.wl("\t\t}") sb.we() sb.wl("\t\tif (err_dtype)") sb.wl( "\t\t\tthrow new myrpc.common.MessageBodyException(\"Struct {} fid \" + fid + \" has unexpected data type \" + dtype);" .format(dtype_name)) sb.wl("\t\telse if (err_dup)") sb.wl( "\t\t\tthrow new myrpc.common.MessageBodyException(\"Struct {} fid \" + fid + \" is duplicated\");" .format(dtype_name)) sb.we() sb.wl("\t\tcodec.read_field_end();") sb.wl("\t}") sb.we() sb.wl("\tcodec.read_struct_end();") if is_validate_needed: sb.we() sb.wl("\tthis.{}(true);".format(_STRUCT_VALIDATE)) sb.wl("};") sb.we() sb.wl("{}.prototype.{} = function(codec)".format( classn, _STRUCT_WRITE)) sb.wl("{") if is_validate_needed: sb.wl("\tthis.{}(false);".format(_STRUCT_VALIDATE)) sb.we() sb.wl("\tcodec.write_struct_begin();") sb.we() for field in fields: fid = field.get_fid() req = field.get_req() field_dtype = field.get_dtype() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) codec_dtype_classn = self._get_codec_dtype_classn(field_dtype) indent = "\t" if not req: sb.wl("\tif ({} != null) {{".format(var_name)) indent += "\t" sb.wl("{}codec.write_field_begin({}, {});".format( indent, fid, codec_dtype_classn)) s = self._gtm.write_dtype(field_dtype, var_name) sb.wlsindent(indent, s) sb.wl("{}codec.write_field_end();".format(indent)) if not req: sb.wl("\t}") sb.we() sb.wl("\tcodec.write_field_stop();") sb.we() sb.wl("\tcodec.write_struct_end();") sb.wl("};") sb.we() if is_validate_needed: sb.wl("{}.prototype.{} = function(is_read)".format( classn, _STRUCT_VALIDATE)) sb.wl("{") sb.wl("\tvar msg;") sb.wl("\tvar name = null;") sb.we() i = 0 for field in fields: req = field.get_req() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) if req: sb.wl("\t{} ({} == null)".format( "else if" if i > 0 else "if", var_name)) sb.wl("\t\tname = \"{}\";".format(name)) i += 1 sb.we() sb.wl("\tif (name != null) {") sb.wl( "\t\tmsg = \"Struct {} field \" + name + \" is null\";".format( dtype_name)) sb.we() sb.wl("\t\tif (is_read)") sb.wl("\t\t\tthrow new myrpc.common.MessageBodyException(msg);") sb.wl("\t\telse") sb.wl("\t\t\tthrow new myrpc.common.MessageEncodeException(msg);") sb.wl("\t}") sb.wl("};") sb.we() return sb.get_string()
def _gen_processor(self): sb = StringBuilder() sb.wl("{} = function(impl)".format(self._processor_classn)) sb.wl("{") sb.wl("\tvar methodmap = {") methods = self._sort_by_name(self._methods) lasti = len(methods) - 1 for (i, method) in enumerate(methods): name = method.get_name() args_seri_classn = self._get_args_seri_classn(name) # Use MYRPC_PREFIX as prefix before exception names. It is # needed because JavaScript objects contain built-in members # (e.g. toString). sb.wl("\t\t\"{0}{1}\": [{2}, myrpc.common.proxy(this._handle_{1}, this)]{3}".format(MYRPC_PREFIX, name, args_seri_classn, "," if i < lasti else "")) sb.wl("\t};") sb.we() sb.wl("\tthis._impl = impl;") sb.wl("\tthis._proc = new myrpc.util.ProcessorSubr(methodmap);") sb.wl("};") sb.we() sb.wl("{}.prototype.process_one = function(tr, codec)".format(self._processor_classn)) sb.wl("{") sb.wl("\tvar finished = this._proc.process_one(tr, codec);") sb.we() sb.wl("\treturn finished;"); sb.wl("};") sb.we() sb.wl("{}.prototype.call_continue = function(func, user_data)".format(self._processor_classn)) sb.wl("{") sb.wl("\tvar finished = this._proc.call_continue(func, user_data);") sb.we() sb.wl("\treturn finished;"); sb.wl("};") sb.we() for method in methods: name = method.get_name() in_struct = method.get_in_struct() excs = method.get_excs() has_result = method.has_result() has_excs = len(excs) > 0 result_seri_classn = self._get_result_seri_classn(name) sb.wl("{}.prototype._handle_{} = function(args_seri, func, user_data)".format(self._processor_classn, name)) sb.wl("{") in_field_names = [field.get_name() for field in in_struct.get_fields()] args = ["arg_{}".format(in_field_name) for in_field_name in in_field_names] argsf = ", ".join(args) for arg in args: sb.wl("\tvar {};".format(arg)) sb.wl("\tvar exc_name = null;") sb.wl("\tvar exc;") sb.wl("\tvar r = null;") sb.wl("\tvar hr;") sb.wl("\tvar result_seri;") sb.we() if len(in_field_names) > 0: sb.wl("\tif (args_seri) {") for i in range(len(in_field_names)): in_field_name = in_field_names[i] arg = "{}".format(args[i]) getter_invoke = self._get_struct_field_getter_invoke("args_seri", in_field_name, arg, _ARGS_RESULT_SERI_SFA) sb.wl("\t\t{};".format(getter_invoke)) sb.wl("\t}") sb.we() indent = "\t" if has_excs: sb.wl("\ttry {") indent += "\t" # Always check method return value, even if it is declared as void. # If the method would like to do asynchronous execution, then # we have to check for ProcessorNotFinished return value. # Since we are in a try block, be sure that only the called functions # (this._impl.method, func) can throw exceptions. sb.wl("{}r = args_seri ? this._impl.{}({}) : func(user_data);".format(indent, name, argsf)) if has_excs: sb.wl("\t} catch (e) {") for (i, exc) in enumerate(excs): exc_name = exc.get_name() exc_classn = self._get_dtype_classn(exc_name) sb.wl("\t\t{} (e instanceof {}) {{".format("} else if" if i > 0 else "if", exc_classn)) sb.wl("\t\t\texc_name = \"{}\";".format(exc_name)) sb.wl("\t\t\texc = e;") sb.wl("\t\t} else {") sb.wl("\t\t\tthrow e;") sb.wl("\t\t}") sb.wl("\t}") sb.we() sb.wl("\thr = new myrpc.util.HandlerReturn();") sb.we() sb.wl("\tif (r instanceof myrpc.util.ProcessorNotFinishedClass) {") sb.wl("\t\thr.set_notfinished();") sb.wl("\t} else if (exc_name != null) {") sb.wl("\t\thr.set_exc(exc, exc_name);") sb.wl("\t} else {") sb.wl("\t\tresult_seri = new {}();".format(result_seri_classn)) if has_result: setter_invoke = self._get_struct_field_setter_invoke("result_seri", RESULT_FIELD_NAME, "r", _ARGS_RESULT_SERI_SFA) sb.wl("\t\t{};".format(setter_invoke)) sb.we() sb.wl("\t\thr.set_result(result_seri);") sb.wl("\t}") sb.we() sb.wl("\treturn hr;") sb.wl("};") sb.we() self._ws(sb.get_string())
def _gen_processor(self): sb = StringBuilder() sb.wl("class Processor:") sb.wl("\tdef __init__(self, impl):") sb.wl("\t\tself._impl = impl") sb.we() sb.wl("\t\tmethodmap = {") classn_prefix = "{}.".format(_TYPES_MODULE) methods = self._sort_by_name(self._methods) lasti = len(methods) - 1 for (i, method) in enumerate(methods): name = method.get_name() args_seri_classn = self._get_args_seri_classn(name, classn_prefix) sb.wl("\t\t\t\"{0}\": ({1}, self._handle_{0}){2}".format(name, args_seri_classn, "," if i < lasti else "")) sb.wl("\t\t}") sb.we() sb.wl("\t\tself._proc = ProcessorSubr(methodmap)") sb.we() sb.wl("\tdef process_one(self, tr, codec):") sb.wl("\t\tfinished = self._proc.process_one(tr, codec)") sb.we() sb.wl("\t\treturn finished") sb.we() sb.wl("\tdef call_continue(self, func, user_data = None):") sb.wl("\t\tfinished = self._proc.call_continue(func, user_data)") sb.we() sb.wl("\t\treturn finished") sb.we() for method in methods: name = method.get_name() in_struct = method.get_in_struct() excs = method.get_excs() has_result = method.has_result() has_excs = len(excs) > 0 result_seri_classn = self._get_result_seri_classn(name, classn_prefix) sb.wl("\tdef _handle_{}(self, args_seri, func, user_data):".format(name)) in_field_names = [field.get_name() for field in in_struct.get_fields()] args = ["arg_{}".format(in_field_name) for in_field_name in in_field_names] argsf = ", ".join(args) if len(in_field_names) > 0: sb.wl("\t\tif args_seri:") for i in range(len(in_field_names)): in_field_name = in_field_names[i] arg = args[i] getter_invoke = self._get_struct_field_getter_invoke("args_seri", in_field_name, arg, _ARGS_RESULT_SERI_SFA) sb.wl("\t\t\t{}".format(getter_invoke)) sb.we() sb.wl("\t\texc_name = None") sb.wl("\t\tr = None") sb.we() indent = "\t\t" if has_excs: sb.wl("\t\ttry:") indent += "\t" # Always check method return value, even if it is declared as void. # If the method would like to do asynchronous execution, then # we have to check for ProcessorNotFinished return value. # Since we are in a try block, be sure that only the called functions # (self._impl.method, func) can throw exceptions. sb.wl("{}r = self._impl.{}({}) if args_seri else func(user_data)".format(indent, name, argsf)) for exc in excs: exc_name = exc.get_name() exc_classn = self._get_dtype_classn(exc_name, classn_prefix) sb.wl("\t\texcept {} as e:".format(exc_classn)) sb.wl("\t\t\texc_name = \"{}\"".format(exc_name)) sb.wl("\t\t\texc = e") sb.we() sb.wl("\t\thr = HandlerReturn()") sb.we() sb.wl("\t\tif isinstance(r, ProcessorNotFinishedClass):") sb.wl("\t\t\thr.set_notfinished()") sb.wl("\t\telif exc_name != None:") sb.wl("\t\t\thr.set_exc(exc, exc_name)") sb.wl("\t\telse:") sb.wl("\t\t\tresult_seri = {}()".format(result_seri_classn)) if has_result: setter_invoke = self._get_struct_field_setter_invoke("result_seri", RESULT_FIELD_NAME, "r", _ARGS_RESULT_SERI_SFA) sb.wl("\t\t\t{}".format(setter_invoke)) sb.we() sb.wl("\t\t\thr.set_result(result_seri)") sb.we() sb.wl("\t\treturn hr") sb.we() self._ws(sb.get_string())
def _dtype_kind_struct_gen(self, dtype, classn = None, sfa = None): sb = StringBuilder() dtype_name = dtype.get_name() fields = dtype.get_fields() # We have the option to override classname, it is used # during method args_seri/result_seri generation (these are # structs). if classn == None: classn = self._get_dtype_classn(dtype_name) # Do we need to generate validation method? is_validate_needed = False for field in fields: if field.get_req(): is_validate_needed = True break if sfa == None: sfa = self._sfa sb.wl("{} = function()".format(classn)) sb.wl("{") for field in fields: name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) sb.wl("\t{} = null;".format(var_name)) sb.wl("};") sb.we() # Generate setter/getter methods. self._sfa_check_start(dtype_name) for field in fields: name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) getter_name = self._get_struct_field_getter_name(name, sfa) setter_name = self._get_struct_field_setter_name(name, sfa) if getter_name != None: self._sfa_check_name(getter_name) sb.wl("{}.prototype.{} = function()".format(classn, getter_name)) sb.wl("{") sb.wl("\treturn {};".format(var_name)) sb.wl("};") sb.we() if setter_name != None: self._sfa_check_name(setter_name) sb.wl("{}.prototype.{} = function({})".format(classn, setter_name, name)) sb.wl("{") sb.wl("\t{} = {};".format(var_name, name)) sb.wl("};") sb.we() # Generate serializer, deserializer and validator methods. sb.wl("{}.prototype.{} = function(codec)".format(classn, _STRUCT_READ)) sb.wl("{") sb.wl("\tvar finfo;") sb.wl("\tvar fid;") sb.wl("\tvar dtype;") sb.wl("\tvar err_dtype;") sb.wl("\tvar err_dup;") sb.we() sb.wl("\tcodec.read_struct_begin();") sb.we() sb.wl("\twhile (true) {") sb.wl("\t\tfinfo = codec.read_field_begin();") sb.wl("\t\tfid = finfo[0];") sb.wl("\t\tdtype = finfo[1];") sb.wl("\t\terr_dtype = false;") sb.wl("\t\terr_dup = false;") sb.we() sb.wl("\t\tif (fid == myrpc.codec.FID_STOP)") sb.wl("\t\t\tbreak;") sb.we() sb.wl("\t\tswitch (fid) {") for field in fields: fid = field.get_fid() field_dtype = field.get_dtype() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) codec_dtype_classn = self._get_codec_dtype_classn(field_dtype) sb.wl("\t\t\tcase {}:".format(fid)) sb.wl("\t\t\t\tif (dtype != {}) {{".format(codec_dtype_classn)) sb.wl("\t\t\t\t\terr_dtype = true;") sb.wl("\t\t\t\t}} else if ({} != null) {{".format(var_name)) sb.wl("\t\t\t\t\terr_dup = true;") sb.wl("\t\t\t\t} else {") s = self._gtm.read_dtype(field_dtype, var_name) sb.wlsindent("\t\t\t\t\t", s) sb.wl("\t\t\t\t}") sb.wl("\t\t\t\tbreak;") sb.we() sb.wl("\t\t\tdefault:") sb.wl("\t\t\t\tthrow new myrpc.common.MessageBodyException(\"Struct {} unknown fid \" + fid);".format(dtype_name)) sb.wl("\t\t}") sb.we() sb.wl("\t\tif (err_dtype)") sb.wl("\t\t\tthrow new myrpc.common.MessageBodyException(\"Struct {} fid \" + fid + \" has unexpected data type \" + dtype);".format(dtype_name)) sb.wl("\t\telse if (err_dup)") sb.wl("\t\t\tthrow new myrpc.common.MessageBodyException(\"Struct {} fid \" + fid + \" is duplicated\");".format(dtype_name)) sb.we() sb.wl("\t\tcodec.read_field_end();") sb.wl("\t}") sb.we() sb.wl("\tcodec.read_struct_end();") if is_validate_needed: sb.we() sb.wl("\tthis.{}(true);".format(_STRUCT_VALIDATE)) sb.wl("};") sb.we() sb.wl("{}.prototype.{} = function(codec)".format(classn, _STRUCT_WRITE)) sb.wl("{") if is_validate_needed: sb.wl("\tthis.{}(false);".format(_STRUCT_VALIDATE)) sb.we() sb.wl("\tcodec.write_struct_begin();") sb.we() for field in fields: fid = field.get_fid() req = field.get_req() field_dtype = field.get_dtype() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) codec_dtype_classn = self._get_codec_dtype_classn(field_dtype) indent = "\t" if not req: sb.wl("\tif ({} != null) {{".format(var_name)) indent += "\t" sb.wl("{}codec.write_field_begin({}, {});".format(indent, fid, codec_dtype_classn)) s = self._gtm.write_dtype(field_dtype, var_name) sb.wlsindent(indent, s) sb.wl("{}codec.write_field_end();".format(indent)) if not req: sb.wl("\t}") sb.we() sb.wl("\tcodec.write_field_stop();") sb.we() sb.wl("\tcodec.write_struct_end();") sb.wl("};") sb.we() if is_validate_needed: sb.wl("{}.prototype.{} = function(is_read)".format(classn, _STRUCT_VALIDATE)) sb.wl("{") sb.wl("\tvar msg;") sb.wl("\tvar name = null;") sb.we() i = 0 for field in fields: req = field.get_req() name = field.get_name() var_name = self._get_struct_field_var_name(name, sfa) if req: sb.wl("\t{} ({} == null)".format("else if" if i > 0 else "if", var_name)) sb.wl("\t\tname = \"{}\";".format(name)) i += 1 sb.we() sb.wl("\tif (name != null) {") sb.wl("\t\tmsg = \"Struct {} field \" + name + \" is null\";".format(dtype_name)) sb.we() sb.wl("\t\tif (is_read)") sb.wl("\t\t\tthrow new myrpc.common.MessageBodyException(msg);") sb.wl("\t\telse") sb.wl("\t\t\tthrow new myrpc.common.MessageEncodeException(msg);") sb.wl("\t}") sb.wl("};") sb.we() return sb.get_string()
def _gen_client(self): sb = StringBuilder() sb.wl("{} = function(tr, codec)".format(self._client_classn)) sb.wl("{") sb.wl("\tthis._client = new myrpc.util.ClientSubr(tr, codec);") sb.wl("};") sb.we() methods = self._sort_by_name(self._methods) for method in methods: name = method.get_name() in_struct = method.get_in_struct() args_seri_classn = self._get_args_seri_classn(name) result_seri_classn = self._get_result_seri_classn(name) exc_handler_funcn = self._get_exc_handler_funcn(name) in_field_names = [ field.get_name() for field in in_struct.get_fields() ] args = [ "arg_{}".format(in_field_name) for in_field_name in in_field_names ] args_oncontinue = args.copy() args_oncontinue.append(_ONCONTINUE) args_oncontinuef = ", ".join(args_oncontinue) sb.wl("{}.prototype.{} = function({})".format( self._client_classn, name, args_oncontinuef)) sb.wl("{") sb.wl("\tvar args_seri;") sb.wl("\tvar result_seri;") sb.wl("\tvar exc_handler;") sb.we() sb.wl("\targs_seri = new {}();".format(args_seri_classn)) for i in range(len(in_field_names)): in_field_name = in_field_names[i] arg = args[i] setter_invoke = self._get_struct_field_setter_invoke( "args_seri", in_field_name, arg, _ARGS_RESULT_SERI_SFA) sb.wl("\t{};".format(setter_invoke)) sb.we() sb.wl("\tresult_seri = new {}();".format(result_seri_classn)) sb.we() sb.wl("\texc_handler = myrpc.common.proxy(this.{}, this);".format( exc_handler_funcn)) sb.we() sb.wl( "\tthis._client.call(\"{}\", args_seri, result_seri, exc_handler, {}, this);" .format(name, _ONCONTINUE)) sb.wl("};") sb.we() sb.wl("{}.prototype.{} = function()".format(self._client_classn, _CONTINUE)) sb.wl("{") sb.wl("\tvar r = this._client.call_continue();") sb.we() sb.wl("\treturn r;") sb.wl("};") sb.we() self._ws(sb.get_string())