1# textX models
2
3Model is a python object graph consisting of POPOs (Plain Old Python Objects)
4constructed from the input string that conforms to your DSL defined by the
5grammar and additional [model and object processors](metamodel.md#processors).
6
7In a sense, this structure is an Abstract Syntax Tree (AST) known from classic
8parsing theory, but it is actually a graph structure where each reference is
9resolved to a proper python reference.
10
11Each object is an instance of a class from the meta-model. Classes are created
12on-the-fly from the grammar rules or are [supplied by the
13user](metamodel.md#custom-classes).
14
15A model is created from the input string using the `model_from_file` and
16`model_from_str` methods of the meta-model instance.
17
18    from textx import metamodel_from_file
19
20    my_mm = metamodel_from_file('mygrammar.tx')
21
22    # Create model
23    my_model = my_mm.model_from_file('some_model.ext')
24
25
26!!! note
27    The `model_from_file` method takes an optional argument `encoding`
28    to control the input encoding of the model file to be loaded.
29
30!!! warning
31
32    textX accepts unicode strings only so `metamodel_from_str` and `model_from_str`
33    parameter should be `str` for Python 3.x or `unicode` for Python 2.x. That is
34    true for all API parameters where string is accepted. The easiest way for Python
35    2.x is to use `from __future__ import unicode_literals` at the top of the file.
36
37
38Let's take the Entity language used in [Custom
39Classes](metamodel.md#custom-classes) section.
40
41Content of `entity.tx` file:
42
43    EntityModel:
44      entities+=Entity    // each model has one or more entities
45    ;
46
47    Entity:
48      'entity' name=ID '{'
49        attributes+=Attribute     // each entity has one or more attributes
50      '}'
51    ;
52
53    Attribute:
54      name=ID ':' type=[Entity]   // type is a reference to an entity. There are
55                                  // built-in entities registered on the meta-model
56                                  // for the primitive types (integer, string)
57    ;
58
59
60For the meta-model construction and built-in registration see [Custom
61Classes](metamodel.md#custom-classes) and
62[Builtins](metamodel.md#built-in-objects) sections.
63
64Now, we can use the `entity_mm` meta-model to parse and create Entity models.
65
66```python
67person_model = entity_mm.model_from_file('person.ent')
68```
69
70Where `person.ent` file might contain this:
71
72    entity Person {
73      name : string
74      address: Address
75      age: integer
76    }
77
78    entity Address {
79      street : string
80      city : string
81      country : string
82    }
83
84## Model API
85
86Functions given in this section can be imported from `textx` module.
87
88### `get_model(obj)`
89
90`obj (model object)`
91
92Finds the root of the model following `parent` references.
93
94
95### `get_metamodel(obj)`
96
97Returns meta-model the model given with `obj` conforms to.
98
99### `get_parent_of_type(typ, obj)`
100
101- `typ (str or class)`: the name of type of the type itself of the model object
102searched for.
103- `obj (model object)`: model object to start search from.
104
105Finds first object up the parent chain of the given type. If no parent of the
106given type exists `None` is returned.
107
108### `get_children_of_type(typ, root, children_first=False, should_follow=lambda obj: True)`
109
110- `typ (str or python class)`: The type of the model object we are looking for.
111- `root (model object)`: Python model object which is the start of the search
112    process.
113- `children_first (bool)`: indicates if children should be returned before their
114  parents.
115- `should_follow (callable)`: a predicate used to decide if the object should be
116  traversed.
117
118Returns a list of all model elements of type `typ` starting from model element
119`root`. The search process will follow containment links only. Non-containing
120references shall not be followed.
121
122### `get_children(selector, root, children_first=False, should_follow=lambda obj: True)`
123
124- `selector (callable)`: a predicate returning True if the object is of interest.
125- `root (model object)`: Python model object which is the start of the search
126    process.
127- `children_first (bool)`: indicates if children should be returned before their
128  parents.
129- `should_follow (callable)`: a predicate used to decide if the object should be
130  traversed.
131
132Returns a list of all selected model elements starting from model element
133`root`. The search process will follow containment links only. Non-containing
134references shall not be followed.
135
136### `get_location(obj)`
137
138Returns the location of the textX model object in the form of a dict with
139`line/col/filename` keys. Filename can be `None` if the model is loaded from a
140string. Return value is convenient for use in TextX exceptions (e.g. `raise
141TextXSemanticError('Some message', **get_location(model_obj))`)
142
143### `textx_isinstance(obj, cls)`
144
145Return `True` if `obj` is instance of `cls` taking into account textX rule/class
146hierarchy. For textX created classes you can get a reference to a class from
147meta-model by keying into it using the class name `metamodel['SomeRule']`.
148
149## Special model object's attributes
150
151Beside attributes specified by the grammar, there are several special
152attributes on model objects created by textX. All special attributes' names
153start with prefix `_tx`.
154
155These special attributes don't exist if the type of the resulting model object
156don't allow dynamic attribute creation (e.g. for Python base builtin types -
157str, int).
158
159### _tx_position and _tx_position_end
160
161`_tx_position` attribute holds the position in the input string where the
162object has been matched by the parser. Each object from the model object graph
163has this attribute.
164
165This is an absolute position in the input stream. To convert it to line/column
166format use `pos_to_linecol` method of the parser.
167
168```python
169line, col = entity_model._tx_parser.pos_to_linecol(
170    person_model.entities[0]._tx_position)
171```
172
173Where `entity_model` is a model constructed by textX.
174
175Previous example will give the line/column position of the first entity.
176
177`_tx_position_end` is the position in the input stream where the object ends.
178This position is one char past the last char belonging to the object. Thus,
179`_tx_position_end - _tx_position == length of the object str representation`.
180
181If you need line, column and filename of a textX object (e.g. for raising
182`TextXSemanticError`) see [get_location above](#get_locationobj).
183
184
185### _tx_filename
186
187This attribute exists only on the root of the model. If the model is loaded
188from a file, this attribute will be the full path of the source file. If the
189model is created from a string this attribute will be `None`.
190
191### _tx_parser
192
193This attribute represents the concrete parser instance used for the model
194(the attribute `_parser` of the `_tx_metamodel` is only a blueprint for the
195parser of each model instance and cannot be used, e.g., to determine model
196element positions in a file. Use the `_tx_parser` attribute of the model
197instead).
198
199### _tx_metamodel
200
201This attribute exists only on the root of the model. It is a reference to the
202meta-model object used for creating the model.
203
204
205### _tx_fqn
206
207Is the fully qualified name of the grammar rule/Python class in regard to the
208import path of the grammar file where the rule is defined. This attribute is
209used in `__repr__` of auto-generated Python classes.
210
211### _tx_model_repository
212
213The model may have a model repository (initiated by some scope provider or by
214the metamodel). This object is responsible to provide and cache other model
215instances (see textx.scoping.providers).
216
217### _tx_model_params
218
219This attribute always exists. It holds all additional parameters passed to
220`model_from_str` or `model_from_file` of a metamodel. These parameters are
221restricted by the `metamodel.model_param_defs` object ([model and object
222processors](metamodel.md#optional-model-parameter-definitions)), which is
223controlled by the metamodel designer.
224