Update GaCy-GO
This commit is contained in:
1 parent
da8a32f60d
commit
0cbe460e49
345 files changed
+98202
-77559
No files matched your search
@@ -0,0 +1,71 @@
|
||||
"""Compare reference CW descriptors with the repository's compiled descriptor set."""
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from google.protobuf import descriptor_pb2 as d
|
||||
|
||||
|
||||
def messages(files):
|
||||
result = {}
|
||||
def visit(rows, prefix):
|
||||
for row in rows:
|
||||
full = prefix+'.'+row.name
|
||||
result[full] = row
|
||||
visit(row.nested_type, full)
|
||||
for file in files:
|
||||
visit(file.message_type, '.'+file.package)
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(description=__doc__)
|
||||
p.add_argument('--reference', type=Path, required=True)
|
||||
p.add_argument('--current', type=Path, required=True)
|
||||
p.add_argument('--commands', type=Path, required=True)
|
||||
p.add_argument('--output', type=Path, required=True)
|
||||
args = p.parse_args()
|
||||
reference = d.FileDescriptorProto.FromString(args.reference.read_bytes())
|
||||
current = d.FileDescriptorSet.FromString(args.current.read_bytes())
|
||||
fm, cm = messages([reference]), messages(current.file)
|
||||
current_names = {int(v):k for k,v in re.findall(r'"([^"]+)":\s*(\d+)',args.commands.read_text())}
|
||||
commands = [{'id':v.number,'ffgo_name':v.name[3:],'current_name':current_names.get(v.number)} for enum in reference.enum_type if enum.name == 'CmdGridFightType' for v in enum.value if v.number]
|
||||
mapping, conflicts = {}, []
|
||||
def match(a,b,seen):
|
||||
if (a,b) in seen:
|
||||
return True
|
||||
seen.add((a,b))
|
||||
if a not in fm or b not in cm:
|
||||
return False
|
||||
xf, yf = ({v.number:v for v in rows.field} for rows in (fm[a],cm[b]))
|
||||
if xf.keys()!=yf.keys():
|
||||
return False
|
||||
for num,u in xf.items():
|
||||
v=yf[num]
|
||||
if u.type!=v.type or u.label!=v.label or u.HasField('oneof_index')!=v.HasField('oneof_index'):
|
||||
return False
|
||||
if u.type==u.TYPE_MESSAGE and not match(u.type_name,v.type_name,seen):
|
||||
return False
|
||||
# Preserve the partition of fields into oneofs, independent of names.
|
||||
groups = lambda fields: sorted(sorted(v.number for v in fields if v.HasField('oneof_index') and v.oneof_index==i) for i in set(v.oneof_index for v in fields if v.HasField('oneof_index')))
|
||||
return groups(fm[a].field)==groups(cm[b].field)
|
||||
for row in commands:
|
||||
row['same_name']=row['ffgo_name']==row['current_name']
|
||||
a='.'+reference.package+'.'+row['ffgo_name']
|
||||
candidates=[k for k in cm if k.rsplit('.',1)[-1]==row['current_name']]
|
||||
seen=set()
|
||||
row['wire_shape_equal']=len(candidates)==1 and match(a,candidates[0],seen)
|
||||
if row['wire_shape_equal']:
|
||||
for k,v in seen:
|
||||
if k in mapping and mapping[k]!=v:
|
||||
conflicts.append([k,mapping[k],v])
|
||||
mapping[k]=v
|
||||
args.output.mkdir(parents=True,exist_ok=True)
|
||||
provenance={'reference_descriptor_sha256':__import__('hashlib').sha256(args.reference.read_bytes()).hexdigest(),'current_descriptor_sha256':__import__('hashlib').sha256(args.current.read_bytes()).hexdigest(),'limitations':['Equal wire shapes do not establish enum meanings, field semantics, runtime success, or permission to register numeric aliases.']}
|
||||
(args.output/'cw-command-comparison.json').write_text(json.dumps({'provenance':provenance,'commands':commands},indent=2))
|
||||
(args.output/'cw-message-mapping.json').write_text(json.dumps({'provenance':provenance,'messages':mapping,'conflicts':conflicts},indent=2))
|
||||
print(json.dumps({'commands':len(commands),'same_names':sum(x['same_name'] for x in commands),'equal_wire_shapes':sum(x['wire_shape_equal'] for x in commands),'mapped_messages':len(mapping),'conflicts':len(conflicts),'shape_differences':[x for x in commands if not x['wire_shape_equal']]}))
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user