001/*
002 * Copyright 2010-2013 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
017package org.jetbrains.jet.lang.psi.stubs.elements;
018
019import com.intellij.lang.ASTNode;
020import com.intellij.psi.stubs.IndexSink;
021import com.intellij.psi.stubs.StubElement;
022import com.intellij.psi.stubs.StubInputStream;
023import com.intellij.psi.stubs.StubOutputStream;
024import com.intellij.util.io.StringRef;
025import org.jetbrains.annotations.NonNls;
026import org.jetbrains.annotations.NotNull;
027import org.jetbrains.jet.lang.psi.JetClass;
028import org.jetbrains.jet.lang.psi.JetEnumEntry;
029import org.jetbrains.jet.lang.psi.JetPsiUtil;
030import org.jetbrains.jet.lang.psi.stubs.PsiJetClassStub;
031import org.jetbrains.jet.lang.psi.stubs.impl.PsiJetClassStubImpl;
032import org.jetbrains.jet.lang.resolve.name.FqName;
033
034import java.io.IOException;
035import java.util.List;
036
037public class JetClassElementType extends JetStubElementType<PsiJetClassStub, JetClass> {
038
039    public JetClassElementType(@NotNull @NonNls String debugName) {
040        super(debugName);
041    }
042
043    @Override
044    public JetClass createPsi(@NotNull PsiJetClassStub stub) {
045        return !stub.isEnumEntry() ? new JetClass(stub) : new JetEnumEntry(stub);
046    }
047
048    @Override
049    public JetClass createPsiFromAst(@NotNull ASTNode node) {
050        return node.getElementType() != JetStubElementTypes.ENUM_ENTRY ? new JetClass(node) : new JetEnumEntry(node);
051    }
052
053    @Override
054    public PsiJetClassStub createStub(@NotNull JetClass psi, StubElement parentStub) {
055        FqName fqName = JetPsiUtil.getFQName(psi);
056        boolean isEnumEntry = psi instanceof JetEnumEntry;
057        return new PsiJetClassStubImpl(getStubType(isEnumEntry), parentStub, fqName != null ? fqName.asString() : null, psi.getName(),
058                                       psi.getSuperNames(), psi.isTrait(), psi.isEnum(), isEnumEntry, psi.isAnnotation(), psi.isInner());
059    }
060
061    @Override
062    public void serialize(PsiJetClassStub stub, StubOutputStream dataStream) throws IOException {
063        dataStream.writeName(stub.getName());
064        FqName fqName = stub.getFqName();
065        dataStream.writeName(fqName == null ? null : fqName.asString());
066        dataStream.writeBoolean(stub.isTrait());
067        dataStream.writeBoolean(stub.isEnumClass());
068        dataStream.writeBoolean(stub.isEnumEntry());
069        dataStream.writeBoolean(stub.isAnnotation());
070        dataStream.writeBoolean(stub.isInner());
071
072        List<String> superNames = stub.getSuperNames();
073        dataStream.writeVarInt(superNames.size());
074        for (String name : superNames) {
075            dataStream.writeName(name);
076        }
077    }
078
079    @Override
080    public PsiJetClassStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
081        StringRef name = dataStream.readName();
082        StringRef qualifiedName = dataStream.readName();
083        boolean isTrait = dataStream.readBoolean();
084        boolean isEnumClass = dataStream.readBoolean();
085        boolean isEnumEntry = dataStream.readBoolean();
086        boolean isAnnotation = dataStream.readBoolean();
087        boolean isInner = dataStream.readBoolean();
088
089        int superCount = dataStream.readVarInt();
090        StringRef[] superNames = StringRef.createArray(superCount);
091        for (int i = 0; i < superCount; i++) {
092            superNames[i] = dataStream.readName();
093        }
094
095        return new PsiJetClassStubImpl(getStubType(isEnumEntry), parentStub, qualifiedName, name, superNames,
096                                       isTrait, isEnumClass, isEnumEntry, isAnnotation, isInner);
097    }
098
099    @Override
100    public void indexStub(PsiJetClassStub stub, IndexSink sink) {
101        StubIndexServiceFactory.getInstance().indexClass(stub, sink);
102    }
103
104    private static JetClassElementType getStubType(boolean isEnumEntry) {
105        return isEnumEntry ? JetStubElementTypes.ENUM_ENTRY : JetStubElementTypes.CLASS;
106    }
107}