def resolve_ptr(near_endpoint: s_sources.Source, pointer_name: str, *, direction: s_pointers.PointerDirection = ( s_pointers.PointerDirection.Outbound), source_context: typing.Optional[parsing.ParserContext] = None, ctx: context.ContextLevel) -> s_pointers.Pointer: if not isinstance(near_endpoint, s_sources.Source): # Reference to a property on non-object msg = 'invalid property reference on a primitive type expression' raise errors.InvalidReferenceError(msg, context=source_context) ctx.env.schema, ptr = near_endpoint.resolve_pointer(ctx.env.schema, pointer_name, direction=direction) if ptr is None: if isinstance(near_endpoint, s_links.Link): msg = (f'{near_endpoint.get_displayname(ctx.env.schema)} ' f'has no property {pointer_name!r}') elif direction == s_pointers.PointerDirection.Outbound: msg = (f'{near_endpoint.get_displayname(ctx.env.schema)} ' f'has no link or property {pointer_name!r}') else: nep_name = near_endpoint.get_displayname(ctx.env.schema) path = f'{nep_name}.{direction}{pointer_name}' msg = f'{path!r} does not resolve to any known path' err = errors.InvalidReferenceError(msg, context=source_context) if direction == s_pointers.PointerDirection.Outbound: near_enpoint_pointers = near_endpoint.get_pointers(ctx.env.schema) s_utils.enrich_schema_lookup_error( err, pointer_name, modaliases=ctx.modaliases, item_types=(s_pointers.Pointer, ), collection=near_enpoint_pointers.objects(ctx.env.schema), schema=ctx.env.schema) raise err return ptr
def tuple_indirection_set(path_tip: irast.Set, *, source: s_sources.Source, ptr_name: str, source_context: parsing.ParserContext, ctx: context.ContextLevel) -> irast.Set: el_name = ptr_name el_norm_name = source.normalize_index(ctx.env.schema, el_name) el_type = source.get_subtype(ctx.env.schema, el_name) path_id = pathctx.get_tuple_indirection_path_id(path_tip.path_id, el_norm_name, el_type, ctx=ctx) expr = irast.TupleIndirection(expr=path_tip, name=el_norm_name, path_id=path_id, context=source_context) return expression_set(expr, ctx=ctx)
def _fixup_cardinalities( subj_source: s_sources.Source, tpl_source: s_sources.Source, *, ctx: context.ContextLevel, ) -> None: """Copy pointer cardinalities from *tpl_source* to *subj_source*.""" subj_ptrs = subj_source.get_pointers(ctx.env.schema).items(ctx.env.schema) tpl_ptrs = dict( tpl_source.get_pointers(ctx.env.schema).items(ctx.env.schema)) for pn, ptrcls in subj_ptrs: card = ptrcls.get_cardinality(ctx.env.schema) tpl_ptrcls = tpl_ptrs.get(pn) if tpl_ptrcls is None: raise AssertionError( f'expected to find {pn!r} in template source object' ) if not card.is_known(): tpl_card = tpl_ptrcls.get_cardinality(ctx.env.schema) if not tpl_card.is_known(): raise AssertionError( f'{pn!r} cardinality in template source is unknown' ) ctx.env.schema = ptrcls.set_field_value( ctx.env.schema, 'cardinality', tpl_card, ) subj_target = ptrcls.get_target(ctx.env.schema) if ( isinstance(subj_target, s_sources.Source) and subj_target.is_view(ctx.env.schema) ): tpl_target = tpl_ptrcls.get_target(ctx.env.schema) assert isinstance(tpl_target, s_sources.Source) _fixup_cardinalities(subj_target, tpl_target, ctx=ctx)
def resolve_ptr( near_endpoint: s_sources.Source, pointer_name: str, *, direction: s_pointers.PointerDirection=( s_pointers.PointerDirection.Outbound ), source_context: typing.Optional[parsing.ParserContext]=None, ctx: context.ContextLevel) -> s_pointers.Pointer: if not isinstance(near_endpoint, s_sources.Source): # Reference to a property on non-object msg = 'invalid property reference on a primitive type expression' raise errors.InvalidReferenceError(msg, context=source_context) if direction is s_pointers.PointerDirection.Outbound: ptr = near_endpoint.getptr(ctx.env.schema, pointer_name) else: ptrs = near_endpoint.getrptrs(ctx.env.schema, pointer_name) if not ptrs: ptr = None else: if len(ptrs) == 1: ptr = next(iter(ptrs)) else: ctx.env.schema_refs.update( p.get_nearest_non_derived_parent(ctx.env.schema) for p in ptrs ) ctx.env.schema, ptr = s_pointers.get_or_create_union_pointer( ctx.env.schema, ptrname=pointer_name, source=near_endpoint, direction=direction, components=ptrs, modname=ctx.derived_target_module) if ptr is None: if isinstance(near_endpoint, s_links.Link): msg = (f'{near_endpoint.get_verbosename(ctx.env.schema)} ' f'has no property {pointer_name!r}') elif direction == s_pointers.PointerDirection.Outbound: msg = (f'{near_endpoint.get_verbosename(ctx.env.schema)} ' f'has no link or property {pointer_name!r}') else: nep_name = near_endpoint.get_displayname(ctx.env.schema) path = f'{nep_name}.{direction}{pointer_name}' msg = f'{path!r} does not resolve to any known path' err = errors.InvalidReferenceError(msg, context=source_context) if direction == s_pointers.PointerDirection.Outbound: near_enpoint_pointers = near_endpoint.get_pointers( ctx.env.schema) s_utils.enrich_schema_lookup_error( err, pointer_name, modaliases=ctx.modaliases, item_types=(s_pointers.Pointer,), collection=near_enpoint_pointers.objects(ctx.env.schema), schema=ctx.env.schema ) raise err ref = ptr.get_nearest_non_derived_parent(ctx.env.schema) ctx.env.schema_refs.add(ref) return ptr