Key string should be avoided

Change-Id: I0708ac8bd7aa8c6993bb329b212b400a6f55cae9
Reviewed-on: https://dart-review.googlesource.com/60424
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/fasta/diagnostics.md b/pkg/front_end/lib/src/fasta/diagnostics.md
index d3711ec..1305e52 100644
--- a/pkg/front_end/lib/src/fasta/diagnostics.md
+++ b/pkg/front_end/lib/src/fasta/diagnostics.md
@@ -41,7 +41,9 @@
 
 ## Avoid Composing Messages Programmatically
 
-Composing messages programmatically can make it hard to translate them.
+Composing messages programmatically can make it hard to translate them. A tool that compose messages programmatically also makes it hard for its clients to distinguish the diagnostics.
+
+For example, [messages.yaml](../../../messages.yaml) includes an error code named `Unspecified`. This code is useful when prototyping a new diagnostic, but shouldn't otherwise be used.
 
 ## Keep Message Short
 
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 989fd27..df83d386 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -64,6 +64,9 @@
 # `#lexeme` a token. The token's `lexeme` property is used.
 #
 # `#string`, `#string2`, `#string3`: strings (that aren't names).
+#    Note: as a rule of thumb, avoid using the `#string` keys. In particular,
+#    do not use them for composing error messages, see [diagnostics.md](
+#    lib/src/fasta/diagnostics.md#avoid-composing-messages-programmatically).
 #
 # `#type`, #type2`: Kernel types.
 #
@@ -864,6 +867,9 @@
   template: "Incomplete token."
   dart2jsCode: UNTERMINATED_TOKEN
 
+# Note: avoid using this template, it should only be used for debugging and
+# prototyping, see [diagnostics.md](
+# lib/src/fasta/diagnostics.md#avoid-composing-messages-programmatically).
 Unspecified:
   template: "#string"
   dart2jsCode: GENERIC