Reference.php 3.49 KB
Newer Older
Guillaume Perréal's avatar
PHP CS.    
Guillaume Perréal committed
1
2
<?php
declare(strict_types=1);
3
/*
Guillaume Perréal's avatar
Guillaume Perréal committed
4
5
6
 * This file is part of "irstea/ng-model-generator-bundle".
 *
 * "irstea/ng-model-generator-bundle" generates Typescript interfaces for Angular using api-platform metadata.
Guillaume Perréal's avatar
PHP CS.    
Guillaume Perréal committed
7
 * Copyright (C) 2018-2021 IRSTEA
8
9
10
11
12
13
14
15
16
17
18
19
20
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the License, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License and the GNU
 * Lesser General Public License along with this program. If not, see
 * <https://www.gnu.org/licenses/>.
21
22
 */

Guillaume Perréal's avatar
Guillaume Perréal committed
23
namespace Irstea\NgModelGeneratorBundle\Models\Types;
24
25

/**
Guillaume Perréal's avatar
Guillaume Perréal committed
26
 * Class Ref.
27
 */
28
class Reference extends AbstractType implements Deferred
29
{
30
31
32
33
    private const UNRESOLVED = 0;
    private const RESOLVING = 1;
    private const RESOLVED = 2;

34
35
    /** @var Type */
    private $target;
Guillaume Perréal's avatar
Guillaume Perréal committed
36

37
38
39
    /** @var string */
    private $name;

Guillaume Perréal's avatar
Guillaume Perréal committed
40
    /** @var int */
41
42
    private $state = self::UNRESOLVED;

43
    /**
Guillaume Perréal's avatar
Guillaume Perréal committed
44
     * Reference constructor.
45
     */
46
    public function __construct(string $name = 'anonymous reference')
47
    {
48
49
        $this->name = $name;
        $this->target = Unresolved::get();
50
51
52
53
54
55
56
57
58
59
60
    }

    /**
     * Get target.
     */
    public function getTarget(): Type
    {
        return $this->target;
    }

    /**
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
     * {@inheritdoc}
     */
    public function resolveWith(callable $callback): Type
    {
        switch ($this->state) {
            case self::UNRESOLVED:
                $this->state = self::RESOLVING;

                return $this->resolve($callback());
            case self::RESOLVING:
                return $this;
            case self::RESOLVED:
                return $this->target;
        }
    }

    /**
     * {@inheritdoc}
79
     */
80
    public function resolve(Type $result): Type
81
    {
82
83
84
85
86
87
        if ($this->state !== self::RESOLVED) {
            $this->state = self::RESOLVED;
            $this->target = $result;
        }

        return $this->target;
88
89
90
91
92
    }

    /**
     * {@inheritdoc}
     */
93
    private function dereference(): Type
94
    {
Guillaume Perréal's avatar
PHP CS.    
Guillaume Perréal committed
95
        return $this->target instanceof self ? $this->target->dereference() : $this->target;
Guillaume Perréal's avatar
Guillaume Perréal committed
96
97
98
99
100
101
102
    }

    /**
     * {@inheritdoc}
     */
    public function getUsage(): string
    {
103
104
105
        return $this->dereference()->getUsage();
    }

106
107
108
109
110
111
112
113
114
115
116
    /**
     * {@inheritdoc}
     */
    public function castToStringOrStringArray(string $expr): string
    {
        return $this->dereference()->castToStringOrStringArray($expr);
    }

    /**
     * {@inheritdoc}
     */
117
    public function checkType(string $expr, bool $explicit = false): string
118
    {
119
        return $this->dereference()->checkType($expr, $explicit);
120
121
    }

122
123
124
125
126
127
    /**
     * {@inheritdoc}
     */
    public function getIterator()
    {
        yield $this->target;
128
    }
129

130
131
132
133
134
    /**
     * @return mixed
     */
    public function jsonSerialize()
    {
Guillaume Perréal's avatar
PHP CS.    
Guillaume Perréal committed
135
        return spl_object_hash($this);
136
137
    }

138
139
140
141
142
    /**
     * {@inheritdoc}
     */
    public function __toString()
    {
143
        return '&' . $this->name;
144
    }
145
146

    /**
147
     * {@inheritdoc}
148
     */
149
    public function findType(string $typeClass): ?Type
150
    {
151
        return parent::findType($typeClass) ?: $this->target->findType($typeClass);
152
    }
153
}