1a5f9918aSopenharmony_ci
2a5f9918aSopenharmony_ci__all__ = ['Serializer', 'SerializerError']
3a5f9918aSopenharmony_ci
4a5f9918aSopenharmony_cifrom .error import YAMLError
5a5f9918aSopenharmony_cifrom .events import *
6a5f9918aSopenharmony_cifrom .nodes import *
7a5f9918aSopenharmony_ci
8a5f9918aSopenharmony_ciclass SerializerError(YAMLError):
9a5f9918aSopenharmony_ci    pass
10a5f9918aSopenharmony_ci
11a5f9918aSopenharmony_ciclass Serializer:
12a5f9918aSopenharmony_ci
13a5f9918aSopenharmony_ci    ANCHOR_TEMPLATE = 'id%03d'
14a5f9918aSopenharmony_ci
15a5f9918aSopenharmony_ci    def __init__(self, encoding=None,
16a5f9918aSopenharmony_ci            explicit_start=None, explicit_end=None, version=None, tags=None):
17a5f9918aSopenharmony_ci        self.use_encoding = encoding
18a5f9918aSopenharmony_ci        self.use_explicit_start = explicit_start
19a5f9918aSopenharmony_ci        self.use_explicit_end = explicit_end
20a5f9918aSopenharmony_ci        self.use_version = version
21a5f9918aSopenharmony_ci        self.use_tags = tags
22a5f9918aSopenharmony_ci        self.serialized_nodes = {}
23a5f9918aSopenharmony_ci        self.anchors = {}
24a5f9918aSopenharmony_ci        self.last_anchor_id = 0
25a5f9918aSopenharmony_ci        self.closed = None
26a5f9918aSopenharmony_ci
27a5f9918aSopenharmony_ci    def open(self):
28a5f9918aSopenharmony_ci        if self.closed is None:
29a5f9918aSopenharmony_ci            self.emit(StreamStartEvent(encoding=self.use_encoding))
30a5f9918aSopenharmony_ci            self.closed = False
31a5f9918aSopenharmony_ci        elif self.closed:
32a5f9918aSopenharmony_ci            raise SerializerError("serializer is closed")
33a5f9918aSopenharmony_ci        else:
34a5f9918aSopenharmony_ci            raise SerializerError("serializer is already opened")
35a5f9918aSopenharmony_ci
36a5f9918aSopenharmony_ci    def close(self):
37a5f9918aSopenharmony_ci        if self.closed is None:
38a5f9918aSopenharmony_ci            raise SerializerError("serializer is not opened")
39a5f9918aSopenharmony_ci        elif not self.closed:
40a5f9918aSopenharmony_ci            self.emit(StreamEndEvent())
41a5f9918aSopenharmony_ci            self.closed = True
42a5f9918aSopenharmony_ci
43a5f9918aSopenharmony_ci    #def __del__(self):
44a5f9918aSopenharmony_ci    #    self.close()
45a5f9918aSopenharmony_ci
46a5f9918aSopenharmony_ci    def serialize(self, node):
47a5f9918aSopenharmony_ci        if self.closed is None:
48a5f9918aSopenharmony_ci            raise SerializerError("serializer is not opened")
49a5f9918aSopenharmony_ci        elif self.closed:
50a5f9918aSopenharmony_ci            raise SerializerError("serializer is closed")
51a5f9918aSopenharmony_ci        self.emit(DocumentStartEvent(explicit=self.use_explicit_start,
52a5f9918aSopenharmony_ci            version=self.use_version, tags=self.use_tags))
53a5f9918aSopenharmony_ci        self.anchor_node(node)
54a5f9918aSopenharmony_ci        self.serialize_node(node, None, None)
55a5f9918aSopenharmony_ci        self.emit(DocumentEndEvent(explicit=self.use_explicit_end))
56a5f9918aSopenharmony_ci        self.serialized_nodes = {}
57a5f9918aSopenharmony_ci        self.anchors = {}
58a5f9918aSopenharmony_ci        self.last_anchor_id = 0
59a5f9918aSopenharmony_ci
60a5f9918aSopenharmony_ci    def anchor_node(self, node):
61a5f9918aSopenharmony_ci        if node in self.anchors:
62a5f9918aSopenharmony_ci            if self.anchors[node] is None:
63a5f9918aSopenharmony_ci                self.anchors[node] = self.generate_anchor(node)
64a5f9918aSopenharmony_ci        else:
65a5f9918aSopenharmony_ci            self.anchors[node] = None
66a5f9918aSopenharmony_ci            if isinstance(node, SequenceNode):
67a5f9918aSopenharmony_ci                for item in node.value:
68a5f9918aSopenharmony_ci                    self.anchor_node(item)
69a5f9918aSopenharmony_ci            elif isinstance(node, MappingNode):
70a5f9918aSopenharmony_ci                for key, value in node.value:
71a5f9918aSopenharmony_ci                    self.anchor_node(key)
72a5f9918aSopenharmony_ci                    self.anchor_node(value)
73a5f9918aSopenharmony_ci
74a5f9918aSopenharmony_ci    def generate_anchor(self, node):
75a5f9918aSopenharmony_ci        self.last_anchor_id += 1
76a5f9918aSopenharmony_ci        return self.ANCHOR_TEMPLATE % self.last_anchor_id
77a5f9918aSopenharmony_ci
78a5f9918aSopenharmony_ci    def serialize_node(self, node, parent, index):
79a5f9918aSopenharmony_ci        alias = self.anchors[node]
80a5f9918aSopenharmony_ci        if node in self.serialized_nodes:
81a5f9918aSopenharmony_ci            self.emit(AliasEvent(alias))
82a5f9918aSopenharmony_ci        else:
83a5f9918aSopenharmony_ci            self.serialized_nodes[node] = True
84a5f9918aSopenharmony_ci            self.descend_resolver(parent, index)
85a5f9918aSopenharmony_ci            if isinstance(node, ScalarNode):
86a5f9918aSopenharmony_ci                detected_tag = self.resolve(ScalarNode, node.value, (True, False))
87a5f9918aSopenharmony_ci                default_tag = self.resolve(ScalarNode, node.value, (False, True))
88a5f9918aSopenharmony_ci                implicit = (node.tag == detected_tag), (node.tag == default_tag)
89a5f9918aSopenharmony_ci                self.emit(ScalarEvent(alias, node.tag, implicit, node.value,
90a5f9918aSopenharmony_ci                    style=node.style))
91a5f9918aSopenharmony_ci            elif isinstance(node, SequenceNode):
92a5f9918aSopenharmony_ci                implicit = (node.tag
93a5f9918aSopenharmony_ci                            == self.resolve(SequenceNode, node.value, True))
94a5f9918aSopenharmony_ci                self.emit(SequenceStartEvent(alias, node.tag, implicit,
95a5f9918aSopenharmony_ci                    flow_style=node.flow_style))
96a5f9918aSopenharmony_ci                index = 0
97a5f9918aSopenharmony_ci                for item in node.value:
98a5f9918aSopenharmony_ci                    self.serialize_node(item, node, index)
99a5f9918aSopenharmony_ci                    index += 1
100a5f9918aSopenharmony_ci                self.emit(SequenceEndEvent())
101a5f9918aSopenharmony_ci            elif isinstance(node, MappingNode):
102a5f9918aSopenharmony_ci                implicit = (node.tag
103a5f9918aSopenharmony_ci                            == self.resolve(MappingNode, node.value, True))
104a5f9918aSopenharmony_ci                self.emit(MappingStartEvent(alias, node.tag, implicit,
105a5f9918aSopenharmony_ci                    flow_style=node.flow_style))
106a5f9918aSopenharmony_ci                for key, value in node.value:
107a5f9918aSopenharmony_ci                    self.serialize_node(key, node, None)
108a5f9918aSopenharmony_ci                    self.serialize_node(value, node, key)
109a5f9918aSopenharmony_ci                self.emit(MappingEndEvent())
110a5f9918aSopenharmony_ci            self.ascend_resolver()
111a5f9918aSopenharmony_ci
112