in scripts/schema/loader.py [0:0]
def merge_fields(a: Dict[str, FieldEntry], b: Dict[str, FieldEntry]) -> Dict[str, FieldEntry]:
"""Merge ECS field sets with custom field sets."""
a = copy.deepcopy(a)
b = copy.deepcopy(b)
for key in b:
if key not in a:
a[key] = b[key]
continue
# merge field details
if 'normalize' in b[key]['field_details']:
a[key].setdefault('field_details', {})
a[key]['field_details'].setdefault('normalize', [])
a[key]['field_details']['normalize'].extend(b[key]['field_details'].pop('normalize'))
if 'multi_fields' in b[key]['field_details']:
a[key].setdefault('field_details', {})
a[key]['field_details'].setdefault('multi_fields', [])
a[key]['field_details']['multi_fields'] = dedup_and_merge_lists(
a[key]['field_details']['multi_fields'], b[key]['field_details']['multi_fields'])
# if we don't do this then the update call below will overwrite a's field_details, with the original
# contents of b, which undoes our merging the multi_fields
del b[key]['field_details']['multi_fields']
a[key]['field_details'].update(b[key]['field_details'])
# merge schema details
if 'schema_details' in b[key]:
asd = a[key]['schema_details']
bsd = b[key]['schema_details']
if 'reusable' in b[key]['schema_details']:
asd.setdefault('reusable', {})
if 'top_level' in bsd['reusable']:
asd['reusable']['top_level'] = bsd['reusable']['top_level']
else:
asd['reusable'].setdefault('top_level', True)
if 'order' in bsd['reusable']:
asd['reusable']['order'] = bsd['reusable']['order']
asd['reusable'].setdefault('expected', [])
asd['reusable']['expected'].extend(bsd['reusable']['expected'])
bsd.pop('reusable')
asd.update(bsd)
# merge nested fields
if 'fields' in b[key]:
a[key].setdefault('fields', {})
a[key]['fields'] = merge_fields(a[key]['fields'], b[key]['fields'])
return a