<commit_before>"""
The json module introduces JSON resource and JSON parsing.
"""
from functools import lru_cache
import json
from .resource import Resource
from .. import ecore as Ecore


class JsonResource(Resource):
    def __init__(self, uri=None, use_uuid=False, indent=None):
        super().__init__(uri, use_uuid)
        self._resolve_later = []
        self._already_saved = []
        self._load_href = {}
        self.indent = indent

    def load(self):
        json_value = self.uri.create_instream()
        d = json.loads(json_value.read().decode('utf-8'))
        self.to_obj(d, first=True)
        self.uri.close_stream()
        for inst, refs in self._load_href.items():
            self.process_inst(inst, refs)
        self._load_href.clear()

    def save(self, output=None):
        stream = self.open_out_stream(output)
        root = self.contents[0]  # Only single root atm
        stream.write(json.dumps(self.to_dict(root), indent=self.indent)
                     .encode('utf-8'))
        self.uri.close_stream()

    def _uri_fragment(self, obj):
        if obj.eResource == self:
            use_id = self.use_uuid
        else:
            use_id = obj.eResource and obj.eResource.use_uuid
        if use_id:
            self._assign_uuid(obj)
            return obj._xmiid
        else:
            return obj.eURIFragment()

    def serialize_eclass(self, eclass):
        return '{}{}'.format(eclass.eRoot().nsURI, eclass.eURIFragment())

    def _to_ref_from_obj(self, obj):
        uri = self.serialize_eclass(obj.eClass)
        ref = {'eClass': uri}
        if obj.eResource == self:
            resource_uri = ''
        else:
            resource_uri = obj.eResource.uri if obj.eResource else ''
        ref['$ref'] = '{}{}'.format(resource_uri, self._uri_fragment(obj))
        return ref

    def _to_dict_from_obj(self, obj):
        uri = self.serialize_eclass(obj.eClass)
        d = {'eClass': uri}
        containingFeature = obj.eContainmentFeature()
        for attr in obj._isset:
            is_ereference = isinstance(attr, Ecore.EReference)
            is_ref = is_ereference and not attr.containment
            if is_ereference and attr.eOpposite:
                if attr.eOpposite is containingFeature:
                    continue
            value = obj.eGet(attr)
            if value == attr.get_default_value():
                continue
            d[attr.name] = self.to_dict(value, is_ref=is_ref)
            if self.use_uuid:
                self._assign_uuid(obj)
                d['uuid'] = obj._xmiid
        self._already_saved.append(obj)
        return d

    def to_dict(self, obj, is_ref=False):
        if isinstance(obj, Ecore.EObject):
            fun = self._to_ref_from_obj if is_ref else self._to_dict_from_obj
            return fun(obj)
        elif isinstance(obj, type) and issubclass(obj, Ecore.EObject):
            fun = self._to_ref_from_obj if is_ref else self._to_dict_from_obj
            return fun(obj.eClass)
        elif isinstance(obj, Ecore.ECollection):
            fun = self._to_ref_from_obj if is_ref else self.to_dict
            return [fun(x) for x in obj]
        else:
            return obj

    @lru_cache()
    def resolve_eclass(self, uri_eclass):
        decoders = self._get_href_decoder(uri_eclass)
        return decoders.resolve(uri_eclass, self)

    def to_obj(self, d, owning_feature=None, first=False):
        uri_eclass = d['eClass']
        is_ref = '$ref' in d
        if is_ref:
            return Ecore.EProxy(path=d['$ref'], resource=self)
        excludes = ['eClass', '$ref', 'uuid']
        eclass = self.resolve_eclass(uri_eclass)
        if not eclass:
            raise ValueError('Unknown metaclass for uri "{}"'
                             .format(uri_eclass))
        if eclass in (Ecore.EClass.eClass, Ecore.EClass):
            inst = eclass(d['name'])
            excludes.append('name')
        else:
            inst = eclass()
        if first:
            self.use_uuid = 'uuid' in d
            self.append(inst)

        if self.use_uuid:
            self.uuid_dict[d['uuid']] = inst

        eattributes = []
        containments = []
        ereferences = []
        eclass = inst.eClass
        for key, value in d.items():
            if key in excludes:
                continue
            feature = eclass.findEStructuralFeature(key)
            if not feature:
                raise ValueError('Unknown feature {} for object "{}"'
                                 .format(key, eclass))
            if isinstance(feature, Ecore.EAttribute):
                eattributes.append((feature, value))
            elif isinstance(feature, Ecore.EReference):
                if feature.containment:<commit_msg>Remove systematic serialization of EClass reference<commit_after>"""
The json module introduces JSON resource and JSON parsing.
"""
from functools import lru_cache
import json
from .resource import Resource
from .. import ecore as Ecore


