Skip to content

Commit

Permalink
No public description
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 709168906
  • Loading branch information
lukesandberg authored and copybara-github committed Dec 23, 2024
1 parent d8424a2 commit 735c277
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,13 @@ public abstract LoggingAdvisingAppendable append(CharSequence csq, int start, in
public abstract LoggingAdvisingAppendable exitLoggableElement();

/** Flushes all pending logging attributes. */
public final LoggingAdvisingAppendable flushPendingLoggingAttributes() {
// TODO(b/383661457): Implement this.
return this;
public final LoggingAdvisingAppendable flushPendingLoggingAttributes(boolean isAnchor)
throws IOException {
return appendLoggingFunctionInvocation(
isAnchor
? LoggingFunctionInvocation.FLUSH_PENDING_ATTRIBUTES_FOR_ANCHOR
: LoggingFunctionInvocation.FLUSH_PENDING_ATTRIBUTES_FOR_NON_ANCHOR,
ImmutableList.of());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package com.google.template.soy.data;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.template.soy.data.restricted.BooleanData;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
Expand All @@ -24,12 +26,31 @@
/** The result of executing the logging function. */
@AutoValue
public abstract class LoggingFunctionInvocation {
static final LoggingFunctionInvocation FLUSH_PENDING_ATTRIBUTES_FOR_ANCHOR =
new AutoValue_LoggingFunctionInvocation(
"$$flushPendingAttributes",
"",
ImmutableList.of(BooleanData.FALSE),
/* isFlushPendingAttributes= */ true,
Optional.<Consumer<String>>empty());

static final LoggingFunctionInvocation FLUSH_PENDING_ATTRIBUTES_FOR_NON_ANCHOR =
new AutoValue_LoggingFunctionInvocation(
"$$flushPendingAttributes",
"",
ImmutableList.of(BooleanData.FALSE),
/* isFlushPendingAttributes= */ true,
Optional.<Consumer<String>>empty());

@Nonnull
public static LoggingFunctionInvocation create(
String functionName, String placeholderValue, List<SoyValue> args) {
return new AutoValue_LoggingFunctionInvocation(
functionName, placeholderValue, args, Optional.<Consumer<String>>empty());
functionName,
placeholderValue,
args,
/* isFlushPendingAttributes= */ false,
Optional.<Consumer<String>>empty());
}

/**
Expand All @@ -46,6 +67,14 @@ public static LoggingFunctionInvocation create(
*/
public abstract List<SoyValue> args();

/**
* Returns whether the function is a special case that should flush pending attributes.
*
* <p>This is a special case for the {@code $$flushPendingAttributes} function. User logger
* implementations should never see this set to true.
*/
public abstract boolean isFlushPendingAttributes();

/**
* When set, informs the ultimate logger that the content should be sent to the consumer instead
* of the output.
Expand All @@ -55,11 +84,15 @@ public static LoggingFunctionInvocation create(
/** Returns a new invocation that will send the result to the given consumer. */
LoggingFunctionInvocation withResultConsumer(Consumer<String> resultConsumer) {
if (resultConsumer().isPresent()) {
// There is no known usecase where multiple consumers are needed. If they are it is trivial
// to compose `Consumer` objects via `Consumer.andThen
// There is no known use case where multiple consumers are needed. If we discover one then we
// can compose `Consumer` objects via `Consumer.andThen`.
throw new IllegalStateException("resultConsumer already set");
}
return new AutoValue_LoggingFunctionInvocation(
functionName(), placeholderValue(), args(), Optional.of(resultConsumer));
functionName(),
placeholderValue(),
args(),
isFlushPendingAttributes(),
Optional.of(resultConsumer));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ static Statement concat(List<Statement> statements) {
MethodRef.createNonPure(LoggingAdvisingAppendable.class, "flushBuffers", int.class);

private static final MethodRef FLUSH_PENDING_LOGGING_ATTRBIUTES =
MethodRef.createNonPure(LoggingAdvisingAppendable.class, "flushPendingLoggingAttributes");
MethodRef.createNonPure(
LoggingAdvisingAppendable.class, "flushPendingLoggingAttributes", boolean.class);

static AppendableExpression forExpression(Expression delegate) {
return new AppendableExpression(delegate, e -> e, /* supportsSoftLimiting= */ true);
Expand Down Expand Up @@ -271,8 +272,8 @@ AppendableExpression setSanitizedContentKindAndDirectionality(SanitizedContentKi
BytecodeUtils.constantSanitizedContentKindAsContentKind(kind)));
}

AppendableExpression flushPendingLoggingAttributes() {
return withNewDelegate(e -> e.invoke(FLUSH_PENDING_LOGGING_ATTRBIUTES));
AppendableExpression flushPendingLoggingAttributes(boolean isAnchor) {
return withNewDelegate(e -> e.invoke(FLUSH_PENDING_LOGGING_ATTRBIUTES, constant(isAnchor)));
}

Statement flushBuffers(int depth) {
Expand Down
8 changes: 5 additions & 3 deletions java/src/com/google/template/soy/jbcsrc/SoyNodeCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ private Optional<Statement> tryCompileSwitchToSwitchInstruction(
asSwitchableInt(switchExpr, casesByKey.navigableKeySet()), casesByKey, defaultBlock));

} else {
// Otherwise we need more complex matching logic that we outsource to an invoke dyanmic
// Otherwise we need more complex matching logic that we outsource to an invoke dynamic
// bootstrap. Create a fake key for each case and then rely on the bootstrap to figure it
// out.
// update the map with the pseudo keys, so that the loops below can find them
Expand Down Expand Up @@ -843,7 +843,9 @@ protected Statement visitPrintNode(PrintNode node) {
return visitLoggingFunction(node, fn, (LoggingFunction) fn.getSoyFunction());
}
if (fn.getSoyFunction() == BuiltinFunction.FLUSH_PENDING_LOGGING_ATTRIBUTES) {
return appendableExpression.flushPendingLoggingAttributes().toStatement();
return appendableExpression
.flushPendingLoggingAttributes(((BooleanNode) fn.getParams().get(0)).getValue())
.toStatement();
}
}
// First check our special case where all print directives are streamable and an expression that
Expand Down Expand Up @@ -1049,7 +1051,7 @@ protected Statement visitRawTextNode(RawTextNode node) {

@Override
protected Statement visitDebuggerNode(DebuggerNode node) {
// Call JbcSrcRuntime.debuggger. This logs a stack trace by default and is an obvious place to
// Call JbcSrcRuntime.debugger. This logs a stack trace by default and is an obvious place to
// put a breakpoint.
return MethodRefs.RUNTIME_DEBUGGER.invokeVoid(
constant(node.getSourceLocation().getFilePath().path()),
Expand Down
22 changes: 15 additions & 7 deletions java/src/com/google/template/soy/jbcsrc/api/OutputAppendable.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,18 @@ public LoggingAdvisingAppendable appendLoggingFunctionInvocation(
LoggingFunctionInvocation funCall, ImmutableList<Function<String, String>> escapers)
throws IOException {
if (!isLogOnly()) {
String value =
logger == null ? funCall.placeholderValue() : logger.evalLoggingFunction(funCall);
String value;
if (logger == null) {
value = funCall.placeholderValue();
} else {
if (funCall.isFlushPendingAttributes()) {
// For now, just no-op these calls.
// TODO-b/383661457: implement this.
value = "";
} else {
value = logger.evalLoggingFunction(funCall);
}
}
for (Function<String, String> directive : escapers) {
value = directive.apply(value);
}
Expand All @@ -115,7 +125,9 @@ public LoggingAdvisingAppendable appendLoggingFunctionInvocation(
if (consumer.isPresent()) {
consumer.get().accept(value);
} else {
outputAppendable.append(value);
if (!value.isEmpty()) {
outputAppendable.append(value);
}
}
}
return this;
Expand Down Expand Up @@ -159,10 +171,6 @@ public LoggingAdvisingAppendable exitLoggableElement() {
return this;
}

@Override
public void flushBuffers(int depth) {
throw new AssertionError("shouldn't be called");
}

private void appendDebugOutput(Optional<SafeHtml> veDebugOutput) {
if (veDebugOutput.isPresent()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.google.template.soy.base.internal.IdGenerator;
import com.google.template.soy.base.internal.Identifier;
import com.google.template.soy.error.ErrorReporter;
import com.google.template.soy.exprtree.BooleanNode;
import com.google.template.soy.exprtree.ExprNode;
import com.google.template.soy.exprtree.FunctionNode;
import com.google.template.soy.shared.internal.BuiltinFunction;
import com.google.template.soy.soytree.HtmlAttributeNode;
Expand Down Expand Up @@ -92,6 +94,7 @@ private void instrumentNode(IdGenerator nodeIdGen, HtmlOpenTagNode openTag) {
BuiltinFunction.FLUSH_PENDING_LOGGING_ATTRIBUTES.name(), SourceLocation.UNKNOWN),
BuiltinFunction.FLUSH_PENDING_LOGGING_ATTRIBUTES,
SourceLocation.UNKNOWN);
functionCall.addChild(getTagIsAnchorNode(openTag));
functionCall.setType(AttributesType.getInstance());
var printNode =
new PrintNode(
Expand All @@ -111,4 +114,12 @@ private void instrumentNode(IdGenerator nodeIdGen, HtmlOpenTagNode openTag) {
attributeNode.addChild(printNode);
openTag.addChild(attributeNode);
}

private static ExprNode getTagIsAnchorNode(HtmlOpenTagNode openTag) {
var tagName = openTag.getTagName();
return new BooleanNode(
// If the tag is dynamic we assume it isn't an anchor
tagName.isStatic() && tagName.getStaticTagNameAsLowerCase().equals("a"),
tagName.getTagLocation());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.template.soy.shared.restricted.SoyFunction;
import com.google.template.soy.types.AnyType;
import com.google.template.soy.types.BoolType;
import com.google.template.soy.types.IterableType;
import com.google.template.soy.types.NullType;
import com.google.template.soy.types.SanitizedType;
Expand Down Expand Up @@ -93,7 +94,6 @@ public Set<Integer> getValidArgsSizes() {
case IS_PRIMARY_MSG_IN_USE:
return ImmutableSet.of(3);
case DEBUG_SOY_TEMPLATE_INFO:
case FLUSH_PENDING_LOGGING_ATTRIBUTES:
return ImmutableSet.of(0);
case SOY_SERVER_KEY:
case CHECK_NOT_NULL:
Expand All @@ -110,6 +110,7 @@ public Set<Integer> getValidArgsSizes() {
case IS_TRUTHY_NON_EMPTY:
case HAS_CONTENT:
case NEW_SET:
case FLUSH_PENDING_LOGGING_ATTRIBUTES:
return ImmutableSet.of(1);
case PROTO_INIT:
throw new UnsupportedOperationException();
Expand All @@ -135,6 +136,8 @@ public Optional<List<SoyType>> getValidArgTypes() {
StringType.getInstance(),
NullType.getInstance(),
UndefinedType.getInstance())));
case FLUSH_PENDING_LOGGING_ATTRIBUTES:
return Optional.of(ImmutableList.of(BoolType.getInstance()));
case NEW_SET:
// This is further constrained in ResolveExpressionTypesPass.
return Optional.of(ImmutableList.of(IterableType.of(AnyType.getInstance())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import com.google.template.soy.data.SoyRecord;
import com.google.template.soy.data.SoyValueConverter;
import com.google.template.soy.data.SoyValueConverterUtility;
import com.google.template.soy.data.SoyValueProvider;
import com.google.template.soy.data.internal.ParamStore;
import com.google.template.soy.error.ErrorReporter;
import com.google.template.soy.jbcsrc.restricted.BytecodeUtils;
Expand Down

0 comments on commit 735c277

Please sign in to comment.