Search in sources :

Example 1 with SoyProtoType

use of com.google.template.soy.types.SoyProtoType in project closure-templates by google.

the class JsType method forSoyType.

/**
 * Returns a {@link JsType} corresponding to the given {@link SoyType}
 *
 * <p>TODO(lukes): consider adding a cache for all the computed types. The same type is probably
 * accessed many many times.
 *
 * @param soyType the soy type
 * @param isIncrementalDom whether or not this is for incremental dom.
 */
static JsType forSoyType(SoyType soyType, boolean isIncrementalDom) {
    switch(soyType.getKind()) {
        case NULL:
            return NULL_OR_UNDEFINED_TYPE;
        case ANY:
            return ANY_TYPE;
        case UNKNOWN:
            return UNKNOWN_TYPE;
        case BOOL:
            return BOOLEAN_TYPE;
        case PROTO_ENUM:
            SoyProtoEnumType enumType = (SoyProtoEnumType) soyType;
            String enumTypeName = enumType.getNameForBackend(SoyBackendKind.JS_SRC);
            return builder().addType("number").addType(enumTypeName).addRequire(GoogRequire.create(enumTypeName)).setPredicate(GOOG_IS_NUMBER).build();
        case FLOAT:
        case INT:
            return NUMBER_TYPE;
        case STRING:
            return STRING_OR_UNSANITIZED_TEXT;
        case ATTRIBUTES:
            if (isIncrementalDom) {
                // idom has a different strategy for handling these
                return IDOM_ATTRIBUTES;
            }
        // fall through
        case HTML:
            if (isIncrementalDom) {
                // idom has a different strategy for handling these
                return IDOM_HTML;
            }
        // fall-through
        case CSS:
        case JS:
        case URI:
        case TRUSTED_RESOURCE_URI:
            return STRICT_TYPES.get(((SanitizedType) soyType).getContentKind());
        case LIST:
            ListType listType = (ListType) soyType;
            if (listType.getElementType().getKind() == SoyType.Kind.ANY) {
                return RAW_ARRAY_TYPE;
            }
            JsType element = forSoyType(listType.getElementType(), isIncrementalDom);
            return builder().addType("!Array<" + element.typeExpr() + ">").addRequires(element.getGoogRequires()).setPredicate(GOOG_IS_ARRAY).build();
        case LEGACY_OBJECT_MAP:
            {
                LegacyObjectMapType mapType = (LegacyObjectMapType) soyType;
                if (mapType.getKeyType().getKind() == SoyType.Kind.ANY && mapType.getValueType().getKind() == SoyType.Kind.ANY) {
                    return RAW_OBJECT_TYPE;
                }
                JsType keyTypeName = forSoyType(mapType.getKeyType(), isIncrementalDom);
                JsType valueTypeName = forSoyType(mapType.getValueType(), isIncrementalDom);
                return builder().addType(String.format("!Object<%s,%s>", keyTypeName.typeExpr(), valueTypeName.typeExpr())).addRequires(keyTypeName.getGoogRequires()).addRequires(valueTypeName.getGoogRequires()).setPredicate(GOOG_IS_OBJECT).build();
            }
        case MAP:
            {
                MapType mapType = (MapType) soyType;
                SoyType keyType = mapType.getKeyType();
                SoyType.Kind keyKind = keyType.getKind();
                Preconditions.checkState(MapType.isAllowedKeyType(keyType));
                // Soy key type of string should translate to a JS key type of string.
                // forSoyType(StringType.getInstance()) normally translates to
                // string|!goog.soy.data.UnsanitizedText, but ES6 Maps always use instance equality for
                // lookups. Using UnsanitizedText instances as keys in Soy maps would cause unexpected
                // behavior (usually a failed map lookup), so don't generate signatures that allow it.
                JsType keyTypeName = keyKind == SoyType.Kind.STRING ? STRING_TYPE : forSoyType(keyType, isIncrementalDom);
                JsType valueTypeName = forSoyType(mapType.getValueType(), isIncrementalDom);
                return builder().addType(String.format("!soy.map.Map<%s,%s>", keyTypeName.typeExpr(), valueTypeName.typeExpr())).addRequires(keyTypeName.getGoogRequires()).addRequires(valueTypeName.getGoogRequires()).addRequire(GoogRequire.create("soy.map")).setPredicate(TypePredicate.NO_OP).build();
            }
        case PROTO:
            final SoyProtoType protoType = (SoyProtoType) soyType;
            final String protoTypeName = protoType.getNameForBackend(SoyBackendKind.JS_SRC);
            // isn't clear that this is very useful for users.
            return builder().addType(protoTypeName).addRequire(GoogRequire.create(protoTypeName)).addCoercionStrategy(ValueCoercionStrategy.PROTO).setPredicate(new TypePredicate() {

                @Override
                public Optional<CodeChunk.WithValue> maybeCheck(CodeChunk.WithValue value, Generator codeGenerator) {
                    return Optional.of(value.instanceof_(JsRuntime.protoConstructor(protoType)));
                }
            }).build();
        case RECORD:
            {
                RecordType recordType = (RecordType) soyType;
                if (recordType.getMembers().isEmpty()) {
                    return RAW_OBJECT_TYPE;
                }
                Builder builder = builder();
                Map<String, String> members = new LinkedHashMap<>();
                for (Map.Entry<String, SoyType> member : recordType.getMembers().entrySet()) {
                    JsType forSoyType = forSoyType(member.getValue(), isIncrementalDom);
                    builder.addRequires(forSoyType.getGoogRequires());
                    members.put(member.getKey(), forSoyType.typeExprForRecordMember(/* isOptional= */
                    false));
                }
                return builder.addType("{" + Joiner.on(", ").withKeyValueSeparator(": ").join(members) + ",}").setPredicate(GOOG_IS_OBJECT).build();
            }
        case UNION:
            {
                UnionType unionType = (UnionType) soyType;
                Builder builder = builder();
                final Set<JsType> types = new LinkedHashSet<>();
                final boolean isNullable = unionType.isNullable();
                // handle null first so that if other type tests dereference the param they won't fail
                if (isNullable) {
                    builder.addTypes(NULL_OR_UNDEFINED_TYPE.typeExpressions);
                    builder.addCoercionStrategy(ValueCoercionStrategy.NULL);
                    types.add(NULL_OR_UNDEFINED_TYPE);
                }
                for (SoyType member : unionType.getMembers()) {
                    if (member.getKind() == Kind.NULL) {
                        // handled above
                        continue;
                    }
                    JsType memberType = forSoyType(member, isIncrementalDom);
                    builder.addRequires(memberType.extraRequires);
                    builder.addTypes(memberType.typeExpressions);
                    builder.addCoercionStrategies(memberType.coercionStrategies);
                    types.add(memberType);
                }
                return builder.setPredicate(new TypePredicate() {

                    @Override
                    public Optional<CodeChunk.WithValue> maybeCheck(CodeChunk.WithValue value, Generator codeGenerator) {
                        CodeChunk.WithValue result = null;
                        // this automatically.
                        for (JsType memberType : types) {
                            Optional<CodeChunk.WithValue> typeAssertion = memberType.getTypeAssertion(value, codeGenerator);
                            if (!typeAssertion.isPresent()) {
                                return Optional.absent();
                            }
                            if (result == null) {
                                result = typeAssertion.get();
                            } else {
                                result = result.or(typeAssertion.get(), codeGenerator);
                            }
                        }
                        return Optional.of(result);
                    }
                }).build();
            }
        default:
            throw new AssertionError("unhandled soytype: " + soyType);
    }
}
Also used : UnionType(com.google.template.soy.types.UnionType) EnumSet(java.util.EnumSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) LegacyObjectMapType(com.google.template.soy.types.LegacyObjectMapType) MapType(com.google.template.soy.types.MapType) RecordType(com.google.template.soy.types.RecordType) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) ListType(com.google.template.soy.types.ListType) Kind(com.google.template.soy.types.SoyType.Kind) SoyBackendKind(com.google.template.soy.base.SoyBackendKind) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind) Optional(com.google.common.base.Optional) LegacyObjectMapType(com.google.template.soy.types.LegacyObjectMapType) SoyProtoType(com.google.template.soy.types.SoyProtoType) SoyType(com.google.template.soy.types.SoyType) SoyProtoEnumType(com.google.template.soy.types.SoyProtoEnumType) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) EnumMap(java.util.EnumMap) Generator(com.google.template.soy.jssrc.dsl.CodeChunk.Generator)

