def gen_field_scalar_size(f): wt = util.gen_wire_type(f) vt = util.field_pb_type(f) fname = f.name + ("[i]" if util.field_is_repeated(f) else "") if wt == "Varint": if vt == "bool": return "1" else: return ("_pb._sz_{valtype}(r.{field})").format( valtype=vt, field=fname, ) elif wt == "Fixed64": return "8" elif wt == "Fixed32": return "4" elif wt == "LengthDelim": if vt == "bytes": return ("_pb._sz_lendelim(r.{field}.length)").format(field=fname) elif vt == "string": return ("_pb._sz_lendelim(bytes(r.{field}).length)").format( field=fname) elif vt == "message": st = util.field_sol_type(f) if st is None: return ("_pb._sz_lendelim({lib}._estimate(r.{field}))").format( lib=util.gen_struct_codec_lib_name_from_field(f), field=fname, ) else: return "{}".format(util.gen_soltype_estimate_len(st)) else: return ("__does not support pb type {t}__").format(t=vt) else: return ("__does not support wire type {t}__").format(t=wt)
def gen_store_code_for_field(f, msg, parent_struct_name): tmpl = "" if util.field_is_message(f) and util.field_is_repeated(f): tmpl = ( " output.{field}.length = input.{field}.length; \n" " for(uint i{i}=0; i{i}<input.{field}.length; i{i}++) {{ \n" " {lib}.store(input.{field}[i{i}], output.{field}[i{i}]); \n" " {map_insert_code}" " }}" ) elif util.field_is_message(f): tmpl = ( " {lib}.store(input.{field}, output.{field}); \n" ) else: return ( " output.{field} = input.{field}; \n" ).format( field = f.name, ) libname = util.gen_struct_codec_lib_name_from_field(f) return tmpl.format( i = f.number, field = f.name, lib = libname, map_insert_code = gen_map_insert_on_store(f, msg, parent_struct_name) )
def gen_field_estimator(f): return ((" for(i=0; i<r.{field}.length; i++) e+= {szKey} + {szItem}; \n" ) if util.field_is_repeated(f) else (" e += {szKey} + {szItem}; \n")).format( field=f.name, szKey=(1 if f.number < 16 else 2), szItem=gen_field_scalar_size(f))
def gen_field_reader(f, parent_struct_name, msg, file): suffix = ("[r.{field}.length - counters[{i}]]").format( field=f.name, i=f.number) if util.field_is_repeated(f) else "" if f.type == FieldDescriptorProto.TYPE_ENUM: type_name = util.gen_enum_name_from_field(f) library_name = "" if msg.name == type_name.split(".")[0] else ( type_name.split(".")[0] + ".") if library_name == ".": library_name = util.gen_global_enum_name(file) + library_name decode_type = util.gen_global_type_decl_from_field(f) if decode_type[0] == ".": decode_type = util.gen_global_enum_name(file) + decode_type return (decoder_constants.ENUM_FIELD_READER).format( field=f.name, decoder=util.gen_decoder_name(f), decode_type=decode_type, t=util.gen_internal_struct_name(msg, parent_struct_name), i=f.number, n=util.max_field_number(msg) + 1, suffix=suffix, enum_name=type_name.split(".")[-1], library_name=library_name) return (decoder_constants.FIELD_READER).format( field=f.name, decoder=util.gen_decoder_name(f), decode_type=util.gen_global_type_decl_from_field(f), t=util.gen_internal_struct_name(msg, parent_struct_name), i=f.number, n=util.max_field_number(msg) + 1, suffix=suffix)
def gen_field_estimator(f, msg, file): if util.field_is_repeated(f): if util.is_map_type(f, msg.nested_type): template = encoder_constants.FIELD_ESTIMATOR_REPEATED_MAP else: template = encoder_constants.FIELD_ESTIMATOR_REPEATED else: template = encoder_constants.FIELD_ESTIMATOR_NOT_REPEATED return template.format(field=f.name, szKey=(1 if f.number < 16 else 2), szItem=gen_field_scalar_size(f, msg, file))
def gen_field_scalar_size(f, msg, file): wt = util.gen_wire_type(f) vt = util.field_pb_type(f) fname = f.name + ("[i]" if util.field_is_repeated(f) else "") if wt == "Varint": if vt == "bool": return "1" if vt == "enum": type_name = util.gen_enum_name_from_field(f) library_name = "" if msg.name == type_name.split(".")[0] else ( type_name.split(".")[0] + ".") if library_name == ".": library_name = util.gen_global_enum_name(file) + library_name return ( "ProtoBufRuntime._sz_{valtype}({library_name}encode_{enum_name}(r.{field}))" ).format(valtype=vt, field=fname, enum_name=type_name.split(".")[-1], library_name=library_name) else: return ("ProtoBufRuntime._sz_{valtype}(r.{field})").format( valtype=vt, field=fname, ) elif wt == "Fixed64": return "8" elif wt == "Fixed32": return "4" elif wt == "LengthDelim": if vt == "bytes": return ("ProtoBufRuntime._sz_lendelim(r.{field}.length)").format( field=fname) elif vt == "string": return ("ProtoBufRuntime._sz_lendelim(bytes(r.{field}).length)" ).format(field=fname) elif vt == "message": st = util.field_sol_type(f) if st is None: return ( "ProtoBufRuntime._sz_lendelim({lib}._estimate(r.{field}))" ).format( lib=util.gen_struct_codec_lib_name_from_field(f), field=fname, ) else: return "{}".format(util.gen_soltype_estimate_len(st)) else: return ("__does not support pb type {t}__").format(t=vt) else: return ("__does not support wire type {t}__").format(t=wt)
def gen_inner_field_encoder(f): #sys.stderr.write("fname={}, type={}\n".format(f.name, f.type)) return (( " for(i=0; i<r.{field}.length; i++) {{ \n" " p += _pb._encode_key({key}, _pb.WireType.{wiretype}, p, bs); \n" " p += {encoder}(r.{field}[i], p, bs); \n" " }} \n" ) if util.field_is_repeated(f) else ( " p += _pb._encode_key({key}, _pb.WireType.{wiretype}, p, bs); \n" " p += {encoder}(r.{field}, p, bs); \n")).format( field=f.name, key=f.number, wiretype=util.gen_wire_type(f), encoder=util.gen_encoder_name(f), )
def gen_store_code_for_field(f, msg, parent_struct_name): tmpl = "" if util.field_is_message(f) and util.field_is_repeated(f): tmpl = sol_constants.STORE_REPEATED elif util.field_is_message(f): tmpl = sol_constants.STORE_MESSAGE else: return (sol_constants.STORE_OTHER).format(field=f.name) libname = util.gen_struct_codec_lib_name_from_field(f) return tmpl.format(i=f.number, field=f.name, lib=libname, map_insert_code=gen_map_insert_on_store( f, msg, parent_struct_name))
def gen_inner_field_decoder(field, parent_struct_name, first_pass, index): args = "" repeated = util.field_is_repeated(field) if repeated: if first_pass: args = decoder_constants.INNER_FIELD_DECODER_NIL else: args = decoder_constants.INNER_FIELD_DECODER_REGULAR else: if first_pass: args = decoder_constants.INNER_FIELD_DECODER_REGULAR else: args = decoder_constants.INNER_FIELD_DECODER_NIL return (decoder_constants.INNER_FIELD_DECODER).format( control=("else " if index > 0 else ""), id=field.number, field=field.name, args=args)
def gen_map_helper_codes_for_field(f, nested_type): kf = nested_type.field[0] vf = nested_type.field[1] return (""" //map helpers for {name} function get_{name}(Data storage self, {key_type} key) internal view returns ({value_type} {storage_type}) {{ return {val_name}[{map_name}[key] - 1].value; }} function search_{name}(Data storage self, {key_type} key) internal view returns (bool, {value_type} {storage_type}) {{ if ({map_name}[key] <= 0) {{ return (false, {val_name}[0].value); }} return (true, {val_name}[{map_name}[key] - 1].value); }} function add_{name}(Data storage self, {key_type} key, {value_type} value) internal {{ if ({map_name}[key] != 0) {{ {copy_value_exists} }} else {{ {val_name}.length++; {val_name}[{val_name}.length - 1].key = key; {copy_value_new} {map_name}[key] = {val_name}.length; }} }} function rm_{name}(Data storage self, {key_type} key) internal {{ uint pos = {map_name}[key]; if (pos == 0) {{ return; }} {val_name}[pos - 1] = {val_name}[{val_name}.length - 1]; {val_name}.length--; delete {map_name}[key]; }} """ ).format( name = f.name, val_name="self.{0}".format(f.name), map_name = "self._{0}_map".format(f.name), key_type=util.gen_global_type_name_from_field(kf), value_type=util.gen_global_type_name_from_field(vf), storage_type="storage" if (util.field_is_repeated(vf) or util.field_is_message(vf)) else "", container_type=util.gen_global_type_name_from_field(f), copy_value_exists=gen_value_copy_code(vf, ("self.{0}[self._{0}_map[key] - 1]").format(f.name)), copy_value_new=gen_value_copy_code(vf, ("self.{0}[self.{0}.length - 1]").format(f.name)), );
def gen_inner_field_decoder(field, parent_struct_name, first_pass): args = "" repeated = util.field_is_repeated(field) if repeated: if first_pass: args = "p, bs, nil(), counters" else: args = "p, bs, r, counters" else: if first_pass: args = "p, bs, r, counters" else: args = "p, bs, nil(), counters" return (" else if(fieldId == {id}) \n" " p += _read_{field}({args});\n").format( id=field.number, field=field.name, args=args, )
def gen_field_reader(f, parent_struct_name, msg): suffix = ("[ r.{field}.length - counters[{i}] ]").format( field=f.name, i=f.number) if util.field_is_repeated(f) else "" return ( " function _read_{field}(uint p, bytes bs, {t} r, uint[{n}] counters) internal pure returns (uint) {{ \n" " ({decode_type} x, uint sz) = {decoder}(p, bs); \n" " if(isNil(r)) {{ \n" " counters[{i}] += 1; \n" " }} else {{ \n" " r.{field}{suffix} = x; \n" " if(counters[{i}] > 0) counters[{i}] -= 1; \n" " }} \n" " return sz; \n" " }} \n" ).format( field=f.name, decoder=util.gen_decoder_name(f), decode_type=util.gen_global_type_decl_from_field(f), t=util.gen_internal_struct_name(msg, parent_struct_name), i=f.number, n=util.max_field_number(msg) + 1, suffix=suffix, )
def gen_inner_field_encoder(f, msg, file): type_name = util.gen_enum_name_from_field(f) if util.field_is_repeated(f): if util.is_map_type(f, msg.nested_type): template = encoder_constants.INNER_FIELD_ENCODER_REPEATED_MAP elif f.type == FieldDescriptorProto.TYPE_ENUM: template = encoder_constants.INNER_FIELD_ENCODER_REPEATED_ENUM else: template = encoder_constants.INNER_FIELD_ENCODER_REPEATED elif f.type == FieldDescriptorProto.TYPE_ENUM: template = encoder_constants.INNER_FIELD_ENCODER_NOT_REPEATED_ENUM else: template = encoder_constants.INNER_FIELD_ENCODER_NOT_REPEATED library_name = "" if msg.name == type_name.split(".")[0] else ( type_name.split(".")[0] + ".") if library_name == ".": library_name = util.gen_global_enum_name(file) + library_name return template.format(field=f.name, key=f.number, wiretype=util.gen_wire_type(f), encoder=util.gen_encoder_name(f), enum_name=type_name.split(".")[-1], library_name=library_name)
def gen_inner_array_allocators(msg, parent_struct_name): return ''.join( map( lambda f: gen_inner_array_allocator(f, parent_struct_name, util.field_is_repeated(f)), msg.field))
def gen_array_helpers(msg, parent_struct_name, all_map_fields): array_fields = filter( lambda t: util.field_is_repeated(t) and t not in all_map_fields, msg.field) return ''.join( map(lambda f: gen_array_helper_codes_for_field(f), array_fields))
def gen_inner_arraty_allocators(msg, parent_struct_name): return ''.join( list( map((lambda f: gen_inner_array_allocator(f, parent_struct_name) if util.field_is_repeated(f) else ""), msg.field)))
def has_repeated_field(fields): for f in fields: if util.field_is_repeated(f): return True return False