blob: ba66e4cad643ad09d52ad84deb469da670debccb [file] [log] [blame]
import enum
from lark.tree import Meta
from dataclasses import dataclass, field
from typing import List, Set, Optional, Union
# Information about parsing location for specific items
# Helpful when referencing data items in logs when processing
@dataclass
class ParseMetaData:
line: int
column: int
def __init__(self, meta: Meta = None, line: int = None, column: int = None):
if meta:
self.line = meta.line
self.column = meta.column
else:
self.line = line
self.column = column
class StructQuality(enum.Flag):
NONE = 0
FABRIC_SCOPED = enum.auto()
class FieldQuality(enum.Flag):
NONE = 0
OPTIONAL = enum.auto()
NULLABLE = enum.auto()
FABRIC_SENSITIVE = enum.auto()
class CommandQuality(enum.Flag):
NONE = 0
TIMED_INVOKE = enum.auto()
FABRIC_SCOPED = enum.auto()
class AttributeQuality(enum.Flag):
NONE = 0
READABLE = enum.auto()
WRITABLE = enum.auto()
NOSUBSCRIBE = enum.auto()
class AttributeStorage(enum.Enum):
RAM = enum.auto()
PERSIST = enum.auto()
CALLBACK = enum.auto()
class EventPriority(enum.Enum):
DEBUG = enum.auto()
INFO = enum.auto()
CRITICAL = enum.auto()
class EventQuality(enum.Flag):
NONE = 0
FABRIC_SENSITIVE = enum.auto()
class ClusterSide(enum.Enum):
CLIENT = enum.auto()
SERVER = enum.auto()
class StructTag(enum.Enum):
REQUEST = enum.auto()
RESPONSE = enum.auto()
class EndpointContentType(enum.Enum):
SERVER_CLUSTER = enum.auto()
CLIENT_BINDING = enum.auto()
class AccessPrivilege(enum.Enum):
VIEW = enum.auto()
OPERATE = enum.auto()
MANAGE = enum.auto()
ADMINISTER = enum.auto()
class AttributeOperation(enum.Enum):
READ = enum.auto()
WRITE = enum.auto()
@dataclass
class DataType:
name: str
# Applies for strings (char or binary)
max_length: Optional[int] = None
@dataclass
class Field:
data_type: DataType
code: int
name: str
is_list: bool = False
qualities: FieldQuality = FieldQuality.NONE
@property
def is_optional(self):
return FieldQuality.OPTIONAL & self.qualities
@property
def is_nullable(self):
return FieldQuality.NULLABLE & self.qualities
@dataclass
class Attribute:
definition: Field
qualities: AttributeQuality = AttributeQuality.NONE
readacl: AccessPrivilege = AccessPrivilege.VIEW
writeacl: AccessPrivilege = AccessPrivilege.OPERATE
default: Optional[Union[str, int]] = None
@property
def is_readable(self):
return AttributeQuality.READABLE & self.qualities
@property
def is_writable(self):
return AttributeQuality.WRITABLE & self.qualities
@property
def is_subscribable(self):
return not (AttributeQuality.NOSUBSCRIBE & self.qualities)
@dataclass
class Struct:
name: str
fields: List[Field]
tag: Optional[StructTag] = None
code: Optional[int] = None # for responses only
qualities: StructQuality = StructQuality.NONE
@dataclass
class Event:
priority: EventPriority
name: str
code: int
fields: List[Field]
readacl: AccessPrivilege = AccessPrivilege.VIEW
qualities: EventQuality = EventQuality.NONE
@property
def is_fabric_sensitive(self):
return EventQuality.FABRIC_SENSITIVE & self.qualities
@dataclass
class ConstantEntry:
name: str
code: int
@dataclass
class Enum:
name: str
base_type: str
entries: List[ConstantEntry]
@dataclass
class Bitmap:
name: str
base_type: str
entries: List[ConstantEntry]
@dataclass
class Command:
name: str
code: int
input_param: Optional[str]
output_param: str
qualities: CommandQuality = CommandQuality.NONE
invokeacl: AccessPrivilege = AccessPrivilege.OPERATE
@property
def is_timed_invoke(self):
return CommandQuality.TIMED_INVOKE & self.qualities
@dataclass
class Cluster:
side: ClusterSide
name: str
code: int
enums: List[Enum] = field(default_factory=list)
bitmaps: List[Bitmap] = field(default_factory=list)
events: List[Event] = field(default_factory=list)
attributes: List[Attribute] = field(default_factory=list)
structs: List[Struct] = field(default_factory=list)
commands: List[Command] = field(default_factory=list)
# Parsing meta data missing only when skip meta data is requested
parse_meta: Optional[ParseMetaData] = field(default=None)
@dataclass
class AttributeInstantiation:
name: str
storage: AttributeStorage
default: Optional[Union[str, int, bool]] = None
# Parsing meta data missing only when skip meta data is requested
parse_meta: Optional[ParseMetaData] = field(default=None)
@dataclass
class ServerClusterInstantiation:
name: str
attributes: List[AttributeInstantiation] = field(default_factory=list)
# Parsing meta data missing only when skip meta data is requested
parse_meta: Optional[ParseMetaData] = field(default=None)
@dataclass
class DeviceType:
name: str
code: int
@dataclass
class Endpoint:
number: int
device_types: List[DeviceType] = field(default_factory=list)
server_clusters: List[ServerClusterInstantiation] = field(default_factory=list)
client_bindings: List[str] = field(default_factory=list)
@dataclass
class Idl:
# Enums and structs represent globally used items
enums: List[Enum] = field(default_factory=list)
structs: List[Struct] = field(default_factory=list)
clusters: List[Cluster] = field(default_factory=list)
endpoints: List[Endpoint] = field(default_factory=list)
# IDL file name is available only if parsing provides a file name
parse_file_name: Optional[str] = field(default=None)