StrictDoc Documentation
strictdoc/backend/sdoc/models/model.py
Source file coverage
Path:
strictdoc/backend/sdoc/models/model.py
Lines:
202
Non-empty lines:
158
Non-empty lines covered with requirements:
158 / 158 (100.0%)
Functions:
25
Functions covered by requirements:
25 / 25 (100.0%)
1
"""
2
@relation(SDOC-SRS-18, scope=file)
3
"""
4
 
5
from abc import ABC, abstractmethod
6
from typing import TYPE_CHECKING, Dict, Final, Generator, List, Optional, Union
7
 
8
if TYPE_CHECKING:
9
    from strictdoc.backend.sdoc.models.grammar_element import GrammarElement
10
 
11
from strictdoc.backend.sdoc.models.document_config import (
12
    DocumentConfig,
13
)
14
from strictdoc.backend.sdoc_source_code.models.source_file_info import (
15
    SourceFileTraceabilityInfo,
16
)
17
from strictdoc.core.document_meta import DocumentMeta
18
from strictdoc.helpers.mid import MID
19
 
20
 
21
class RequirementFieldName:
22
    MID = "MID"
23
    UID = "UID"
24
    PREFIX = "PREFIX"
25
    LEVEL = "LEVEL"
26
    STATUS = "STATUS"
27
    TAGS = "TAGS"
28
    TITLE = "TITLE"
29
 
30
    # {STATEMENT, DESCRIPTION, CONTENT} are aliases.
31
    # It is assumed that either field is provided for each node.
32
    STATEMENT = "STATEMENT"
33
    DESCRIPTION = "DESCRIPTION"
34
    CONTENT = "CONTENT"
35
 
36
    RATIONALE = "RATIONALE"
37
    COMMENT = "COMMENT"
38
 
39
    RESERVED_SINGLELINE_FIELDS: Final[frozenset[str]] = frozenset(
40
        (
41
            MID,
42
            UID,
43
            PREFIX,
44
            LEVEL,
45
            STATUS,
46
            TAGS,
47
            TITLE,
48
        )
49
    )
50
 
51
    RESERVED_NON_META_FIELDS: Final[frozenset[str]] = frozenset(
52
        (
53
            TITLE,
54
            STATEMENT,
55
            DESCRIPTION,
56
            CONTENT,
57
            COMMENT,
58
            RATIONALE,
59
        )
60
    )
61
 
62
 
63
class SDocNodeFieldIF(ABC):
64
    parent: "SDocNodeIF"
65
 
66
 
67
class SDocNodeIF(ABC):
68
    reserved_mid: MID
69
    mid_permanent: bool
70
    parent: Union["SDocNodeIF", "SDocDocumentIF"]
71
    node_type: str
72
    section_contents: List["SDocElementIF"]
73
    ng_level: Optional[int]
74
    ng_resolved_custom_level: Optional[str]
75
    ng_has_requirements: bool
76
    autogen: bool
77
 
78
    @property
79
    @abstractmethod
80
    def reserved_uid(self) -> Optional[str]:
81
        raise NotImplementedError
82
 
83
    @reserved_uid.setter
84
    @abstractmethod
85
    def reserved_uid(self, uid: Optional[str]) -> None:
86
        raise NotImplementedError
87
 
88
    @property
89
    def reserved_title(self) -> Optional[str]:
90
        raise NotImplementedError
91
 
92
    @abstractmethod
93
    def is_normative_node(self) -> bool:
94
        raise NotImplementedError
95
 
96
    @abstractmethod
97
    def is_text_node(self) -> bool:
98
        raise NotImplementedError
99
 
100
    @abstractmethod
101
    def get_debug_info(self) -> str:
102
        raise NotImplementedError
103
 
104
    @abstractmethod
105
    def get_document(self) -> Optional["SDocDocumentIF"]:
106
        raise NotImplementedError
107
 
108
    @abstractmethod
109
    def get_including_document(self) -> Optional["SDocDocumentIF"]:
110
        raise NotImplementedError
111
 
112
    @abstractmethod
113
    def get_parent_or_including_document(self) -> "SDocDocumentIF":
114
        raise NotImplementedError
115
 
116
    @abstractmethod
117
    def get_prefix(self) -> Optional[str]:
118
        raise NotImplementedError
119
 
120
 
121
class SDocGrammarIF:
122
    elements_by_type: Dict[str, "GrammarElement"]
123
 
124
 
125
class SDocDocumentIF(ABC):
126
    reserved_mid: MID
127
    mid_permanent: bool
128
    section_contents: List["SDocElementIF"]
129
    included_documents: List["SDocDocumentIF"]
130
    config: DocumentConfig
131
    grammar: Optional[SDocGrammarIF]
132
    meta: Optional[DocumentMeta]
133
    is_bundle_document: bool
134
    ng_level: Optional[int]
135
    ng_has_requirements: bool
136
    autogen: bool
137
 
138
    # FIXME: Get rid of @property everywhere.
139
    @property
140
    def reserved_uid(self) -> Optional[str]:
141
        raise NotImplementedError
142
 
143
    @abstractmethod
144
    def get_prefix(self) -> str:
145
        raise NotImplementedError
146
 
147
    @abstractmethod
148
    def get_debug_info(self) -> str:
149
        raise NotImplementedError
150
 
151
    @abstractmethod
152
    def iterate_included_documents_depth_first(
153
        self,
154
    ) -> Generator["SDocDocumentIF", None, None]:
155
        raise NotImplementedError
156
 
157
    def document_is_included(self) -> bool:
158
        raise NotImplementedError
159
 
160
    @abstractmethod
161
    def get_display_title(self, include_toc_number: bool = True) -> str:
162
        raise NotImplementedError
163
 
164
    @property
165
    def ng_resolved_custom_level(self) -> Optional[str]:
166
        raise NotImplementedError
167
 
168
 
169
class SDocDocumentFromFileIF(ABC):
170
    parent: Union[SDocDocumentIF, SDocNodeIF]
171
    ng_resolved_custom_level: Optional[str]
172
    autogen: bool
173
 
174
    @abstractmethod
175
    def iterate_nodes(
176
        self,
177
        element_type: Optional[str] = None,
178
    ) -> Generator[SDocNodeIF, None, None]:
179
        raise NotImplementedError
180
 
181
    @property
182
    def section_contents(self) -> List[SDocDocumentIF]:
183
        raise NotImplementedError
184
 
185
 
186
SDocElementIF = Union[
187
    SDocNodeIF,
188
    SDocDocumentIF,
189
    SDocDocumentFromFileIF,
190
]
191
 
192
 
193
SDocIteratedElementIF = Union[
194
    SDocNodeIF,
195
    SDocDocumentIF,
196
]
197
 
198
 
199
SDocExtendedElementIF = Union[
200
    SDocElementIF,
201
    SourceFileTraceabilityInfo,
202
]