FileInfo: Include file size

Together with the size delta which is already contained in FileInfo,
having the file size allows clients to show the file size
increase/decrease as percentages.

Change-Id: I7f462991ee26151b4e99da5599fcec47e36c3a44
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index 55764b1..8ae56e5 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -414,35 +414,42 @@
           "files": {
             "gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeCache.java": {
               "lines_deleted": 8,
-              "size_delta": -412
+              "size_delta": -412,
+              "size": 7782
             },
             "gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java": {
               "lines_inserted": 1,
-              "size_delta": 23
+              "size_delta": 23,
+              "size": 6762
             },
             "gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeScreen.java": {
               "lines_inserted": 11,
               "lines_deleted": 19,
-              "size_delta": -298
+              "size_delta": -298,
+              "size": 47023
             },
             "gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeTable.java": {
               "lines_inserted": 23,
               "lines_deleted": 20,
-              "size_delta": 132
+              "size_delta": 132,
+              "size": 17727
             },
             "gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/StarCache.java": {
               "status": "D",
               "lines_deleted": 139,
-              "size_delta": -5512
+              "size_delta": -5512,
+              "size": 13098
             },
             "gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/StarredChanges.java": {
               "status": "A",
               "lines_inserted": 204,
-              "size_delta": 8345
+              "size_delta": 8345,
+              "size": 8345
             },
             "gerrit-gwtui/src/main/java/com/google/gerrit/client/ui/Screen.java": {
               "lines_deleted": 9,
-              "size_delta": -343
+              "size_delta": -343,
+              "size": 5385
             }
           }
         }
@@ -3270,12 +3277,14 @@
     "/COMMIT_MSG": {
       "status": "A",
       "lines_inserted": 7,
-      "size_delta": 551
+      "size_delta": 551,
+      "size": 551
     },
     "gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java": {
       "lines_inserted": 5,
       "lines_deleted": 3,
-      "size_delta": 98
+      "size_delta": 98,
+      "size": 23348
     }
   }
 ----
@@ -4218,6 +4227,8 @@
 Not set for binary files or if no lines were deleted.
 |`size_delta`    ||
 Number of bytes by which the file size increased/decreased.
+|`size`          ||
+File size in bytes.
 |=============================
 
 [[fix-input]]
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/FileInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/FileInfo.java
index 00d0c18..a812908 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/FileInfo.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/FileInfo.java
@@ -21,4 +21,5 @@
   public Integer linesInserted;
   public Integer linesDeleted;
   public long sizeDelta;
+  public long size;
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/FileInfoJson.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/FileInfoJson.java
index 71974c4..e31b11f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/FileInfoJson.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/FileInfoJson.java
@@ -64,6 +64,7 @@
           ? e.getChangeType().getCode() : null;
       d.oldPath = e.getOldName();
       d.sizeDelta = e.getSizeDelta();
+      d.size = e.getSize();
       if (e.getPatchType() == Patch.PatchType.BINARY) {
         d.binary = true;
       } else {
@@ -78,6 +79,7 @@
         // a single record with data from both sides.
         d.status = Patch.ChangeType.REWRITE.getCode();
         d.sizeDelta = o.sizeDelta;
+        d.size = o.size;
         if (o.binary != null && o.binary) {
           d.binary = true;
         }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListEntry.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListEntry.java
index 5de28f3..d130175 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListEntry.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListEntry.java
@@ -51,7 +51,7 @@
 
   static PatchListEntry empty(final String fileName) {
     return new PatchListEntry(ChangeType.MODIFIED, PatchType.UNIFIED, null,
-        fileName, EMPTY_HEADER, Collections.<Edit> emptyList(), 0, 0, 0);
+        fileName, EMPTY_HEADER, Collections.<Edit> emptyList(), 0, 0, 0, 0);
   }
 
   private final ChangeType changeType;
@@ -62,11 +62,13 @@
   private final List<Edit> edits;
   private final int insertions;
   private final int deletions;
+  private final long size;
   private final long sizeDelta;
   // Note: When adding new fields, the serialVersionUID in PatchListKey must be
   // incremented so that entries from the cache are automatically invalidated.
 
