def body(self): # declare serializer class self.add( TSimple( StringTemplate(""" class _${messageName}Serializer: def serialize(self, message):""").substitute( {'messageName': self._message.get_name()}))) # serializer function body # serialize fields of message self.add(TSimple("fields = {}", indent=2)) for field in self._message.get_fields(): self.add( TSimple(StringTemplate( """fields["$fieldName"] = $serializer""").substitute({ 'fieldName': field.get_var_name(), 'serializer': SerializersFactory().get_serializer(field)( field, "message." + field.get_var_name()) }), indent=2)) self.add( TSimple( """serializedFields = ','.join([Template('"$fieldName" : $fieldValue').substitute({'fieldName' : key, 'fieldValue' : fields[key]}) for key in fields.keys()])""", indent=2)) # combine all into message self.add( TSimple(StringTemplate( """return Template('{ "$messageName" : { $$fields }}').substitute({'fields' : serializedFields})""" ).substitute({'messageName': self._message.get_name()}), indent=2))
def body(self): self.add(TSimple("#deserialization")) self.add(TSimple("import json")) # message deserializers for msg in self._protocol.get_messages().as_list(): self.add(JsonMessageDeserializer(msg)) # main deserializer self.add(TSimple(StringTemplate(""" class JsonDeserializer: def __init__(self): self._deserializers = {} $deserializersInit def deserialize(self, buffer): decoded = json.loads(buffer) return self._deserialize_json(decoded) def _deserialize_json(self, decoded): MessageName = decoded.keys()[0] return self._deserializers[MessageName].deserialize(decoded[MessageName]) """).substitute({'deserializersInit' : # deserializers init "\n".join([StringTemplate( indent(2, 'self._deserializers["$messageName"] = _${messageName}Deserializer()') ).substitute({'messageName' : msg.get_name()}) for msg in self._protocol.get_messages().as_list()])}))) self.add(TSimple("jsonDeserializer = JsonDeserializer()"))
def body(self): self.add( TSimple( StringTemplate("class $messageName:").substitute( {'messageName': self._message.get_name()}))) # __init__ if (len(self._message.get_fields())) > 0: self.add( TSimple( StringTemplate("def __init__(self, $fields):").substitute({ 'fields': ",".join([ field.get_var_name() for field in self._message.get_fields() ]) }), indent=1)) else: # handle empty messages self.add(TSimple("def __init__(self): pass", indent=1)) # set value of fields for field in self._message.get_fields(): self.add( TSimple( StringTemplate("self.$fieldName = $fieldName").substitute( {'fieldName': field.get_var_name()}), indent=2)) self.add(TNewLine(count=2))
def body(self): code = "" code += StringTemplate( "-module(${protoname}_json_messaging).\n").substitute( {'protoname': self._protocol.get_name()}) code += "-export([serialize_message/1, deserialize_message/1]).\n" code += StringTemplate( '-include("${protoname}_messaging.hrl")').substitute( {'protoname': self._protocol.get_name()}) self.add(MessageSerializers(self._protocol)) self.add(MessageDeserializers(self._protocol)) return code
def replaceSymbols(sourceCodePath: Path, mapping: dict) -> str: """ Read sourcecode and replace symbols by mapping. """ with open(sourceCodePath, "r") as sourceCodeFile: template = StringTemplate(sourceCodeFile.read()) return template.substitute(mapping)
def p_exp_lvalue_assign(p): p[0] = NonTerminal() if p[1].is_array: index, name = index_name_from_str(p[1].value) init_index = get_array_index(name) new_index = new_temp() update_output_table(new_index, "int") p[0].code += p[1].code p[0].code += new_index + "=" + str(index) + "+" + str( init_index) + ";" p[1].value = "array[" + new_index + "]" if p[3].is_array: index, name = index_name_from_str(p[3].value) init_index = get_array_index(name) p[3].value = "array[" + p[3].in_place + "]" if p[3].bool_gen: p[0].code += p[1].value + "= 0;" replace_code = p[1].value + "=1;" p[0].code += StringTemplate( p[3].code).substitute(code=replace_code) elif p[3].relop_parts: p[0].code += p[1].code + p[3].code p[0].code += p[1].value + "= 0;" label = new_label() for item in p[3].relop_parts: p[0].code += "if (" + item + ")" + "goto " + label + ";" p[0].code += p[1].value + "= 1;" p[0].code += label + ": " else: CodeGenerator.assign_lvalue(p)
def list_serializer(field, valueName): elementType = field.get_element_type() serializer = SerializersFactory().get_serializer(elementType)(elementType, "val") return StringTemplate( """ "[" + ",".join([$serializer for val in $valueName]) + "]" """ ).substitute(locals())
def body(self): protocolName = self._protocol.get_name() self.add( TSimple( StringTemplate( "-module(${protocolName}_json_messaging).").substitute( locals()))) self.add( TSimple( StringTemplate( '-include("${protocolName}_messaging.hrl").').substitute( locals()))) self.add( TSimple("-export([serialize_message/1, deserialize_message/1]).")) self.add(MessageSerializers(self._protocol)) self.add(MessageDeserializers(self._protocol))
def p_simple_switch(p): "simple : ON LRB exp RRB LCB cases RCB SEMICOLON" p[0] = NonTerminal() cases = StringTemplate(p[6].code) p[0].code += cases.substitute(cond=p[3].value) if DEBUG: print("p_simple_switch" + " : " + p[0].code)
def body(self): # class and function header self.add(TSimple(StringTemplate(""" class _${messageName}Deserializer: def deserialize(self, decoded): return $messageName(""").substitute({'messageName' : self._message.get_name()}))) # deserializer function body self.add(TComaSeparated([TSimple( StringTemplate("$fieldName=$deserializer").substitute( {'fieldName' : field.get_var_name(), 'deserializer' : DeserializersFactory().get_deserializer(field)(field, StringTemplate('decoded["$fieldName"]').substitute({'fieldName' : field.get_var_name()}))})) for field in self._message.get_fields()])) # deserialize fields of message self.add(TSimple(")", indent=2))
def body(self): self.add(TSimple('serialize_list(fun (Value) ->')) self.add(FieldSerializersFactory().get_field_serializer( self._field.get_element_type(), 'Value')) self.add( TSimple( StringTemplate('end, $valueName)').substitute( {'valueName': self._valueName})))
def body(self): # generate by message serializers for message in self._protocol.get_messages().as_list(): self.add(JsonMessageSerializer(message)) # generate main serializer self.add(TSimple("from string import Template")) self.add(TSimple(StringTemplate(""" class JsonSerializer: def __init__(self): self._serializers = {} $serializersInit def serialize(self, message): return self._serializers[message.__class__].serialize(message) """).substitute({'serializersInit' : # serializers dict initialization "\n".join([StringTemplate( indent(2, "self._serializers[$messageName] = _${messageName}Serializer()") ).substitute({'messageName' : msg.get_name()}) for msg in self._protocol.get_messages().as_list()])}))) self.add(TSimple("jsonSerializer = JsonSerializer()"))
def body(self): self.add( TSimple( StringTemplate("$fieldName=").substitute({ 'fieldName': make_erlang_atom(self._field.get_var_name()) }))) self.add(FieldDeserializersFactory().get_deserializer( self._field, 'proplists:get_value(<<"%s">>, MsgBody)' % self._field.get_var_name()))
def p_block(p): "block : LCB stmtlist RCB" p[0] = p[2] table = {} for key, value in assign_table.items(): if "$" + key in p[0].code: table.update({key: value}) p[0].code = StringTemplate(p[0].code).substitute(**table) if DEBUG: print("p_block" + " : " + p[0].code)
def body(self): # function header self.add( TSimple( StringTemplate( 'inner_deserialize_message(<<"$messageName">>, MsgBody) ->' ).substitute({'messageName': self._message.get_name()}))) self.add( TSimple( StringTemplate('#$messageName{').substitute({ 'messageName': make_erlang_atom(self._message.get_name()) }), 1)) # serialize fields deserializers = [] for field in self._message.get_fields(): deserializers.append(TFieldDeserializer(self._message, field)) self.add(TComaSeparated(deserializers)) # finish function self.add(TSimple("};", indent=1))
def bool_arithmetic(p): CodeGenerator.arith_basics(p, None) # TODO: This place is prone to forward duplicate labels, fix it! if p[1].value == 0 or p[1].value == 1: p[1].relop_parts += [str(1 - p[1].value)] elif p[1].value != "": p[1].relop_parts += [p[1].value + "==0"] if p[3].value == 0 or p[3].value == 1: p[3].relop_parts += [str(1 - p[3].value)] elif p[3].value != "": p[3].relop_parts += [p[3].value + "==0"] l1, label = new_label(), "" for item in p[1].relop_parts: p[0].code += "if (" + item + ")" + "goto " + l1 + ";" if p[3].bool_gen: p[3].code = StringTemplate(p[3].code).substitute(code="") if p[1].bool_gen: p[1].code = StringTemplate(p[1].code).substitute(code="") if p[2] == "and": label = l1 for item in p[3].relop_parts: p[0].code += "if (" + item + ")" + "goto " + l1 + ";" p[0].code += " $code " else: label = new_label() p[0].code += " $code " p[0].code += l1 + ": " for item in p[3].relop_parts: p[0].code += "if (" + item + ")" + "goto " + label + ";" last_semi = p[3].code.rfind(";") + 1 if p[3].bool_gen: p[0].code += p[3].code[:last_semi] p[0].code += " $code " if p[3].bool_gen: p[0].code += p[3].code[last_semi:] if p[3].relop_parts: p[0].code += label + ": " p[0].bool_gen = True
def p_declist_mult(p): "declist : declist dec" p[0] = NonTerminal() p[0].code += p[2].code p[0].iddec_assigns = {**p[1].iddec_assigns, **p[2].iddec_assigns} # p[0].iddec_assigns = p[1].iddec_assigns + p[2].iddec_assigns try: p[0].code += " " + p[1].code except: pass try: p[0].code = StringTemplate(p[0].code).substitute(code="") except: pass table = {} for key, value in assign_table.items(): if "$" + key in p[0].code: table.update({key: ""}) p[0].code = StringTemplate(p[0].code).substitute(**table) if DEBUG: print("p_declist_mult" + " : " + p[0].code)
def body(self): # generate header self.add( TSimple(""" # serialization tools for json messaging # auto generated # do not edit """)) # imports self.add( TSimple( StringTemplate( "from ${protocolName}_messaging import *").substitute( {'protocolName': self._protocol.get_name()}))) # generate serializers self.add(JsonSerializers(self._protocol)) # generate deserializers self.add(JsonDeserializers(self._protocol))
def do(self, evt, name="", subst={}, import_data=False): if self.needed_classes and self.check_classes(self.needed_classes): return project = self.artub.project resource = CGlumolObject(project) resource.template = getattr(self, "template", True) if not name: name = self.resource_name resource.name = name if subst: resource.listing = StringTemplate(self.listing).substitute(**subst) else: resource.listing = self.listing project.add_template(self.name) self.artub.add_template(resource) if import_data and hasattr(self, "data"): for res in self.data: self.import_data(res, res) return resource
def _build_tex(self): labelA = self.labelA labelB = self.labelB function = self.function try: texA = labelA.tex except AttributeError: texA = labelA try: texB = labelB.tex except AttributeError: texB = labelB template = StringTemplate(function) tex = template.safe_substitute(labelA=texA, labelB=texB) while tex.find(r"\,\,") >= 0: tex = tex.replace(r"\,\,", r"\,") self._tex = tex
def message_deserializer(field, valueName): return StringTemplate(""" jsonDeserializer.deserialize($valueName)""").substitute(locals())
def body(self): self.add( TSimple(StringTemplate( " inner_deserialize_message(element(2, $valueName))"). substitute({'valueName': self._valueName}), indent=1))
def get_template(self, name): with open(join(THIS_DIR, "templates", name + ".tmpl"), "r") as h: tmpl = StringTemplate(h.read()) return tmpl
def body(self): self.add( TSimple( StringTemplate('deserialize_string($valueName)').substitute( {'valueName': self._valueName}), indent=1))
def body(self): tmp = StringTemplate("""serialize_int($valueName)""") return tmp.substitute({'valueName': self._valueName})
def integer_deserializer(field, valueName): return StringTemplate(""" int($valueName) """).substitute(locals())
def float_deserializer(field, valueName): return StringTemplate(""" float($valueName) """).substitute(locals())
def list_deserializer(field, valueName): elementType = field.get_element_type() deserializer = DeserializersFactory().get_deserializer(elementType)(elementType, "val") return StringTemplate(""" [$deserializer for val in $valueName] """).substitute(locals())
def load_config(config_path: str, apply_defaults: bool = True, show_warnings: bool = False) -> Dict[str, str]: """ Load the configuration file. :param config_path: path to the configuration file :param apply_defaults: If True (default), apply all known default values. If False, just return what's in the config file. :param show_warnings: Warn about some things. Generally only desirable at program startup. :return: A dictionary of configuration items """ bad = False comment = re.compile("^\s*#.*$") cfg = {} parent_dir = os.path.dirname(config_path) if os.path.isfile(parent_dir): raise CourseError( f'''"{parent_dir}" already exists, but it isn't a directory.''') if not os.path.exists(parent_dir): os.makedirs(parent_dir) if os.path.exists(config_path): with open(config_path) as f: for (i, line) in enumerate([l.rstrip() for l in f.readlines()]): lno = i + 1 if len(line.strip()) == 0: continue if comment.search(line): continue fields = line.split('=') if len(fields) != 2: bad = True error(f'"{config_path}", line {lno}: Malformed line') continue cfg[fields[0]] = fields[1] if bad: raise CourseError("Configuration error(s).") setting_keys_and_defaults = ( # The second item in each tuple is a default value. The third item # indicates whether it can be overridden in the configuration or # the environment. # # The default is treated as a Python string template, so it can # substitute values from previous entries in the list. If the default # value is None, that generally means it can be overridden on the # command line (or depends on something else that can be), so it's # checked at runtime. ('DB_CONFIG_PATH', DB_CONFIG_PATH_DEFAULT, True), ('DB_PROFILE', DB_PROFILE_DEFAULT, True), ('DB_SHARD_HOME', None, True), ('PREFIX', None, True), # set later ('COURSE_NAME', None, True), # can be overridden ('COURSE_REPO', COURSE_REPO_DEFAULT, True), ('COURSE_HOME', None, False), # depends on COURSE_NAME ('COURSE_YAML', None, True), ('COURSE_MODULES', None, False), # depends on COURSE_NAME ('COURSE_REMOTE_SOURCE', None, False), # depends on COURSE_NAME ('COURSE_REMOTE_TARGET', None, False), # depends on COURSE_NAME ('COURSE_AWS_PROFILE', AWS_PROFILE_DEFAULT, True), ('SELF_PACED_PATH', SELF_PACED_PATH_DEFAULT, True), ('SOURCE', SOURCE_DEFAULT, True), ('TARGET', TARGET_DEFAULT, True), ('EDITOR', EDITOR_DEFAULT, True), ('PAGER', PAGER_DEFAULT, True), ('OPEN_DIR', OPEN_DIR_DEFAULT, True), ) # Remove anything that cannot be overridden. for e, default, allow_override in setting_keys_and_defaults: if (default is not None): continue v = cfg.get(e) if not v: continue if not allow_override: if show_warnings: warn(f'Ignoring "{e}" in the configuration file, because ' + "it's calculated at run-time.") del cfg[e] if apply_defaults: # Apply environment overrides. Then, check for missing ones where # appropriate, and apply defaults. for e, default, _ in setting_keys_and_defaults: v = os.environ.get(e) if v is not None and ("FORCE_" + e) not in cfg: cfg[e] = v if not cfg.get(e) and default: t = StringTemplate(default) cfg[e] = t.substitute(cfg) return cfg
def string_deserializer(field, valueName): return StringTemplate(""" str($valueName) """).substitute(locals())