2
2
* Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3
3
*/
4
4
5
+ package kotlinx.rpc.protobuf.model
6
+
7
+ import org.slf4j.Logger
8
+
5
9
// The NameResolver isn't used as we rely on the Java Descriptor for message resolving.
6
- // However, it might be useful if we write a bootstrapped plugin in K/N.
7
- //
8
- // package kotlinx.rpc.protobuf.model
9
- //
10
- // import org.slf4j.Logger
11
- //
12
- //
13
- // internal class NameResolver private constructor(
14
- // private val logger: Logger,
15
- // private val root: Node = Node(FqName.Package.Root.simpleName, FqName.Package.Root),
16
- // private val scope: Node = root,
17
- // private val imports: List<Node> = emptyList(),
18
- // ) {
19
- // fun add(name: FqName) {
20
- // val parentNode = getParentNodeFor(name)
21
- //
22
- // if (parentNode.children.containsKey(name.simpleName)) {
23
- // error("Name ${name.fullName()} already exists")
24
- // }
25
- //
26
- // parentNode.children[name.simpleName] = Node(name.simpleName, name, parentNode)
27
- // }
28
- //
29
- // private fun getParentNodeFor(name: FqName): Node {
30
- // var next: FqName = name
31
- // val parents = mutableListOf<FqName>()
32
- // while (next.parent != next) {
33
- // next = next.parent
34
- // if (next != next.parent) {
35
- // parents += next
36
- // }
37
- // }
38
- //
39
- // var parentNode = root
40
- // parents.reversed().forEach { parent ->
41
- // parentNode = parentNode.resolve(parent)
42
- // }
43
- // return parentNode
44
- // }
45
- //
46
- // private fun Node.resolve(name: FqName): Node {
47
- // if (name is FqName.Declaration && !children.containsKey(name.simpleName)) {
48
- // error("Name ${name.fullName()} doesn't exist, can't resolve ${name.fullName()}")
49
- // }
50
- //
51
- // return children.getOrPut(name.simpleName) {
52
- // Node(name.simpleName, name, this)
53
- // }
54
- // }
55
- //
56
- // fun resolve(name: String): FqName {
57
- // return resolveOrNull(name) ?: error("Name $name doesn't exist")
58
- // }
59
- //
60
- // fun resolveOrNull(name: String): FqName? {
61
- // val (parents, simpleName) = name.asParentsAndSimpleName()
62
- //
63
- // return resolveInScope(parents, simpleName, scope)
64
- // ?: run {
65
- // for (import in imports) {
66
- // resolveInScope(parents, simpleName, import)
67
- // ?.let { return it }
68
- // }
69
- //
70
- // null
71
- // }
72
- // }
73
- //
74
- // private fun resolveInScope(parents: List<String>, simpleName: String, scope: Node): FqName? {
75
- // val inScope = resolveFromNode(scope, parents, simpleName)
76
- //
77
- // return when (inScope) {
78
- // is ResolveResult.Success -> {
79
- // inScope.fqName
80
- // }
81
- //
82
- // is ResolveResult.PartialResolve -> {
83
- // null
84
- // }
85
- //
86
- // is ResolveResult.NoResolve -> {
87
- // val inRoot = resolveFromNode(root, parents, simpleName)
88
- //
89
- // when (inRoot) {
90
- // is ResolveResult.Success -> {
91
- // inRoot.fqName
92
- // }
93
- //
94
- // else -> {
95
- // var node = scope.parent
96
- // while (node != null && node.fqName is FqName.Declaration) {
97
- // val inImport = resolveFromNode(node, parents, simpleName)
98
- //
99
- // if (inImport is ResolveResult.Success) {
100
- // return inImport.fqName
101
- // }
102
- //
103
- // node = node.parent
104
- // }
105
- //
106
- // null
107
- // }
108
- // }
109
- // }
110
- // }
111
- // }
112
- //
113
- // private fun resolveFromNode(start: Node, parents: List<String>, simpleName: String): ResolveResult {
114
- // val declarationOnlyResolve = start.fqName != FqName.Package.Root && start.fqName is FqName.Package
115
- // var node: Node? = start
116
- // var i = 0
117
- // var entered = false
118
- // while (i != parents.size) {
119
- // node = node?.children[parents[i++]]
120
- // if (node == null) {
121
- // break
122
- // } else if (node.fqName is FqName.Package && declarationOnlyResolve) {
123
- // return ResolveResult.NoResolve
124
- // }
125
- // entered = true
126
- // }
127
- //
128
- // if (node != null) {
129
- // val name = node.children[simpleName]
130
- // if (name != null) {
131
- // return ResolveResult.Success(name.fqName)
132
- // }
133
- // }
134
- //
135
- // return if (entered) {
136
- // ResolveResult.PartialResolve
137
- // } else {
138
- // ResolveResult.NoResolve
139
- // }
140
- // }
141
- //
142
- // sealed interface ResolveResult {
143
- // data class Success(val fqName: FqName) : ResolveResult
144
- // data object PartialResolve : ResolveResult
145
- // data object NoResolve : ResolveResult
146
- // }
147
- //
148
- // fun withImports(imports: List<FqName.Package>): NameResolver {
149
- // return NameResolver(logger, root, scope, imports.map { getParentNodeFor(it).resolve(it) })
150
- // }
151
- //
152
- // fun withScope(name: FqName): NameResolver {
153
- // val node = getParentNodeFor(name).resolve(name)
154
- // return NameResolver(logger, root, node, imports)
155
- // }
156
- //
157
- // companion object {
158
- // fun create(logger: Logger): NameResolver {
159
- // return NameResolver(logger)
160
- // }
161
- // }
162
- //
163
- // private class Node(
164
- // val name: String,
165
- // val fqName: FqName,
166
- // val parent: Node? = null,
167
- // val children: MutableMap<String, Node> = mutableMapOf<String, Node>(),
168
- // ) {
169
- // private var _list: List<String>? = null
170
- //
171
- // fun asList(): List<String> {
172
- // if (_list != null) {
173
- // return _list!!
174
- // }
175
- //
176
- // if (parent == null) {
177
- // return emptyList()
178
- // }
179
- //
180
- // _list = parent.asList() + name
181
- // return _list!!
182
- // }
183
- // }
184
- //
185
- // @Suppress("unused")
186
- // fun pprint(): String {
187
- // return buildString { pprint(root, 0) }
188
- // }
189
- //
190
- // private fun StringBuilder.pprint(node: Node, indent: Int) {
191
- // val spaces = " ".repeat(indent)
192
- // appendLine("$spaces${node.fqName.fullName()}")
193
- // for (child in node.children.values) {
194
- // pprint(child, indent + 4)
195
- // }
196
- // }
197
- // }
10
+ // However, it might be useful if we write a bootstrapped plugin in K/N,
11
+ // so we leave it here and for tests
12
+ @Suppress(" unused" )
13
+ internal class NameResolver private constructor(
14
+ private val logger : Logger ,
15
+ private val root : Node = Node (FqName .Package .Root .simpleName, FqName .Package .Root ),
16
+ private val scope : Node = root,
17
+ private val imports : List <Node > = emptyList(),
18
+ ) {
19
+ fun add (name : FqName ) {
20
+ val parentNode = getParentNodeFor(name)
21
+
22
+ if (parentNode.children.containsKey(name.simpleName)) {
23
+ error(" Name ${name.fullName()} already exists" )
24
+ }
25
+
26
+ parentNode.children[name.simpleName] = Node (name.simpleName, name, parentNode)
27
+ }
28
+
29
+ private fun getParentNodeFor (name : FqName ): Node {
30
+ var next: FqName = name
31
+ val parents = mutableListOf<FqName >()
32
+ while (next.parent != next) {
33
+ next = next.parent
34
+ if (next != next.parent) {
35
+ parents + = next
36
+ }
37
+ }
38
+
39
+ var parentNode = root
40
+ parents.reversed().forEach { parent ->
41
+ parentNode = parentNode.resolve(parent)
42
+ }
43
+ return parentNode
44
+ }
45
+
46
+ private fun Node.resolve (name : FqName ): Node {
47
+ if (name is FqName .Declaration && ! children.containsKey(name.simpleName)) {
48
+ error(" Name ${name.fullName()} doesn't exist, can't resolve ${name.fullName()} " )
49
+ }
50
+
51
+ return children.getOrPut(name.simpleName) {
52
+ Node (name.simpleName, name, this )
53
+ }
54
+ }
55
+
56
+ fun resolve (name : String ): FqName {
57
+ return resolveOrNull(name) ? : error(" Name $name doesn't exist" )
58
+ }
59
+
60
+ fun resolveOrNull (name : String ): FqName ? {
61
+ val (parents, simpleName) = name.asParentsAndSimpleName()
62
+
63
+ return resolveInScope(parents, simpleName, scope)
64
+ ? : run {
65
+ for (import in imports) {
66
+ resolveInScope(parents, simpleName, import)
67
+ ?.let { return it }
68
+ }
69
+
70
+ null
71
+ }
72
+ }
73
+
74
+ private fun resolveInScope (parents : List <String >, simpleName : String , scope : Node ): FqName ? {
75
+ val inScope = resolveFromNode(scope, parents, simpleName)
76
+
77
+ return when (inScope) {
78
+ is ResolveResult .Success -> {
79
+ inScope.fqName
80
+ }
81
+
82
+ is ResolveResult .PartialResolve -> {
83
+ null
84
+ }
85
+
86
+ is ResolveResult .NoResolve -> {
87
+ val inRoot = resolveFromNode(root, parents, simpleName)
88
+
89
+ when (inRoot) {
90
+ is ResolveResult .Success -> {
91
+ inRoot.fqName
92
+ }
93
+
94
+ else -> {
95
+ var node = scope.parent
96
+ while (node != null && node.fqName is FqName .Declaration ) {
97
+ val inImport = resolveFromNode(node, parents, simpleName)
98
+
99
+ if (inImport is ResolveResult .Success ) {
100
+ return inImport.fqName
101
+ }
102
+
103
+ node = node.parent
104
+ }
105
+
106
+ null
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ private fun resolveFromNode (start : Node , parents : List <String >, simpleName : String ): ResolveResult {
114
+ val declarationOnlyResolve = start.fqName != FqName .Package .Root && start.fqName is FqName .Package
115
+ var node: Node ? = start
116
+ var i = 0
117
+ var entered = false
118
+ while (i != parents.size) {
119
+ node = node?.children[parents[i++ ]]
120
+ if (node == null ) {
121
+ break
122
+ } else if (node.fqName is FqName .Package && declarationOnlyResolve) {
123
+ return ResolveResult .NoResolve
124
+ }
125
+ entered = true
126
+ }
127
+
128
+ if (node != null ) {
129
+ val name = node.children[simpleName]
130
+ if (name != null ) {
131
+ return ResolveResult .Success (name.fqName)
132
+ }
133
+ }
134
+
135
+ return if (entered) {
136
+ ResolveResult .PartialResolve
137
+ } else {
138
+ ResolveResult .NoResolve
139
+ }
140
+ }
141
+
142
+ sealed interface ResolveResult {
143
+ data class Success (val fqName : FqName ) : ResolveResult
144
+ data object PartialResolve : ResolveResult
145
+ data object NoResolve : ResolveResult
146
+ }
147
+
148
+ fun withImports (imports : List <FqName .Package >): NameResolver {
149
+ return NameResolver (logger, root, scope, imports.map { getParentNodeFor(it).resolve(it) })
150
+ }
151
+
152
+ fun withScope (name : FqName ): NameResolver {
153
+ val node = getParentNodeFor(name).resolve(name)
154
+ return NameResolver (logger, root, node, imports)
155
+ }
156
+
157
+ companion object {
158
+ fun create (logger : Logger ): NameResolver {
159
+ return NameResolver (logger)
160
+ }
161
+ }
162
+
163
+ private class Node (
164
+ val name : String ,
165
+ val fqName : FqName ,
166
+ val parent : Node ? = null ,
167
+ val children : MutableMap <String , Node > = mutableMapOf<String , Node >(),
168
+ ) {
169
+ private var _list : List <String >? = null
170
+
171
+ fun asList (): List <String > {
172
+ if (_list != null ) {
173
+ return _list !!
174
+ }
175
+
176
+ if (parent == null ) {
177
+ return emptyList()
178
+ }
179
+
180
+ _list = parent.asList() + name
181
+ return _list !!
182
+ }
183
+ }
184
+
185
+ @Suppress(" unused" )
186
+ fun pprint (): String {
187
+ return buildString { pprint(root, 0 ) }
188
+ }
189
+
190
+ private fun StringBuilder.pprint (node : Node , indent : Int ) {
191
+ val spaces = " " .repeat(indent)
192
+ appendLine(" $spaces${node.fqName.fullName()} " )
193
+ for (child in node.children.values) {
194
+ pprint(child, indent + 4 )
195
+ }
196
+ }
197
+ }
0 commit comments