| // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 | package com.android.tools.r8; | 
 |  | 
 | import com.android.tools.r8.origin.Origin; | 
 | import com.android.tools.r8.origin.PathOrigin; | 
 | import com.android.tools.r8.utils.StreamUtils; | 
 | import java.io.ByteArrayInputStream; | 
 | import java.io.IOException; | 
 | import java.io.InputStream; | 
 | import java.nio.file.Files; | 
 | import java.nio.file.Path; | 
 | import java.util.Set; | 
 |  | 
 | /** | 
 |  * Represents program application resources. | 
 |  * | 
 |  * The content kind or format of a program resource can be either a Java class-file or an Android | 
 |  * DEX file. In both cases, the resource must be able to provide the content as a byte stream. | 
 |  * A resource may optionally include a set describing the class descriptors for each type that is | 
 |  * defined by the resource. | 
 |  */ | 
 | @KeepForSubclassing | 
 | public interface ProgramResource extends Resource { | 
 |  | 
 |   /** Type of program-format kinds. */ | 
 |   @Keep | 
 |   enum Kind { | 
 |     /** Format-kind for Java class-file resources. */ | 
 |     CF, | 
 |     /** Format-kind for Android dex-file resources. */ | 
 |     DEX, | 
 |   } | 
 |  | 
 |   /** | 
 |    * Create a program resource for a given file. | 
 |    * | 
 |    * <p>The origin of a file resource is the path of the file. | 
 |    */ | 
 |   static ProgramResource fromFile(Kind kind, Path file) { | 
 |     return new FileResource(kind, file, null); | 
 |   } | 
 |  | 
 |   /** | 
 |    * Create a program resource for a given type, content and type descriptor. | 
 |    * | 
 |    * <p>The origin must be supplied upon construction. If no reasonable origin | 
 |    * exits, use {@code Origin.unknown()}. | 
 |    */ | 
 |   static ProgramResource fromBytes( | 
 |       Origin origin, Kind kind, byte[] bytes, Set<String> typeDescriptors) { | 
 |     return new ByteResource(origin, kind, bytes, typeDescriptors); | 
 |   } | 
 |  | 
 |   /** Get the program format-kind of the resource. */ | 
 |   Kind getKind(); | 
 |  | 
 |   /** Get the bytes of the program resource. */ | 
 |   InputStream getByteStream() throws ResourceException; | 
 |  | 
 |   /** Optional getter to obtain the bytes of the program resource as an array. */ | 
 |   default byte[] getBytes() throws ResourceException { | 
 |     try { | 
 |       return StreamUtils.StreamToByteArrayClose(getByteStream()); | 
 |     } catch (IOException e) { | 
 |       throw new ResourceException(getOrigin(), e); | 
 |     } | 
 |   } | 
 |  | 
 |   /** | 
 |    * Get the set of class descriptors for classes defined by this resource. | 
 |    * | 
 |    * <p>This is not deprecated and will remain after Resource::getClassDescriptors is removed. | 
 |    * | 
 |    * @return Set of class descriptors defined by the resource or null if unknown. | 
 |    */ | 
 |   Set<String> getClassDescriptors(); | 
 |  | 
 |   /** File-based program resource. */ | 
 |   @Keep | 
 |   class FileResource implements ProgramResource { | 
 |     private final Origin origin; | 
 |     private final Kind kind; | 
 |     private final Path file; | 
 |     private final Set<String> classDescriptors; | 
 |  | 
 |     private FileResource(Kind kind, Path file, Set<String> classDescriptors) { | 
 |       this.origin = new PathOrigin(file); | 
 |       this.kind = kind; | 
 |       this.file = file; | 
 |       this.classDescriptors = classDescriptors; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public Origin getOrigin() { | 
 |       return origin; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public Kind getKind() { | 
 |       return kind; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public InputStream getByteStream() throws ResourceException { | 
 |       try { | 
 |         return Files.newInputStream(file); | 
 |       } catch (IOException e) { | 
 |         throw new ResourceException(getOrigin(), e); | 
 |       } | 
 |     } | 
 |  | 
 |     @Override | 
 |     public byte[] getBytes() throws ResourceException { | 
 |       try { | 
 |         return Files.readAllBytes(file); | 
 |       } catch (IOException e) { | 
 |         throw new ResourceException(getOrigin(), e); | 
 |       } | 
 |     } | 
 |  | 
 |     @Override | 
 |     public Set<String> getClassDescriptors() { | 
 |       return classDescriptors; | 
 |     } | 
 |   } | 
 |  | 
 |   /** Byte-content based program resource. */ | 
 |   @Keep | 
 |   class ByteResource implements ProgramResource { | 
 |     private final Origin origin; | 
 |     private final Kind kind; | 
 |     private final byte[] bytes; | 
 |     private final Set<String> classDescriptors; | 
 |  | 
 |     private ByteResource(Origin origin, Kind kind, byte[] bytes, Set<String> classDescriptors) { | 
 |       assert bytes != null; | 
 |       this.origin = origin; | 
 |       this.kind = kind; | 
 |       this.bytes = bytes; | 
 |       this.classDescriptors = classDescriptors; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public Origin getOrigin() { | 
 |       return origin; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public Kind getKind() { | 
 |       return kind; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public InputStream getByteStream() throws ResourceException { | 
 |       return new ByteArrayInputStream(bytes); | 
 |     } | 
 |  | 
 |     @Override | 
 |     public byte[] getBytes() throws ResourceException { | 
 |       return bytes; | 
 |     } | 
 |  | 
 |     @Override | 
 |     public Set<String> getClassDescriptors() { | 
 |       return classDescriptors; | 
 |     } | 
 |   } | 
 | } |