/*
* Copyright 2015 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.soytree;
import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.template.soy.base.SourceLocation;
import com.google.template.soy.base.internal.Identifier;
import com.google.template.soy.error.ErrorReporter;
import java.util.List;
import javax.annotation.Nullable;
/** A {@code {namespace ..}} declaration. */
public final class NamespaceDeclaration {
/** The default autoescape mode if none is specified in the command text. */
private static final AutoescapeMode DEFAULT_FILE_WIDE_DEFAULT_AUTOESCAPE_MODE =
AutoescapeMode.STRICT;
private final Identifier namespace;
@Nullable private final AutoescapeMode autoescapeMode;
@Nullable private final SourceLocation autoescapeModeLocation;
private final ImmutableList<String> requiredCssNamespaces;
private final String cssBaseNamespace;
private final StrictHtmlMode strictHtml;
@Nullable private final SourceLocation strictHtmlLocation;
final ImmutableList<CommandTagAttribute> attrs;
public NamespaceDeclaration(
Identifier namespace, List<CommandTagAttribute> attrs, ErrorReporter errorReporter) {
AutoescapeMode autoescapeMode = null;
SourceLocation autoescapeModeLocation = null;
ImmutableList<String> requiredCssNamespaces = ImmutableList.of();
String cssBaseNamespace = null;
StrictHtmlMode strictHtml = StrictHtmlMode.UNSET;
SourceLocation strictHtmlLocation = null;
for (CommandTagAttribute attr : attrs) {
switch (attr.getName().identifier()) {
case "autoescape":
autoescapeMode = attr.valueAsAutoescapeMode(errorReporter);
autoescapeModeLocation = attr.getValueLocation();
break;
case "requirecss":
requiredCssNamespaces = attr.valueAsRequireCss(errorReporter);
break;
case "cssbase":
cssBaseNamespace = attr.getValue();
break;
case "stricthtml":
strictHtml = attr.valueAsStrictHtmlMode(errorReporter);
strictHtmlLocation = attr.getValueLocation();
break;
default:
errorReporter.report(
attr.getName().location(),
CommandTagAttribute.UNSUPPORTED_ATTRIBUTE_KEY,
attr.getName().identifier(),
ImmutableList.of("autoescape", "cssbase", "requirecss", "stricthtml"));
break;
}
}
this.namespace = namespace;
this.autoescapeMode = autoescapeMode;
this.autoescapeModeLocation = autoescapeModeLocation;
this.requiredCssNamespaces = requiredCssNamespaces;
this.cssBaseNamespace = cssBaseNamespace;
this.strictHtml = strictHtml;
this.strictHtmlLocation = strictHtmlLocation;
this.attrs = ImmutableList.copyOf(attrs);
}
public AutoescapeMode getDefaultAutoescapeMode() {
return autoescapeMode == null ? DEFAULT_FILE_WIDE_DEFAULT_AUTOESCAPE_MODE : autoescapeMode;
}
/**
* Returns the location of {@code autoescape} attribute.
*
* @throws IllegalStateException if there is no autoescape attribute.
*/
public SourceLocation getAutoescapeModeLocation() {
checkState(autoescapeModeLocation != null, "there is no autoescape attribute");
return autoescapeModeLocation;
}
public String getNamespace() {
return namespace.identifier();
}
ImmutableList<String> getRequiredCssNamespaces() {
return requiredCssNamespaces;
}
@Nullable
String getCssBaseNamespace() {
return cssBaseNamespace;
}
public StrictHtmlMode getStrictHtmlMode() {
return strictHtml;
}
/**
* Returns the location of {@code stricthtml} attribute.
*
* @throws IllegalStateException if there is no attribute.
*/
public SourceLocation getStrictHtmlModeLocation() {
checkState(strictHtmlLocation != null, "there is no stricthtml attribute");
return strictHtmlLocation;
}
/** Returns an approximation of what the original source for this namespace looked like. */
public String toSourceString() {
return "{namespace "
+ namespace.identifier()
+ (attrs.isEmpty() ? "" : " " + Joiner.on(' ').join(attrs))
+ "}\n";
}
}