-  PatchListEntry(FileHeader hdr, List<Edit> editList, long sizeDelta) {
+  PatchListEntry(FileHeader hdr, List<Edit> editList, long size,
+      long sizeDelta) {
     changeType = toChangeType(hdr);
     patchType = toPatchType(hdr);
 
@@ -111,12 +113,13 @@
     }
     insertions = ins;
     deletions = del;
+    this.size = size;
     this.sizeDelta = sizeDelta;
   }
 
   private PatchListEntry(ChangeType changeType, PatchType patchType,
       String oldName, String newName, byte[] header, List<Edit> edits,
-      int insertions, int deletions, long sizeDelta) {
+      int insertions, int deletions, long size, long sizeDelta) {
     this.changeType = changeType;
     this.patchType = patchType;
     this.oldName = oldName;
@@ -125,6 +128,7 @@
     this.edits = edits;
     this.insertions = insertions;
     this.deletions = deletions;
+    this.size = size;
     this.sizeDelta = sizeDelta;
   }
 
@@ -172,6 +176,10 @@
     return deletions;
   }
 
+  public long getSize() {
+    return size;
+  }
+
   public long getSizeDelta() {
     return sizeDelta;
   }
@@ -208,6 +216,7 @@
     writeBytes(out, header);
     writeVarInt32(out, insertions);
     writeVarInt32(out, deletions);
+    writeFixInt64(out, size);
     writeFixInt64(out, sizeDelta);
 
     writeVarInt32(out, edits.size());
@@ -227,6 +236,7 @@
     byte[] hdr = readBytes(in);
     int ins = readVarInt32(in);
     int del = readVarInt32(in);
+    long size = readFixInt64(in);
     long sizeDelta = readFixInt64(in);
 
     int editCount = readVarInt32(in);
@@ -240,7 +250,7 @@
     }
 
     return new PatchListEntry(changeType, patchType, oldName, newName, hdr,
-        toList(editArray), ins, del, sizeDelta);
+        toList(editArray), ins, del, size, sizeDelta);
   }
 
   private static List<Edit> toList(Edit[] l) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListKey.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListKey.java
index 15277b2..0200fa5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListKey.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListKey.java
@@ -34,7 +34,7 @@
 import java.io.Serializable;
 
 public class PatchListKey implements Serializable {
-  static final long serialVersionUID = 18L;
+  static final long serialVersionUID = 19L;
 
   public static final BiMap<Whitespace, Character> WHITESPACE_TYPES = ImmutableBiMap.of(
       Whitespace.IGNORE_NONE, 'N',
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
index aa2a8a8..10ea61c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
@@ -206,7 +206,7 @@
               getFileSize(repo, reader, e.getOldMode(), e.getOldPath(), aTree);
           long newSize =
               getFileSize(repo, reader, e.getNewMode(), e.getNewPath(), bTree);
-          entries.add(newEntry(aTree, fh, newSize - oldSize));
+          entries.add(newEntry(aTree, fh, newSize, newSize - oldSize));
         }
       }
       return new PatchList(a, b, againstParent,
@@ -301,37 +301,38 @@
     byte[] rawHdr = hdr.toString().getBytes(UTF_8);
     byte[] aContent = aText.getContent();
     byte[] bContent = bText.getContent();
+    long size = bContent.length;
     long sizeDelta = bContent.length - aContent.length;
     RawText aRawText = new RawText(aContent);
     RawText bRawText = new RawText(bContent);
     EditList edits = new HistogramDiff().diff(cmp, aRawText, bRawText);
     FileHeader fh = new FileHeader(rawHdr, edits, PatchType.UNIFIED);
-    return new PatchListEntry(fh, edits, sizeDelta);
+    return new PatchListEntry(fh, edits, size, sizeDelta);
   }
 
   private PatchListEntry newEntry(RevTree aTree, FileHeader fileHeader,
-      long sizeDelta) {
+      long size, long sizeDelta) {
     final FileMode oldMode = fileHeader.getOldMode();
     final FileMode newMode = fileHeader.getNewMode();
 
     if (oldMode == FileMode.GITLINK || newMode == FileMode.GITLINK) {
       return new PatchListEntry(fileHeader, Collections.<Edit> emptyList(),
-          sizeDelta);
+          size, sizeDelta);
     }
 
     if (aTree == null // want combined diff
         || fileHeader.getPatchType() != PatchType.UNIFIED
         || fileHeader.getHunks().isEmpty()) {
       return new PatchListEntry(fileHeader, Collections.<Edit> emptyList(),
-          sizeDelta);
+          size, sizeDelta);
     }
 
     List<Edit> edits = fileHeader.toEditList();
     if (edits.isEmpty()) {
       return new PatchListEntry(fileHeader, Collections.<Edit> emptyList(),
-          sizeDelta);
+          size, sizeDelta);
     } else {
-      return new PatchListEntry(fileHeader, edits, sizeDelta);
+      return new PatchListEntry(fileHeader, edits, size, sizeDelta);
     }
   }