Reference.php 3.66 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
26
use Irstea\NgModelGeneratorBundle\Exceptions\DomainException;

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

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

39
40
41
    /** @var string */
    private $name;

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

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

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

    /**
63
64
65
66
67
68
69
70
71
72
73
74
75
     * {@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;
76
77
            default:
                throw new DomainException('invalid reference state: ' . $this->state);
78
79
80
81
82
        }
    }

    /**
     * {@inheritdoc}
83
     */
84
    public function resolve(Type $result): Type
85
    {
86
87
88
89
90
91
        if ($this->state !== self::RESOLVED) {
            $this->state = self::RESOLVED;
            $this->target = $result;
        }

        return $this->target;
92
93
94
95
96
    }

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

    /**
     * {@inheritdoc}
     */
    public function getUsage(): string
    {
107
108
109
        return $this->dereference()->getUsage();
    }

110
111
112
113
114
115
116
117
118
119
120
    /**
     * {@inheritdoc}
     */
    public function castToStringOrStringArray(string $expr): string
    {
        return $this->dereference()->castToStringOrStringArray($expr);
    }

    /**
     * {@inheritdoc}
     */
121
    public function checkType(string $expr, bool $explicit = false): string
122
    {
123
        return $this->dereference()->checkType($expr, $explicit);
124
125
    }

126
127
128
129
130
131
    /**
     * {@inheritdoc}
     */
    public function getIterator()
    {
        yield $this->target;
132
    }
133

134
135
136
137
138
    /**
     * @return mixed
     */
    public function jsonSerialize()
    {
Guillaume Perréal's avatar
PHP CS.    
Guillaume Perréal committed
139
        return spl_object_hash($this);
140
141
    }

142
143
144
145
146
    /**
     * {@inheritdoc}
     */
    public function __toString()
    {
147
        return '&' . $this->name;
148
    }
149
150

    /**
151
     * {@inheritdoc}
152
     */
153
    public function findType(string $typeClass): ?Type
154
    {
155
        return parent::findType($typeClass) ?: $this->target->findType($typeClass);
156
    }
157
}