// Copyright (c) 2019, 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.retrace;

import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.FieldReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.retrace.RetraceClassResult.Element;
import com.android.tools.r8.retrace.RetraceRegularExpression.ClassNameGroup.ClassNameGroupHandler;
import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class RetraceRegularExpression {

  private final RetraceApi retracer;
  private final List<String> stackTrace;
  private final DiagnosticsHandler diagnosticsHandler;
  private final String regularExpression;

  private static final int NO_MATCH = -1;

  private final SourceFileLineNumberGroup sourceFileLineNumberGroup =
      new SourceFileLineNumberGroup();
  private final TypeNameGroup typeNameGroup = new TypeNameGroup();
  private final BinaryNameGroup binaryNameGroup = new BinaryNameGroup();
  private final SourceFileGroup sourceFileGroup = new SourceFileGroup();
  private final LineNumberGroup lineNumberGroup = new LineNumberGroup();
  private final FieldOrReturnTypeGroup fieldOrReturnTypeGroup = new FieldOrReturnTypeGroup();
  private final MethodArgumentsGroup methodArgumentsGroup = new MethodArgumentsGroup();

  private final MethodNameGroup methodNameGroup;
  private final FieldNameGroup fieldNameGroup;

  private static final String CAPTURE_GROUP_PREFIX = "captureGroup";
  private static final int FIRST_CAPTURE_GROUP_INDEX = 0;

  RetraceRegularExpression(
      RetraceApi retracer,
      List<String> stackTrace,
      DiagnosticsHandler diagnosticsHandler,
      String regularExpression,
      boolean isVerbose) {
    this.retracer = retracer;
    this.stackTrace = stackTrace;
    this.diagnosticsHandler = diagnosticsHandler;
    this.regularExpression = regularExpression;
    methodNameGroup = new MethodNameGroup(isVerbose);
    fieldNameGroup = new FieldNameGroup(isVerbose);
  }

  public RetraceCommandLineResult retrace() {
    List<RegularExpressionGroupHandler> handlers = new ArrayList<>();
    StringBuilder refinedRegularExpressionBuilder = new StringBuilder();
    registerGroups(
        this.regularExpression,
        refinedRegularExpressionBuilder,
        handlers,
        FIRST_CAPTURE_GROUP_INDEX);
    String refinedRegularExpression = refinedRegularExpressionBuilder.toString();
    Pattern compiledPattern = Pattern.compile(refinedRegularExpression);
    List<String> result = new ArrayList<>();
    for (String string : stackTrace) {
      Matcher matcher = compiledPattern.matcher(string);
      if (!matcher.matches()) {
        result.add(string);
        continue;
      }
      // Iterate through handlers to set contexts. That will allow us to process all handlers from
      // left to right.
      RetraceStringContext initialContext = RetraceStringContext.empty();
      for (RegularExpressionGroupHandler handler : handlers) {
        initialContext = handler.buildInitial(initialContext, matcher, retracer);
      }
      final RetraceString initialRetraceString = RetraceString.start(initialContext);
      List<RetraceString> retracedStrings = Lists.newArrayList(initialRetraceString);
      for (RegularExpressionGroupHandler handler : handlers) {
        retracedStrings = handler.handleMatch(string, retracedStrings, matcher, retracer);
      }
      if (retracedStrings.isEmpty()) {
        // We could not find a match. Output the identity.
        result.add(string);
      }
      boolean isAmbiguous = retracedStrings.size() > 1 && retracedStrings.get(0).isAmbiguous();
      if (isAmbiguous) {
        retracedStrings.sort(new RetraceLineComparator());
      }
      ClassReference previousContext = null;
      for (RetraceString retracedString : retracedStrings) {
        String finalString = retracedString.builder.build(string);
        if (!isAmbiguous) {
          result.add(finalString);
          continue;
        }
        assert retracedString.getClassContext() != null;
        ClassReference currentContext = retracedString.getClassContext().getClassReference();
        if (currentContext.equals(previousContext)) {
          int firstNonWhitespaceCharacter = StringUtils.firstNonWhitespaceCharacter(finalString);
          finalString =
              finalString.substring(0, firstNonWhitespaceCharacter)
                  + "<OR> "
                  + finalString.substring(firstNonWhitespaceCharacter);
        }
        previousContext = currentContext;
        result.add(finalString);
      }
    }
    return new RetraceCommandLineResult(result);
  }

  static class RetraceLineComparator extends AmbiguousComparator<RetraceString> {

    RetraceLineComparator() {
      super(
          (line, t) -> {
            switch (t) {
              case CLASS:
                return line.getClassContext().getClassReference().getTypeName();
              case METHOD:
                return line.getMethodContext().getMethodReference().getMethodName();
              case SOURCE:
                return line.getSource();
              case LINE:
                return line.getLineNumber() + "";
              default:
                assert false;
            }
            throw new RuntimeException("Comparator key is unknown");
          });
    }
  }

  private int registerGroups(
      String regularExpression,
      StringBuilder refinedRegularExpression,
      List<RegularExpressionGroupHandler> handlers,
      int captureGroupIndex) {
    int lastCommittedIndex = 0;
    RegularExpressionGroupHandler lastHandler = null;
    boolean seenPercentage = false;
    boolean escaped = false;
    for (int i = 0; i < regularExpression.length(); i++) {
      if (seenPercentage) {
        assert !escaped;
        final RegularExpressionGroup group = getGroupFromVariable(regularExpression.charAt(i));
        refinedRegularExpression.append(regularExpression, lastCommittedIndex, i - 1);
        if (group.isSynthetic()) {
          captureGroupIndex =
              registerGroups(
                  group.subExpression(), refinedRegularExpression, handlers, captureGroupIndex);
        } else {
          String captureGroupName = CAPTURE_GROUP_PREFIX + (captureGroupIndex++);
          refinedRegularExpression
              .append("(?<")
              .append(captureGroupName)
              .append(">")
              .append(group.subExpression())
              .append(")");
          final RegularExpressionGroupHandler handler = group.createHandler(captureGroupName);
          // If we see a pattern as %c.%m or %C/%m, then register the groups to allow delaying
          // writing of the class string until we have the fully qualified member.
          if (lastHandler != null
              && handler.isQualifiedHandler()
              && lastHandler.isClassNameGroupHandler()
              && lastCommittedIndex == i - 3
              && isTypeOrBinarySeparator(regularExpression, lastCommittedIndex, i - 2)) {
            final ClassNameGroupHandler classNameGroupHandler =
                lastHandler.asClassNameGroupHandler();
            final QualifiedRegularExpressionGroupHandler qualifiedHandler =
                handler.asQualifiedHandler();
            classNameGroupHandler.setQualifiedHandler(qualifiedHandler);
            qualifiedHandler.setClassNameGroupHandler(classNameGroupHandler);
          }
          lastHandler = handler;
          handlers.add(handler);
        }
        lastCommittedIndex = i + 1;
        seenPercentage = false;
      } else {
        seenPercentage = !escaped && regularExpression.charAt(i) == '%';
        escaped = !escaped && regularExpression.charAt(i) == '\\';
      }
    }
    refinedRegularExpression.append(
        regularExpression, lastCommittedIndex, regularExpression.length());
    return captureGroupIndex;
  }

  private boolean isTypeOrBinarySeparator(String regularExpression, int startIndex, int endIndex) {
    assert endIndex < regularExpression.length();
    if (startIndex + 1 != endIndex) {
      return false;
    }
    if (regularExpression.charAt(startIndex) != '\\') {
      return false;
    }
    return regularExpression.charAt(startIndex + 1) == '.'
        || regularExpression.charAt(startIndex + 1) == '/';
  }

  private RegularExpressionGroup getGroupFromVariable(char variable) {
    switch (variable) {
      case 'c':
        return typeNameGroup;
      case 'C':
        return binaryNameGroup;
      case 'm':
        return methodNameGroup;
      case 'f':
        return fieldNameGroup;
      case 's':
        return sourceFileGroup;
      case 'l':
        return lineNumberGroup;
      case 'S':
        return sourceFileLineNumberGroup;
      case 't':
        return fieldOrReturnTypeGroup;
      case 'a':
        return methodArgumentsGroup;
      default:
        throw new Unreachable("Unexpected variable: " + variable);
    }
  }

  static class RetraceStringContext {
    private final Element classContext;
    private final ClassReference qualifiedContext;
    private final String methodName;
    private final RetraceMethodResult.Element methodContext;
    private final int minifiedLineNumber;
    private final int originalLineNumber;
    private final String source;
    private final boolean isAmbiguous;

    private RetraceStringContext(
        Element classContext,
        ClassReference qualifiedContext,
        String methodName,
        RetraceMethodResult.Element methodContext,
        int minifiedLineNumber,
        int originalLineNumber,
        String source,
        boolean isAmbiguous) {
      this.classContext = classContext;
      this.qualifiedContext = qualifiedContext;
      this.methodName = methodName;
      this.methodContext = methodContext;
      this.minifiedLineNumber = minifiedLineNumber;
      this.originalLineNumber = originalLineNumber;
      this.source = source;
      this.isAmbiguous = isAmbiguous;
    }

    private static RetraceStringContext empty() {
      return new RetraceStringContext(null, null, null, null, NO_MATCH, NO_MATCH, null, false);
    }

    private RetraceStringContext withClassContext(
        Element classContext, ClassReference qualifiedContext) {
      return new RetraceStringContext(
          classContext,
          qualifiedContext,
          methodName,
          methodContext,
          minifiedLineNumber,
          originalLineNumber,
          source,
          isAmbiguous);
    }

    private RetraceStringContext withMethodName(String methodName) {
      return new RetraceStringContext(
          classContext,
          qualifiedContext,
          methodName,
          methodContext,
          minifiedLineNumber,
          originalLineNumber,
          source,
          isAmbiguous);
    }

    private RetraceStringContext withMethodContext(
        RetraceMethodResult.Element methodContext,
        ClassReference qualifiedContext,
        boolean isAmbiguous) {
      return new RetraceStringContext(
          classContext,
          qualifiedContext,
          methodName,
          methodContext,
          minifiedLineNumber,
          originalLineNumber,
          source,
          isAmbiguous);
    }

    private RetraceStringContext withQualifiedContext(ClassReference qualifiedContext) {
      return new RetraceStringContext(
          classContext,
          qualifiedContext,
          methodName,
          methodContext,
          minifiedLineNumber,
          originalLineNumber,
          source,
          isAmbiguous);
    }

    public RetraceStringContext withSource(String source) {
      return new RetraceStringContext(
          classContext,
          qualifiedContext,
          methodName,
          methodContext,
          minifiedLineNumber,
          originalLineNumber,
          source,
          isAmbiguous);
    }

    public RetraceStringContext withLineNumbers(int minifiedLineNumber, int originalLineNumber) {
      return new RetraceStringContext(
          classContext,
          qualifiedContext,
          methodName,
          methodContext,
          minifiedLineNumber,
          originalLineNumber,
          source,
          isAmbiguous);
    }
  }

  static class RetraceStringBuilder {

    private final StringBuilder retracedString;
    private int lastCommittedIndex;

    private RetraceStringBuilder(String retracedString, int lastCommittedIndex) {
      this.retracedString = new StringBuilder(retracedString);
      this.lastCommittedIndex = lastCommittedIndex;
    }

    private void appendRetracedString(
        String source, String stringToAppend, int originalFromIndex, int originalToIndex) {
      retracedString.append(source, lastCommittedIndex, originalFromIndex);
      retracedString.append(stringToAppend);
      lastCommittedIndex = originalToIndex;
    }

    private String build(String source) {
      return retracedString.append(source, lastCommittedIndex, source.length()).toString();
    }
  }

  private static class RetraceString {

    private final RetraceStringBuilder builder;
    private final RetraceStringContext context;

    private RetraceString(RetraceStringBuilder builder, RetraceStringContext context) {
      this.builder = builder;
      this.context = context;
    }

    private Element getClassContext() {
      return context.classContext;
    }

    private RetraceMethodResult.Element getMethodContext() {
      return context.methodContext;
    }

    private String getSource() {
      return context.source;
    }

    private int getLineNumber() {
      return context.originalLineNumber;
    }

    private boolean isAmbiguous() {
      return context.isAmbiguous;
    }

    private static RetraceString start(RetraceStringContext initialContext) {
      return new RetraceString(new RetraceStringBuilder("", 0), initialContext);
    }

    private RetraceString updateContext(
        Function<RetraceStringContext, RetraceStringContext> update) {
      return new RetraceString(builder, update.apply(context));
    }

    private RetraceString duplicate(RetraceStringContext newContext) {
      return new RetraceString(
          new RetraceStringBuilder(builder.retracedString.toString(), builder.lastCommittedIndex),
          newContext);
    }

    private RetraceString appendRetracedString(
        String source, String stringToAppend, int originalFromIndex, int originalToIndex) {
      builder.appendRetracedString(source, stringToAppend, originalFromIndex, originalToIndex);
      return this;
    }
  }

  private interface RegularExpressionGroupHandler {

    List<RetraceString> handleMatch(
        String original, List<RetraceString> strings, Matcher matcher, RetraceApi retracer);

    default RetraceStringContext buildInitial(
        RetraceStringContext context, Matcher matcher, RetraceApi retracer) {
      return context;
    }

    default boolean isClassNameGroupHandler() {
      return false;
    }

    default ClassNameGroupHandler asClassNameGroupHandler() {
      return null;
    }

    default boolean isQualifiedHandler() {
      return false;
    }

    default QualifiedRegularExpressionGroupHandler asQualifiedHandler() {
      return null;
    }
  }

  private interface QualifiedRegularExpressionGroupHandler extends RegularExpressionGroupHandler {

    @Override
    default boolean isQualifiedHandler() {
      return true;
    }

    @Override
    default QualifiedRegularExpressionGroupHandler asQualifiedHandler() {
      return this;
    }

    void setClassNameGroupHandler(ClassNameGroupHandler handler);
  }

  private abstract static class RegularExpressionGroup {

    abstract String subExpression();

    abstract RegularExpressionGroupHandler createHandler(String captureGroup);

    boolean isSynthetic() {
      return false;
    }
  }

  // TODO(b/145731185): Extend support for identifiers with strings inside back ticks.
  private static final String javaIdentifierSegment =
      "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*";

  private static final String METHOD_NAME_REGULAR_EXPRESSION =
      "(?:(" + javaIdentifierSegment + "|\\<init\\>|\\<clinit\\>))";

  abstract static class ClassNameGroup extends RegularExpressionGroup {

    abstract String getClassName(ClassReference classReference);

    abstract ClassReference classFromMatch(String match);

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      return new ClassNameGroupHandler(this, captureGroup);
    }

    static class ClassNameGroupHandler implements RegularExpressionGroupHandler {

      private RetraceClassResult retraceClassResult = null;
      private final ClassNameGroup classNameGroup;
      private final String captureGroup;
      private RegularExpressionGroupHandler qualifiedHandler;

      public ClassNameGroupHandler(ClassNameGroup classNameGroup, String captureGroup) {
        this.classNameGroup = classNameGroup;
        this.captureGroup = captureGroup;
      }

      @Override
      public List<RetraceString> handleMatch(
          String original, List<RetraceString> strings, Matcher matcher, RetraceApi retracer) {
        final int startOfGroup = matcher.start(captureGroup);
        if (startOfGroup == NO_MATCH) {
          return strings;
        }
        String typeName = matcher.group(captureGroup);
        RetraceClassResult retraceResult =
            retraceClassResult == null
                ? retracer.retrace(classNameGroup.classFromMatch(typeName))
                : retraceClassResult;
        assert !retraceResult.isAmbiguous();
        List<RetraceString> retraceStrings = new ArrayList<>(strings.size());
        for (RetraceString retraceString : strings) {
          retraceResult.forEach(
              element -> {
                final RetraceString newRetraceString =
                    retraceString.updateContext(
                        context -> context.withClassContext(element, element.getClassReference()));
                retraceStrings.add(newRetraceString);
                if (qualifiedHandler == null) {
                  // If there is no qualified handler, commit right away.
                  newRetraceString.builder.appendRetracedString(
                      original,
                      classNameGroup.getClassName(element.getClassReference()),
                      startOfGroup,
                      matcher.end(captureGroup));
                }
              });
        }
        return retraceStrings;
      }

      void commitClassName(
          String original,
          RetraceString retraceString,
          ClassReference qualifiedContext,
          Matcher matcher) {
        if (matcher.start(captureGroup) == NO_MATCH) {
          return;
        }
        retraceString.builder.appendRetracedString(
            original,
            classNameGroup.getClassName(qualifiedContext),
            matcher.start(captureGroup),
            matcher.end(captureGroup));
      }

      @Override
      public RetraceStringContext buildInitial(
          RetraceStringContext context, Matcher matcher, RetraceApi retracer) {
        // Reset the local class context since this the same handler is used for multiple lines.
        retraceClassResult = null;
        if (matcher.start(captureGroup) == NO_MATCH || context.classContext != null) {
          return context;
        }
        String typeName = matcher.group(captureGroup);
        retraceClassResult = retracer.retrace(classNameGroup.classFromMatch(typeName));
        assert !retraceClassResult.isAmbiguous();
        Box<RetraceStringContext> box = new Box<>();
        retraceClassResult.forEach(
            element -> box.set(context.withClassContext(element, element.getClassReference())));
        return box.get();
      }

      public void setQualifiedHandler(RegularExpressionGroupHandler handler) {
        assert handler.isQualifiedHandler();
        this.qualifiedHandler = handler;
      }

      @Override
      public boolean isClassNameGroupHandler() {
        return true;
      }

      @Override
      public ClassNameGroupHandler asClassNameGroupHandler() {
        return this;
      }
    }
  }

  private static class TypeNameGroup extends ClassNameGroup {

    @Override
    String subExpression() {
      return "(" + javaIdentifierSegment + "\\.)*" + javaIdentifierSegment;
    }

    @Override
    String getClassName(ClassReference classReference) {
      return classReference.getTypeName();
    }

    @Override
    ClassReference classFromMatch(String match) {
      return Reference.classFromTypeName(match);
    }
  }

  private static class BinaryNameGroup extends ClassNameGroup {

    @Override
    String subExpression() {
      return "(?:" + javaIdentifierSegment + "\\/)*" + javaIdentifierSegment;
    }

    @Override
    String getClassName(ClassReference classReference) {
      return classReference.getBinaryName();
    }

    @Override
    ClassReference classFromMatch(String match) {
      return Reference.classFromBinaryName(match);
    }
  }

  private static class MethodNameGroup extends RegularExpressionGroup {

    private final boolean printVerbose;

    public MethodNameGroup(boolean printVerbose) {
      this.printVerbose = printVerbose;
    }

    @Override
    String subExpression() {
      return METHOD_NAME_REGULAR_EXPRESSION;
    }

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      return new QualifiedRegularExpressionGroupHandler() {

        private ClassNameGroupHandler classNameGroupHandler;

        @Override
        public void setClassNameGroupHandler(ClassNameGroupHandler handler) {
          classNameGroupHandler = handler;
        }

        @Override
        public List<RetraceString> handleMatch(
            String original, List<RetraceString> strings, Matcher matcher, RetraceApi retracer) {
          final int startOfGroup = matcher.start(captureGroup);
          if (startOfGroup == NO_MATCH) {
            if (classNameGroupHandler != null) {
              for (RetraceString string : strings) {
                classNameGroupHandler.commitClassName(
                    original, string, string.context.qualifiedContext, matcher);
              }
            }
            return strings;
          }
          String methodName = matcher.group(captureGroup);
          List<RetraceString> retracedStrings = new ArrayList<>();
          for (RetraceString retraceString : strings) {
            retraceMethodForString(
                retraceString,
                methodName,
                (element, newContext) -> {
                  final RetraceString newRetraceString = retraceString.duplicate(newContext);
                  if (classNameGroupHandler != null) {
                    classNameGroupHandler.commitClassName(
                        original,
                        newRetraceString,
                        element.getMethodReference().getHolderClass(),
                        matcher);
                  }
                  retracedStrings.add(
                      newRetraceString.appendRetracedString(
                          original,
                          printVerbose
                              ? RetraceUtils.methodDescriptionFromMethodReference(
                                  element.getMethodReference(), false, true)
                              : element.getMethodReference().getMethodName(),
                          startOfGroup,
                          matcher.end(captureGroup)));
                });
          }
          return retracedStrings;
        }

        @Override
        public RetraceStringContext buildInitial(
            RetraceStringContext context, Matcher matcher, RetraceApi retracer) {
          final int startOfGroup = matcher.start(captureGroup);
          if (startOfGroup == NO_MATCH || context.methodName != null) {
            return context;
          }
          return context.withMethodName(matcher.group(captureGroup));
        }
      };
    }

    private static void retraceMethodForString(
        RetraceString retraceString,
        String methodName,
        BiConsumer<RetraceMethodResult.Element, RetraceStringContext> process) {
      if (retraceString.context.classContext == null) {
        return;
      }
      RetraceMethodResult retraceMethodResult =
          retraceString.getClassContext().lookupMethod(methodName);
      if (retraceString.context.minifiedLineNumber > NO_MATCH) {
        retraceMethodResult =
            retraceMethodResult.narrowByLine(retraceString.context.minifiedLineNumber);
      }
      retraceMethodResult.forEach(
          element ->
              process.accept(
                  element,
                  retraceString.context.withMethodContext(
                      element,
                      element.getMethodReference().getHolderClass(),
                      element.getRetraceMethodResult().isAmbiguous())));
    }
  }

  private static class FieldNameGroup extends RegularExpressionGroup {

    private final boolean printVerbose;

    public FieldNameGroup(boolean printVerbose) {
      this.printVerbose = printVerbose;
    }

    @Override
    String subExpression() {
      return javaIdentifierSegment;
    }

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      return new QualifiedRegularExpressionGroupHandler() {

        private ClassNameGroupHandler classNameGroupHandler;

        @Override
        public void setClassNameGroupHandler(ClassNameGroupHandler handler) {
          classNameGroupHandler = handler;
        }

        @Override
        public List<RetraceString> handleMatch(
            String original, List<RetraceString> strings, Matcher matcher, RetraceApi retracer) {
          final int startOfGroup = matcher.start(captureGroup);
          if (startOfGroup == NO_MATCH) {
            if (classNameGroupHandler != null) {
              for (RetraceString string : strings) {
                classNameGroupHandler.commitClassName(
                    original, string, string.context.qualifiedContext, matcher);
              }
            }
            return strings;
          }
          String methodName = matcher.group(captureGroup);
          List<RetraceString> retracedStrings = new ArrayList<>();
          for (RetraceString retraceString : strings) {
            if (retraceString.getClassContext() == null) {
              assert classNameGroupHandler == null;
              return strings;
            }
            final RetraceFieldResult retraceFieldResult =
                retraceString.getClassContext().lookupField(methodName);
            assert !retraceFieldResult.isAmbiguous();
            retraceFieldResult.forEach(
                element -> {
                  if (classNameGroupHandler != null) {
                    classNameGroupHandler.commitClassName(
                        original,
                        retraceString,
                        element.getFieldReference().getHolderClass(),
                        matcher);
                  }
                  retracedStrings.add(
                      retraceString
                          .updateContext(
                              context ->
                                  context.withQualifiedContext(
                                      element.getFieldReference().getHolderClass()))
                          .appendRetracedString(
                              original,
                              getFieldString(element.getFieldReference()),
                              startOfGroup,
                              matcher.end(captureGroup)));
                });
          }
          return retracedStrings;
        }
      };
    }

    private String getFieldString(FieldReference fieldReference) {
      if (!printVerbose) {
        return fieldReference.getFieldName();
      }
      return fieldReference.getFieldType().getTypeName() + " " + fieldReference.getFieldName();
    }
  }

  private static class SourceFileGroup extends RegularExpressionGroup {

    @Override
    String subExpression() {
      return "(?:(\\w*[\\. ])?(\\w*)?)";
    }

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      return (original, strings, matcher, retracer) -> {
        final int startOfGroup = matcher.start(captureGroup);
        if (startOfGroup == NO_MATCH) {
          return strings;
        }
        String fileName = matcher.group(captureGroup);
        List<RetraceString> retracedStrings = null;
        for (RetraceString retraceString : strings) {
          if (retraceString.context.classContext == null) {
            return strings;
          }
          if (retracedStrings == null) {
            retracedStrings = new ArrayList<>();
          }
          RetraceSourceFileResult sourceFileResult =
              retraceString.getMethodContext() != null
                  ? retraceString.getMethodContext().retraceSourceFile(fileName)
                  : RetraceUtils.getSourceFile(
                      retraceString.getClassContext(),
                      retraceString.context.qualifiedContext,
                      fileName,
                      retracer);
          retracedStrings.add(
              retraceString
                  .updateContext(context -> context.withSource(sourceFileResult.getFilename()))
                  .appendRetracedString(
                      original,
                      sourceFileResult.getFilename(),
                      startOfGroup,
                      matcher.end(captureGroup)));
        }
        return retracedStrings;
      };
    }
  }

  private class LineNumberGroup extends RegularExpressionGroup {

    @Override
    String subExpression() {
      return "\\d*";
    }

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      return new RegularExpressionGroupHandler() {
        @Override
        public List<RetraceString> handleMatch(
            String original, List<RetraceString> strings, Matcher matcher, RetraceApi retracer) {
          final int startOfGroup = matcher.start(captureGroup);
          if (startOfGroup == NO_MATCH) {
            return strings;
          }
          String lineNumberAsString = matcher.group(captureGroup);
          if (lineNumberAsString.isEmpty()) {
            return strings;
          }
          int lineNumber = Integer.parseInt(lineNumberAsString);
          List<RetraceString> retracedStrings = new ArrayList<>();
          for (RetraceString retraceString : strings) {
            RetraceMethodResult.Element methodContext = retraceString.context.methodContext;
            if (methodContext == null) {
              if (retraceString.context.classContext == null
                  || retraceString.context.methodName == null) {
                // We have no way of retracing the line number.
                retracedStrings.add(retraceString);
                continue;
              }
              // This situation arises when we have a matched pattern as %l..%c.%m where the
              // line number handler is defined before the methodname handler.
              MethodNameGroup.retraceMethodForString(
                  retraceString,
                  retraceString.context.methodName,
                  (element, newContext) -> {
                    // The same method can be represented multiple times if it has multiple
                    // mappings.
                    if (element.hasNoLineNumberRange()
                        || !element.containsMinifiedLineNumber(lineNumber)) {
                      diagnosticsHandler.info(
                          new StringDiagnostic(
                              "Pruning "
                                  + retraceString.builder.retracedString.toString()
                                  + " from result because method is not in range on line number "
                                  + lineNumber));
                    }
                    final int originalLineNumber = element.getOriginalLineNumber(lineNumber);
                    retracedStrings.add(
                        retraceString
                            .updateContext(
                                context -> context.withLineNumbers(lineNumber, originalLineNumber))
                            .appendRetracedString(
                                original,
                                originalLineNumber + "",
                                startOfGroup,
                                matcher.end(captureGroup)));
                  });
              continue;
            }
            // If the method context is unknown, do nothing.
            if (methodContext.getMethodReference().isUnknown()
                || methodContext.hasNoLineNumberRange()) {
              retracedStrings.add(retraceString);
              continue;
            }
            int originalLineNumber = methodContext.getOriginalLineNumber(lineNumber);
            retracedStrings.add(
                retraceString
                    .updateContext(
                        context -> context.withLineNumbers(lineNumber, originalLineNumber))
                    .appendRetracedString(
                        original,
                        originalLineNumber + "",
                        startOfGroup,
                        matcher.end(captureGroup)));
          }
          return retracedStrings;
        }

        @Override
        public RetraceStringContext buildInitial(
            RetraceStringContext context, Matcher matcher, RetraceApi retracer) {
          if (matcher.start(captureGroup) == NO_MATCH || context.minifiedLineNumber > NO_MATCH) {
            return context;
          }
          String lineNumberAsString = matcher.group(captureGroup);
          return context.withLineNumbers(
              lineNumberAsString.isEmpty() ? NO_MATCH : Integer.parseInt(lineNumberAsString),
              NO_MATCH);
        }
      };
    }
  }

  private static class SourceFileLineNumberGroup extends RegularExpressionGroup {

    @Override
    String subExpression() {
      return "%s(?::%l)?";
    }

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      throw new Unreachable("Should never be called");
    }

    @Override
    boolean isSynthetic() {
      return true;
    }
  }

  private static final String JAVA_TYPE_REGULAR_EXPRESSION =
      "(" + javaIdentifierSegment + "\\.)*" + javaIdentifierSegment + "[\\[\\]]*";

  private static class FieldOrReturnTypeGroup extends RegularExpressionGroup {

    @Override
    String subExpression() {
      return JAVA_TYPE_REGULAR_EXPRESSION;
    }

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      return (original, strings, matcher, retracer) -> {
        final int startOfGroup = matcher.start(captureGroup);
        if (startOfGroup == NO_MATCH) {
          return strings;
        }
        String typeName = matcher.group(captureGroup);
        String descriptor = DescriptorUtils.javaTypeToDescriptor(typeName);
        if (!DescriptorUtils.isDescriptor(descriptor) && !"V".equals(descriptor)) {
          return strings;
        }
        TypeReference typeReference = Reference.returnTypeFromDescriptor(descriptor);
        RetraceTypeResult retracedType = retracer.retrace(typeReference);
        assert !retracedType.isAmbiguous();
        for (RetraceString retraceString : strings) {
          retracedType.forEach(
              element -> {
                TypeReference retracedReference = element.getTypeReference();
                retraceString.appendRetracedString(
                    original,
                    retracedReference == null ? "void" : retracedReference.getTypeName(),
                    startOfGroup,
                    matcher.end(captureGroup));
              });
        }
        return strings;
      };
    }
  }

  private static class MethodArgumentsGroup extends RegularExpressionGroup {

    @Override
    String subExpression() {
      return "((" + JAVA_TYPE_REGULAR_EXPRESSION + "\\,)*" + JAVA_TYPE_REGULAR_EXPRESSION + ")?";
    }

    @Override
    RegularExpressionGroupHandler createHandler(String captureGroup) {
      return (original, strings, matcher, retracer) -> {
        final int startOfGroup = matcher.start(captureGroup);
        if (startOfGroup == NO_MATCH) {
          return strings;
        }
        final String formals =
            Arrays.stream(matcher.group(captureGroup).split(","))
                .map(
                    typeName -> {
                      typeName = typeName.trim();
                      if (typeName.isEmpty()) {
                        return null;
                      }
                      String descriptor = DescriptorUtils.javaTypeToDescriptor(typeName);
                      if (!DescriptorUtils.isDescriptor(descriptor) && !"V".equals(descriptor)) {
                        return typeName;
                      }
                      final RetraceTypeResult retraceResult =
                          retracer.retrace(Reference.returnTypeFromDescriptor(descriptor));
                      assert !retraceResult.isAmbiguous();
                      final Box<TypeReference> elementBox = new Box<>();
                      retraceResult.forEach(element -> elementBox.set(element.getTypeReference()));
                      return elementBox.get().getTypeName();
                    })
                .filter(Objects::nonNull)
                .collect(Collectors.joining(","));
        for (RetraceString string : strings) {
          string.appendRetracedString(original, formals, startOfGroup, matcher.end(captureGroup));
        }
        return strings;
      };
    }
  }
}