Example 2 with SoyProtoType

use of com.google.template.soy.types.SoyProtoType in project closure-templates by google.

the class GenerateParseInfoVisitor method visitSoyFileNode.

@Override
protected void visitSoyFileNode(SoyFileNode node) {
    if (node.getSoyFileKind() != SoyFileKind.SRC) {
        // don't generate code for deps
        return;
    }
    String javaClassName = soyFileToJavaClassNameMap.get(node);
    // Collect the following:
    // + all the public basic templates (non-private, non-delegate) in a map from the
    // upper-underscore template name to the template's node,
    // + all the param keys from all templates (including private),
    // + for each param key, the list of templates that list it directly.
    // + for any params whose type is a proto, get the proto name and Java class name.
    LinkedHashMap<String, TemplateNode> publicBasicTemplateMap = Maps.newLinkedHashMap();
    List<String> deltemplates = new ArrayList<>();
    Set<String> allParamKeys = Sets.newHashSet();
    SetMultimap<String, TemplateNode> paramKeyToTemplatesMultimap = LinkedHashMultimap.create();
    SortedSet<String> protoTypes = Sets.newTreeSet();
    for (TemplateNode template : node.getChildren()) {
        if (template.getVisibility() == Visibility.PUBLIC && template instanceof TemplateBasicNode) {
            publicBasicTemplateMap.put(convertToUpperUnderscore(template.getPartialTemplateName().substring(1)), template);
        }
        if (template instanceof TemplateDelegateNode) {
            deltemplates.add("\"" + template.getTemplateName() + "\"");
        }
        for (TemplateParam param : template.getAllParams()) {
            if (!param.isInjected()) {
                allParamKeys.add(param.name());
                paramKeyToTemplatesMultimap.put(param.name(), template);
            }
            if (param instanceof HeaderParam) {
                SoyType paramType = ((HeaderParam) param).type();
                findProtoTypesRecurse(paramType, protoTypes);
            }
        }
        // Field access nodes need special handling to ensure that extension references are handled.
        for (FieldAccessNode fieldAccess : SoyTreeUtils.getAllNodesOfType(template, FieldAccessNode.class)) {
            SoyType baseType = fieldAccess.getBaseExprChild().getType();
            if (baseType.getKind() == SoyType.Kind.PROTO) {
                FieldDescriptor desc = ((SoyProtoType) baseType).getFieldDescriptor(fieldAccess.getFieldName());
                if (desc.isExtension()) {
                    protoTypes.add(ProtoUtils.getTofuExtensionImport(desc));
                }
            }
        }
        // Add enums
        for (GlobalNode global : SoyTreeUtils.getAllNodesOfType(template, GlobalNode.class)) {
            if (global.isResolved() && global.getType().getKind() == SoyType.Kind.PROTO_ENUM) {
                protoTypes.add(((SoyProtoEnumType) global.getType()).getDescriptorExpression());
            }
        }
        // Add proto init
        for (ProtoInitNode protoInit : SoyTreeUtils.getAllNodesOfType(template, ProtoInitNode.class)) {
            if (protoInit.getType().getKind() == SoyType.Kind.PROTO) {
                protoTypes.add(((SoyProtoType) protoInit.getType()).getDescriptorExpression());
            }
        }
    }
    // allParamKeysMap is a map from upper-underscore key to original key.
    SortedMap<String, String> allParamKeysMap = Maps.newTreeMap();
    for (String key : allParamKeys) {
        String upperUnderscoreKey = convertToUpperUnderscore(key);
        // stage of the compiler.
        while (allParamKeysMap.containsKey(upperUnderscoreKey)) {
            upperUnderscoreKey = upperUnderscoreKey + "_";
        }
        allParamKeysMap.put(upperUnderscoreKey, key);
        // Updates the convertedIdents here, since we might have changed the value by adding
        // prepending underscores. Without this, the generated SoyTemplateInfo still use the
        // old mapping and will fail.
        convertedIdents.put(key, upperUnderscoreKey);
    }
    ilb = new IndentedLinesBuilder(2);
    // ------ Header. ------
    ilb.appendLine("// This file was automatically generated from ", node.getFileName(), ".");
    ilb.appendLine("// Please don't edit this file by hand.");
    ilb.appendLine();
    ilb.appendLine("package ", javaPackage, ";");
    ilb.appendLine();
    ilb.appendLine("import com.google.common.collect.ImmutableList;");
    ilb.appendLine("import com.google.common.collect.ImmutableMap;");
    ilb.appendLine("import com.google.common.collect.ImmutableSortedSet;");
    if (!protoTypes.isEmpty()) {
        ilb.appendLine("import com.google.protobuf.Descriptors.GenericDescriptor;");
    }
    ilb.appendLine("import com.google.template.soy.parseinfo.SoyFileInfo;");
    ilb.appendLine("import com.google.template.soy.parseinfo.SoyTemplateInfo;");
    // ------ Class start. ------
    ilb.appendLine();
    ilb.appendLine();
    appendJavadoc(ilb, "Soy parse info for " + node.getFileName() + ".", true, false);
    ilb.appendLine("public final class ", javaClassName, " extends SoyFileInfo {");
    ilb.increaseIndent();
    // ------ Constant for namespace. ------
    ilb.appendLine();
    ilb.appendLine();
    ilb.appendLine("/** This Soy file's namespace. */");
    ilb.appendLine("public static final String __NAMESPACE__ = \"", node.getNamespace(), "\";");
    // ------ Proto types map. ------
    if (!protoTypes.isEmpty()) {
        ilb.appendLine();
        ilb.appendLine();
        ilb.appendLine("/** Protocol buffer types used by these templates. */");
        ilb.appendLine("@Override public ImmutableList<GenericDescriptor> getProtoDescriptors() {");
        ilb.increaseIndent();
        // Note we use fully-qualified names instead of imports to avoid potential collisions.
        List<String> defaultInstances = Lists.newArrayList();
        defaultInstances.addAll(protoTypes);
        appendListOrSetHelper(ilb, "return ImmutableList.<GenericDescriptor>of", defaultInstances);
        ilb.appendLineEnd(";");
        ilb.decreaseIndent();
        ilb.appendLine("}");
    }
    // ------ Template names. ------
    ilb.appendLine();
    ilb.appendLine();
    ilb.appendLine("public static final class TemplateName {");
    ilb.increaseIndent();
    ilb.appendLine("private TemplateName() {}");
    ilb.appendLine();
    for (Entry<String, TemplateNode> templateEntry : publicBasicTemplateMap.entrySet()) {
        StringBuilder javadocSb = new StringBuilder();
        javadocSb.append("The full template name of the ").append(templateEntry.getValue().getPartialTemplateName()).append(" template.");
        appendJavadoc(ilb, javadocSb.toString(), false, true);
        ilb.appendLine("public static final String ", templateEntry.getKey(), " = \"", templateEntry.getValue().getTemplateName(), "\";");
    }
    ilb.decreaseIndent();
    ilb.appendLine("}");
    // ------ Params. ------
    ilb.appendLine();
    ilb.appendLine();
    ilb.appendLine("/**");
    ilb.appendLine(" * Param names from all templates in this Soy file.");
    ilb.appendLine(" */");
    ilb.appendLine("public static final class Param {");
    ilb.increaseIndent();
    ilb.appendLine("private Param() {}");
    ilb.appendLine();
    for (Map.Entry<String, String> paramEntry : allParamKeysMap.entrySet()) {
        String upperUnderscoreKey = paramEntry.getKey();
        String key = paramEntry.getValue();
        StringBuilder javadocSb = new StringBuilder();
        javadocSb.append("Listed by ");
        boolean isFirst = true;
        for (TemplateNode template : paramKeyToTemplatesMultimap.get(key)) {
            if (isFirst) {
                isFirst = false;
            } else {
                javadocSb.append(", ");
            }
            javadocSb.append(buildTemplateNameForJavadoc(node, template));
        }
        javadocSb.append('.');
        appendJavadoc(ilb, javadocSb.toString(), false, true);
        ilb.appendLine("public static final String ", upperUnderscoreKey, " = \"", key, "\";");
    }
    ilb.decreaseIndent();
    ilb.appendLine("}");
    // ------ Templates. ------
    for (TemplateNode template : publicBasicTemplateMap.values()) {
        visit(template);
    }
    // ------ Constructor. ------
    ilb.appendLine();
    ilb.appendLine();
    ilb.appendLine("private ", javaClassName, "() {");
    ilb.increaseIndent();
    ilb.appendLine("super(");
    ilb.increaseIndent(2);
    ilb.appendLine("\"", node.getFileName(), "\",");
    ilb.appendLine("\"", node.getNamespace(), "\",");
    // Templates.
    List<String> itemSnippets = Lists.newArrayList();
    itemSnippets.addAll(publicBasicTemplateMap.keySet());
    appendImmutableList(ilb, "<SoyTemplateInfo>", itemSnippets);
    ilb.appendLineEnd(",");
    // CSS names.
    SortedMap<String, CssTagsPrefixPresence> cssNameMap = new CollectCssNamesVisitor().exec(node);
    ImmutableMap.Builder<String, String> cssTagPrefixes = ImmutableMap.builder();
    for (Map.Entry<String, CssTagsPrefixPresence> entry : cssNameMap.entrySet()) {
        cssTagPrefixes.put("\"" + entry.getKey() + "\"", "CssTagsPrefixPresence." + entry.getValue().name());
    }
    appendImmutableMap(ilb, "<String, CssTagsPrefixPresence>", cssTagPrefixes.build());
    ilb.appendLineEnd(",");
    appendImmutableList(ilb, "<String>", deltemplates);
    ilb.appendLineEnd(");");
    ilb.decreaseIndent(2);
    ilb.decreaseIndent();
    ilb.appendLine("}");
    // ------ Singleton instance and its getter. ------
    ilb.appendLine();
    ilb.appendLine();
    ilb.appendLine("private static final ", javaClassName, " __INSTANCE__ =");
    ilb.increaseIndent(2);
    ilb.appendLine("new ", javaClassName, "();");
    ilb.decreaseIndent(2);
    ilb.appendLine();
    ilb.appendLine("public static ", javaClassName, " getInstance() {");
    ilb.increaseIndent();
    ilb.appendLine("return __INSTANCE__;");
    ilb.decreaseIndent();
    ilb.appendLine("}");
    // ------ Class end. ------
    ilb.appendLine();
    ilb.decreaseIndent();
    ilb.appendLine("}");
    generatedFiles.put(javaClassName + ".java", ilb.toString());
    ilb = null;
}
Also used : TemplateBasicNode(com.google.template.soy.soytree.TemplateBasicNode) HeaderParam(com.google.template.soy.soytree.defn.HeaderParam) IndentedLinesBuilder(com.google.template.soy.base.internal.IndentedLinesBuilder) ArrayList(java.util.ArrayList) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor) ProtoInitNode(com.google.template.soy.exprtree.ProtoInitNode) TemplateParam(com.google.template.soy.soytree.defn.TemplateParam) TemplateNode(com.google.template.soy.soytree.TemplateNode) TemplateDelegateNode(com.google.template.soy.soytree.TemplateDelegateNode) FieldAccessNode(com.google.template.soy.exprtree.FieldAccessNode) SoyProtoType(com.google.template.soy.types.SoyProtoType) ImmutableMap(com.google.common.collect.ImmutableMap) SoyType(com.google.template.soy.types.SoyType) GlobalNode(com.google.template.soy.exprtree.GlobalNode) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) LinkedHashMap(java.util.LinkedHashMap) CssTagsPrefixPresence(com.google.template.soy.parseinfo.SoyFileInfo.CssTagsPrefixPresence)

