jjg@46: /* xdono@229: * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved. jjg@46: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jjg@46: * jjg@46: * This code is free software; you can redistribute it and/or modify it jjg@46: * under the terms of the GNU General Public License version 2 only, as jjg@46: * published by the Free Software Foundation. Sun designates this jjg@46: * particular file as subject to the "Classpath" exception as provided jjg@46: * by Sun in the LICENSE file that accompanied this code. jjg@46: * jjg@46: * This code is distributed in the hope that it will be useful, but WITHOUT jjg@46: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jjg@46: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jjg@46: * version 2 for more details (a copy is included in the LICENSE file that jjg@46: * accompanied this code). jjg@46: * jjg@46: * You should have received a copy of the GNU General Public License version jjg@46: * 2 along with this work; if not, write to the Free Software Foundation, jjg@46: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jjg@46: * jjg@46: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, jjg@46: * CA 95054 USA or visit www.sun.com if you need additional information or jjg@46: * have any questions. jjg@46: */ jjg@46: jjg@46: package com.sun.tools.classfile; jjg@46: jjg@46: import java.io.IOException; jjg@46: jjg@46: /** jjg@46: * See JVMS3, section 4.8.16. jjg@46: * jjg@46: *

This is NOT part of any API supported by Sun Microsystems. If jjg@46: * you write code that depends on this, you do so at your own risk. jjg@46: * This code and its internal interfaces are subject to change or jjg@46: * deletion without notice. jjg@46: */ jjg@46: public class Annotation { jjg@46: static class InvalidAnnotation extends AttributeException { jjg@198: private static final long serialVersionUID = -4620480740735772708L; jjg@46: InvalidAnnotation(String msg) { jjg@46: super(msg); jjg@46: } jjg@46: } jjg@46: jjg@46: Annotation(ClassReader cr) throws IOException, InvalidAnnotation { jjg@46: type_index = cr.readUnsignedShort(); jjg@46: num_element_value_pairs = cr.readUnsignedShort(); jjg@46: element_value_pairs = new element_value_pair[num_element_value_pairs]; jjg@46: for (int i = 0; i < element_value_pairs.length; i++) jjg@46: element_value_pairs[i] = new element_value_pair(cr); jjg@46: } jjg@46: jjg@46: public Annotation(ConstantPool constant_pool, jjg@46: int type_index, jjg@46: element_value_pair[] element_value_pairs) { jjg@46: this.type_index = type_index; jjg@46: num_element_value_pairs = element_value_pairs.length; jjg@46: this.element_value_pairs = element_value_pairs; jjg@46: } jjg@46: jjg@46: public int length() { jjg@46: int n = 2 /*type_index*/ + 2 /*num_element_value_pairs*/; jjg@46: for (element_value_pair pair: element_value_pairs) jjg@46: n += pair.length(); jjg@46: return n; jjg@46: } jjg@46: jjg@46: public final int type_index; jjg@46: public final int num_element_value_pairs; jjg@46: public final element_value_pair element_value_pairs[]; jjg@46: jjg@46: /** jjg@46: * See JVMS3, section 4.8.16.1. jjg@46: */ jjg@46: public static abstract class element_value { jjg@46: public static element_value read(ClassReader cr) jjg@46: throws IOException, InvalidAnnotation { jjg@46: int tag = cr.readUnsignedByte(); jjg@46: switch (tag) { jjg@46: case 'B': jjg@46: case 'C': jjg@46: case 'D': jjg@46: case 'F': jjg@46: case 'I': jjg@46: case 'J': jjg@46: case 'S': jjg@46: case 'Z': jjg@46: case 's': jjg@46: return new Primitive_element_value(cr, tag); jjg@46: jjg@46: case 'e': jjg@46: return new Enum_element_value(cr, tag); jjg@46: jjg@46: case 'c': jjg@46: return new Class_element_value(cr, tag); jjg@46: jjg@46: case '@': jjg@46: return new Annotation_element_value(cr, tag); jjg@46: jjg@46: case '[': jjg@46: return new Array_element_value(cr, tag); jjg@46: jjg@46: default: jjg@46: throw new InvalidAnnotation("unrecognized tag: " + tag); jjg@46: } jjg@46: } jjg@46: jjg@46: protected element_value(int tag) { jjg@46: this.tag = tag; jjg@46: } jjg@46: jjg@46: public abstract int length(); jjg@46: jjg@46: public abstract R accept(Visitor visitor, P p); jjg@46: jjg@46: public interface Visitor { jjg@46: R visitPrimitive(Primitive_element_value ev, P p); jjg@46: R visitEnum(Enum_element_value ev, P p); jjg@46: R visitClass(Class_element_value ev, P p); jjg@46: R visitAnnotation(Annotation_element_value ev, P p); jjg@46: R visitArray(Array_element_value ev, P p); jjg@46: } jjg@46: jjg@46: public final int tag; jjg@46: } jjg@46: jjg@46: public static class Primitive_element_value extends element_value { jjg@46: Primitive_element_value(ClassReader cr, int tag) throws IOException { jjg@46: super(tag); jjg@46: const_value_index = cr.readUnsignedShort(); jjg@46: } jjg@46: jjg@46: @Override jjg@46: public int length() { jjg@46: return 2; jjg@46: } jjg@46: jjg@46: public R accept(Visitor visitor, P p) { jjg@46: return visitor.visitPrimitive(this, p); jjg@46: } jjg@46: jjg@46: public final int const_value_index; jjg@46: jjg@46: } jjg@46: jjg@46: public static class Enum_element_value extends element_value { jjg@46: Enum_element_value(ClassReader cr, int tag) throws IOException { jjg@46: super(tag); jjg@46: type_name_index = cr.readUnsignedShort(); jjg@46: const_name_index = cr.readUnsignedShort(); jjg@46: } jjg@46: jjg@46: @Override jjg@46: public int length() { jjg@46: return 4; jjg@46: } jjg@46: jjg@46: public R accept(Visitor visitor, P p) { jjg@46: return visitor.visitEnum(this, p); jjg@46: } jjg@46: jjg@46: public final int type_name_index; jjg@46: public final int const_name_index; jjg@46: } jjg@46: jjg@46: public static class Class_element_value extends element_value { jjg@46: Class_element_value(ClassReader cr, int tag) throws IOException { jjg@46: super(tag); jjg@46: class_info_index = cr.readUnsignedShort(); jjg@46: } jjg@46: jjg@46: @Override jjg@46: public int length() { jjg@46: return 2; jjg@46: } jjg@46: jjg@46: public R accept(Visitor visitor, P p) { jjg@46: return visitor.visitClass(this, p); jjg@46: } jjg@46: jjg@46: public final int class_info_index; jjg@46: } jjg@46: jjg@46: public static class Annotation_element_value extends element_value { jjg@46: Annotation_element_value(ClassReader cr, int tag) jjg@46: throws IOException, InvalidAnnotation { jjg@46: super(tag); jjg@46: annotation_value = new Annotation(cr); jjg@46: } jjg@46: jjg@46: @Override jjg@46: public int length() { jjg@46: return annotation_value.length(); jjg@46: } jjg@46: jjg@46: public R accept(Visitor visitor, P p) { jjg@46: return visitor.visitAnnotation(this, p); jjg@46: } jjg@46: jjg@46: public final Annotation annotation_value; jjg@46: } jjg@46: jjg@46: public static class Array_element_value extends element_value { jjg@46: Array_element_value(ClassReader cr, int tag) jjg@46: throws IOException, InvalidAnnotation { jjg@46: super(tag); jjg@46: num_values = cr.readUnsignedShort(); jjg@46: values = new element_value[num_values]; jjg@46: for (int i = 0; i < values.length; i++) jjg@46: values[i] = element_value.read(cr); jjg@46: } jjg@46: jjg@46: @Override jjg@46: public int length() { jjg@46: int n = 2; jjg@46: for (int i = 0; i < values.length; i++) jjg@46: n += values[i].length(); jjg@46: return n; jjg@46: } jjg@46: jjg@46: public R accept(Visitor visitor, P p) { jjg@46: return visitor.visitArray(this, p); jjg@46: } jjg@46: jjg@46: public final int num_values; jjg@46: public final element_value[] values; jjg@46: } jjg@46: jjg@46: public static class element_value_pair { jjg@46: element_value_pair(ClassReader cr) jjg@46: throws IOException, InvalidAnnotation { jjg@46: element_name_index = cr.readUnsignedShort(); jjg@46: value = element_value.read(cr); jjg@46: } jjg@46: jjg@46: public int length() { jjg@46: return 2 + value.length(); jjg@46: } jjg@46: jjg@46: public final int element_name_index; jjg@46: public final element_value value; jjg@46: } jjg@46: }