• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.turbine.bytecode;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import com.google.auto.value.AutoValue;
22 import com.google.common.collect.ImmutableList;
23 import com.google.turbine.bytecode.ClassFile.AnnotationInfo.ElementValue;
24 import com.google.turbine.model.Const;
25 import com.google.turbine.model.Const.Value;
26 import java.util.ArrayDeque;
27 import java.util.Deque;
28 import java.util.List;
29 import java.util.Map;
30 import org.jspecify.annotations.Nullable;
31 
32 /** A JVMS §4.1 ClassFile. */
33 public class ClassFile {
34 
35   private final int access;
36   private final int majorVersion;
37   private final String name;
38   private final @Nullable String signature;
39   private final @Nullable String superClass;
40   private final List<String> interfaces;
41   private final List<String> permits;
42   private final List<MethodInfo> methods;
43   private final List<FieldInfo> fields;
44   private final List<AnnotationInfo> annotations;
45   private final List<InnerClass> innerClasses;
46   private final ImmutableList<TypeAnnotationInfo> typeAnnotations;
47   private final @Nullable ModuleInfo module;
48   private final @Nullable String nestHost;
49   private final ImmutableList<String> nestMembers;
50   private final @Nullable RecordInfo record;
51   private final @Nullable String transitiveJar;
52 
ClassFile( int access, int majorVersion, String name, @Nullable String signature, @Nullable String superClass, List<String> interfaces, List<String> permits, List<MethodInfo> methods, List<FieldInfo> fields, List<AnnotationInfo> annotations, List<InnerClass> innerClasses, ImmutableList<TypeAnnotationInfo> typeAnnotations, @Nullable ModuleInfo module, @Nullable String nestHost, ImmutableList<String> nestMembers, @Nullable RecordInfo record, @Nullable String transitiveJar)53   public ClassFile(
54       int access,
55       int majorVersion,
56       String name,
57       @Nullable String signature,
58       @Nullable String superClass,
59       List<String> interfaces,
60       List<String> permits,
61       List<MethodInfo> methods,
62       List<FieldInfo> fields,
63       List<AnnotationInfo> annotations,
64       List<InnerClass> innerClasses,
65       ImmutableList<TypeAnnotationInfo> typeAnnotations,
66       @Nullable ModuleInfo module,
67       @Nullable String nestHost,
68       ImmutableList<String> nestMembers,
69       @Nullable RecordInfo record,
70       @Nullable String transitiveJar) {
71     this.access = access;
72     this.majorVersion = majorVersion;
73     this.name = name;
74     this.signature = signature;
75     this.superClass = superClass;
76     this.interfaces = interfaces;
77     this.permits = permits;
78     this.methods = methods;
79     this.fields = fields;
80     this.annotations = annotations;
81     this.innerClasses = innerClasses;
82     this.typeAnnotations = typeAnnotations;
83     this.module = module;
84     this.nestHost = nestHost;
85     this.nestMembers = nestMembers;
86     this.record = record;
87     this.transitiveJar = transitiveJar;
88   }
89 
90   /** Class access and property flags. */
access()91   public int access() {
92     return access;
93   }
94 
95   /** Class file major version. */
majorVersion()96   public int majorVersion() {
97     return majorVersion;
98   }
99 
100   /** The name of the class or interface. */
name()101   public String name() {
102     return name;
103   }
104 
105   /** The value of the Signature attribute. */
signature()106   public @Nullable String signature() {
107     return signature;
108   }
109 
110   /** The super class. */
superName()111   public @Nullable String superName() {
112     return superClass;
113   }
114 
115   /** The direct superinterfaces. */
interfaces()116   public List<String> interfaces() {
117     return interfaces;
118   }
119 
120   /** The permitted direct subclasses. */
permits()121   public List<String> permits() {
122     return permits;
123   }
124 
125   /** Methods declared by this class or interfaces type. */
methods()126   public List<MethodInfo> methods() {
127     return methods;
128   }
129 
130   /** Fields declared by this class or interfaces type. */
fields()131   public List<FieldInfo> fields() {
132     return fields;
133   }
134 
135   /** Declaration annotations of the class. */
annotations()136   public List<AnnotationInfo> annotations() {
137     return annotations;
138   }
139 
140   /** Inner class information. */
innerClasses()141   public List<InnerClass> innerClasses() {
142     return innerClasses;
143   }
144 
145   /** Type annotations. */
typeAnnotations()146   public ImmutableList<TypeAnnotationInfo> typeAnnotations() {
147     return typeAnnotations;
148   }
149 
150   /** A module attribute. */
module()151   public @Nullable ModuleInfo module() {
152     return module;
153   }
154 
nestHost()155   public @Nullable String nestHost() {
156     return nestHost;
157   }
158 
nestMembers()159   public ImmutableList<String> nestMembers() {
160     return nestMembers;
161   }
162 
record()163   public @Nullable RecordInfo record() {
164     return record;
165   }
166 
167   /** The original jar of a repackaged transitive class. */
transitiveJar()168   public @Nullable String transitiveJar() {
169     return transitiveJar;
170   }
171 
172   /** The contents of a JVMS §4.5 field_info structure. */
173   public static class FieldInfo {
174 
175     private final int access;
176     private final String name;
177     private final String descriptor;
178     private final @Nullable String signature;
179     private final @Nullable Value value;
180     private final List<AnnotationInfo> annotations;
181     private final ImmutableList<TypeAnnotationInfo> typeAnnotations;
182 
FieldInfo( int access, String name, String descriptor, @Nullable String signature, @Nullable Value value, List<AnnotationInfo> annotations, ImmutableList<TypeAnnotationInfo> typeAnnotations)183     public FieldInfo(
184         int access,
185         String name,
186         String descriptor,
187         @Nullable String signature,
188         @Nullable Value value,
189         List<AnnotationInfo> annotations,
190         ImmutableList<TypeAnnotationInfo> typeAnnotations) {
191       this.access = access;
192       this.name = name;
193       this.descriptor = descriptor;
194       this.signature = signature;
195       this.value = value;
196       this.annotations = annotations;
197       this.typeAnnotations = typeAnnotations;
198     }
199 
200     /** Field access and property flags. */
access()201     public int access() {
202       return access;
203     }
204 
205     /** The name of the field. */
name()206     public String name() {
207       return name;
208     }
209 
210     /** The descriptor. */
descriptor()211     public String descriptor() {
212       return descriptor;
213     }
214 
215     /** The value of Signature attribute. */
signature()216     public @Nullable String signature() {
217       return signature;
218     }
219 
220     /** The compile-time constant value. */
value()221     public Const.@Nullable Value value() {
222       return value;
223     }
224 
225     /** Declaration annotations of the field. */
annotations()226     public List<AnnotationInfo> annotations() {
227       return annotations;
228     }
229 
230     /** Type annotations. */
typeAnnotations()231     public ImmutableList<TypeAnnotationInfo> typeAnnotations() {
232       return typeAnnotations;
233     }
234   }
235 
236   /** A JVMS §4.7.6 InnerClasses attribute. */
237   public static class InnerClass {
238 
239     private final String innerClass;
240     private final String outerClass;
241     private final String innerName;
242     private final int access;
243 
InnerClass(String innerClass, String outerClass, String innerName, int access)244     public InnerClass(String innerClass, String outerClass, String innerName, int access) {
245       this.innerClass = requireNonNull(innerClass);
246       this.outerClass = requireNonNull(outerClass);
247       this.innerName = requireNonNull(innerName);
248       this.access = access;
249     }
250 
251     /** The binary name of the inner class. */
innerClass()252     public String innerClass() {
253       return innerClass;
254     }
255 
256     /** The binary name of the enclosing class. */
outerClass()257     public String outerClass() {
258       return outerClass;
259     }
260 
261     /** The simple name of the inner class. */
innerName()262     public String innerName() {
263       return innerName;
264     }
265 
266     /** Access and property flags of the inner class; see JVMS table 4.8. */
access()267     public int access() {
268       return access;
269     }
270   }
271 
272   /** The contents of a JVMS §4.6 method_info structure. */
273   public static class MethodInfo {
274 
275     private final int access;
276     private final String name;
277     private final String descriptor;
278     private final @Nullable String signature;
279     private final List<String> exceptions;
280     private final AnnotationInfo.@Nullable ElementValue defaultValue;
281     private final List<AnnotationInfo> annotations;
282     private final ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations;
283     private final ImmutableList<TypeAnnotationInfo> typeAnnotations;
284     private final ImmutableList<ParameterInfo> parameters;
285 
MethodInfo( int access, String name, String descriptor, @Nullable String signature, List<String> exceptions, @Nullable ElementValue defaultValue, List<AnnotationInfo> annotations, ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations, ImmutableList<TypeAnnotationInfo> typeAnnotations, ImmutableList<ParameterInfo> parameters)286     public MethodInfo(
287         int access,
288         String name,
289         String descriptor,
290         @Nullable String signature,
291         List<String> exceptions,
292         @Nullable ElementValue defaultValue,
293         List<AnnotationInfo> annotations,
294         ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations,
295         ImmutableList<TypeAnnotationInfo> typeAnnotations,
296         ImmutableList<ParameterInfo> parameters) {
297       this.access = access;
298       this.name = name;
299       this.descriptor = descriptor;
300       this.signature = signature;
301       this.exceptions = exceptions;
302       this.defaultValue = defaultValue;
303       this.annotations = annotations;
304       this.parameterAnnotations = parameterAnnotations;
305       this.typeAnnotations = typeAnnotations;
306       this.parameters = parameters;
307     }
308 
309     /** Method access and property flags. */
access()310     public int access() {
311       return access;
312     }
313 
314     /** The name of the method. */
name()315     public String name() {
316       return name;
317     }
318 
319     /** The descriptor. */
descriptor()320     public String descriptor() {
321       return descriptor;
322     }
323 
324     /** The value of Signature attribute. */
signature()325     public @Nullable String signature() {
326       return signature;
327     }
328 
329     /** The value of Exceptions attribute. */
exceptions()330     public List<String> exceptions() {
331       return exceptions;
332     }
333 
334     /** The value of the AnnotationDefault attribute. */
defaultValue()335     public AnnotationInfo.@Nullable ElementValue defaultValue() {
336       return defaultValue;
337     }
338 
339     /** Declaration annotations of the method. */
annotations()340     public List<AnnotationInfo> annotations() {
341       return annotations;
342     }
343 
344     /** Declaration annotations of the formal parameters. */
parameterAnnotations()345     public ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations() {
346       return parameterAnnotations;
347     }
348 
349     /** Type annotations. */
typeAnnotations()350     public ImmutableList<TypeAnnotationInfo> typeAnnotations() {
351       return typeAnnotations;
352     }
353 
354     /** Formal parameters. */
parameters()355     public ImmutableList<ParameterInfo> parameters() {
356       return parameters;
357     }
358 
359     /** A formal parameter. */
360     public static class ParameterInfo {
361       private final String name;
362       private final int access;
363 
ParameterInfo(String name, int access)364       public ParameterInfo(String name, int access) {
365         this.name = name;
366         this.access = access;
367       }
368 
369       /** Returns the parameter's name. */
name()370       public String name() {
371         return name;
372       }
373 
374       /** Returns the parameter's modifiers. */
access()375       public int access() {
376         return access;
377       }
378     }
379   }
380 
381   /** The contents of a JVMS §4.7.16 annotation structure. */
382   public static class AnnotationInfo {
383 
384     /** Whether the annotation is visible at runtime. */
385     public enum RuntimeVisibility {
386       VISIBLE,
387       INVISIBLE
388     }
389 
390     private final String typeName;
391     private final RuntimeVisibility runtimeVisibility;
392     private final Map<String, ElementValue> elementValuePairs;
393 
AnnotationInfo( String typeName, RuntimeVisibility runtimeVisibility, Map<String, ElementValue> elementValuePairs)394     public AnnotationInfo(
395         String typeName,
396         RuntimeVisibility runtimeVisibility,
397         Map<String, ElementValue> elementValuePairs) {
398       this.typeName = typeName;
399       this.runtimeVisibility = runtimeVisibility;
400       this.elementValuePairs = elementValuePairs;
401     }
402 
403     /** The JVMS §4.3.2 field descriptor for the type of the annotation. */
typeName()404     public String typeName() {
405       return typeName;
406     }
407 
408     /** Returns true if the annotation is visible at runtime. */
isRuntimeVisible()409     public boolean isRuntimeVisible() {
410       return runtimeVisibility == RuntimeVisibility.VISIBLE;
411     }
412 
413     /** The element-value pairs of the annotation. */
elementValuePairs()414     public Map<String, ElementValue> elementValuePairs() {
415       return elementValuePairs;
416     }
417 
418     /** A value of a JVMS §4.7.16.1 element-value pair. */
419     public interface ElementValue {
420 
421       /** The value kind. */
kind()422       ElementValue.Kind kind();
423 
424       /** Element value kinds. */
425       enum Kind {
426         ENUM,
427         CONST,
428         ARRAY,
429         CLASS,
430         ANNOTATION
431       }
432 
433       /** An enum constant value. */
434       class EnumConstValue implements ElementValue {
435 
436         private final String typeName;
437         private final String constName;
438 
EnumConstValue(String typeName, String constName)439         public EnumConstValue(String typeName, String constName) {
440           this.typeName = typeName;
441           this.constName = constName;
442         }
443 
444         @Override
kind()445         public ElementValue.Kind kind() {
446           return ElementValue.Kind.ENUM;
447         }
448 
449         /** The type of the enum. */
typeName()450         public String typeName() {
451           return typeName;
452         }
453 
454         /** The name of the enum constant. */
constName()455         public String constName() {
456           return constName;
457         }
458       }
459 
460       /** A primitive or string constant value. */
461       class ConstValue implements ElementValue {
462 
463         private final Const.Value value;
464 
ConstValue(Const.Value value)465         public ConstValue(Const.Value value) {
466 
467           this.value = value;
468         }
469 
470         @Override
kind()471         public ElementValue.Kind kind() {
472           return ElementValue.Kind.CONST;
473         }
474 
475         /** The constant value. */
value()476         public Const.Value value() {
477           return value;
478         }
479       }
480 
481       /** A constant array value. */
482       class ArrayValue implements ElementValue {
483 
484         private final List<ElementValue> elements;
485 
ArrayValue(List<ElementValue> elements)486         public ArrayValue(List<ElementValue> elements) {
487           this.elements = elements;
488         }
489 
490         @Override
kind()491         public ElementValue.Kind kind() {
492           return ElementValue.Kind.ARRAY;
493         }
494 
495         /** The elements of the array. */
elements()496         public List<ElementValue> elements() {
497           return elements;
498         }
499       }
500 
501       /** A constant class literal value. */
502       class ConstTurbineClassValue implements ElementValue {
503 
504         private final String className;
505 
ConstTurbineClassValue(String className)506         public ConstTurbineClassValue(String className) {
507           this.className = className;
508         }
509 
510         @Override
kind()511         public ElementValue.Kind kind() {
512           return ElementValue.Kind.CLASS;
513         }
514 
515         /** The class name. */
className()516         public String className() {
517           return className;
518         }
519       }
520 
521       /** A nested annotation value. */
522       class ConstTurbineAnnotationValue implements ElementValue {
523 
524         private final AnnotationInfo annotation;
525 
ConstTurbineAnnotationValue(AnnotationInfo annotation)526         public ConstTurbineAnnotationValue(AnnotationInfo annotation) {
527           this.annotation = annotation;
528         }
529 
530         @Override
kind()531         public ElementValue.Kind kind() {
532           return ElementValue.Kind.ANNOTATION;
533         }
534 
535         /** The annotation. */
annotation()536         public AnnotationInfo annotation() {
537           return annotation;
538         }
539       }
540     }
541   }
542 
543   /** The contents of a JVMS §4.7.20 type annotation structure. */
544   public static class TypeAnnotationInfo {
545     private final TargetType targetType;
546     private final Target target;
547     private final TypePath path;
548     private final AnnotationInfo anno;
549 
TypeAnnotationInfo( TargetType targetType, Target target, TypePath path, AnnotationInfo anno)550     public TypeAnnotationInfo(
551         TargetType targetType, Target target, TypePath path, AnnotationInfo anno) {
552       this.targetType = targetType;
553       this.target = target;
554       this.path = path;
555       this.anno = anno;
556     }
557 
558     /**
559      * The underlying annotation info (type, visibility, element-value pairs); shared with
560      * declaration annotations.
561      */
anno()562     public AnnotationInfo anno() {
563       return anno;
564     }
565 
566     /** A JVMS 4.7.20 target_type kind, denotes the type context where the annotation appears. */
targetType()567     public TargetType targetType() {
568       return targetType;
569     }
570 
571     /** A JVMS 4.7.20 target_info structure. */
target()572     public Target target() {
573       return target;
574     }
575 
576     /**
577      * A JVMS 4.7.20 type_path structure, denotes which part of the type the annotation applies to.
578      */
path()579     public TypePath path() {
580       return path;
581     }
582 
583     /** A JVMS 4.7.20-A target_type kind. */
584     public enum TargetType {
585       CLASS_TYPE_PARAMETER(0x00),
586       METHOD_TYPE_PARAMETER(0x01),
587       SUPERTYPE(0x10),
588       CLASS_TYPE_PARAMETER_BOUND(0x11),
589       METHOD_TYPE_PARAMETER_BOUND(0x12),
590       FIELD(0x13),
591       METHOD_RETURN(0x14),
592       METHOD_RECEIVER_PARAMETER(0x15),
593       METHOD_FORMAL_PARAMETER(0x16),
594       METHOD_THROWS(0x17);
595 
596       private final int tag;
597 
TargetType(int tag)598       TargetType(int tag) {
599         this.tag = tag;
600       }
601 
tag()602       public int tag() {
603         return tag;
604       }
605 
606       /**
607        * Returns the {@link TargetType} for the given JVMS 4.7.20-A target_type value, and {@code
608        * null} for target_type values that do not correspond to API elements (see JVMS 4.7.20-B).
609        */
forTag(int targetType)610       static @Nullable TargetType forTag(int targetType) {
611         switch (targetType) {
612           case 0x00:
613             return CLASS_TYPE_PARAMETER;
614           case 0x01:
615             return METHOD_TYPE_PARAMETER;
616           case 0x10:
617             return SUPERTYPE;
618           case 0x11:
619             return CLASS_TYPE_PARAMETER_BOUND;
620           case 0x12:
621             return METHOD_TYPE_PARAMETER_BOUND;
622           case 0x13:
623             return FIELD;
624           case 0x14:
625             return METHOD_RETURN;
626           case 0x15:
627             return METHOD_RECEIVER_PARAMETER;
628           case 0x16:
629             return METHOD_FORMAL_PARAMETER;
630           case 0x17:
631             return METHOD_THROWS;
632           default:
633             return null;
634         }
635       }
636     }
637 
638     /** A JVMS 4.7.20 target_info. */
639     public abstract static class Target {
640       /** Target info kind. */
641       public enum Kind {
642         TYPE_PARAMETER,
643         SUPERTYPE,
644         TYPE_PARAMETER_BOUND,
645         EMPTY,
646         FORMAL_PARAMETER,
647         THROWS;
648       }
649 
650       /** Returns the target info kind. */
kind()651       public abstract Target.Kind kind();
652     }
653 
654     /** A JVMS 4.7.20.1 type_parameter_target. */
655     @AutoValue
656     public abstract static class TypeParameterTarget extends Target {
create(int index)657       public static TypeParameterTarget create(int index) {
658         return new AutoValue_ClassFile_TypeAnnotationInfo_TypeParameterTarget(index);
659       }
660 
index()661       public abstract int index();
662 
663       @Override
kind()664       public Target.Kind kind() {
665         return Target.Kind.TYPE_PARAMETER;
666       }
667     }
668 
669     /** A JVMS 4.7.20.1 supertype_target. */
670     @AutoValue
671     public abstract static class SuperTypeTarget extends Target {
create(int index)672       public static SuperTypeTarget create(int index) {
673         return new AutoValue_ClassFile_TypeAnnotationInfo_SuperTypeTarget(index);
674       }
675 
676       @Override
kind()677       public Target.Kind kind() {
678         return Target.Kind.SUPERTYPE;
679       }
680 
index()681       public abstract int index();
682     }
683 
684     /** A JVMS 4.7.20.1 type_parameter_bound_target. */
685     @AutoValue
686     public abstract static class TypeParameterBoundTarget extends Target {
create(int typeParameterIndex, int boundIndex)687       public static TypeParameterBoundTarget create(int typeParameterIndex, int boundIndex) {
688         return new AutoValue_ClassFile_TypeAnnotationInfo_TypeParameterBoundTarget(
689             typeParameterIndex, boundIndex);
690       }
691 
692       @Override
kind()693       public Target.Kind kind() {
694         return Target.Kind.TYPE_PARAMETER_BOUND;
695       }
696 
typeParameterIndex()697       public abstract int typeParameterIndex();
698 
boundIndex()699       public abstract int boundIndex();
700     }
701 
702     /** A JVMS 4.7.20.1 empty_target. */
703     public static final Target EMPTY_TARGET =
704         new Target() {
705           @Override
706           public Target.Kind kind() {
707             return Target.Kind.EMPTY;
708           }
709         };
710 
711     /** A JVMS 4.7.20.1 formal_parameter_target. */
712     @AutoValue
713     public abstract static class FormalParameterTarget extends Target {
714 
create(int index)715       public static FormalParameterTarget create(int index) {
716         return new AutoValue_ClassFile_TypeAnnotationInfo_FormalParameterTarget(index);
717       }
718 
719       @Override
kind()720       public Target.Kind kind() {
721         return Target.Kind.FORMAL_PARAMETER;
722       }
723 
index()724       public abstract int index();
725     }
726 
727     /** A JVMS 4.7.20.1 throws_target. */
728     @AutoValue
729     public abstract static class ThrowsTarget extends Target {
730 
create(int index)731       public static ThrowsTarget create(int index) {
732         return new AutoValue_ClassFile_TypeAnnotationInfo_ThrowsTarget(index);
733       }
734 
735       @Override
kind()736       public Target.Kind kind() {
737         return Target.Kind.THROWS;
738       }
739 
index()740       public abstract int index();
741     }
742 
743     /**
744      * A JVMS 4.7.20.2 type_path.
745      *
746      * <p>Represented as an immutable linked-list of nodes, which is built out by {@code Lower}
747      * while recursively searching for type annotations to process.
748      */
749     @AutoValue
750     public abstract static class TypePath {
751 
752       /** The root type_path_kind, used for initialization. */
root()753       public static TypePath root() {
754         return create(null, null);
755       }
756 
757       /** Adds an array type_path_kind entry. */
array()758       public TypePath array() {
759         return create(TypePath.Kind.ARRAY, this);
760       }
761 
762       /** Adds a nested type type_path_kind entry. */
nested()763       public TypePath nested() {
764         return create(TypePath.Kind.NESTED, this);
765       }
766 
767       /** Adds a wildcard bound type_path_kind entry. */
wild()768       public TypePath wild() {
769         return create(TypePath.Kind.WILDCARD_BOUND, this);
770       }
771 
772       /** Adds a type argument type_path_kind entry. */
typeArgument(int idx)773       public TypePath typeArgument(int idx) {
774         return create(idx, TypePath.Kind.TYPE_ARGUMENT, this);
775       }
776 
777       /** A type_path_kind. */
778       public enum Kind {
779         ARRAY(0),
780         NESTED(1),
781         WILDCARD_BOUND(2),
782         TYPE_ARGUMENT(3);
783 
784         final int tag;
785 
Kind(int tag)786         Kind(int tag) {
787           this.tag = tag;
788         }
789       }
790 
791       /** The type argument index; set only if the kind is {@code TYPE_ARGUMENT}. */
typeArgumentIndex()792       public abstract int typeArgumentIndex();
793 
kind()794       public abstract @Nullable Kind kind();
795 
parent()796       public abstract @Nullable TypePath parent();
797 
create(TypePath.@ullable Kind kind, @Nullable TypePath parent)798       private static TypePath create(TypePath.@Nullable Kind kind, @Nullable TypePath parent) {
799         // JVMS 4.7.20.2: type_argument_index is 0 if the bound kind is not TYPE_ARGUMENT
800         return create(0, kind, parent);
801       }
802 
create( int index, TypePath.@Nullable Kind kind, @Nullable TypePath parent)803       private static TypePath create(
804           int index, TypePath.@Nullable Kind kind, @Nullable TypePath parent) {
805         return new AutoValue_ClassFile_TypeAnnotationInfo_TypePath(index, kind, parent);
806       }
807 
808       /** The JVMS 4.7.20.2-A serialized value of the type_path_kind. */
tag()809       public byte tag() {
810         return (byte) requireNonNull(kind()).tag;
811       }
812 
813       /** Returns a flattened view of the type path. */
flatten()814       public ImmutableList<TypePath> flatten() {
815         Deque<TypePath> flat = new ArrayDeque<>();
816         for (TypePath curr = this; requireNonNull(curr).kind() != null; curr = curr.parent()) {
817           flat.addFirst(curr);
818         }
819         return ImmutableList.copyOf(flat);
820       }
821     }
822   }
823 
824   /** A JVMS 4.7.25 module attribute. */
825   public static class ModuleInfo {
826 
827     private final String name;
828     private final @Nullable String version;
829     private final int flags;
830     private final ImmutableList<RequireInfo> requires;
831     private final ImmutableList<ExportInfo> exports;
832     private final ImmutableList<OpenInfo> opens;
833     private final ImmutableList<UseInfo> uses;
834     private final ImmutableList<ProvideInfo> provides;
835 
ModuleInfo( String name, int flags, @Nullable String version, ImmutableList<RequireInfo> requires, ImmutableList<ExportInfo> exports, ImmutableList<OpenInfo> opens, ImmutableList<UseInfo> uses, ImmutableList<ProvideInfo> provides)836     public ModuleInfo(
837         String name,
838         int flags,
839         @Nullable String version,
840         ImmutableList<RequireInfo> requires,
841         ImmutableList<ExportInfo> exports,
842         ImmutableList<OpenInfo> opens,
843         ImmutableList<UseInfo> uses,
844         ImmutableList<ProvideInfo> provides) {
845       this.name = name;
846       this.flags = flags;
847       this.version = version;
848       this.requires = requires;
849       this.exports = exports;
850       this.opens = opens;
851       this.uses = uses;
852       this.provides = provides;
853     }
854 
name()855     public String name() {
856       return name;
857     }
858 
flags()859     public int flags() {
860       return flags;
861     }
862 
version()863     public @Nullable String version() {
864       return version;
865     }
866 
requires()867     public ImmutableList<RequireInfo> requires() {
868       return requires;
869     }
870 
exports()871     public ImmutableList<ExportInfo> exports() {
872       return exports;
873     }
874 
opens()875     public ImmutableList<OpenInfo> opens() {
876       return opens;
877     }
878 
uses()879     public ImmutableList<UseInfo> uses() {
880       return uses;
881     }
882 
provides()883     public ImmutableList<ProvideInfo> provides() {
884       return provides;
885     }
886 
887     /** A JVMS 4.7.25 module requires directive. */
888     public static class RequireInfo {
889 
890       private final String moduleName;
891       private final int flags;
892       private final @Nullable String version;
893 
RequireInfo(String moduleName, int flags, @Nullable String version)894       public RequireInfo(String moduleName, int flags, @Nullable String version) {
895         this.moduleName = moduleName;
896         this.flags = flags;
897         this.version = version;
898       }
899 
moduleName()900       public String moduleName() {
901         return moduleName;
902       }
903 
flags()904       public int flags() {
905         return flags;
906       }
907 
version()908       public @Nullable String version() {
909         return version;
910       }
911     }
912 
913     /** A JVMS 4.7.25 module exports directive. */
914     public static class ExportInfo {
915 
916       private final String moduleName;
917       private final int flags;
918       private final ImmutableList<String> modules;
919 
ExportInfo(String moduleName, int flags, ImmutableList<String> modules)920       public ExportInfo(String moduleName, int flags, ImmutableList<String> modules) {
921         this.moduleName = moduleName;
922         this.flags = flags;
923         this.modules = modules;
924       }
925 
moduleName()926       public String moduleName() {
927         return moduleName;
928       }
929 
flags()930       public int flags() {
931         return flags;
932       }
933 
modules()934       public ImmutableList<String> modules() {
935         return modules;
936       }
937     }
938 
939     /** A JVMS 4.7.25 module opens directive. */
940     public static class OpenInfo {
941 
942       private final String moduleName;
943       private final int flags;
944       private final ImmutableList<String> modules;
945 
OpenInfo(String moduleName, int flags, ImmutableList<String> modules)946       public OpenInfo(String moduleName, int flags, ImmutableList<String> modules) {
947         this.moduleName = moduleName;
948         this.flags = flags;
949         this.modules = modules;
950       }
951 
moduleName()952       public String moduleName() {
953         return moduleName;
954       }
955 
flags()956       public int flags() {
957         return flags;
958       }
959 
modules()960       public ImmutableList<String> modules() {
961         return modules;
962       }
963     }
964 
965     /** A JVMS 4.7.25 module uses directive. */
966     public static class UseInfo {
967 
968       private final String descriptor;
969 
UseInfo(String descriptor)970       public UseInfo(String descriptor) {
971         this.descriptor = descriptor;
972       }
973 
descriptor()974       public String descriptor() {
975         return descriptor;
976       }
977     }
978 
979     /** A JVMS 4.7.25 module provides directive. */
980     public static class ProvideInfo {
981 
982       private final String descriptor;
983       private final ImmutableList<String> implDescriptors;
984 
ProvideInfo(String descriptor, ImmutableList<String> implDescriptors)985       public ProvideInfo(String descriptor, ImmutableList<String> implDescriptors) {
986         this.descriptor = descriptor;
987         this.implDescriptors = implDescriptors;
988       }
989 
descriptor()990       public String descriptor() {
991         return descriptor;
992       }
993 
implDescriptors()994       public ImmutableList<String> implDescriptors() {
995         return implDescriptors;
996       }
997     }
998   }
999 
1000   /** A JVMS §4.7.30 Record attribute. */
1001   public static class RecordInfo {
1002 
1003     /** A JVMS §4.7.30 Record component attribute. */
1004     public static class RecordComponentInfo {
1005 
1006       private final String name;
1007       private final String descriptor;
1008       private final @Nullable String signature;
1009       private final ImmutableList<AnnotationInfo> annotations;
1010       private final ImmutableList<TypeAnnotationInfo> typeAnnotations;
1011 
RecordComponentInfo( String name, String descriptor, @Nullable String signature, ImmutableList<AnnotationInfo> annotations, ImmutableList<TypeAnnotationInfo> typeAnnotations)1012       public RecordComponentInfo(
1013           String name,
1014           String descriptor,
1015           @Nullable String signature,
1016           ImmutableList<AnnotationInfo> annotations,
1017           ImmutableList<TypeAnnotationInfo> typeAnnotations) {
1018         this.name = name;
1019         this.descriptor = descriptor;
1020         this.signature = signature;
1021         this.annotations = annotations;
1022         this.typeAnnotations = typeAnnotations;
1023       }
1024 
name()1025       public String name() {
1026         return name;
1027       }
1028 
descriptor()1029       public String descriptor() {
1030         return descriptor;
1031       }
1032 
signature()1033       public @Nullable String signature() {
1034         return signature;
1035       }
1036 
annotations()1037       public ImmutableList<AnnotationInfo> annotations() {
1038         return annotations;
1039       }
1040 
typeAnnotations()1041       public ImmutableList<TypeAnnotationInfo> typeAnnotations() {
1042         return typeAnnotations;
1043       }
1044     }
1045 
RecordInfo(ImmutableList<RecordComponentInfo> recordComponents)1046     public RecordInfo(ImmutableList<RecordComponentInfo> recordComponents) {
1047       this.recordComponents = recordComponents;
1048     }
1049 
1050     private final ImmutableList<RecordComponentInfo> recordComponents;
1051 
recordComponents()1052     public ImmutableList<RecordComponentInfo> recordComponents() {
1053       return recordComponents;
1054     }
1055   }
1056 }
1057