|
5 | 5 |
|
6 | 6 | use Soap\Engine\Metadata\Model\XsdType; |
7 | 7 | use stdClass; |
| 8 | +use WeakMap; |
8 | 9 |
|
9 | 10 | final class EncoderDetector |
10 | 11 | { |
| 12 | + /** |
| 13 | + * @var WeakMap<XsdType, XmlEncoder<mixed, string>> |
| 14 | + */ |
| 15 | + private WeakMap $cache; |
| 16 | + |
| 17 | + public static function default(): self |
| 18 | + { |
| 19 | + /** @var self $self */ |
| 20 | + static $self = new self(); |
| 21 | + |
| 22 | + return $self; |
| 23 | + } |
| 24 | + |
| 25 | + private function __construct() |
| 26 | + { |
| 27 | + /** @var WeakMap<XsdType, XmlEncoder<mixed, string>> cache */ |
| 28 | + $this->cache = new WeakMap(); |
| 29 | + } |
| 30 | + |
11 | 31 | /** |
12 | 32 | * @return XmlEncoder<mixed, string> |
13 | 33 | * |
14 | | - * @psalm-suppress InvalidReturnType, PossiblyInvalidArgument, InvalidReturnStatement - The simple type detector could return string|null, but should not be an issue here. |
| 34 | + * @psalm-suppress InvalidArgument, InvalidReturnType, PossiblyInvalidArgument, InvalidReturnStatement - The simple type detector could return string|null, but should not be an issue here. |
15 | 35 | */ |
16 | 36 | public function __invoke(Context $context): XmlEncoder |
17 | 37 | { |
18 | 38 | $type = $context->type; |
| 39 | + if ($cached = $this->cache[$type] ?? null) { |
| 40 | + return $cached; |
| 41 | + } |
| 42 | + |
19 | 43 | $meta = $type->getMeta(); |
20 | 44 |
|
21 | 45 | $encoder = match(true) { |
22 | | - $meta->isSimple()->unwrapOr(false) => (new SimpleType\EncoderDetector())($context), |
| 46 | + $meta->isSimple()->unwrapOr(false) => SimpleType\EncoderDetector::default()($context), |
23 | 47 | default => $this->detectComplexTypeEncoder($type, $context), |
24 | 48 | }; |
25 | 49 |
|
26 | 50 | if (!$encoder instanceof Feature\ListAware && $meta->isRepeatingElement()->unwrapOr(false)) { |
27 | 51 | $encoder = new RepeatingElementEncoder($encoder); |
28 | 52 | } |
29 | 53 |
|
30 | | - return new ErrorHandlingEncoder($encoder); |
| 54 | + $encoder = new ErrorHandlingEncoder($encoder); |
| 55 | + |
| 56 | + return $this->cache[$type] = $encoder; |
31 | 57 | } |
32 | 58 |
|
33 | 59 | /** |
|
0 commit comments