001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS,
013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 *  See the License for the specific language governing permissions and
015 *  limitations under the License.
016 */
017
018package org.apache.bcel.classfile;
019
020import java.io.DataInput;
021import java.io.DataOutputStream;
022import java.io.IOException;
023
024/**
025 * @since 6.0
026 */
027public abstract class ElementValue {
028    public static final byte STRING = 's';
029
030    public static final byte ENUM_CONSTANT = 'e';
031
032    public static final byte CLASS = 'c';
033
034    public static final byte ANNOTATION = '@';
035
036    public static final byte ARRAY = '[';
037
038    public static final byte PRIMITIVE_INT = 'I';
039
040    public static final byte PRIMITIVE_BYTE = 'B';
041
042    public static final byte PRIMITIVE_CHAR = 'C';
043    public static final byte PRIMITIVE_DOUBLE = 'D';
044    public static final byte PRIMITIVE_FLOAT = 'F';
045    public static final byte PRIMITIVE_LONG = 'J';
046    public static final byte PRIMITIVE_SHORT = 'S';
047    public static final byte PRIMITIVE_BOOLEAN = 'Z';
048
049    public static ElementValue readElementValue(final DataInput input, final ConstantPool cpool) throws IOException {
050        final byte type = input.readByte();
051        switch (type) {
052        case PRIMITIVE_BYTE:
053        case PRIMITIVE_CHAR:
054        case PRIMITIVE_DOUBLE:
055        case PRIMITIVE_FLOAT:
056        case PRIMITIVE_INT:
057        case PRIMITIVE_LONG:
058        case PRIMITIVE_SHORT:
059        case PRIMITIVE_BOOLEAN:
060        case STRING:
061            return new SimpleElementValue(type, input.readUnsignedShort(), cpool);
062
063        case ENUM_CONSTANT:
064            return new EnumElementValue(ENUM_CONSTANT, input.readUnsignedShort(), input.readUnsignedShort(), cpool);
065
066        case CLASS:
067            return new ClassElementValue(CLASS, input.readUnsignedShort(), cpool);
068
069        case ANNOTATION:
070            // TODO isRuntimeVisible
071            return new AnnotationElementValue(ANNOTATION, AnnotationEntry.read(input, cpool, false), cpool);
072
073        case ARRAY:
074            final int numArrayVals = input.readUnsignedShort();
075            final ElementValue[] evalues = new ElementValue[numArrayVals];
076            for (int j = 0; j < numArrayVals; j++) {
077                evalues[j] = ElementValue.readElementValue(input, cpool);
078            }
079            return new ArrayElementValue(ARRAY, evalues, cpool);
080
081        default:
082            throw new IllegalArgumentException("Unexpected element value kind in annotation: " + type);
083        }
084    }
085
086    /**
087     * @deprecated (since 6.0) will be made private and final; do not access directly, use getter
088     */
089    @java.lang.Deprecated
090    protected int type; // TODO should be final
091    /**
092     * @deprecated (since 6.0) will be made private and final; do not access directly, use getter
093     */
094    @java.lang.Deprecated
095    protected ConstantPool cpool; // TODO should be final
096
097    protected ElementValue(final int type, final ConstantPool cpool) {
098        this.type = type;
099        this.cpool = cpool;
100    }
101
102    public abstract void dump(DataOutputStream dos) throws IOException;
103
104    /** @since 6.0 */
105    final ConstantPool getConstantPool() {
106        return cpool;
107    }
108
109    public int getElementValueType() {
110        return type;
111    }
112
113    /** @since 6.0 */
114    final int getType() {
115        return type;
116    }
117
118    public abstract String stringifyValue();
119
120    public String toShortString() {
121        return stringifyValue();
122    }
123
124    @Override
125    public String toString() {
126        return stringifyValue();
127    }
128}