1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace LaravelUi5\OData\Service\Contracts;
6:
7: use LaravelUi5\OData\Edm\Contracts\Container\EntitySetInterface;
8: use LaravelUi5\OData\Edm\Contracts\Container\FunctionImportInterface;
9: use LaravelUi5\OData\Edm\Contracts\Container\SingletonInterface;
10: use LaravelUi5\OData\Edm\Contracts\Type\EnumTypeInterface;
11: use LaravelUi5\OData\Edm\Contracts\EdmxInterface;
12: use LaravelUi5\OData\Edm\Contracts\FunctionInterface;
13: use LaravelUi5\OData\Edm\Contracts\Property\NavigationPropertyInterface;
14: use LaravelUi5\OData\Edm\Contracts\ReferenceInterface;
15: use LaravelUi5\OData\Edm\Vocabularies\Vocabulary;
16: use LaravelUi5\OData\Edm\Contracts\Type\ComplexTypeInterface;
17: use LaravelUi5\OData\Edm\Contracts\Type\EntityTypeInterface;
18: use LaravelUi5\OData\Edm\Contracts\Type\TypeDefinitionInterface;
19:
20: /**
21: * Mutable accumulator that produces a frozen EdmxInterface.
22: *
23: * This is Stage 1 of the two-stage builder. It holds only Edm structure —
24: * no resolvers, no runtime state. The result of build() is safe to cache
25: * to a generated PHP file by odata:cache and reloaded by EdmxLoader.
26: *
27: * ODataService subclasses return an instance of this interface from
28: * discover() and populate it with their entity types, functions, and
29: * container members.
30: *
31: * @see RuntimeSchemaBuilderInterface Stage 2 — binds resolvers to the EdmxInterface
32: */
33: interface EdmBuilderInterface
34: {
35: // ── Schema identity ───────────────────────────────────────────────────────
36:
37: /**
38: * Sets the namespace of the schema, e.g. "MyService.Data".
39: */
40: public function namespace(string $namespace): static;
41:
42: /**
43: * Sets the optional alias for the schema namespace, e.g. "self".
44: */
45: public function alias(string $alias): static;
46:
47: /**
48: * Sets the name of the entity container.
49: *
50: * Must be set explicitly — the concrete EdmBuilder defaults to
51: * "DefaultContainer" when this is not called, matching the behaviour
52: * of the legacy implementation.
53: */
54: public function containerName(string $name): static;
55:
56: // ── References ────────────────────────────────────────────────────────────
57:
58: public function addReference(ReferenceInterface $reference): static;
59:
60: /**
61: * Declare a built-in vocabulary reference by enum.
62: *
63: * Shorthand for looking up the vocabulary in the default catalog
64: * and calling addReference() with the resulting Reference object.
65: */
66: public function useVocabulary(Vocabulary $vocabulary): static;
67:
68: // ── Types ─────────────────────────────────────────────────────────────────
69:
70: public function addEntityType(EntityTypeInterface $type): static;
71:
72: public function addComplexType(ComplexTypeInterface $type): static;
73:
74: public function addEnumType(EnumTypeInterface $type): static;
75:
76: public function addTypeDefinition(TypeDefinitionInterface $type): static;
77:
78: public function addFunction(FunctionInterface $function): static;
79:
80: // ── Container members (no resolvers at this stage) ────────────────────────
81:
82: /**
83: * Adds an entity set to the container.
84: *
85: * No resolver is registered here — resolver binding is Stage 2 and
86: * happens exclusively in RuntimeSchemaBuilderInterface.
87: */
88: public function addEntitySet(EntitySetInterface $set): static;
89:
90: /**
91: * Inject a navigation property into an already-added entity type and set.
92: *
93: * Used by virtual expand wiring to add navigation properties to entity
94: * types that were already registered (by discovery or manual configure()).
95: */
96: public function injectNavigationProperty(
97: string $entityTypeName,
98: NavigationPropertyInterface $navProperty,
99: string $targetEntitySetName,
100: ): static;
101:
102: /**
103: * Adds a singleton to the container.
104: *
105: * Singletons carry their value as part of the Edm structure; no separate
106: * resolver binding is required in the read-only engine.
107: */
108: public function addSingleton(SingletonInterface $singleton): static;
109:
110: /**
111: * Adds a function import to the container.
112: *
113: * No resolver is registered here — resolver binding is Stage 2.
114: */
115: public function addFunctionImport(FunctionImportInterface $import): static;
116:
117: // ── Produce the frozen model ──────────────────────────────────────────────
118:
119: /**
120: * Freeze the accumulated state into an immutable EdmxInterface.
121: *
122: * After this call the builder's state must not be mutated; implementations
123: * should enforce this by marking themselves as built.
124: */
125: public function build(): EdmxInterface;
126: }
127: