2727import com .diffplug .spotless .JarState ;
2828import com .diffplug .spotless .LineEnding ;
2929import com .diffplug .spotless .Provisioner ;
30+ import com .diffplug .spotless .ThrowingEx .BiFunction ;
3031import com .diffplug .spotless .ThrowingEx .Function ;
3132
3233/** Wraps up <a href="https://github.com/google/google-java-format">google-java-format</a> as a FormatterStep. */
@@ -35,6 +36,7 @@ public class GoogleJavaFormatStep {
3536 private GoogleJavaFormatStep () {}
3637
3738 private static final String DEFAULT_STYLE = "GOOGLE" ;
39+ private static final boolean DEFAULT_REFLOW_LONG_STRINGS = false ;
3840 static final String NAME = "google-java-format" ;
3941 static final String MAVEN_COORDINATE = "com.google.googlejavaformat:google-java-format:" ;
4042 static final String FORMATTER_CLASS = "com.google.googlejavaformat.java.Formatter" ;
@@ -56,6 +58,9 @@ private GoogleJavaFormatStep() {}
5658 private static final String IMPORT_ORDERER_CLASS = "com.google.googlejavaformat.java.ImportOrderer" ;
5759 private static final String IMPORT_ORDERER_METHOD = "reorderImports" ;
5860
61+ private static final String STRING_WRAPPER_CLASS = "com.google.googlejavaformat.java.StringWrapper" ;
62+ private static final String STRING_WRAPPER_METHOD = "wrap" ;
63+
5964 /** Creates a step which formats everything - code, import order, and unused imports. */
6065 public static FormatterStep create (Provisioner provisioner ) {
6166 return create (defaultVersion (), provisioner );
@@ -68,11 +73,16 @@ public static FormatterStep create(String version, Provisioner provisioner) {
6873
6974 /** Creates a step which formats everything - code, import order, and unused imports. */
7075 public static FormatterStep create (String version , String style , Provisioner provisioner ) {
76+ return create (version , style , provisioner , DEFAULT_REFLOW_LONG_STRINGS );
77+ }
78+
79+ /** Creates a step which formats everything - code, import order, and unused imports - and optionally reflows long strings. */
80+ public static FormatterStep create (String version , String style , Provisioner provisioner , boolean reflowLongStrings ) {
7181 Objects .requireNonNull (version , "version" );
7282 Objects .requireNonNull (style , "style" );
7383 Objects .requireNonNull (provisioner , "provisioner" );
7484 return FormatterStep .createLazy (NAME ,
75- () -> new State (NAME , version , style , provisioner ),
85+ () -> new State (NAME , version , style , provisioner , reflowLongStrings ),
7686 State ::createFormat );
7787 }
7888
@@ -106,6 +116,10 @@ public static String defaultStyle() {
106116 return DEFAULT_STYLE ;
107117 }
108118
119+ public static boolean defaultReflowLongStrings () {
120+ return DEFAULT_REFLOW_LONG_STRINGS ;
121+ }
122+
109123 static final class State implements Serializable {
110124 private static final long serialVersionUID = 1L ;
111125
@@ -114,16 +128,22 @@ static final class State implements Serializable {
114128 final String stepName ;
115129 final String version ;
116130 final String style ;
131+ final boolean reflowLongStrings ;
117132
118133 State (String stepName , String version , Provisioner provisioner ) throws IOException {
119134 this (stepName , version , DEFAULT_STYLE , provisioner );
120135 }
121136
122137 State (String stepName , String version , String style , Provisioner provisioner ) throws IOException {
138+ this (stepName , version , style , provisioner , DEFAULT_REFLOW_LONG_STRINGS );
139+ }
140+
141+ State (String stepName , String version , String style , Provisioner provisioner , boolean reflowLongStrings ) throws IOException {
123142 this .jarState = JarState .from (MAVEN_COORDINATE + version , provisioner );
124143 this .stepName = stepName ;
125144 this .version = version ;
126145 this .style = style ;
146+ this .reflowLongStrings = reflowLongStrings ;
127147 }
128148
129149 @ SuppressWarnings ({"unchecked" , "rawtypes" })
@@ -153,11 +173,14 @@ FormatterFunc createFormat() throws Exception {
153173 Class <?> importOrdererClass = classLoader .loadClass (IMPORT_ORDERER_CLASS );
154174 Method importOrdererMethod = importOrdererClass .getMethod (IMPORT_ORDERER_METHOD , String .class );
155175
176+ BiFunction <String , Object , String > reflowLongStrings = this .reflowLongStrings ? constructReflowLongStringsFunction (classLoader , formatterClazz ) : (s , f ) -> s ;
177+
156178 return suggestJre11 (input -> {
157179 String formatted = (String ) formatterMethod .invoke (formatter , input );
158180 String removedUnused = removeUnused .apply (formatted );
159181 String sortedImports = (String ) importOrdererMethod .invoke (null , removedUnused );
160- return fixWindowsBug (sortedImports , version );
182+ String reflowedLongStrings = reflowLongStrings .apply (sortedImports , formatter );
183+ return fixWindowsBug (reflowedLongStrings , version );
161184 });
162185 }
163186
@@ -191,6 +214,20 @@ private static Function<String, String> constructRemoveUnusedFunction(ClassLoade
191214 }
192215 return removeUnused ;
193216 }
217+
218+ private static BiFunction <String , Object , String > constructReflowLongStringsFunction (ClassLoader classLoader , Class <?> formatterClazz ) throws NoSuchMethodException {
219+ Class <?> stringWrapperClass ;
220+ try {
221+ stringWrapperClass = classLoader .loadClass (STRING_WRAPPER_CLASS );
222+ } catch (ClassNotFoundException e ) {
223+ // google-java-format 1.7 or lower, which happen to be LATEST_VERSION_JRE_8, so rely on suggestJre11 for the error
224+ return (s , f ) -> {
225+ throw e ;
226+ };
227+ }
228+ Method stringWrapperMethod = stringWrapperClass .getMethod (STRING_WRAPPER_METHOD , String .class , formatterClazz );
229+ return (s , f ) -> (String ) stringWrapperMethod .invoke (null , s , f );
230+ }
194231 }
195232
196233 private static final boolean IS_WINDOWS = LineEnding .PLATFORM_NATIVE .str ().equals ("\r \n " );
0 commit comments