Example 3 with SoyProtoType

use of com.google.template.soy.types.SoyProtoType in project closure-templates by google.

the class TranslateExprNodeVisitor method genCodeForFieldAccess.

/**
 * Generates the code for a field access, e.g. {@code .foo} or {@code .getFoo()}.
 *
 * @param baseType The type of the object that contains the field.
 * @param fieldAccessNode The field access node.
 * @param fieldName The field name.
 */
private FieldAccess genCodeForFieldAccess(SoyType baseType, FieldAccessNode fieldAccessNode, String fieldName) {
    Preconditions.checkNotNull(baseType);
    // type, and then see if they all agree.
    if (baseType.getKind() == SoyType.Kind.UNION) {
        // TODO(msamuel): We will need to generate fallback code for each variant.
        UnionType unionType = (UnionType) baseType;
        FieldAccess fieldAccess = null;
        for (SoyType memberType : unionType.getMembers()) {
            if (memberType.getKind() != SoyType.Kind.NULL) {
                FieldAccess fieldAccessForType = genCodeForFieldAccess(memberType, fieldAccessNode, fieldName);
                if (fieldAccess == null) {
                    fieldAccess = fieldAccessForType;
                } else if (!fieldAccess.equals(fieldAccessForType)) {
                    errorReporter.report(fieldAccessNode.getSourceLocation(), UNION_ACCESSOR_MISMATCH, fieldName, baseType);
                }
            }
        }
        return fieldAccess;
    }
    if (baseType.getKind() == SoyType.Kind.PROTO) {
        SoyProtoType protoType = (SoyProtoType) baseType;
        FieldDescriptor desc = protoType.getFieldDescriptor(fieldName);
        Preconditions.checkNotNull(desc, "Error in proto %s, field not found: %s", protoType.getDescriptor().getFullName(), fieldName);
        return FieldAccess.protoCall(fieldName, desc);
    }
    return FieldAccess.id(fieldName);
}
Also used : UnionType(com.google.template.soy.types.UnionType) SoyType(com.google.template.soy.types.SoyType) FieldAccess(com.google.template.soy.jssrc.internal.NullSafeAccumulator.FieldAccess) SoyProtoType(com.google.template.soy.types.SoyProtoType) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor)

