Skip to content

The generator must derive resource method metadata from the implementation, not the interface #658

Closed

Description

@David-Noble-at-work

Feature: #625 · ahead of #642. Found by #641.

Sealing a provider silently shrinks its Starlark surface, and nothing reports it.

What happens

The generator derives a resource's method metadata by inspecting the exported type. Sealing moves the methods onto the unexported struct, where the generator cannot see them, so it emits none:

-		map[string][]string{
-			"Equal":          {"other"},
-			"CanConvertFrom": {"source"},
-			"ConvertFrom":    {"value"},
-		},
+		nil,

Every stage downstream tolerates that quietly — nil metadata is legal, parseParameters returns an empty map, announcedMethods matches nothing, and the resource ends up with zero dispatchable methods. No error at any point.

For service (#641) the three lost entries were framework-facing and nothing noticed. The next provider with an author-facing resource method will lose it, and the suite will stay green.

Why there is no build error, and cannot be

An interface omitting a method its implementation has is well-formed Go. var _ Resource = (*resource)(nil) proves the struct satisfies the interface; the converse — that the interface exposes everything worth dispatching — is not expressible as a type constraint.

The fix: point the generator at the implementation

The emitted metadata is plain strings and never names a type. Only the inspection target is the exported interface, and that is incidental. Inspect the implementation instead, and the metadata describes the struct that dispatch actually reflects on — the two can no longer disagree, so there is nothing left to detect.

Ruling 3 makes the resolution deterministic rather than a guess: the interface is Resource, the struct is resource, uniformly across providers.

Why before #642 rather than after

Otherwise phases 2-5 each inherit the same silent risk, and each needs a manual "does this resource have author-facing methods?" review — five chances to miss one, with no signal when you do. Fixing the generator once makes the remaining phases safe by construction, and narrows #646 to asserting the shape rather than also policing dispatch.

What this does not fix

Whether a method belongs on the sealed interface stays a real design question per provider. It stops being a silent dispatch regression and becomes an ordinary question about the public contract.

Exit

A sealed provider's generated announcement carries the same method metadata it carried before sealing. Verified by re-generating service and seeing its three entries return, with no hand-editing of *.gen.go.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions