/* * Copyright 2017 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.jssrc.internal; import static com.google.template.soy.jssrc.dsl.CodeChunk.dottedIdNoRequire; import static com.google.template.soy.jssrc.dsl.CodeChunk.id; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.template.soy.base.SoyBackendKind; import com.google.template.soy.data.SanitizedContent.ContentKind; import com.google.template.soy.data.internalutils.NodeContentKinds; import com.google.template.soy.jssrc.dsl.CodeChunk; import com.google.template.soy.jssrc.dsl.GoogRequire; import com.google.template.soy.types.proto.Protos; import com.google.template.soy.types.proto.SoyProtoType; /** * Constants for commonly used js runtime functions and objects. * * <p>Unlike {@code JsExprUtils}, this is only intended for use by the compiler itself and deals * exclusively with the {@link CodeChunk} api. */ public final class JsRuntime { private static final GoogRequire GOOG_ARRAY = GoogRequire.create("goog.array"); private static final GoogRequire GOOG_ASSERTS = GoogRequire.create("goog.asserts"); private static final GoogRequire GOOG_STRING = GoogRequire.create("goog.string"); private static final GoogRequire SOY = GoogRequire.create("soy"); private static final GoogRequire SOY_ASSERTS = GoogRequire.create("soy.asserts"); private static final GoogRequire XID_REQUIRE = GoogRequire.create("xid"); private JsRuntime() {} public static final CodeChunk.WithValue GOOG_ARRAY_MAP = GOOG_ARRAY.reference().dotAccess("map"); public static final CodeChunk.WithValue GOOG_ASSERTS_ASSERT = GOOG_ASSERTS.reference().dotAccess("assert"); public static final CodeChunk.WithValue GOOG_DEBUG = dottedIdNoRequire("goog.DEBUG"); public static final CodeChunk.WithValue GOOG_GET_CSS_NAME = dottedIdNoRequire("goog.getCssName"); public static final CodeChunk.WithValue GOOG_GET_MSG = dottedIdNoRequire("goog.getMsg"); public static final CodeChunk.WithValue GOOG_IS_ARRAY = dottedIdNoRequire("goog.isArray"); public static final CodeChunk.WithValue GOOG_IS_BOOLEAN = dottedIdNoRequire("goog.isBoolean"); public static final CodeChunk.WithValue GOOG_IS_FUNCTION = dottedIdNoRequire("goog.isFunction"); public static final CodeChunk.WithValue GOOG_IS_NUMBER = dottedIdNoRequire("goog.isNumber"); public static final CodeChunk.WithValue GOOG_IS_OBJECT = dottedIdNoRequire("goog.isObject"); public static final CodeChunk.WithValue GOOG_IS_STRING = dottedIdNoRequire("goog.isString"); public static final CodeChunk.WithValue GOOG_REQUIRE = dottedIdNoRequire("goog.require"); public static final CodeChunk.WithValue GOOG_SOY_DATA_SANITIZED_CONTENT = GoogRequire.create("goog.soy.data.SanitizedContent").reference(); public static final CodeChunk.WithValue GOOG_STRING_UNESCAPE_ENTITIES = GOOG_STRING.dotAccess("unescapeEntities"); public static final CodeChunk.WithValue GOOG_I18N_MESSAGE_FORMAT = GoogRequire.create("goog.i18n.MessageFormat").reference(); public static final CodeChunk.WithValue SOY_ASSERTS_ASSERT_TYPE = SOY_ASSERTS.dotAccess("assertType"); public static final CodeChunk.WithValue SOY_ASSIGN_DEFAULTS = SOY.dotAccess("$$assignDefaults"); public static final CodeChunk.WithValue SOY_CHECK_MAP_KEY = SOY.dotAccess("$$checkMapKey"); public static final CodeChunk.WithValue SOY_CHECK_NOT_NULL = SOY.dotAccess("$$checkNotNull"); public static final CodeChunk.WithValue SOY_ESCAPE_HTML = SOY.dotAccess("$$escapeHtml"); public static final CodeChunk.WithValue SOY_GET_DELEGATE_FN = SOY.dotAccess("$$getDelegateFn"); public static final CodeChunk.WithValue SOY_REGISTER_DELEGATE_FN = SOY.dotAccess("$$registerDelegateFn"); public static final CodeChunk.WithValue SOY_GET_DELTEMPLATE_ID = SOY.dotAccess("$$getDelTemplateId"); public static final CodeChunk.WithValue WINDOW_CONSOLE_LOG = dottedIdNoRequire("window.console.log"); public static final CodeChunk.WithValue XID = XID_REQUIRE.reference(); /** A constant for the template parameter {@code opt_data}. */ public static final CodeChunk.WithValue OPT_DATA = id("opt_data"); /** A constant for the template parameter {@code opt_ijData}. */ public static final CodeChunk.WithValue OPT_IJ_DATA = id("opt_ijData"); /** Returns the field containing the extension object for the given field descriptor. */ public static CodeChunk.WithValue extensionField(FieldDescriptor desc) { String jsExtensionImport = Protos.getJsExtensionImport(desc); String jsExtensionName = Protos.getJsExtensionName(desc); return symbolWithNamespace(jsExtensionImport, jsExtensionName); } /** Returns a function that can 'unpack' safe proto types into sanitized content types.. */ public static CodeChunk.WithValue protoToSanitizedContentConverterFunction( Descriptor messageType) { return GoogRequire.create(NodeContentKinds.toJsUnpackFunction(messageType)).reference(); } /** Returns a function that can 'unpack' safe proto types into sanitized content types.. */ public static CodeChunk.WithValue sanitizedContentToProtoConverterFunction( Descriptor messageType) { return GoogRequire.create(NodeContentKinds.toJsPackFunction(messageType)).reference(); } /** * Returns an 'ordainer' function that can be used wrap a {@code string} in a {@code * SanitizedContent} object with no escaping. */ public static CodeChunk.WithValue sanitizedContentOrdainerFunction(ContentKind kind) { return symbolWithNamespace( NodeContentKinds.getJsImportForOrdainersFunctions(kind), NodeContentKinds.toJsSanitizedContentOrdainer(kind)); } /** * Returns an 'ordainer' function that can be used wrap a {@code string} in a {@code * SanitizedContent} object with no escaping. */ public static CodeChunk.WithValue sanitizedContentOrdainerFunctionForInternalBlocks( ContentKind kind) { return symbolWithNamespace( NodeContentKinds.getJsImportForOrdainersFunctions(kind), NodeContentKinds.toJsSanitizedContentOrdainerForInternalBlocks(kind)); } /** Returns the constructor for the proto. */ public static CodeChunk.WithValue protoConstructor(SoyProtoType type) { return GoogRequire.create(type.getNameForBackend(SoyBackendKind.JS_SRC)).reference(); } /** * Returns the js type for the sanitized content object corresponding to the given ContentKind. */ public static CodeChunk.WithValue sanitizedContentType(ContentKind kind) { return GoogRequire.create(NodeContentKinds.toJsSanitizedContentCtorName(kind)).reference(); } /** * Returns a code chunk that accesses the given symbol. * * @param requireSymbol The symbol to {@code goog.require} * @param fullyQualifiedSymbol The symbol we want to access. */ private static CodeChunk.WithValue symbolWithNamespace( String requireSymbol, String fullyQualifiedSymbol) { GoogRequire require = GoogRequire.create(requireSymbol); if (fullyQualifiedSymbol.equals(require.symbol())) { return require.reference(); } String ident = fullyQualifiedSymbol.substring(require.symbol().length() + 1); return require.dotAccess(ident); } }