Object Mapping¶
Every value that lives inside a FLYNC workspace — whether it is the root model,
a nested ECU, a list of controllers, or a single scalar — is tracked in two
parallel dictionaries on FLYNCWorkspace:
objects— maps eachObjectIdto its validatedSemanticObject.sources— maps eachObjectIdto aSourceRefthat records which file the value came from and the exact line/column range.
This page explains how those two dictionaries are built during loading and how to query them at runtime.
Object IDs¶
An ObjectId is a plain dot-separated string
that encodes the full path from the root model to a value.
Segment |
Meaning |
Example ID fragment |
|---|---|---|
|
Named attribute on a model |
|
|
Concrete dict key (resolved at load time) |
|
|
Numeric list index (see List Item IDs and ListObjectsMode) |
|
|
Optional name-based alias for a list item (see List Item IDs and ListObjectsMode) |
|
The root model itself is stored under the empty string "".
Note
available_flync_nodes() returns
schema-level paths that use {} and [] as wildcards. The IDs stored
in the workspace use concrete keys and indices that are resolved when the
files are actually parsed. See Discovering Node Paths for the distinction.
List Item IDs and ListObjectsMode¶
When the workspace encounters a list (a SequenceNode in the YAML or a
folder-based External list on disk), each item needs one or more
ObjectId values so it can be retrieved
individually. The
list_objects_mode
setting on WorkspaceConfiguration
controls which IDs are generated via
add_list_item_object_path().
- class ListObjectsMode(*values)¶
Bases:
IntFlagFlags controlling how list items are keyed in the workspace object map.
Flags can be combined with
|. The default isINDEX | NAME.- Attributes:
- INDEX: Register each list item under its zero-based integer index
(e.g.
controllers.0).- NAME: Register each list item under its name — the file/directory stem
for folder-based lists, or the model’s
nameattribute for inline YAML lists. Items without a name are skipped.
- INDEX = 1¶
- NAME = 2¶
- FLYNCWorkspace.add_list_item_object_path(item_name, current_object_paths, idx)¶
Build the object path(s) for a single list item.
Depending on
list_objects_mode, the item may be registered under its numeric index, its name, or both:INDEX: appends the zero-based integer index as a path segment.NAME: appendsitem_nameas an additional path segment when the name is non-empty. For external (folder-based) lists the name comes from the file/directory stem; for inline lists it comes from the model’snameattribute.
Both flags are active by default, so a list item is accessible under two IDs simultaneously (e.g.
controllers.0andcontrollers.my_ctrl).- Args:
- item_name (str | None): Name of the list item, or
None/ empty string when the item has no name.
current_object_paths (list[str]): Parent path(s) to extend. idx (int): Zero-based position of the item in the list.
- item_name (str | None): Name of the list item, or
- Returns:
list[str]: New list of object paths for this item.
Modes¶
Mode |
Effect |
|---|---|
|
Each item is registered under its zero-based integer index.
|
|
Each item is registered under its name (the |
|
Both IDs are registered for the same item. The item is reachable under
either path.
|
Source of the name¶
The name used for NAME mode depends on where the list lives:
Folder-based
Externallists — the name is the file or directory stem (everything before the first.in the filename). This is derived fromsub_item_path.stemas the directory is iterated.Inline YAML
SequenceNodelists — the name is the ``name`` attribute of the validated Pydantic model at that index (getattr(model[idx], "name", None)). If the model has nonamefield the item gets an index-only ID even whenNAMEmode is active.
Configuring the mode¶
Pass a custom
WorkspaceConfiguration when
loading the workspace:
from flync.sdk.context.workspace_config import WorkspaceConfiguration, ListObjectsMode
from flync.sdk.workspace.flync_workspace import FLYNCWorkspace
# Index-only — useful when item names are not stable
config = WorkspaceConfiguration(
list_objects_mode=ListObjectsMode.INDEX,
)
ws = FLYNCWorkspace.load_workspace("my_config", "/path/to/config", config)
# Name-only — useful when indices may shift across reloads or for easier object lookup for manual users
config = WorkspaceConfiguration(
list_objects_mode=ListObjectsMode.NAME,
)
# Both (the default)
config = WorkspaceConfiguration(
list_objects_mode=ListObjectsMode.INDEX | ListObjectsMode.NAME,
)
Example — dual IDs in practice¶
Given a workspace whose controllers/ directory contains
eth_ctrl.flync.yaml and the default INDEX | NAME mode:
ws = FLYNCWorkspace.load_workspace("cfg", "/path/to/config")
# Both of these refer to the same SemanticObject
by_index = ws.get_object("ecus.gateway.controllers.0")
by_name = ws.get_object("ecus.gateway.controllers.eth_ctrl")
assert by_index.model is by_name.model # same validated instance
Source Types¶
- class SourceRef(uri: str, range: Range)¶
Bases:
objectReference to the source location of a semantic object.
- Attributes:
uri (str): Document URI where the object is defined. range (Range): The range within the document.
- uri: str¶
- class Range(start: Position, end: Position)¶
Bases:
objectRepresents a range between two positions in a document.
- Attributes:
start (Position): The start position of the range. end (Position): The end position of the range.
- class Position(line: int, character: int)¶
Bases:
objectRepresents a position in a text document.
For objects backed by a YAML file both
lineandcharacterare 1-based, derived from ruamel.yamlstart_mark/end_markby adding 1 to the 0-based mark offsets.For objects that have no YAML source (e.g. implied or externally loaded objects without a resolved file) both fields are 0, acting as a sentinel meaning “no location available”.
- Attributes:
line (int): 1-based line number, or 0 when no source is available. character (int): 1-based character offset, or 0 when no source is
available.
- line: int¶
- character: int¶
- class SemanticObject(id: ObjectId, model: BaseModel)¶
Bases:
objectWrapper around a validated semantic model.
- Attributes:
id (ObjectId): Identifier of the semantic object. model (BaseModel): The validated Pydantic model.
- class ObjectId¶
A string-based unique identifier for a semantic object in the workspace.
alias of
str
Runtime Retrieval¶
Once the workspace is loaded, four methods expose the object and source maps.
List all object IDs¶
- FLYNCWorkspace.list_objects() list[ObjectId]¶
Return a list of all ObjectIds present in the workspace.
- Returns:
- list[ObjectId]:
List of object identifiers.
ws = FLYNCWorkspace.load_workspace("my_config", "/path/to/config")
for oid in ws.list_objects():
print(oid)
# ""
# "ecus"
# "ecus.gateway"
# "ecus.gateway.controllers.0" ← index-based ID
# "ecus.gateway.controllers.eth_ctrl" ← name-based ID (same object)
# ...
Retrieve a semantic object¶
- FLYNCWorkspace.get_object(id: ObjectId) SemanticObject¶
Retrieve a semantic object by its ObjectId.
- Args:
- id (ObjectId):
Identifier of the semantic object.
- Returns:
- SemanticObject:
The requested semantic object.
obj = ws.get_object("ecus.gateway")
print(obj.model) # EcuConfig instance
print(obj.id) # "ecus.gateway"
Retrieve the source location¶
- FLYNCWorkspace.get_source(id: ObjectId) SourceRef¶
Retrieve the source reference for a given ObjectId.
- Args:
- id (ObjectId):
Identifier of the object.
- Returns:
- SourceRef:
The source reference associated with the object.
src = ws.get_source("ecus.gateway")
print(src.uri) # "ecus/gateway/ecu_metadata.flync.yaml"
print(src.range.start) # Position(line=1, character=1) ← 1-based (YAML-backed)
print(src.range.end) # Position(line=42, character=1)
Note
Position values are 1-based for
objects loaded from a YAML file (ruamel.yaml marks are shifted by +1).
Objects that have no YAML source (implied or externally loaded without a
resolved file) carry Position(line=0, character=0) as a sentinel.
Look up objects by file position¶
- FLYNCWorkspace.objects_at(uri: str, line: int, character: int) list[ObjectId]¶
Return the list of ObjectIds located at the specified position in a document.
- Args:
- uri (str):
Document URI.
- line (int):
1-based line number, consistent with the
Positionvalues stored during YAML parsing.- character (int):
1-based character offset within the line.
- Returns:
- list[ObjectId]:
List of object identifiers at the given position.
This is the primary entry point for language-server features such as hover and
go-to-definition. Given a document URI and a cursor position, it returns every
ObjectId whose source range contains that
position.
ids = ws.objects_at(
uri="ecus/gateway/ecu_metadata.flync.yaml",
line=10,
character=5,
)
for oid in ids:
obj = ws.get_object(oid)
print(oid, "→", type(obj.model).__name__)
Note
objects_at uses 1-based line and character numbers, matching the
Position values stored during YAML
parsing. Pass line=0, character=0 to query objects with no YAML source.
Object Path Helpers¶
These utility methods are used internally during loading but are also available for tooling that needs to build or resolve object paths at runtime.
- FLYNCWorkspace.document_id_from_path(doc_path: Path) str¶
Return the workspace-relative string identifier for a document path.
- Args:
doc_path (Path): An absolute path to a document file.
- Returns:
str: The path relative to the workspace root, as a string.
- static FLYNCWorkspace.new_object_path(current_path: str, new_object_name: int | str) str¶
Extend a dot-separated object path with a new segment.
- Args:
current_path (str): The existing dot-separated path. new_object_name (int | str): The segment to append.
- Returns:
str: The extended path string.
- FLYNCWorkspace.update_objects_path(current_paths: list[str], new_object_name: str) list[str]¶
Extend every path in a list with a new segment.
- Args:
current_paths (list[str]): Existing dot-separated paths. new_object_name (str): The segment to append to each path.
- Returns:
list[str]: New list of extended path strings.
- FLYNCWorkspace.fill_path_from_object(model_object: FLYNCBaseModel, object_path: str) str¶
Replace placeholder segments in an object path with concrete keys.
Traverses the workspace’s root model following
object_path, substituting[]with the actual list index and{}with the actual dict key whenmodel_objectis found.- Args:
model_object (FLYNCBaseModel): The model instance to locate. object_path (str): Dot-separated path containing
[]or{}placeholders.
- Returns:
- str: The resolved dot-separated path with concrete index/key
values.
Data structure summary¶
FLYNCWorkspace
├── objects: Dict[ObjectId, SemanticObject]
│ │ │
│ │ └── .model (validated Pydantic value)
│ │ └── .id (same as the key)
│ │
│ ├── "ecus.gateway.controllers.0" ─┐ both point to the
│ └── "ecus.gateway.controllers.eth_ctrl" ─┘ same SemanticObject
│ (generated by add_list_item_object_path via ListObjectsMode)
│
└── sources: Dict[ObjectId, SourceRef]
│ │
│ └── .uri (workspace-relative file path)
│ └── .range ─┬─ .start Position(line, character) ← 1-based for YAML; (0,0) if no source
│ └─ .end Position(line, character) ← 1-based for YAML; (0,0) if no source
│
└── key: same ObjectId used in objects
(one entry per ID, so index and name both have a SourceRef)