1a5f9918aSopenharmony_ci 2a5f9918aSopenharmony_ci__all__ = ['Composer', 'ComposerError'] 3a5f9918aSopenharmony_ci 4a5f9918aSopenharmony_cifrom .error import MarkedYAMLError 5a5f9918aSopenharmony_cifrom .events import * 6a5f9918aSopenharmony_cifrom .nodes import * 7a5f9918aSopenharmony_ci 8a5f9918aSopenharmony_ciclass ComposerError(MarkedYAMLError): 9a5f9918aSopenharmony_ci pass 10a5f9918aSopenharmony_ci 11a5f9918aSopenharmony_ciclass Composer: 12a5f9918aSopenharmony_ci 13a5f9918aSopenharmony_ci def __init__(self): 14a5f9918aSopenharmony_ci self.anchors = {} 15a5f9918aSopenharmony_ci 16a5f9918aSopenharmony_ci def check_node(self): 17a5f9918aSopenharmony_ci # Drop the STREAM-START event. 18a5f9918aSopenharmony_ci if self.check_event(StreamStartEvent): 19a5f9918aSopenharmony_ci self.get_event() 20a5f9918aSopenharmony_ci 21a5f9918aSopenharmony_ci # If there are more documents available? 22a5f9918aSopenharmony_ci return not self.check_event(StreamEndEvent) 23a5f9918aSopenharmony_ci 24a5f9918aSopenharmony_ci def get_node(self): 25a5f9918aSopenharmony_ci # Get the root node of the next document. 26a5f9918aSopenharmony_ci if not self.check_event(StreamEndEvent): 27a5f9918aSopenharmony_ci return self.compose_document() 28a5f9918aSopenharmony_ci 29a5f9918aSopenharmony_ci def get_single_node(self): 30a5f9918aSopenharmony_ci # Drop the STREAM-START event. 31a5f9918aSopenharmony_ci self.get_event() 32a5f9918aSopenharmony_ci 33a5f9918aSopenharmony_ci # Compose a document if the stream is not empty. 34a5f9918aSopenharmony_ci document = None 35a5f9918aSopenharmony_ci if not self.check_event(StreamEndEvent): 36a5f9918aSopenharmony_ci document = self.compose_document() 37a5f9918aSopenharmony_ci 38a5f9918aSopenharmony_ci # Ensure that the stream contains no more documents. 39a5f9918aSopenharmony_ci if not self.check_event(StreamEndEvent): 40a5f9918aSopenharmony_ci event = self.get_event() 41a5f9918aSopenharmony_ci raise ComposerError("expected a single document in the stream", 42a5f9918aSopenharmony_ci document.start_mark, "but found another document", 43a5f9918aSopenharmony_ci event.start_mark) 44a5f9918aSopenharmony_ci 45a5f9918aSopenharmony_ci # Drop the STREAM-END event. 46a5f9918aSopenharmony_ci self.get_event() 47a5f9918aSopenharmony_ci 48a5f9918aSopenharmony_ci return document 49a5f9918aSopenharmony_ci 50a5f9918aSopenharmony_ci def compose_document(self): 51a5f9918aSopenharmony_ci # Drop the DOCUMENT-START event. 52a5f9918aSopenharmony_ci self.get_event() 53a5f9918aSopenharmony_ci 54a5f9918aSopenharmony_ci # Compose the root node. 55a5f9918aSopenharmony_ci node = self.compose_node(None, None) 56a5f9918aSopenharmony_ci 57a5f9918aSopenharmony_ci # Drop the DOCUMENT-END event. 58a5f9918aSopenharmony_ci self.get_event() 59a5f9918aSopenharmony_ci 60a5f9918aSopenharmony_ci self.anchors = {} 61a5f9918aSopenharmony_ci return node 62a5f9918aSopenharmony_ci 63a5f9918aSopenharmony_ci def compose_node(self, parent, index): 64a5f9918aSopenharmony_ci if self.check_event(AliasEvent): 65a5f9918aSopenharmony_ci event = self.get_event() 66a5f9918aSopenharmony_ci anchor = event.anchor 67a5f9918aSopenharmony_ci if anchor not in self.anchors: 68a5f9918aSopenharmony_ci raise ComposerError(None, None, "found undefined alias %r" 69a5f9918aSopenharmony_ci % anchor, event.start_mark) 70a5f9918aSopenharmony_ci return self.anchors[anchor] 71a5f9918aSopenharmony_ci event = self.peek_event() 72a5f9918aSopenharmony_ci anchor = event.anchor 73a5f9918aSopenharmony_ci if anchor is not None: 74a5f9918aSopenharmony_ci if anchor in self.anchors: 75a5f9918aSopenharmony_ci raise ComposerError("found duplicate anchor %r; first occurrence" 76a5f9918aSopenharmony_ci % anchor, self.anchors[anchor].start_mark, 77a5f9918aSopenharmony_ci "second occurrence", event.start_mark) 78a5f9918aSopenharmony_ci self.descend_resolver(parent, index) 79a5f9918aSopenharmony_ci if self.check_event(ScalarEvent): 80a5f9918aSopenharmony_ci node = self.compose_scalar_node(anchor) 81a5f9918aSopenharmony_ci elif self.check_event(SequenceStartEvent): 82a5f9918aSopenharmony_ci node = self.compose_sequence_node(anchor) 83a5f9918aSopenharmony_ci elif self.check_event(MappingStartEvent): 84a5f9918aSopenharmony_ci node = self.compose_mapping_node(anchor) 85a5f9918aSopenharmony_ci self.ascend_resolver() 86a5f9918aSopenharmony_ci return node 87a5f9918aSopenharmony_ci 88a5f9918aSopenharmony_ci def compose_scalar_node(self, anchor): 89a5f9918aSopenharmony_ci event = self.get_event() 90a5f9918aSopenharmony_ci tag = event.tag 91a5f9918aSopenharmony_ci if tag is None or tag == '!': 92a5f9918aSopenharmony_ci tag = self.resolve(ScalarNode, event.value, event.implicit) 93a5f9918aSopenharmony_ci node = ScalarNode(tag, event.value, 94a5f9918aSopenharmony_ci event.start_mark, event.end_mark, style=event.style) 95a5f9918aSopenharmony_ci if anchor is not None: 96a5f9918aSopenharmony_ci self.anchors[anchor] = node 97a5f9918aSopenharmony_ci return node 98a5f9918aSopenharmony_ci 99a5f9918aSopenharmony_ci def compose_sequence_node(self, anchor): 100a5f9918aSopenharmony_ci start_event = self.get_event() 101a5f9918aSopenharmony_ci tag = start_event.tag 102a5f9918aSopenharmony_ci if tag is None or tag == '!': 103a5f9918aSopenharmony_ci tag = self.resolve(SequenceNode, None, start_event.implicit) 104a5f9918aSopenharmony_ci node = SequenceNode(tag, [], 105a5f9918aSopenharmony_ci start_event.start_mark, None, 106a5f9918aSopenharmony_ci flow_style=start_event.flow_style) 107a5f9918aSopenharmony_ci if anchor is not None: 108a5f9918aSopenharmony_ci self.anchors[anchor] = node 109a5f9918aSopenharmony_ci index = 0 110a5f9918aSopenharmony_ci while not self.check_event(SequenceEndEvent): 111a5f9918aSopenharmony_ci node.value.append(self.compose_node(node, index)) 112a5f9918aSopenharmony_ci index += 1 113a5f9918aSopenharmony_ci end_event = self.get_event() 114a5f9918aSopenharmony_ci node.end_mark = end_event.end_mark 115a5f9918aSopenharmony_ci return node 116a5f9918aSopenharmony_ci 117a5f9918aSopenharmony_ci def compose_mapping_node(self, anchor): 118a5f9918aSopenharmony_ci start_event = self.get_event() 119a5f9918aSopenharmony_ci tag = start_event.tag 120a5f9918aSopenharmony_ci if tag is None or tag == '!': 121a5f9918aSopenharmony_ci tag = self.resolve(MappingNode, None, start_event.implicit) 122a5f9918aSopenharmony_ci node = MappingNode(tag, [], 123a5f9918aSopenharmony_ci start_event.start_mark, None, 124a5f9918aSopenharmony_ci flow_style=start_event.flow_style) 125a5f9918aSopenharmony_ci if anchor is not None: 126a5f9918aSopenharmony_ci self.anchors[anchor] = node 127a5f9918aSopenharmony_ci while not self.check_event(MappingEndEvent): 128a5f9918aSopenharmony_ci #key_event = self.peek_event() 129a5f9918aSopenharmony_ci item_key = self.compose_node(node, None) 130a5f9918aSopenharmony_ci #if item_key in node.value: 131a5f9918aSopenharmony_ci # raise ComposerError("while composing a mapping", start_event.start_mark, 132a5f9918aSopenharmony_ci # "found duplicate key", key_event.start_mark) 133a5f9918aSopenharmony_ci item_value = self.compose_node(node, item_key) 134a5f9918aSopenharmony_ci #node.value[item_key] = item_value 135a5f9918aSopenharmony_ci node.value.append((item_key, item_value)) 136a5f9918aSopenharmony_ci end_event = self.get_event() 137a5f9918aSopenharmony_ci node.end_mark = end_event.end_mark 138a5f9918aSopenharmony_ci return node 139a5f9918aSopenharmony_ci 140