001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.serialization.deserialization;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.kotlin.name.ClassId;
021 import org.jetbrains.kotlin.name.FqName;
022 import org.jetbrains.kotlin.name.Name;
023 import org.jetbrains.kotlin.serialization.ProtoBuf;
024 import org.jetbrains.kotlin.utils.UtilsPackage;
025
026 import java.io.IOException;
027 import java.io.InputStream;
028 import java.util.LinkedList;
029
030 import static org.jetbrains.kotlin.serialization.ProtoBuf.QualifiedNameTable.QualifiedName;
031
032 public class NameResolver {
033 @NotNull
034 public static NameResolver read(@NotNull InputStream in) {
035 try {
036 ProtoBuf.StringTable simpleNames = ProtoBuf.StringTable.parseDelimitedFrom(in);
037 ProtoBuf.QualifiedNameTable qualifiedNames = ProtoBuf.QualifiedNameTable.parseDelimitedFrom(in);
038 return new NameResolver(simpleNames, qualifiedNames);
039 }
040 catch (IOException e) {
041 throw UtilsPackage.rethrow(e);
042 }
043 }
044
045 private final ProtoBuf.StringTable strings;
046 private final ProtoBuf.QualifiedNameTable qualifiedNames;
047
048 public NameResolver(
049 @NotNull ProtoBuf.StringTable strings,
050 @NotNull ProtoBuf.QualifiedNameTable qualifiedNames
051 ) {
052 this.strings = strings;
053 this.qualifiedNames = qualifiedNames;
054 }
055
056 @NotNull
057 public ProtoBuf.StringTable getStringTable() {
058 return strings;
059 }
060
061 @NotNull
062 public ProtoBuf.QualifiedNameTable getQualifiedNameTable() {
063 return qualifiedNames;
064 }
065
066 @NotNull
067 public String getString(int index) {
068 return strings.getString(index);
069 }
070
071 @NotNull
072 public Name getName(int index) {
073 String name = strings.getString(index);
074 return Name.guess(name);
075 }
076
077 @NotNull
078 public ClassId getClassId(int index) {
079 LinkedList<String> packageFqName = new LinkedList<String>();
080 LinkedList<String> relativeClassName = new LinkedList<String>();
081 boolean local = false;
082
083 while (index != -1) {
084 QualifiedName proto = qualifiedNames.getQualifiedName(index);
085 String shortName = strings.getString(proto.getShortName());
086 switch (proto.getKind()) {
087 case CLASS:
088 relativeClassName.addFirst(shortName);
089 break;
090 case PACKAGE:
091 packageFqName.addFirst(shortName);
092 break;
093 case LOCAL:
094 relativeClassName.addFirst(shortName);
095 local = true;
096 break;
097 }
098
099 index = proto.getParentQualifiedName();
100 }
101
102 return new ClassId(FqName.fromSegments(packageFqName), FqName.fromSegments(relativeClassName), local);
103 }
104
105 @NotNull
106 public FqName getFqName(int index) {
107 QualifiedName qualifiedName = qualifiedNames.getQualifiedName(index);
108 Name shortName = getName(qualifiedName.getShortName());
109 if (!qualifiedName.hasParentQualifiedName()) {
110 return FqName.topLevel(shortName);
111 }
112 return getFqName(qualifiedName.getParentQualifiedName()).child(shortName);
113 }
114 }