[Retrace] Add doc describing retrace version and synthetic

RELNOTES: R8 supports additional information in mapping files
for improved retracing. The additions enable shrinkers to better
reduce output size of the program while allowing retracers to
improve the accuracy of retracing back to the original program.
Additional information available at
https://r8.googlesource.com/r8/+/refs/heads/main/doc/retrace.md

Bug: 197066019
Change-Id: I76c4a32a37c2c33fcbc510916479b67848e21b2d
diff --git a/doc/retrace.md b/doc/retrace.md
new file mode 100644
index 0000000..aaea59b
--- /dev/null
+++ b/doc/retrace.md
@@ -0,0 +1,133 @@
+# R8, Retrace and map file versioning
+
+Programs compiled by R8 are not structurally the same as the input. For example,
+names, invokes and line numbers can all change when compiling with R8. The
+correspondence between the input and the output is recorded in a mapping file.
+The mapping file can be used with retrace to recover the original stack trace
+from the stack traces produced by running the R8 compiled program. More
+information about R8 and mapping files can be found
+[here](https://developer.android.com/studio/build/shrink-code#decode-stack-trace).
+
+## Additional information appended as comments to the file
+
+The format for additional information is encoded as comments with json formatted
+data. The data has an ID to disambiguate it from other information.
+
+### Version
+
+The version information states what version the content of the mapping file is
+using.
+
+The format of the version information is:
+```
+# {"id":"com.android.tools.r8.mapping","version":"1.0"}
+```
+Here `id` must be `com.android.tools.r8.mapping` and `version` is the version of
+the mapping file.
+
+The version information applies to content of the file following the position of
+the version entry until either the end of the file or another version entry is
+present.
+
+If no version information is present, the content is assumed to have version
+zero and no additional mapping information except [Source File](#source-file).
+
+When interpreting the mapping file, any additional mapping information
+pertaining to a later version should be ignored. In other words, treated as a
+normal comment.
+
+Retracing tools supporting this versioning scheme should issue a warning when
+given mapping files with versions higher than the version supported by the tool.
+
+### Source File
+
+The source file information states what source file a class originated from.
+
+The source file information must be placed directly below the class mapping it
+pertains to. The format of the source file information is:
+```
+some.package.Class -> foo.a:
+# {"id":"sourceFile","fileName":"R8Test.kt"}
+```
+Here `id` must be the string `sourceFile` and `fileName` is the source file name
+as a string value (in this example `R8Test.kt`).
+
+Note that the `id` of the source file information is unqualified. It is the only
+allowed unqualified identifier as it was introduced prior to the versioning
+scheme.
+
+### Synthesized (Introduced at version 1.0)
+
+The synthesized information states what parts of the compiled output program are
+synthesized by the compiler. A retracing tool should use the synthesized
+information to strip out synthesized method frames from retraced stacks.
+
+The synthesized information must be placed directly below the class, field or
+method mapping it pertains to. The format of the synthesized information is:
+```
+# {'id':'com.android.tools.r8.synthesized'}
+```
+Here `id` must be `com.android.tools.r8.synthesized`. There is no other content.
+
+A class mapping would be:
+```
+some.package.SomeSynthesizedClass -> x.y.z:
+# {'id':'com.android.tools.r8.synthesized'}
+```
+This specifies that the class `x.y.z` has been synthesized by the compiler and
+thus it did not exist in the original input program.
+
+Notice that the left-hand side and right-hand side, here
+`some.package.SomeSynthesizedClass` and `x.y.z` respectively, could be any class
+name. It is likely that the mapping for synthetics is the identity, but a useful
+name can be placed here if possible which legacy retrace tools would use when
+retracing.
+
+A field mapping would be:
+```
+some.package.Class -> x.y.z:
+  int someField -> a
+  # {'id':'com.android.tools.r8.synthesized'}
+```
+This specifies that the field `x.y.z.a` has been synthesized by the compiler. As
+for classes, since the field is not part of the original input program, the
+left- and right-hand side names could be anything. Note that a field can be
+synthesized without the class being synthesized.
+
+A method mapping would be:
+```
+some.package.SomeSynthesizedClass -> x.y.z:
+  void someMethod() -> a
+  # {'id':'com.android.tools.r8.synthesized'}
+```
+This specifies that the method `x.y.z.a()` has been synthesized by the compiler.
+As for classes, since the method is not part of the original input program, the
+left- and right-hand side names could be anything. Note that a method can be
+synthesized without the class being synthesized.
+
+For inline frames a mapping would be:
+```
+some.package.Class -> foo.a:
+    4:4:void example.Foo.lambda$main$0():225 -> a
+    4:4:void run(example.Foo):2 -> a
+    # {'id':'com.android.tools.r8.synthesized'}
+    5:5:void example.Foo.lambda$main$1():228 -> a
+    5:5:void run(example.Foo):4 -> a
+    # {'id':'com.android.tools.r8.synthesized'} <-- redundant
+```
+This specifies that line 4 in the method `foo.a.a` is in a method that has
+been synthesized by the compiler. Since the method is either synthesized or not
+any extra synthesized comments will have no effect.
+
+Synthesized information should never be placed on inlined frames:
+```
+some.package.Class -> foo.a:
+4:4:void example.Foo.syntheticThatIsInlined():225 -> a
+# {'id':'com.android.tools.r8.synthesized'}
+4:4:void run(example.Foo):2 -> a
+```
+In the above, the mapping information suggests that the inline frame
+`example.Foo.syntheticThatIsInlined` should be marked as `synthesized`. However,
+since that method was not part of the input program it should not be in the
+output mapping information at all.
+