Example 4 with SoyProtoType

use of com.google.template.soy.types.SoyProtoType in project closure-templates by google.

the class EvalVisitor method visitProtoInitNode.

@Override
protected SoyValue visitProtoInitNode(ProtoInitNode node) {
    // The downcast is safe because if it was anything else, compilation would have already failed.
    SoyProtoType soyProto = (SoyProtoType) node.getType();
    ImmutableList<String> paramNames = node.getParamNames();
    SoyProtoValueImpl.Builder builder = new SoyProtoValueImpl.Builder(soyProto.getDescriptor());
    for (int i = 0; i < node.numChildren(); i++) {
        SoyValue visit = visit(node.getChild(i));
        // null means don't assign
        if (visit instanceof NullData || visit instanceof UndefinedData) {
            continue;
        }
        builder.setField(paramNames.get(i), visit);
    }
    return builder.build();
}
Also used : NullData(com.google.template.soy.data.restricted.NullData) UndefinedData(com.google.template.soy.data.restricted.UndefinedData) SoyValue(com.google.template.soy.data.SoyValue) SoyProtoType(com.google.template.soy.types.SoyProtoType) SoyProtoValueImpl(com.google.template.soy.data.SoyProtoValueImpl)

Example 5 with SoyProtoType

use of com.google.template.soy.types.SoyProtoType in project closure-templates by google.

