Package com.google.template.soy.soyparse

Source Code of com.google.template.soy.soyparse.SoyFileSetParser

/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.template.soy.soyparse;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.template.soy.base.IdGenerator;
import com.google.template.soy.base.IncrementingIdGenerator;
import com.google.template.soy.base.SoyFileSupplier;
import com.google.template.soy.base.SoySyntaxException;
import com.google.template.soy.internal.base.Pair;
import com.google.template.soy.parsepasses.CheckCallsVisitor;
import com.google.template.soy.parsepasses.CheckDelegatesVisitor;
import com.google.template.soy.parsepasses.CheckOverridesVisitor;
import com.google.template.soy.parsepasses.ReplaceHasDataFunctionVisitor;
import com.google.template.soy.parsepasses.RewriteNullCoalescingOpVisitor;
import com.google.template.soy.parsepasses.RewriteRemainderNodesVisitor;
import com.google.template.soy.parsepasses.SetFullCalleeNamesVisitor;
import com.google.template.soy.parsepasses.VerifyPhnameAttrOnlyOnPlaceholdersVisitor;
import com.google.template.soy.sharedpasses.AssertSyntaxVersionV2Visitor;
import com.google.template.soy.sharedpasses.CheckSoyDocVisitor;
import com.google.template.soy.sharedpasses.RemoveHtmlCommentsVisitor;
import com.google.template.soy.soytree.SoyFileNode;
import com.google.template.soy.soytree.SoyFileSetNode;

import java.io.IOException;
import java.io.Reader;
import java.util.List;


/**
* Static functions for parsing a set of Soy files into a {@link SoyFileSetNode}.
*
* <p> Important: Do not use outside of Soy code (treat as superpackage-private).
*
* @author Kai Huang
*/
public class SoyFileSetParser {


  /** The suppliers of the Soy files to parse. */
  private final List<SoyFileSupplier> soyFileSuppliers;

  /** Whether to run initial parsing passes. */
  private boolean doRunInitialParsingPasses;

  /** Whether to run checking passes. */
  private boolean doRunCheckingPasses;

  /** Whether to enforce V2 syntax. */
  private boolean doEnforceSyntaxVersionV2;

  /** Whether to check overrides. */
  private boolean doCheckOverrides;


  /**
   * @param soyFileSuppliers The suppliers for the Soy files.
   */
  public SoyFileSetParser(SoyFileSupplier... soyFileSuppliers) {
    this(Lists.newArrayList(soyFileSuppliers));
  }


  /**
   * @param soyFileSuppliers The suppliers for the Soy files.
   */
  public SoyFileSetParser(List<SoyFileSupplier> soyFileSuppliers) {
    this.soyFileSuppliers = soyFileSuppliers;
    this.doRunInitialParsingPasses = true;
    this.doRunCheckingPasses = true;
    this.doEnforceSyntaxVersionV2 = true;
    this.doCheckOverrides = true;
  }


  /**
   * Sets whether to run initial parsing passes. Returns self.
   */
  public SoyFileSetParser setDoRunInitialParsingPasses(boolean doRunInitialParsingPasses) {
    this.doRunInitialParsingPasses = doRunInitialParsingPasses;
    if (! doRunInitialParsingPasses) {
      this.doRunCheckingPasses = false;
      this.doEnforceSyntaxVersionV2 = false;
      this.doCheckOverrides = false;
    }
    return this;
  }


  /**
   * Sets whether to run checking passes. Returns self.
   */
  public SoyFileSetParser setDoRunCheckingPasses(boolean doRunCheckingPasses) {
    this.doRunCheckingPasses = doRunCheckingPasses;
    if (doRunCheckingPasses) {
      Preconditions.checkState(doRunInitialParsingPasses);
    } else {
      this.doEnforceSyntaxVersionV2 = false;
      this.doCheckOverrides = false;
    }
    return this;
  }


  /**
   * Sets whether to enforce V2 syntax. Returns self.
   */
  public SoyFileSetParser setDoEnforceSyntaxVersionV2(boolean doEnforceSyntaxVersionV2) {
    this.doEnforceSyntaxVersionV2 = doEnforceSyntaxVersionV2;
    if (doEnforceSyntaxVersionV2) {
      Preconditions.checkState(doRunCheckingPasses);
    }
    return this;
  }


  /**
   * Sets whether to check overrides. Returns self.
   */
  public SoyFileSetParser setDoCheckOverrides(boolean doCheckOverrides) {
    this.doCheckOverrides = doCheckOverrides;
    if (doCheckOverrides) {
      Preconditions.checkState(doRunCheckingPasses);
    }
    return this;
  }


  /**
   * Parses a set of Soy files and returns the parse tree.
   *
   * @return The resulting parse tree.
   * @throws SoySyntaxException If there is an error reading the file or a syntax error is found.
   */
  public SoyFileSetNode parse() throws SoySyntaxException {
    return parseWithVersions().first;
  }


