internal/format: add interface

This is analogous to fmt.Formatter.
It is a bit questionable to use fmt.Formatter for
localized text rendering as it is unclear what the
meaning is in some cases. Use this until we know
for sure.

Change-Id: I3571c1bb3db1efeb6e7daf23afd7a6147b5a3dbc
Reviewed-on: https://go-review.googlesource.com/60731
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Nigel Tao <nigeltao@golang.org>
diff --git a/internal/format/format.go b/internal/format/format.go
index c70bc0f..ee1c57a 100644
--- a/internal/format/format.go
+++ b/internal/format/format.go
@@ -24,20 +24,18 @@
 	// Language reports the requested language in which to render a message.
 	Language() language.Tag
 
+	// TODO: consider this and removing rune from the Format method in the
+	// Formatter interface.
+	//
+	// Verb returns the format variant to render, analogous to the types used
+	// in fmt. Use 'v' for the default or only variant.
+	// Verb() rune
+
 	// TODO: more info:
-	// - sentence context
-	// - user preferences, like measurement systems
-	// - options
+	// - sentence context such as linguistic features passed by the translator.
 }
 
-// A Statement is a Var or an Expression.
-type Statement interface {
-	statement()
+// Formatter is analogous to fmt.Formatter.
+type Formatter interface {
+	Format(state State, verb rune)
 }
-
-// A String a literal string format.
-type String string
-
-func (String) statement() {}
-
-// TODO: Select, Var, Case, StatementSequence
diff --git a/message/print.go b/message/print.go
index 07feaa2..5819cba 100644
--- a/message/print.go
+++ b/message/print.go
@@ -11,6 +11,7 @@
 	"reflect"
 	"unicode/utf8"
 
+	"golang.org/x/text/internal/format"
 	"golang.org/x/text/internal/number"
 	"golang.org/x/text/language"
 	"golang.org/x/text/message/catalog"
@@ -605,6 +606,12 @@
 		return
 	}
 	// Is it a Formatter?
+	if formatter, ok := p.arg.(format.Formatter); ok {
+		handled = true
+		defer p.catchPanic(p.arg, verb)
+		formatter.Format(p, verb)
+		return
+	}
 	if formatter, ok := p.arg.(fmt.Formatter); ok {
 		handled = true
 		defer p.catchPanic(p.arg, verb)