<commit_before>/*
 * Copyright 2010 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.parsepasses.contextautoesc;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Ascii;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.errorprone.annotations.Immutable;
import com.google.template.soy.base.internal.SanitizedContentKind;
import com.google.template.soy.soytree.EscapingMode;
import com.google.template.soy.soytree.HtmlAttributeNode;
import com.google.template.soy.soytree.HtmlContext;
import com.google.template.soy.soytree.HtmlTagNode;
import com.google.template.soy.soytree.PrintDirectiveNode;
import com.google.template.soy.soytree.SoyNode;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.regex.Pattern;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;

/**
 * Encapsulates the context in which a Soy node appears. This helps us distinguish Soy nodes that
 * can only be preceded by fully formed HTML tags and text chunks from ones that appear inside
 * JavaScript, from ones that appear inside URIs, etc.
 *
 * <p>This is an immutable bit-packable struct that contains a number of enums. These enums have
 * their own nullish values like {@link Context.ElementType#NONE} so should always be non-null.
 *
 * <p>The contextual autoescape rewriter propagates contexts so that it can infer an appropriate
 * {@link EscapingMode escaping function} for each <code>{print ...}</code> command.
 *
 * <p>To make sure it can correctly identify a unique escape convention for all paths to a
 * particular print command, it may clone a template for each context in which it is called, using
 * the {@link Context#packedBits bitpacked} form of the context to generate a unique template name.
 *
 */
@Immutable
public final class Context {

  /**
   * List of link types (values of the <link rel=...> attribute) for which the link is a regular
   * URL, and not a trusted resource URL. Most of these values are described at
   * https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types
   */
  private static final ImmutableSet<String> REGULAR_LINK_REL_VALUES =
      ImmutableSet.of(
          "alternate",
          "amphtml",
          "apple-touch-icon",
          "apple-touch-icon-precomposed",
          "apple-touch-startup-image",
          "author",
          "bookmark",
          "canonical",
          "cite",
          "dns-prefetch",
          "help",
          "icon",
          "license",
          "next",
          "prefetch",
          "preload",
          "prerender",
          "prev",
          "search",
          "shortcut",
          "subresource",
          "tag");

  /** Whitespace-separated sequence of regular link types. */
  private static final Pattern REGULAR_LINK_PATTERN =
      Pattern.compile(
          "((^|\\s+)(" + Joiner.on("|").join(REGULAR_LINK_REL_VALUES) + "))*\\s*",
          Pattern.CASE_INSENSITIVE);

  /** The state the text preceding the context point describes. */
  public final HtmlContext state;

  /**
   * Describes the innermost element that the text preceding the context point is in. An element is
   * considered entered once its name has been seen in the start tag and is considered closed once
   * the name of its end tag is seen. E.g. the open point is marked with O below and C marks the
   * close point.
   *<commit_msg>Add preconnect to list of <link> attributes which accept regular link URLs<commit_after>/*
 * Copyright 2010 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.parsepasses.contextautoesc;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Ascii;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.errorprone.annotations.Immutable;
import com.google.template.soy.base.internal.SanitizedContentKind;
import com.google.template.soy.soytree.EscapingMode;
import com.google.template.soy.soytree.HtmlAttributeNode;
import com.google.template.soy.soytree.HtmlContext;
import com.google.template.soy.soytree.HtmlTagNode;
import com.google.template.soy.soytree.PrintDirectiveNode;
import com.google.template.soy.soytree.SoyNode;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.regex.Pattern;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;

/**
 * Encapsulates the context in which a Soy node appears. This helps us distinguish Soy nodes that
 * can only be preceded by fully formed HTML tags and text chunks from ones that appear inside
 * JavaScript, from ones that appear inside URIs, etc.
 *
 * <p>This is an immutable bit-packable struct that contains a number of enums. These enums have
 * their own nullish values like {@link Context.ElementType#NONE} so should always be non-null.
 *
 * <p>The contextual autoescape rewriter propagates contexts so that it can infer an appropriate
 * {@link EscapingMode escaping function} for each <code>{print ...}</code> command.
 *
 * <p>To make sure it can correctly identify a unique escape convention for all paths to a
 * particular print command, it may clone a template for each context in which it is called, using
 * the {@link Context#packedBits bitpacked} form of the context to generate a unique template name.
 *
 */
@Immutable
public final class Context {

  /**
   * List of link types (values of the <link rel=...> attribute) for which the link is a regular
   * URL, and not a trusted resource URL. Most of these values are described at
   * https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types
   */
  private static final ImmutableSet<String> REGULAR_LINK_REL_VALUES =
      ImmutableSet.of(
          "alternate",
          "amphtml",
          "apple-touch-icon",
          "apple-touch-icon-precomposed",
          "apple-touch-startup-image",
          "author",
          "bookmark",
          "canonical",
          "cite",
          "dns-prefetch",
          "help",
          "icon",
          "license",
          "next",
          "preconnect",
          "prefetch",
          "preload",
          "prerender",
          "prev",
          "search",
          "shortcut",
          "subresource",
          "tag");

  /** Whitespace-separated sequence of regular link types. */
  private static final Pattern REGULAR_LINK_PATTERN =
      Pattern.compile(
          "((^|\\s+)(" + Joiner.on("|").join(REGULAR_LINK_REL_VALUES) + "))*\\s*",
          Pattern.CASE_INSENSITIVE);

  /** The state the text preceding the context point describes. */
  public final HtmlContext state;

  /**
   * Describes the innermost element that the text preceding the context point is in. An element is
   * considered entered once its name has been seen in the start tag and is considered closed once
   * the name of its end tag is seen. E.g. the open point is marked with O below and C marks the
   * close point.
   *
{'fraction_non_alphanumeric': 0.09413773477518497, 'fraction_numerical': 0.001821286283437678, 'mean_word_length': 3.3864203694458315, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7152303', 'n_tokens_mistral': 2484, 'n_tokens_neox': 2430, 'n_words': 866}