Ensure RevTag is parsed before using its body

Ideally these methods in RevTag should be calling parseBody.  As a
stopgap, we can do it ourselves.

No visible change intended.  This is intended as preparation for
callers to be able to use setRetainBody(false).

Change-Id: I2e9e4d3550156ea5d77f5624ab35f3ab66bea6e5
diff --git a/java/com/google/gitiles/LogServlet.java b/java/com/google/gitiles/LogServlet.java
index 0dd00f3..6982e0a 100644
--- a/java/com/google/gitiles/LogServlet.java
+++ b/java/com/google/gitiles/LogServlet.java
@@ -110,7 +110,7 @@
         List<Map<String, Object>> tags = Lists.newArrayListWithExpectedSize(1);
         for (RevObject o : RevisionServlet.listObjects(paginator.getWalk(), view.getRevision())) {
           if (o instanceof RevTag) {
-            tags.add(new TagSoyData(linkifier, req).toSoyData((RevTag) o, df));
+            tags.add(new TagSoyData(linkifier, req).toSoyData(paginator.getWalk(), (RevTag) o, df));
           }
         }
         if (!tags.isEmpty()) {
diff --git a/java/com/google/gitiles/RevisionServlet.java b/java/com/google/gitiles/RevisionServlet.java
index 17ad143..597c053 100644
--- a/java/com/google/gitiles/RevisionServlet.java
+++ b/java/com/google/gitiles/RevisionServlet.java
@@ -122,7 +122,7 @@
                       "type",
                       Constants.TYPE_TAG,
                       "data",
-                      new TagSoyData(linkifier, req).toSoyData((RevTag) obj, df)));
+                      new TagSoyData(linkifier, req).toSoyData(walk, (RevTag) obj, df)));
               break;
             default:
               log.warn("Bad object type for {}: {}", ObjectId.toString(obj.getId()), obj.getType());
diff --git a/java/com/google/gitiles/TagSoyData.java b/java/com/google/gitiles/TagSoyData.java
index 831cb8e..32b319a 100644
--- a/java/com/google/gitiles/TagSoyData.java
+++ b/java/com/google/gitiles/TagSoyData.java
@@ -15,10 +15,13 @@
 package com.google.gitiles;
 
 import com.google.common.collect.Maps;
+import java.io.IOException;
 import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
+import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
 
 /** Soy data converter for git tags. */
 public class TagSoyData {
@@ -30,7 +33,10 @@
     this.req = req;
   }
 
-  public Map<String, Object> toSoyData(RevTag tag, DateFormatter df) {
+  public Map<String, Object> toSoyData(RevWalk walk, RevTag tag, DateFormatter df)
+      throws MissingObjectException, IOException {
+    walk.parseBody(tag);
+
     Map<String, Object> data = Maps.newHashMapWithExpectedSize(4);
     data.put("sha", ObjectId.toString(tag));
     if (tag.getTaggerIdent() != null) {
diff --git a/java/com/google/gitiles/TimeCache.java b/java/com/google/gitiles/TimeCache.java
index a019d0f..e1e55ce 100644
--- a/java/com/google/gitiles/TimeCache.java
+++ b/java/com/google/gitiles/TimeCache.java
@@ -60,6 +60,8 @@
           () -> {
             RevObject o = walk.parseAny(id);
             while (o instanceof RevTag) {
+              walk.parseBody(o);
+
               RevTag tag = (RevTag) o;
               PersonIdent ident = tag.getTaggerIdent();
               if (ident != null) {