the class TranslateExprNodeVisitor method visitProtoInitNode.

@Override
protected CodeChunk.WithValue visitProtoInitNode(ProtoInitNode node) {
    SoyProtoType type = (SoyProtoType) node.getType();
    CodeChunk.WithValue proto = new_(protoConstructor(type)).call();
    if (node.numChildren() == 0) {
        // If there's no further structure to the proto, no need to declare a variable.
        return proto;
    }
    CodeChunk.WithValue protoVar = codeGenerator.declarationBuilder().setRhs(proto).build().ref();
    ImmutableList.Builder<CodeChunk> initialStatements = ImmutableList.builder();
    for (int i = 0; i < node.numChildren(); i++) {
        String fieldName = node.getParamName(i);
        FieldDescriptor fieldDesc = type.getFieldDescriptor(fieldName);
        CodeChunk.WithValue fieldValue = visit(node.getChild(i));
        if (ProtoUtils.isSanitizedContentField(fieldDesc)) {
            CodeChunk.WithValue sanitizedContentPackFn = sanitizedContentToProtoConverterFunction(fieldDesc.getMessageType());
            fieldValue = fieldDesc.isRepeated() ? GOOG_ARRAY_MAP.call(fieldValue, sanitizedContentPackFn) : sanitizedContentPackFn.call(fieldValue);
        }
        if (fieldDesc.isExtension()) {
            CodeChunk.WithValue extInfo = extensionField(fieldDesc);
            initialStatements.add(protoVar.dotAccess("setExtension").call(extInfo, fieldValue));
        } else if (fieldDesc.isMapField()) {
            // Protocol buffer in JS does not generate setters for map fields. To construct a proto map
            // field, we first save a reference to the empty instance using the getter,  and then load
            // it with the contents of the SoyMap.
            String getFn = "get" + LOWER_CAMEL.to(UPPER_CAMEL, fieldName);
            CodeChunk.WithValue protoMap = protoVar.dotAccess(getFn).call();
            CodeChunk.WithValue protoMapVar = codeGenerator.declarationBuilder().setRhs(protoMap).build().ref();
            if (ProtoUtils.isSanitizedContentMap(fieldDesc)) {
                CodeChunk.WithValue sanitizedContentPackFn = sanitizedContentToProtoConverterFunction(ProtoUtils.getMapValueMessageType(fieldDesc));
                fieldValue = SOY_NEWMAPS_TRANSFORM_VALUES.call(fieldValue, sanitizedContentPackFn);
            }
            initialStatements.add(SOY_MAP_POPULATE.call(protoMapVar, fieldValue));
        } else {
            String setFn = "set" + LOWER_CAMEL.to(UPPER_CAMEL, fieldName);
            initialStatements.add(protoVar.dotAccess(setFn).call(fieldValue));
        }
    }
    return protoVar.withInitialStatements(initialStatements.build());
}
Also used : WithValue(com.google.template.soy.jssrc.dsl.CodeChunk.WithValue) CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) ImmutableList(com.google.common.collect.ImmutableList) WithValue(com.google.template.soy.jssrc.dsl.CodeChunk.WithValue) SoyProtoType(com.google.template.soy.types.SoyProtoType) FieldDescriptor(com.google.protobuf.Descriptors.FieldDescriptor)

Aggregations

SoyProtoType (com.google.template.soy.types.SoyProtoType)5 FieldDescriptor (com.google.protobuf.Descriptors.FieldDescriptor)3 SoyType (com.google.template.soy.types.SoyType)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)2 UnionType (com.google.template.soy.types.UnionType)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 Optional (com.google.common.base.Optional)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ImmutableSortedSet (com.google.common.collect.ImmutableSortedSet)1 SoyBackendKind (com.google.template.soy.base.SoyBackendKind)1 IndentedLinesBuilder (com.google.template.soy.base.internal.IndentedLinesBuilder)1 SanitizedContentKind (com.google.template.soy.base.internal.SanitizedContentKind)1 SoyProtoValueImpl (com.google.template.soy.data.SoyProtoValueImpl)1 SoyValue (com.google.template.soy.data.SoyValue)1 NullData (com.google.template.soy.data.restricted.NullData)1 UndefinedData (com.google.template.soy.data.restricted.UndefinedData)1 FieldAccessNode (com.google.template.soy.exprtree.FieldAccessNode)1