Fix MarkdownRenderer to accept templates that are not built-in resources

PiperOrigin-RevId: 259413791
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
index 1bbbe5c..8334f69 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/MarkdownRenderer.java
@@ -14,11 +14,20 @@
 
 package com.google.devtools.build.skydoc.rendering;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
 import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.UserDefinedFunctionInfo;
+import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
 import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.apache.velocity.exception.MethodInvocationException;
@@ -31,7 +40,7 @@
  * Produces skydoc output in markdown form.
  */
 public class MarkdownRenderer {
-
+  // TODO(kendalllane): Refactor MarkdownRenderer to take in something other than filepaths.
   private final String headerTemplateFilename;
   private final String ruleTemplateFilename;
   private final String providerTemplateFilename;
@@ -48,7 +57,7 @@
     this.ruleTemplateFilename = ruleTemplate;
     this.providerTemplateFilename = providerTemplate;
     this.functionTemplateFilename = functionTemplate;
-
+    
     this.velocityEngine = new VelocityEngine();
     velocityEngine.setProperty("resource.loader", "classpath, jar");
     velocityEngine.setProperty("classpath.resource.loader.class",
@@ -65,9 +74,9 @@
    */
   public String renderMarkdownHeader() throws IOException {
     StringWriter stringWriter = new StringWriter();
+    Reader reader = readerFromPath(headerTemplateFilename);
     try {
-      velocityEngine.mergeTemplate(
-          headerTemplateFilename, "UTF-8", new VelocityContext(), stringWriter);
+      velocityEngine.evaluate(new VelocityContext(), stringWriter, headerTemplateFilename, reader);
     } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
       throw new IOException(e);
     }
@@ -85,8 +94,9 @@
     context.put("ruleInfo", ruleInfo);
 
     StringWriter stringWriter = new StringWriter();
+    Reader reader = readerFromPath(ruleTemplateFilename);
     try {
-      velocityEngine.mergeTemplate(ruleTemplateFilename, "UTF-8", context, stringWriter);
+      velocityEngine.evaluate(context, stringWriter, ruleTemplateFilename, reader);
     } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
       throw new IOException(e);
     }
@@ -104,8 +114,9 @@
     context.put("providerInfo", providerInfo);
 
     StringWriter stringWriter = new StringWriter();
+    Reader reader = readerFromPath(providerTemplateFilename);
     try {
-      velocityEngine.mergeTemplate(providerTemplateFilename, "UTF-8", context, stringWriter);
+      velocityEngine.evaluate(context, stringWriter, providerTemplateFilename, reader);
     } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
       throw new IOException(e);
     }
@@ -122,11 +133,30 @@
     context.put("funcInfo", functionInfo);
 
     StringWriter stringWriter = new StringWriter();
+    Reader reader = readerFromPath(functionTemplateFilename);
     try {
-      velocityEngine.mergeTemplate(functionTemplateFilename, "UTF-8", context, stringWriter);
+      velocityEngine.evaluate(context, stringWriter, functionTemplateFilename, reader);
     } catch (ResourceNotFoundException | ParseErrorException | MethodInvocationException e) {
       throw new IOException(e);
     }
     return stringWriter.toString();
   }
+
+  /**
+   * Returns a reader from the given path.
+   *
+   * @param filePath The given path, either a filesystem path or a java Resource
+   */
+  private static Reader readerFromPath(String filePath) throws IOException {
+    if (Files.exists(Paths.get(filePath))) {
+      Path path = Paths.get(filePath);
+      return Files.newBufferedReader(path);
+    }
+
+    InputStream inputStream = MarkdownRenderer.class.getClassLoader().getResourceAsStream(filePath);
+    if (inputStream == null) {
+      throw new FileNotFoundException(filePath + " was not found as a resource.");
+    }
+    return new InputStreamReader(inputStream, UTF_8);
+  }
 }