docs: private void checkStrictParamType(
        final TemplateNode node, final TemplateParam param, @Nullable SoyValueProvider paramValue) {
      Kind kind = param.type().getKind();
      if (kind == Kind.ANY || kind == Kind.UNKNOWN) {
        // Nothing to check.  ANY and UKNOWN match all types.
        return;
      }
      if (paramValue == null) {
        paramValue = NullData.INSTANCE;
      } else if (paramValue instanceof SoyAbstractCachingValueProvider) {
        SoyAbstractCachingValueProvider typedValue = (SoyAbstractCachingValueProvider) paramValue;
        if (!typedValue.isComputed()) {
          // in order to preserve laziness we tell the value provider to assert the type when
          // computation is triggered
          typedValue.addValueAssertion(
              new ValueAssertion() {
                @Override
                public void check(SoyValue value) {
                  checkValueType(param, value, node);
                }
              });
          return;
        }
      } else if (param.hasDefault() && paramValue.resolve() instanceof UndefinedData) {
        // Default parameters are undefined if they're unset.
        return;
      }
      checkValueType(param, paramValue.resolve(), node);
    }