content: package com.airbnb.lottie;
  
  import androidx.annotation.Nullable;
  import androidx.annotation.RestrictTo;
  import androidx.annotation.VisibleForTesting;
  
  import java.util.HashMap;
  import java.util.Map;
  
  /**
   * To replace static text in an animation at runtime, create an instance of this class and call {@link #setText(String, String)} to
   * replace the hard coded animation text (input) with the text of your choosing (output).
   * <p>
   * Alternatively, extend this class and override {@link #getText(String)} and if the text hasn't already been set
   * by {@link #setText(String, String)} then it will call {@link #getText(String)}.
   */
  public class TextDelegate {
  
    private final Map<String, String> stringMap = new HashMap<>();
  
    @Nullable private final LottieAnimationView animationView;
    @Nullable private final LottieDrawable drawable;
    private boolean cacheText = true;
  
    /**
     * This normally needs to be able to invalidate the view/drawable but not for the test.
     */
    @VisibleForTesting TextDelegate() {
      animationView = null;
      drawable = null;
    }
  
    public TextDelegate(
        @SuppressWarnings("NullableProblems") LottieAnimationView animationView) {
      this.animationView = animationView;
      drawable = null;
    }
  
    @SuppressWarnings("unused")
    public TextDelegate(@SuppressWarnings("NullableProblems") LottieDrawable drawable) {
      this.drawable = drawable;
      animationView = null;
    }
  
    /**
     * Override this to replace the animation text with something dynamic. This can be used for
     * translations or custom data.
     * @param layerName the name of the layer with text
     * @param input the string at the layer with text
     * @return a String to use for the specific data, by default this is the same as getText(input)
     */
    public String getText(String layerName, String input) {
      return getText(input);
    }
  
    /**
     * Override this to replace the animation text with something dynamic. This can be used for
     * translations or custom data.
     */
    public String getText(String input) {
      return input;
    }
  
    /**
     * Update the text that will be rendered for the given input text.
     */
    public void setText(String input, String output) {
      stringMap.put(input, output);
      invalidate();
    }
  
    /**
     * Sets whether or not {@link TextDelegate} will cache (memoize) the results of getText.
     * If this isn't necessary then set it to false.
     */
    public void setCacheText(boolean cacheText) {
      this.cacheText = cacheText;
    }
  
    /**
     * Invalidates a cached string with the given input.
     */
    public void invalidateText(String input) {
      stringMap.remove(input);
      invalidate();
    }
  
    /**
     * Invalidates all cached strings.
     */
    public void invalidateAllText() {
      stringMap.clear();
      invalidate();
    }
  
    @RestrictTo(RestrictTo.Scope.LIBRARY)
    public final String getTextInternal(String layerName, String input) {
      if (cacheText && stringMap.containsKey(input)) {
        return stringMap.get(input);
      }
      String text = getText(layerName, input);
      if (cacheText) {
        stringMap.put(input, text);
      }
      return text;
    }
  
    private void invalidate() {
      if (animationView != null) {
        animationView.invalidate();
      }
      if (drawable != null) {
        drawable.invalidateSelf();
      }
    }
  }
  