|  | // Copyright (c) 2018, 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.shaking; | 
|  |  | 
|  | import com.android.tools.r8.errors.Unreachable; | 
|  |  | 
|  | public abstract class ProguardWildcard { | 
|  |  | 
|  | abstract void setCaptured(String captured); | 
|  | abstract void clearCaptured(); | 
|  | abstract String getCaptured(); | 
|  | abstract ProguardWildcard materialize(); | 
|  |  | 
|  | boolean isPattern() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | Pattern asPattern() { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | boolean isBackReference() { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | BackReference asBackReference() { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | static class Pattern extends ProguardWildcard { | 
|  | final String pattern; | 
|  | private String captured = null; | 
|  |  | 
|  | Pattern(String pattern) { | 
|  | this.pattern = pattern; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | synchronized void setCaptured(String captured) { | 
|  | this.captured = captured; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | synchronized void clearCaptured() { | 
|  | captured = null; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | synchronized String getCaptured() { | 
|  | return captured; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | Pattern materialize() { | 
|  | if (captured == null) { | 
|  | return this; | 
|  | } | 
|  | Pattern copy = new Pattern(pattern); | 
|  | copy.setCaptured(captured); | 
|  | return copy; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | boolean isPattern() { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | Pattern asPattern() { | 
|  | return this; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public String toString() { | 
|  | return pattern; | 
|  | } | 
|  | } | 
|  |  | 
|  | static class BackReference extends ProguardWildcard { | 
|  | // Back-reference is not referable, hence the other type, Pattern, here. | 
|  | Pattern reference; | 
|  | final int referenceIndex; | 
|  |  | 
|  | BackReference(int referenceIndex) { | 
|  | this.referenceIndex = referenceIndex; | 
|  | } | 
|  |  | 
|  | void setReference(Pattern reference) { | 
|  | this.reference = reference; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | void setCaptured(String captured) { | 
|  | throw new Unreachable("A back reference refers back to a previously matched wildcard."); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | void clearCaptured() { | 
|  | // no-op | 
|  | } | 
|  |  | 
|  | @Override | 
|  | String getCaptured() { | 
|  | return reference != null ? reference.getCaptured() : null; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | BackReference materialize() { | 
|  | if (reference == null || reference.getCaptured() == null) { | 
|  | return this; | 
|  | } | 
|  | BackReference copy = new BackReference(referenceIndex); | 
|  | copy.setReference(reference.materialize()); | 
|  | return copy; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | boolean isBackReference() { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | BackReference asBackReference() { | 
|  | return this; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public String toString() { | 
|  | return "<" + referenceIndex + ">"; | 
|  | } | 
|  | } | 
|  |  | 
|  | } |