def _Kind(kinds, spec, scope): """Convert a type name into a mojom.Kind object. As a side-effect this function adds the result to 'kinds'. Args: kinds: {Dict[str, mojom.Kind]} All known kinds up to this point, indexed by their names. spec: {str} A name uniquely identifying a type. scope: {Tuple[str, str]} A tuple that looks like (namespace, struct/interface), referring to the location where the type is referenced. Returns: {mojom.Kind} The type corresponding to 'spec'. """ kind = _LookupKind(kinds, spec, scope) if kind: return kind if spec.startswith('?'): kind = _Kind(kinds, spec[1:], scope).MakeNullableKind() elif spec.startswith('a:'): kind = mojom.Array(_Kind(kinds, spec[2:], scope)) elif spec.startswith('asso:'): inner_kind = _Kind(kinds, spec[5:], scope) if isinstance(inner_kind, mojom.InterfaceRequest): kind = mojom.AssociatedInterfaceRequest(inner_kind) else: kind = mojom.AssociatedInterface(inner_kind) elif spec.startswith('a'): colon = spec.find(':') length = int(spec[1:colon]) kind = mojom.Array(_Kind(kinds, spec[colon + 1:], scope), length) elif spec.startswith('r:'): kind = mojom.InterfaceRequest(_Kind(kinds, spec[2:], scope)) elif spec.startswith('rmt:'): kind = mojom.PendingRemote(_Kind(kinds, spec[4:], scope)) elif spec.startswith('rcv:'): kind = mojom.PendingReceiver(_Kind(kinds, spec[4:], scope)) elif spec.startswith('m['): # Isolate the two types from their brackets. # It is not allowed to use map as key, so there shouldn't be nested ']'s # inside the key type spec. key_end = spec.find(']') assert key_end != -1 and key_end < len(spec) - 1 assert spec[key_end + 1] == '[' and spec[-1] == ']' first_kind = spec[2:key_end] second_kind = spec[key_end + 2:-1] kind = mojom.Map(_Kind(kinds, first_kind, scope), _Kind(kinds, second_kind, scope)) else: kind = mojom.Kind(spec) kinds[spec] = kind return kind
def KindFromData(kinds, data, scope): kind = LookupKind(kinds, data, scope) if kind: return kind if data.startswith('?'): kind = KindFromData(kinds, data[1:], scope).MakeNullableKind() elif data.startswith('a:'): kind = mojom.Array(KindFromData(kinds, data[2:], scope)) elif data.startswith('asso:'): inner_kind = KindFromData(kinds, data[5:], scope) if isinstance(inner_kind, mojom.InterfaceRequest): kind = mojom.AssociatedInterfaceRequest(inner_kind) else: kind = mojom.AssociatedInterface(inner_kind) elif data.startswith('a'): colon = data.find(':') length = int(data[1:colon]) kind = mojom.Array(KindFromData(kinds, data[colon + 1:], scope), length) elif data.startswith('r:'): kind = mojom.InterfaceRequest(KindFromData(kinds, data[2:], scope)) elif data.startswith('m['): # Isolate the two types from their brackets. # It is not allowed to use map as key, so there shouldn't be nested ']'s # inside the key type spec. key_end = data.find(']') assert key_end != -1 and key_end < len(data) - 1 assert data[key_end + 1] == '[' and data[-1] == ']' first_kind = data[2:key_end] second_kind = data[key_end + 2:-1] kind = mojom.Map(KindFromData(kinds, first_kind, scope), KindFromData(kinds, second_kind, scope)) else: kind = mojom.Kind(data) kinds[data] = kind return kind