22 * Copyright 2023-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
33 */
44
5+ package kotlinx.rpc.protobuf.model
6+
7+ import org.slf4j.Logger
8+
59// 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