In progress: [Issue 13] Implement a formatter

* Fixed line wrap for normal and public imports
* Added tests to verify correct formatting
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/TestSourceReader.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentReader.java
similarity index 70%
rename from com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/TestSourceReader.java
rename to com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentReader.java
index ba99394..793dee2 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/TestSourceReader.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentReader.java
@@ -1,9 +1,8 @@
 /*
- * Copyright (c) 2011 Google Inc.
+ * Copyright (c) 2012 Google Inc.
  *
- * All rights reserved. This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License v1.0 which
- * accompanies this distribution, and is available at
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
@@ -12,6 +11,7 @@
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
 import static java.io.File.separator;
+import static java.util.Collections.emptyList;
 
 import java.io.*;
 import java.util.*;
@@ -21,32 +21,26 @@
 import com.google.eclipse.protobuf.junit.util.MultiLineTextBuilder;
 
 /**
+ * Reads the comments of test methods.
+ *
  * @author alruiz@google.com (Alex Ruiz)
  */
-class TestSourceReader {
+public class CommentReader {
   private static final String COMMENT_START = "//";
 
-  private final Map<String, List<String>> comments = newHashMap();
-  private final CommentProcessor processor = new CommentProcessor();
-
+  private final Map<String, List<String>> commentsByMethod = newHashMap();
   private boolean initialized;
 
   private final Object lock = new Object();
 
-  String commentsIn(FrameworkMethod method) {
+  public List<String> commentsIn(FrameworkMethod method) {
     synchronized (lock) {
       ensureCommentsAreRead(method.getMethod().getDeclaringClass());
-      List<String> allComments = comments.get(method.getName());
-      if (allComments == null || allComments.isEmpty()) {
-        return null;
+      List<String> comments = commentsByMethod.get(method.getName());
+      if (comments != null) {
+        return comments;
       }
-      for (String comment : allComments) {
-        Object processed = processor.processComment(comment);
-        if (processed instanceof String) {
-          return (String) processed;
-        }
-      }
-      return null;
+      return emptyList();
     }
   }
 
@@ -64,7 +58,7 @@
     String classFile = fqn + ".java";
     File file = new File("src" + separator + classFile);
     Scanner scanner = null;
-    List<String> allComments = newArrayList();
+    List<String> comments = newArrayList();
     MultiLineTextBuilder comment = new MultiLineTextBuilder();
     try {
       scanner = new Scanner(new FileInputStream(file));
@@ -81,14 +75,14 @@
         line = line.trim();
         String testName = testName(line);
         if (line.length() == 0 || testName != null) {
-          if (!allComments.contains(comment)) {
-            allComments.add(comment.toString());
+          if (!comments.contains(comment)) {
+            comments.add(comment.toString());
           }
           comment = new MultiLineTextBuilder();
         }
         if (testName != null) {
-          comments.put(testName, allComments);
-          allComments = newArrayList();
+          commentsByMethod.put(testName, comments);
+          comments = newArrayList();
         }
       }
     } catch (IOException e) {
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java
index bb407d3..55e1df1 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java
@@ -34,13 +34,21 @@
 import com.google.inject.*;
 
 /**
- * Rule that performs configuration of a standalone Xtext environment.
+ * JUnit <code>{@link MethodRule}</code> that:
+ * <ol>
+ * <li>Performs configuration of a standalone Xtext environment</li>
+ * <li>Creates an <code>{@link XtextResource}</code> from method-level comments</li>
+ * <li>Creates .proto files in the file system based on method-level comments (if the comment starts with
+ * "// Create file" followed by the name of the file to create)</li>
+ * <li>Finds model objects and nodes in the created <code>{@link XtextResource}</code> (from #2)</li>
+ * </ol>
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
 public class XtextRule implements MethodRule {
   private final Injector injector;
-  private final TestSourceReader reader;
+  private final CommentProcessor processor;
+  private final CommentReader reader;
 
   private Protobuf root;
   private XtextResource resource;
@@ -60,13 +68,14 @@
 
   private XtextRule(Injector injector) {
     this.injector = injector;
-    reader = new TestSourceReader();
+    processor = new CommentProcessor();
+    reader = new CommentReader();
   }
 
   @Override public Statement apply(Statement base, FrameworkMethod method, Object target) {
     injector.injectMembers(target);
     root = null;
-    String comments = reader.commentsIn(method);
+    String comments = commentsIn(method);
     if (!isEmpty(comments)) {
       parseText(comments);
       finder = new Finder(resource.getParseResult().getRootNode(), comments);
@@ -74,8 +83,14 @@
     return base;
   }
 
-  public Injector injector() {
-    return injector;
+  private String commentsIn(FrameworkMethod method) {
+    for (String comment : reader.commentsIn(method)) {
+      Object processed = processor.processComment(comment);
+      if (processed instanceof String) {
+        return (String) processed;
+      }
+    }
+    return null;
   }
 
   public void parseText(String text) {
@@ -130,6 +145,10 @@
     return injector.getInstance(type);
   }
 
+  public Injector injector() {
+    return injector;
+  }
+
   public XtextResource resource() {
     return resource;
   }
@@ -150,7 +169,7 @@
     return finder.find(text, count, type, asList(options));
   }
 
-  public ILeafNode find(String text) {
+  public ILeafNode findNode(String text) {
     return finder.find(text);
   }
 
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isCommentOrString_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isCommentOrString_Test.java
index 5b8c9e9..90e5aea 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isCommentOrString_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isCommentOrString_Test.java
@@ -34,7 +34,7 @@
   // // This is a test.
   // message Person {}
   @Test public void should_return_true_if_node_belongs_to_single_line_comment() {
-    ILeafNode commentNode = xtext.find("// This is a test.");
+    ILeafNode commentNode = xtext.findNode("// This is a test.");
     assertTrue(nodes.isCommentOrString(commentNode));
   }
 
@@ -43,7 +43,7 @@
   // /* This is a test. */
   // message Person {}
   @Test public void should_return_true_if_node_belongs_to_multiple_line_comment() {
-    ILeafNode commentNode = xtext.find("/* This is a test. */");
+    ILeafNode commentNode = xtext.findNode("/* This is a test. */");
     assertTrue(nodes.isCommentOrString(commentNode));
   }
 
@@ -53,7 +53,7 @@
   //   optional string name = 1 [default = 'Alex'];
   // }
   @Test public void should_return_true_if_node_belongs_to_string() {
-    ILeafNode node = xtext.find("'Alex'");
+    ILeafNode node = xtext.findNode("'Alex'");
     assertTrue(nodes.isCommentOrString(node));
   }
 
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isComment_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isComment_Test.java
index 5092e10..fb21453 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isComment_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isComment_Test.java
@@ -34,7 +34,7 @@
   // // This is a test.
   // message Person {}
   @Test public void should_return_true_if_node_belongs_to_single_line_comment() {
-    ILeafNode commentNode = xtext.find("// This is a test.");
+    ILeafNode commentNode = xtext.findNode("// This is a test.");
     assertTrue(nodes.isComment(commentNode));
   }
 
@@ -43,7 +43,7 @@
   // /* This is a test. */
   // message Person {}
   @Test public void should_return_true_if_node_belongs_to_multiple_line_comment() {
-    ILeafNode commentNode = xtext.find("/* This is a test. */");
+    ILeafNode commentNode = xtext.findNode("/* This is a test. */");
     assertTrue(nodes.isComment(commentNode));
   }
 
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isMultipleLineComment_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isMultipleLineComment_Test.java
index 805f589..35ad0f6 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isMultipleLineComment_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isMultipleLineComment_Test.java
@@ -34,7 +34,7 @@
   // /* This is a test. */
   // message Person {}
   @Test public void should_return_true_if_node_belongs_to_multiple_line_comment() {
-    ILeafNode commentNode = xtext.find("/* This is a test. */");
+    ILeafNode commentNode = xtext.findNode("/* This is a test. */");
     assertTrue(nodes.isMultipleLineComment(commentNode));
   }
 
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isSingleLineComment_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isSingleLineComment_Test.java
index b0dae01..56680a0 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isSingleLineComment_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isSingleLineComment_Test.java
@@ -34,7 +34,7 @@
   // // This is a test.
   // message Person {}
   @Test public void should_return_true_if_node_belongs_to_single_line_comment() {
-    ILeafNode commentNode = xtext.find("// This is a test.");
+    ILeafNode commentNode = xtext.findNode("// This is a test.");
     assertTrue(nodes.isSingleLineComment(commentNode));
   }
 
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isString_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isString_Test.java
index 309a29d..f322859 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isString_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/INodes_isString_Test.java
@@ -35,7 +35,7 @@
   //   optional string name = 1 [default = 'Alex'];
   // }
   @Test public void should_return_true_if_node_belongs_to_string() {
-    ILeafNode node = xtext.find("'Alex'");
+    ILeafNode node = xtext.findNode("'Alex'");
     assertTrue(nodes.isString(node));
   }
 
diff --git a/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/editor/Formatter_Test.java b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/editor/Formatter_Test.java
new file mode 100644
index 0000000..2628aae
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/editor/Formatter_Test.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.editor;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEclipseEditor;
+import org.junit.*;
+
+import com.google.eclipse.protobuf.formatting.ProtobufFormatter;
+import com.google.eclipse.protobuf.ui.junit.core.CommentReaderRule;
+import com.google.eclipse.protobuf.ui.swtbot.*;
+
+/**
+ * Tests for <code>{@link ProtobufFormatter}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class Formatter_Test {
+  private static SWTWorkbenchBot robot;
+  private static FileFactory fileFactory;
+
+  public @Rule CommentReaderRule commentReader = new CommentReaderRule();
+
+  @BeforeClass public static void setUpOnce() throws Exception {
+    robot = new SWTWorkbenchBot();
+    Workbench workbench = new Workbench(robot);
+    workbench.initialize();
+    ProjectFactory projectFactory = new ProjectFactory(robot);
+    projectFactory.createGeneralProject("FormatterTest");
+    fileFactory = new FileFactory(robot);
+    SWTBotEclipseEditor editor = fileFactory.createFile("dummy.proto");
+    editor.setText("syntax = 'proto2';");
+    editor.saveAndClose();
+  }
+
+  // import 'dummy.proto';import 'google/protobuf/descriptor.proto';
+
+  // import 'dummy.proto';
+  // import 'google/protobuf/descriptor.proto';
+  @Test public void should_add_line_wrap_after_normal_import() throws Exception {
+    SWTBotEclipseEditor editor = fileFactory.createFile("formatNormalImport.proto");
+    Comments comments = commentsAbove();
+    editor.setText(comments.beforeFormatting);
+    formatAndSave(editor);
+    assertThat(editor.getText(), equalTo(comments.expected));
+  }
+
+  // import public 'dummy.proto';import 'google/protobuf/descriptor.proto';
+
+  // import public 'dummy.proto';
+  // import 'google/protobuf/descriptor.proto';
+  @Test public void should_add_line_wrap_after_public_import() throws Exception {
+    SWTBotEclipseEditor editor = fileFactory.createFile("formatPublicImport.proto");
+    Comments comments = commentsAbove();
+    editor.setText(comments.beforeFormatting);
+    formatAndSave(editor);
+    assertThat(editor.getText(), equalTo(comments.expected));
+  }
+
+  private Comments commentsAbove() {
+    return new Comments(commentReader.commentsInCurrentTestMethod());
+  }
+
+  private void formatAndSave(SWTBotEclipseEditor editor) {
+    editor.pressShortcut(SWT.MOD1 | SWT.SHIFT, 'F');
+    editor.save();
+  }
+
+  @After public void tearDown() {
+    robot.saveAllEditors();
+    robot.closeAllEditors();
+  }
+
+  private static class Comments {
+    String beforeFormatting;
+    String expected;
+
+    Comments(List<String> comments) {
+      beforeFormatting = comments.get(0);
+      expected = comments.get(1);
+    }
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/junit/core/CommentReaderRule.java b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/junit/core/CommentReaderRule.java
new file mode 100644
index 0000000..6907091
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/junit/core/CommentReaderRule.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.junit.core;
+
+import java.util.List;
+
+import org.junit.rules.MethodRule;
+import org.junit.runners.model.*;
+
+import com.google.eclipse.protobuf.junit.core.CommentReader;
+
+/**
+ * JUnit <code>{@link MethodRule}</code> that keeps a registry of comments per method.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CommentReaderRule implements MethodRule {
+  private final CommentReader reader = new CommentReader();
+
+  private List<String> comments;
+
+  @Override public Statement apply(Statement base, FrameworkMethod method, Object target) {
+    comments = reader.commentsIn(method);
+    return base;
+  }
+
+  public List<String> commentsInCurrentTestMethod() {
+    return comments;
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/FileFactory.java b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/FileFactory.java
new file mode 100644
index 0000000..5332925
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/FileFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.swtbot;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotEclipseEditor;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class FileFactory {
+
+  private final SWTWorkbenchBot robot;
+
+  public FileFactory(SWTWorkbenchBot robot) {
+    this.robot = robot;
+  }
+
+  public SWTBotEclipseEditor createFile(String name) {
+    robot.menu("File").menu("New").menu("File").click();
+    SWTBotShell shell = robot.shell("New File");
+    shell.activate();
+    robot.textWithLabel("File name:").setText(name);
+    robot.button("Finish").click();
+    return robot.editorByTitle(name).toTextEditor();
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/ProjectFactory.java b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/ProjectFactory.java
new file mode 100644
index 0000000..87eb6af
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/ProjectFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.swtbot;
+
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProjectFactory {
+  private final SWTWorkbenchBot robot;
+
+  public ProjectFactory(SWTWorkbenchBot robot) {
+    this.robot = robot;
+  }
+
+  public void createGeneralProject(String name) {
+    robot.menu("File").menu("New").menu("Project...").click();
+    SWTBotShell shell = robot.shell("New Project");
+    shell.activate();
+    robot.tree().expandNode("General").select("Project");
+    robot.button("Next >").click();
+    robot.textWithLabel("Project name:").setText(name);
+    robot.button("Finish").click();
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/Workbench.java b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/Workbench.java
new file mode 100644
index 0000000..50bdc11
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.functional.test/src/com/google/eclipse/protobuf/ui/swtbot/Workbench.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.ui.swtbot;
+
+import static com.google.eclipse.protobuf.ui.util.Workspaces.workspaceRoot;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.*;
+import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
+import org.eclipse.swtbot.swt.finder.exceptions.WidgetNotFoundException;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public final class Workbench {
+  private static final NullProgressMonitor NULL_MONITOR = new NullProgressMonitor();
+
+  private final SWTWorkbenchBot robot;
+
+  public Workbench(SWTWorkbenchBot robot) {
+    this.robot = robot;
+  }
+
+  public void initialize() throws CoreException {
+    robot.closeAllShells();
+    closeWelcomeView();
+    deleteAllProjects();
+  }
+
+  private void closeWelcomeView() {
+    try {
+    robot.viewByTitle("Welcome").close();
+    } catch (WidgetNotFoundException ignored) {}
+  }
+
+  private void deleteAllProjects() throws CoreException {
+    for (IProject project : workspaceRoot().getProjects()) {
+      project.delete(true, true, NULL_MONITOR);
+    }
+  }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/formatting/ProtobufFormatter.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/formatting/ProtobufFormatter.java
index acb0c4b..30cf32f 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/formatting/ProtobufFormatter.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/formatting/ProtobufFormatter.java
@@ -17,7 +17,9 @@
 import com.google.eclipse.protobuf.services.ProtobufGrammarAccess;
 
 /**
- * This class provides custom formatting.
+ * Provides custom formatting.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
  *
  * @see <a href="http://www.eclipse.org/Xtext/documentation/2_0_0/105-formatting.php">Xtext Formatting</a>
  */
@@ -26,9 +28,10 @@
     ProtobufGrammarAccess g = (ProtobufGrammarAccess) getGrammarAccess();
     c.setLinewrap(0, 1, 2).before(g.getSL_COMMENTRule());
     c.setLinewrap(1).after(g.getPackageRule());
+    c.setLinewrap(1).after(g.getNormalImportRule());
+    c.setLinewrap(1).after(g.getPublicImportRule());
     c.setLinewrap(1).after(g.getNativeOptionRule());
     c.setLinewrap(1).after(g.getCustomOptionRule());
-    c.setLinewrap(1).after(g.getImportRule());
     c.setLinewrap(1).after(g.getGroupRule());
     c.setLinewrap(1).after(g.getMessageFieldRule());
     c.setLinewrap(1).after(g.getEnumRule());