  /**
   * Parses a set of Soy files and returns the parse tree and versions of the files.
   *
   * @return The resulting parse tree and the versions of the files read.
   * @throws SoySyntaxException If there is an error reading the file or a syntax error is found.
   */
  public Pair<SoyFileSetNode, List<SoyFileSupplier.Version>> parseWithVersions()
      throws SoySyntaxException {

    IdGenerator nodeIdGen = new IncrementingIdGenerator();
    SoyFileSetNode soyTree = new SoyFileSetNode(nodeIdGen.genId(), nodeIdGen);
    ImmutableList.Builder<SoyFileSupplier.Version> versions = ImmutableList.builder();

    for (SoyFileSupplier soyFileSupplier : soyFileSuppliers) {
      Pair<SoyFileNode, SoyFileSupplier.Version> fileAndVersion =
          parseSoyFileHelper(soyFileSupplier, nodeIdGen);
      soyTree.addChild(fileAndVersion.first);
      versions.add(fileAndVersion.second);
    }

    // Run passes that are considered part of initial parsing.
    if (doRunInitialParsingPasses) {
      (new ReplaceHasDataFunctionVisitor()).exec(soyTree);
      (new RewriteNullCoalescingOpVisitor()).exec(soyTree);
      (new RewriteRemainderNodesVisitor()).exec(soyTree);
      (new SetFullCalleeNamesVisitor()).exec(soyTree);

      // Run passes that check the tree.
      if (doRunCheckingPasses) {
        runCheckingPasses(soyTree);
      }
    }

    return Pair.of(soyTree, (List<SoyFileSupplier.Version>) versions.build());
  }


  /**
   * Private helper for {@code parseWithVersions()} to parse one Soy file.
   *
   * @param soyFileSupplier Supplier of the Soy file content and path.
   * @param nodeIdGen The generator of node ids.
   * @return The resulting parse tree for one Soy file and the version from which it was parsed.
   * @throws SoySyntaxException If there is an error reading the file or a syntax error is found.
   */
  private static Pair<SoyFileNode, SoyFileSupplier.Version> parseSoyFileHelper(
      SoyFileSupplier soyFileSupplier, IdGenerator nodeIdGen)
      throws SoySyntaxException {

    String filePath = soyFileSupplier.getFilePath();

    Reader soyFileReader;
    SoyFileSupplier.Version version;
    try {
      Pair<Reader, SoyFileSupplier.Version> readerAndVersion = soyFileSupplier.open();
      soyFileReader = readerAndVersion.first;
      version = readerAndVersion.second;
    } catch (IOException ioe) {
      throw SoySyntaxException.createWithoutMetaInfo(
          "Error opening Soy file " + filePath + ": " + ioe);
    }

    try {
      SoyFileNode soyFile =
          (new SoyFileParser(soyFileReader, soyFileSupplier.getSoyFileKind(), filePath, nodeIdGen))
              .parseSoyFile();
      if (soyFileSupplier.hasChangedSince(version)) {
        throw SoySyntaxException.createWithoutMetaInfo("Version skew in Soy file " + filePath);
      }
      return Pair.of(soyFile, version);

    } catch (TokenMgrError tme) {
      throw SoySyntaxException.createCausedWithMetaInfo(
          null, tme, null, soyFileSupplier.getFilePath(), null);
    } catch (ParseException pe) {
      throw SoySyntaxException.createCausedWithMetaInfo(
          null, pe, null, soyFileSupplier.getFilePath(), null);
    } catch (SoySyntaxException sse) {
      throw sse.associateMetaInfo(null, soyFileSupplier.getFilePath(), null);

    } finally {
      // Close the Reader.
      try {
        soyFileReader.close();
      } catch (IOException ioe) {
        throw SoySyntaxException.createWithoutMetaInfo(
            "Error closing Soy file " + soyFileSupplier.getFilePath() + ": " + ioe);
      }
    }
  }


  /**
   * Private helper for {@code parseWithVersions()} to run checking passes.
   */
  private void runCheckingPasses(SoyFileSetNode soyTree) {

    if (doEnforceSyntaxVersionV2) {
      (new AssertSyntaxVersionV2Visitor()).exec(soyTree);
    } else {
      (new RemoveHtmlCommentsVisitor()).exec(soyTree);
    }
    (new VerifyPhnameAttrOnlyOnPlaceholdersVisitor()).exec(soyTree);
    (new CheckSoyDocVisitor(doEnforceSyntaxVersionV2)).exec(soyTree);
    if (doCheckOverrides) {
      (new CheckOverridesVisitor()).exec(soyTree);
    }
    (new CheckDelegatesVisitor()).exec(soyTree);
    (new CheckCallsVisitor()).exec(soyTree);
  }

}
TOP

Related Classes of com.google.template.soy.soyparse.SoyFileSetParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.