Parse a TQL schema string into a :class:ParsedSchema.
Uses the Rust TypeSchema parser when available for speed, falling
back to the Lark-based parser otherwise. Annotations and docstrings
(extracted from comments) are always applied on the Python side.
Source code in type_bridge/generator/parser.py
| def parse_tql_schema(schema_content: str) -> ParsedSchema:
"""Parse a TQL schema string into a :class:`ParsedSchema`.
Uses the Rust ``TypeSchema`` parser when available for speed, falling
back to the Lark-based parser otherwise. Annotations and docstrings
(extracted from comments) are always applied on the Python side.
"""
# Step 1: Always extract annotations from comments first
entity_annots, attr_annots, rel_annots, role_annots = extract_annotations(schema_content)
# Step 2: Try Rust parser
if _RUST_SCHEMA_AVAILABLE:
try:
rust_schema = _RustTypeSchema.from_typeql(schema_content) # type: ignore[union-attr]
schema = _rust_schema_to_parsed(
rust_schema, entity_annots, attr_annots, rel_annots, role_annots
)
logger.debug("Parsed schema using Rust core")
# Step 3: If functions/structs present, supplement with Lark
if _HAS_FUN_OR_STRUCT.search(schema_content):
logger.debug("Schema contains functions/structs, supplementing with Lark parser")
lark_schema = _parse_with_lark(
schema_content, entity_annots, attr_annots, rel_annots, role_annots
)
schema.functions = lark_schema.functions
schema.structs = lark_schema.structs
return schema
except Exception:
logger.warning("Rust parser failed, falling back to Lark parser", exc_info=True)
# Step 4: Full Lark fallback
if not _RUST_SCHEMA_AVAILABLE:
logger.debug("Rust core not available, using Lark parser")
return _parse_with_lark(schema_content, entity_annots, attr_annots, rel_annots, role_annots)
|