class JsonResource(Resource):
    def __init__(self, uri=None, use_uuid=False, indent=None):
        super().__init__(uri, use_uuid)
        self._resolve_later = []
        self._already_saved = []
        self._load_href = {}
        self.indent = indent

    def load(self):
        json_value = self.uri.create_instream()
        d = json.loads(json_value.read().decode('utf-8'))
        self.to_obj(d, first=True)
        self.uri.close_stream()
        for inst, refs in self._load_href.items():
            self.process_inst(inst, refs)
        self._load_href.clear()

    def save(self, output=None):
        stream = self.open_out_stream(output)
        root = self.contents[0]  # Only single root atm
        stream.write(json.dumps(self.to_dict(root), indent=self.indent)
                     .encode('utf-8'))
        self.uri.close_stream()

    def _uri_fragment(self, obj):
        if obj.eResource == self:
            use_id = self.use_uuid
        else:
            use_id = obj.eResource and obj.eResource.use_uuid
        if use_id:
            self._assign_uuid(obj)
            return obj._xmiid
        else:
            return obj.eURIFragment()

    def serialize_eclass(self, eclass):
        return '{}{}'.format(eclass.eRoot().nsURI, eclass.eURIFragment())

    def _to_ref_from_obj(self, obj):
        uri = self.serialize_eclass(obj.eClass)
        ref = {'eClass': uri}
        if obj.eResource == self:
            resource_uri = ''
        else:
            resource_uri = obj.eResource.uri if obj.eResource else ''
        ref['$ref'] = '{}{}'.format(resource_uri, self._uri_fragment(obj))
        return ref

    def _to_dict_from_obj(self, obj):
        d = {}
        containingFeature = obj.eContainmentFeature()
        if not containingFeature or obj.eClass is not containingFeature.eType:
            uri = self.serialize_eclass(obj.eClass)
            d['eClass'] = uri
        for attr in obj._isset:
            is_ereference = isinstance(attr, Ecore.EReference)
            is_ref = is_ereference and not attr.containment
            if is_ereference and attr.eOpposite:
                if attr.eOpposite is containingFeature:
                    continue
            value = obj.eGet(attr)
            if value == attr.get_default_value():
                continue
            d[attr.name] = self.to_dict(value, is_ref=is_ref)
            if self.use_uuid:
                self._assign_uuid(obj)
                d['uuid'] = obj._xmiid
        self._already_saved.append(obj)
        return d

    def to_dict(self, obj, is_ref=False):
        if isinstance(obj, Ecore.EObject):
            fun = self._to_ref_from_obj if is_ref else self._to_dict_from_obj
            return fun(obj)
        elif isinstance(obj, type) and issubclass(obj, Ecore.EObject):
            fun = self._to_ref_from_obj if is_ref else self._to_dict_from_obj
            return fun(obj.eClass)
        elif isinstance(obj, Ecore.ECollection):
            fun = self._to_ref_from_obj if is_ref else self.to_dict
            return [fun(x) for x in obj]
        else:
            return obj

    @lru_cache()
    def resolve_eclass(self, uri_eclass):
        decoders = self._get_href_decoder(uri_eclass)
        return decoders.resolve(uri_eclass, self)

    def to_obj(self, d, owning_feature=None, first=False):
        is_ref = '$ref' in d
        if is_ref:
            return Ecore.EProxy(path=d['$ref'], resource=self)
        excludes = ['eClass', '$ref', 'uuid']
        if 'eClass' in d:
            uri_eclass = d['eClass']
            eclass = self.resolve_eclass(uri_eclass)
        else:
            eclass = owning_feature.eType
        if not eclass:
            raise ValueError('Unknown metaclass for uri "{}"'
                             .format(uri_eclass))
        if eclass in (Ecore.EClass.eClass, Ecore.EClass):
            inst = eclass(d['name'])
            excludes.append('name')
        else:
            inst = eclass()
        if first:
            self.use_uuid = 'uuid' in d
            self.append(inst)

        if self.use_uuid:
            self.uuid_dict[d['uuid']] = inst

        eattributes = []
        containments = []
        ereferences = []
        eclass = inst.eClass
        for key, value in d.items():
            if key in excludes:
                continue
            feature = eclass.findEStructuralFeature(key)
            if not feature:
                raise ValueError('Unknown feature {} for object "{}"'
                                 .format(key, eclass))
            if isinstance(feature, Ecore.EAttribute):
                eattributes.append((feature, value))
            elif isinstance(feature, Ecore.EReference):
                if feature.containment:
{'fraction_non_alphanumeric': 0.1026088742810189, 'fraction_numerical': 0.0006162695152013147, 'mean_word_length': 1.9532908704883227, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1847157', 'n_tokens_mistral': 2941, 'n_tokens_neox': 2883, 'n_words': 649}