private static void printParameterCaching(
     PrintWriter writer,
     TypeElement interface_decl,
     ExecutableElement method,
     Mode mode,
     boolean context_specific) {
   for (VariableElement param : method.getParameters()) {
     Class java_type = Utils.getJavaType(param.asType());
     CachedReference cachedReference = param.getAnnotation(CachedReference.class);
     if (Buffer.class.isAssignableFrom(java_type)
         && cachedReference != null
         && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null)
         && param.getAnnotation(Result.class) == null) {
       writer.print("\t\tif ( LWJGLUtil.CHECKS ) StateTracker.");
       if (context_specific) {
         writer.print("getReferences(caps).");
       } else {
         writer.print("getTracker().");
       }
       if (cachedReference.name().length() > 0) {
         writer.print(cachedReference.name());
       } else {
         writer.print(Utils.getReferenceName(interface_decl, method, param));
       }
       if (cachedReference.index().length() > 0) {
         writer.print("[" + cachedReference.index() + "]");
       }
       writer.println(" = " + param.getSimpleName() + ";");
     }
   }
 }
  private static boolean printMethodCallArguments(
      PrintWriter writer,
      ExecutableElement method,
      Map<VariableElement, TypeInfo> typeinfos_instance,
      Mode mode,
      TypeMap type_map) {
    boolean first_parameter = true;
    for (VariableElement param : method.getParameters()) {
      if (param.getAnnotation(Result.class) != null
          || (param.getAnnotation(Helper.class) != null
              && !param.getAnnotation(Helper.class).passToNative())) {
        continue;
      }

      final Constant constant_annotation = param.getAnnotation(Constant.class);
      if (constant_annotation == null || !constant_annotation.isNative()) {
        first_parameter =
            printMethodCallArgument(
                writer, method, param, typeinfos_instance, mode, first_parameter, type_map);
      }
    }
    if (Utils.getNIOBufferType(Utils.getMethodReturnType(method)) != null) {
      if (method.getAnnotation(CachedResult.class) != null
          && method.getAnnotation(CachedResult.class).isRange()) {
        first_parameter = false;
        Utils.printExtraCallArguments(writer, method, "");
      } else {
        AutoSize auto_size_annotation = method.getAnnotation(AutoSize.class);
        if (auto_size_annotation == null || !auto_size_annotation.isNative()) {
          if (!first_parameter) {
            writer.print(", ");
          }
          first_parameter = false;

          String result_size_expression;
          if (mode == Mode.CACHEDRESULT) {
            result_size_expression = Utils.CACHED_BUFFER_LENGTH_NAME;
          } else if (auto_size_annotation == null) {
            result_size_expression = Utils.RESULT_SIZE_NAME;
          } else {
            result_size_expression = auto_size_annotation.value();
          }

          Utils.printExtraCallArguments(writer, method, result_size_expression);
        }
      }
    }
    return first_parameter;
  }
 @Override
 public boolean processVariableElement(VariableElement field, DeclaredTypeName fieldType) {
   boolean isViewProperty = TypeConstants.isBasicPropertyType(fieldType);
   ViewQuery isViewQuery = field.getAnnotation(ViewQuery.class);
   Set<Modifier> modifiers = field.getModifiers();
   if (modifiers.containsAll(TypeConstants.PUBLIC_STATIC_FINAL)) {
     if (isViewQuery != null) {
       if (!TypeConstants.QUERY.equals(fieldType)) {
         utils
             .getMessager()
             .printMessage(
                 Diagnostic.Kind.ERROR,
                 "ViewQuery must be an instance of " + TypeConstants.QUERY.toString());
       } else if (modelSpec.hasMetadata(ViewModelSpecWrapper.METADATA_KEY_QUERY_ELEMENT)) {
         utils
             .getMessager()
             .printMessage(Diagnostic.Kind.ERROR, "Only one ViewQuery can be declared per spec");
       } else {
         modelSpec.putMetadata(ViewModelSpecWrapper.METADATA_KEY_VIEW_QUERY, isViewQuery);
         modelSpec.putMetadata(ViewModelSpecWrapper.METADATA_KEY_QUERY_ELEMENT, field);
       }
       return true;
     } else {
       return super.processVariableElement(field, fieldType);
     }
   } else if (isViewProperty) {
     utils
         .getMessager()
         .printMessage(
             Diagnostic.Kind.ERROR, "View properties must be public static final", field);
   }
   return false;
 }
 private static boolean generateParameterJava(
     PrintWriter writer,
     VariableElement param,
     TypeInfo type_info,
     boolean native_stub,
     final boolean printTypes,
     boolean first_parameter,
     Mode mode) {
   Class buffer_type = Utils.getNIOBufferType(param.asType());
   if (!first_parameter) {
     writer.print(", ");
   }
   BufferObject bo_annotation = param.getAnnotation(BufferObject.class);
   if (bo_annotation != null && mode == Mode.BUFFEROBJECT) {
     if (buffer_type == null) {
       throw new RuntimeException(
           "type of "
               + param
               + " is not a nio Buffer parameter but is annotated as buffer object");
     }
     if (printTypes) {
       writer.print("long ");
     }
     writer.print(param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX);
   } else {
     if (native_stub && param.getAnnotation(PointerWrapper.class) != null) {
       writer.print("long ");
     } else {
       Class type = type_info.getType();
       if (native_stub
           && (type == CharSequence.class
               || type == CharSequence[].class
               || type == PointerBuffer.class
               || Buffer.class.isAssignableFrom(type))) {
         writer.print("long ");
       } else if (printTypes) {
         writer.print(type.getSimpleName() + " ");
       }
     }
     AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class);
     if (auto_size_annotation != null) {
       writer.print(auto_size_annotation.value() + "_");
     }
     writer.print(param.getSimpleName());
   }
   return false;
 }
 @Override
 public Void visitVariable(VariableElement e, Void p) {
   if (e.getAnnotation(Signaller.class) != null) {
     TypeElement typeElement = elementUtils.getTypeElement(e.asType().toString());
     if (typeElement != null) {
       handleTypeElement(typeElement);
     }
   }
   return super.visitVariable(e, p);
 }
  private void buildPathVariables(
      ExecutableElement executableElement, RestDocumentation.Resource.Method doc) {
    RestDocumentation.Resource.Method.UrlFields subs = doc.getUrlSubstitutions();

    for (VariableElement var : executableElement.getParameters()) {
      PathVariable pathVar = var.getAnnotation(PathVariable.class);
      if (pathVar != null) {
        addUrlField(subs, var, pathVar.value());
      }
    }
  }
  private void buildUrlParameters(
      ExecutableElement executableElement, RestDocumentation.Resource.Method doc) {
    RestDocumentation.Resource.Method.UrlFields subs = doc.getUrlParameters();

    for (VariableElement var : executableElement.getParameters()) {
      RequestParam reqParam = var.getAnnotation(RequestParam.class);
      if (reqParam != null) {
        addUrlField(subs, var, reqParam.value());
      }
    }
  }
  private void printMethod(ExecutableElement executableElement) {
    StringBuilder s = new StringBuilder(256);
    s.append("method: " + executableElement).append("\n\t");
    s.append("annotations: " + executableElement.getAnnotationMirrors()).append("\n\t");
    s.append("return: " + executableElement.getReturnType()).append("\n\t");
    for (VariableElement var : executableElement.getParameters()) {
      s.append("parameter: " + var + ", " + var.getAnnotation(ApiParameterDoc.class))
          .append("\n\t");
    }

    generator.log(s.toString());
  }
 private static VariableElement getAutoTypeParameter(
     ExecutableElement method, VariableElement target_parameter) {
   for (VariableElement param : method.getParameters()) {
     AnnotationMirror auto_annotation = Utils.getParameterAutoAnnotation(param);
     if (auto_annotation != null) {
       Class annotation_type =
           NativeTypeTranslator.getClassFromType(auto_annotation.getAnnotationType());
       String parameter_name;
       if (annotation_type.equals(AutoType.class)) {
         parameter_name = param.getAnnotation(AutoType.class).value();
       } else if (annotation_type.equals(AutoSize.class)) {
         parameter_name = param.getAnnotation(AutoSize.class).value();
       } else {
         throw new RuntimeException("Unknown annotation type " + annotation_type);
       }
       if (target_parameter.getSimpleName().toString().equals(parameter_name)) {
         return param;
       }
     }
   }
   return null;
 }
 private static void printBufferObjectChecks(
     PrintWriter writer, ExecutableElement method, Mode mode, boolean context_specific) {
   EnumSet<BufferKind> check_set = EnumSet.noneOf(BufferKind.class);
   for (VariableElement param : method.getParameters()) {
     BufferObject bo_annotation = param.getAnnotation(BufferObject.class);
     if (bo_annotation != null) {
       check_set.add(bo_annotation.value());
     }
   }
   for (BufferKind kind : check_set) {
     printBufferObjectCheck(writer, kind, mode, context_specific);
   }
 }
 @Override
 protected void processVariableElement(VariableElement e, DeclaredTypeName typeName) {
   if (e.getAnnotation(Deprecated.class) != null) {
     return;
   }
   if (e.getAnnotation(ColumnSpec.class) != null) {
     utils
         .getMessager()
         .printMessage(Kind.WARNING, "ColumnSpec is ignored outside of table models", e);
   }
   boolean isViewProperty = TypeConstants.isPropertyType(typeName);
   ViewQuery isViewQuery = e.getAnnotation(ViewQuery.class);
   Set<Modifier> modifiers = e.getModifiers();
   if (modifiers.containsAll(TypeConstants.PUBLIC_STATIC_FINAL)) {
     if (isViewQuery != null) {
       if (!TypeConstants.QUERY.equals(typeName)) {
         utils
             .getMessager()
             .printMessage(
                 Kind.ERROR, "ViewQuery must be an instance of " + TypeConstants.QUERY.toString());
       } else if (queryElement != null) {
         utils.getMessager().printMessage(Kind.ERROR, "Only one ViewQuery per spec allowedd");
       } else {
         viewQueryAnnotation = isViewQuery;
         queryElement = e;
       }
     } else if (!isViewProperty) {
       constantElements.add(e);
     } else {
       initializePropertyGenerator(e);
     }
   } else if (isViewProperty) {
     utils
         .getMessager()
         .printMessage(Kind.ERROR, "View properties must be public static final", e);
   } else {
     utils.getMessager().printMessage(Kind.WARNING, "Unused field in spec", e);
   }
 }
 private static boolean hasAnyParameterAutoTypeAnnotation(
     ExecutableElement method, VariableElement target_param) {
   for (VariableElement param : method.getParameters()) {
     AutoType auto_type_annotation = param.getAnnotation(AutoType.class);
     if (auto_type_annotation != null) {
       VariableElement type_target_param =
           Utils.findParameter(method, auto_type_annotation.value());
       if (target_param.equals(type_target_param)) {
         return true;
       }
     }
   }
   return false;
 }
  private void buildRequestBodies(
      ExecutableElement executableElement, RestDocumentation.Resource.Method doc) {
    List<VariableElement> requestBodies = new ArrayList<VariableElement>();
    for (VariableElement var : executableElement.getParameters()) {
      if (var.getAnnotation(org.springframework.web.bind.annotation.RequestBody.class) != null) {
        requestBodies.add(var);
      }
    }

    if (requestBodies.size() > 1) {
      throw new IllegalStateException(
          String.format(
              "Method %s in class %s has multiple @RequestBody params",
              executableElement.getSimpleName(), executableElement.getEnclosingElement()));
    }

    if (requestBodies.size() == 1) {
      buildRequestBody(requestBodies.get(0), doc);
    }
  }
 @Override
 public PropertyGenerator getPropertyGenerator(
     VariableElement element, DeclaredTypeName elementType, DeclaredTypeName modelClass) {
   Class<? extends PropertyGenerator> generatorClass = generatorMap.get(elementType);
   try {
     if (element.getAnnotation(PrimaryKey.class) != null
         && BasicLongPropertyGenerator.class.equals(generatorClass)) {
       return new BasicIdPropertyGenerator(element, elementType, utils);
     }
     return generatorClass
         .getConstructor(VariableElement.class, DeclaredTypeName.class, AptUtils.class)
         .newInstance(element, modelClass, utils);
   } catch (Exception e) {
     utils
         .getMessager()
         .printMessage(
             Kind.ERROR,
             "Exception instantiating PropertyGenerator: " + generatorClass + ", " + e);
   }
   return null;
 }
  protected Map<String, String> loadEnumValues() {
    List<VariableElement> enumConstants = getEnumConstants();
    Map<String, String> enumValueMap = new LinkedHashMap<String, String>();
    HashSet<String> enumValues = new HashSet<String>(enumConstants.size());
    for (VariableElement enumConstant : enumConstants) {
      String value = enumConstant.getSimpleName().toString();

      if (context.isHonorJaxb()) {
        XmlEnumValue enumValue = enumConstant.getAnnotation(XmlEnumValue.class);
        if (enumValue != null) {
          value = enumValue.value();
        }
      }

      if (!enumValues.add(value)) {
        throw new EnunciateException(getQualifiedName() + ": duplicate enum value: " + value);
      }

      enumValueMap.put(enumConstant.getSimpleName().toString(), value);
    }
    return enumValueMap;
  }
  private static void printParameterChecks(
      PrintWriter writer,
      ExecutableElement method,
      Map<VariableElement, TypeInfo> typeinfos,
      Mode mode,
      final boolean generate_error_checks) {
    if (mode == Mode.NORMAL) {
      final GenerateAutos gen_autos_annotation = method.getAnnotation(GenerateAutos.class);
      if (gen_autos_annotation != null && gen_autos_annotation.sizeVariables().length > 0) {
        // For the auto-generated parameters, declare and init a size variable (that can be reused
        // by @Code)
        for (final VariableElement param : method.getParameters()) {
          if (Arrays.binarySearch(
                  gen_autos_annotation.sizeVariables(), param.getSimpleName().toString())
              >= 0) {
            final int shifting = getBufferElementSizeExponent(typeinfos.get(param).getType());
            final Check check_annotation = param.getAnnotation(Check.class);

            writer.print("\t\tlong " + param.getSimpleName() + "_size = ");
            if (check_annotation == null || !check_annotation.canBeNull()) {
              writer.println(param.getSimpleName() + ".remaining() << " + shifting + ";");
            } else {
              writer.println(
                  param.getSimpleName()
                      + " == null ? 0 : "
                      + param.getSimpleName()
                      + ".remaining() << "
                      + shifting
                      + ";");
            }
          }
        }
      }
    }

    for (VariableElement param : method.getParameters()) {
      Class java_type = Utils.getJavaType(param.asType());
      if (java_type.isArray()
          || (Utils.isAddressableType(java_type)
              && (mode != Mode.BUFFEROBJECT || param.getAnnotation(BufferObject.class) == null)
              && (mode != Mode.AUTOS || getAutoTypeParameter(method, param) == null)
              && param.getAnnotation(Result.class) == null
              && !Utils.isReturnParameter(method, param))) {
        String check_value = null;
        boolean can_be_null = false;
        Check check_annotation = param.getAnnotation(Check.class);
        if (check_annotation != null) {
          check_value = check_annotation.value();
          can_be_null = check_annotation.canBeNull();
        }
        if ((Buffer.class.isAssignableFrom(java_type)
                || PointerBuffer.class.isAssignableFrom(java_type))
            && param.getAnnotation(Constant.class) == null) {
          TypeInfo typeinfo = typeinfos.get(param);
          printParameterCheck(
              writer,
              method,
              param.getSimpleName().toString(),
              typeinfo.getType().getSimpleName(),
              check_value,
              can_be_null,
              param.getAnnotation(NullTerminated.class),
              generate_error_checks);
        } else if (String.class.equals(java_type)) {
          if (!can_be_null) {
            writer.println("\t\tBufferChecks.checkNotNull(" + param.getSimpleName() + ");");
          }
        } else if (java_type.isArray()) {
          printArrayParameterCheck(
              writer, param.getSimpleName().toString(), check_value, can_be_null);
        }
      }
    }
    if (method.getAnnotation(CachedResult.class) != null) {
      printParameterCheck(
          writer, method, Utils.CACHED_BUFFER_NAME, null, null, true, null, generate_error_checks);
    }
  }
  void addMethod(ModuleMetaModel context, AnnotationKey key2, AnnotationState annotation) {

    //
    String id = (String) annotation.get("id");

    ExecutableElement methodElt =
        (ExecutableElement) context.processingContext.get(key2.getElement());

    //
    for (Phase phase : Phase.values()) {
      if (phase.annotation.getName().equals(key2.getType().toString())) {
        ElementHandle.Method origin = (ElementHandle.Method) key2.getElement();

        // First remove the previous method
        Key<MethodMetaModel> key = Key.of(origin, MethodMetaModel.class);
        if (getChild(key) == null) {
          // Parameters
          ArrayList<ParameterMetaModel> parameters = new ArrayList<ParameterMetaModel>();
          List<? extends TypeMirror> parameterTypeMirrors =
              ((ExecutableType) methodElt.asType()).getParameterTypes();
          List<? extends VariableElement> parameterVariableElements = methodElt.getParameters();
          for (int i = 0; i < parameterTypeMirrors.size(); i++) {
            VariableElement parameterVariableElt = parameterVariableElements.get(i);
            TypeMirror parameterTypeMirror = parameterTypeMirrors.get(i);
            String typeLiteral = context.processingContext.getLiteralName(parameterTypeMirror);

            //
            String parameterName = parameterVariableElt.getSimpleName().toString();

            // Determine cardinality
            TypeMirror parameterSimpleTypeMirror;
            Cardinality parameterCardinality;
            switch (parameterTypeMirror.getKind()) {
              case DECLARED:
                DeclaredType dt = (DeclaredType) parameterTypeMirror;
                TypeElement col = context.processingContext.getTypeElement("java.util.List");
                TypeMirror tm = context.processingContext.erasure(col.asType());
                TypeMirror err = context.processingContext.erasure(dt);
                // context.env.isSubtype(err, tm)
                if (err.equals(tm)) {
                  if (dt.getTypeArguments().size() != 1) {
                    throw CONTROLLER_METHOD_PARAMETER_NOT_RESOLVED.failure(parameterVariableElt);
                  } else {
                    parameterCardinality = Cardinality.LIST;
                    parameterSimpleTypeMirror = dt.getTypeArguments().get(0);
                  }
                } else {
                  parameterCardinality = Cardinality.SINGLE;
                  parameterSimpleTypeMirror = parameterTypeMirror;
                }
                break;
              case ARRAY:
                // Unwrap array
                ArrayType arrayType = (ArrayType) parameterTypeMirror;
                parameterCardinality = Cardinality.ARRAY;
                parameterSimpleTypeMirror = arrayType.getComponentType();
                break;
              default:
                throw CONTROLLER_METHOD_PARAMETER_NOT_RESOLVED.failure(parameterVariableElt);
            }
            if (parameterSimpleTypeMirror.getKind() != TypeKind.DECLARED) {
              throw CONTROLLER_METHOD_PARAMETER_NOT_RESOLVED.failure(parameterVariableElt);
            }

            //
            TypeElement te =
                (TypeElement) context.processingContext.asElement(parameterSimpleTypeMirror);
            ElementHandle.Type a = ElementHandle.Type.create(te);

            //
            if (te.toString().equals("java.lang.String")
                || te.getAnnotation(Mapped.class) != null) {
              // Not sure we should use @Param for this (i.e for now it looks hackish)
              // however it does make sense later to use the regex part for non router
              // parameters
              Param param = parameterVariableElt.getAnnotation(Param.class);
              String alias = param != null && param.name().length() > 0 ? param.name() : null;
              parameters.add(
                  new PhaseParameterMetaModel(
                      parameterName, parameterCardinality, a, typeLiteral, alias));
            } else {
              parameters.add(new ContextualParameterMetaModel(parameterName, typeLiteral));
            }
          }

          //
          MethodMetaModel method =
              new MethodMetaModel(
                  origin, id, phase, methodElt.getSimpleName().toString(), parameters);
          addChild(key, method);
          modified = true;
        }
        break;
      }
    }
  }
  private static boolean generateParametersJava(
      PrintWriter writer,
      ExecutableElement method,
      Map<VariableElement, TypeInfo> typeinfos_instance,
      boolean native_stub,
      final boolean printTypes,
      Mode mode) {
    boolean first_parameter = true;
    for (VariableElement param : method.getParameters()) {
      if (native_stub
          && (param.getAnnotation(Helper.class) != null
              && !param.getAnnotation(Helper.class).passToNative())) {
        continue;
      }
      final Constant constant_annotation = param.getAnnotation(Constant.class);
      if (constant_annotation != null && constant_annotation.isNative()) {
        continue;
      }
      AnnotationMirror auto_annotation_mirror = Utils.getParameterAutoAnnotation(param);
      boolean hide_auto_parameter =
          mode == Mode.NORMAL && !native_stub && auto_annotation_mirror != null;
      if (hide_auto_parameter) {
        AutoType auto_type_annotation = param.getAnnotation(AutoType.class);
        if (auto_type_annotation != null) {
          VariableElement auto_parameter =
              Utils.findParameter(method, auto_type_annotation.value());
          TypeInfo auto_param_type_info = typeinfos_instance.get(auto_parameter);
          if (auto_param_type_info.getSignedness() == Signedness.BOTH) {
            if (!first_parameter) {
              writer.print(", ");
            }
            first_parameter = false;
            if (printTypes) {
              writer.print("boolean ");
            }
            writer.print(TypeInfo.UNSIGNED_PARAMETER_NAME);
          }
        }
      } else if (param.getAnnotation(Result.class) == null
          && (native_stub
              || ((param.getAnnotation(Constant.class) == null
                      || param.getAnnotation(Constant.class).keepParam())
                  && !Utils.isReturnParameter(method, param)))
          && (mode != Mode.AUTOS || getAutoTypeParameter(method, param) == null)) {
        first_parameter =
            generateParameterJava(
                writer,
                param,
                typeinfos_instance.get(param),
                native_stub,
                printTypes,
                first_parameter,
                mode);
      }
    }
    CachedResult cached_result_annotation = method.getAnnotation(CachedResult.class);
    TypeMirror result_type = Utils.getMethodReturnType(method);
    if ((native_stub && Utils.getNIOBufferType(result_type) != null)
        || Utils.needResultSize(method)) {
      AutoSize auto_size_annotation = method.getAnnotation(AutoSize.class);
      if (auto_size_annotation == null || !auto_size_annotation.isNative()) {
        if (cached_result_annotation == null || !cached_result_annotation.isRange()) {
          if (!first_parameter) {
            writer.print(", ");
          }
          first_parameter = false;
          if (printTypes) {
            writer.print("long ");
          }
          writer.print(Utils.RESULT_SIZE_NAME);
        }
      }
    }
    if (cached_result_annotation != null) {
      if (!first_parameter) {
        writer.print(", ");
      }

      if (mode == Mode.CACHEDRESULT) {
        if (printTypes) {
          writer.print("long ");
        }
        writer.print(Utils.CACHED_BUFFER_LENGTH_NAME + ", ");
      }

      first_parameter = false;
      if (printTypes) {
        writer.print(getResultType(method, native_stub));
      }
      writer.print(" " + Utils.CACHED_BUFFER_NAME);
    }
    return first_parameter;
  }
  private static boolean printMethodCallArgument(
      PrintWriter writer,
      ExecutableElement method,
      VariableElement param,
      Map<VariableElement, TypeInfo> typeinfos_instance,
      Mode mode,
      boolean first_parameter,
      TypeMap type_map) {
    if (!first_parameter) {
      writer.print(", ");
    }

    AnnotationMirror auto_annotation = Utils.getParameterAutoAnnotation(param);
    Constant constant_annotation = param.getAnnotation(Constant.class);
    if (constant_annotation != null) {
      writer.print(constant_annotation.value());
    } else if (auto_annotation != null && mode == Mode.NORMAL) {
      Class param_type = NativeTypeTranslator.getClassFromType(auto_annotation.getAnnotationType());
      if (AutoType.class.equals(param_type)) {
        final AutoType auto_type_annotation = param.getAnnotation(AutoType.class);
        final VariableElement auto_parameter =
            Utils.findParameter(method, auto_type_annotation.value());
        final String auto_type = typeinfos_instance.get(auto_parameter).getAutoType();
        if (auto_type == null) {
          throw new RuntimeException(
              "No auto type for parameter " + param.getSimpleName() + " in method " + method);
        }
        writer.print(auto_type);
      } else if (AutoSize.class.equals(param_type)) {
        final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class);
        if (!auto_size_annotation.useExpression()) {
          final String auto_parameter_name = auto_size_annotation.value();
          final VariableElement auto_target_param =
              Utils.findParameter(method, auto_parameter_name);
          final TypeInfo auto_target_type_info = typeinfos_instance.get(auto_target_param);
          final boolean shift_remaining =
              !hasAnyParameterAutoTypeAnnotation(method, auto_target_param)
                  && Utils.isParameterMultiTyped(auto_target_param);
          int shifting = 0;
          if (shift_remaining) {
            shifting = getBufferElementSizeExponent(auto_target_type_info.getType());
            if (shifting > 0) {
              writer.print("(");
            }
          }
          if (auto_size_annotation.canBeNull()) {
            writer.print(
                "("
                    + auto_parameter_name
                    + " == null ? 0 : "
                    + auto_parameter_name
                    + ".remaining())");
          } else {
            writer.print(auto_parameter_name + ".remaining()");
          }
          // Shift the remaining if the target parameter is multityped and there's no AutoType to
          // track type
          if (shift_remaining && shifting > 0) {
            writer.print(" << " + shifting);
            writer.print(")");
          }
        }
        writer.print(auto_size_annotation.expression());
      } else {
        throw new RuntimeException("Unknown auto annotation " + param_type);
      }
    } else {
      if (mode == Mode.BUFFEROBJECT && param.getAnnotation(BufferObject.class) != null) {
        writer.print(param.getSimpleName() + Utils.BUFFER_OBJECT_PARAMETER_POSTFIX);
      } else {
        Class type = typeinfos_instance.get(param).getType();
        Check check_annotation = param.getAnnotation(Check.class);
        boolean hide_buffer = mode == Mode.AUTOS && getAutoTypeParameter(method, param) != null;
        if (hide_buffer) {
          writer.print("0L");
        } else {
          if (type == CharSequence.class || type == CharSequence[].class) {
            final String offset = Utils.getStringOffset(method, param);

            writer.print("APIUtil.getBuffer");
            if (param.getAnnotation(NullTerminated.class) != null) {
              writer.print("NT");
            }
            writer.print('(');
            writer.print(type_map.getAPIUtilParam(true));
            writer.print(param.getSimpleName());
            if (offset != null) {
              writer.print(", " + offset);
            }
            writer.print(")");
          } else {
            final AutoSize auto_size_annotation = param.getAnnotation(AutoSize.class);
            if (auto_size_annotation != null) {
              writer.print(auto_size_annotation.value() + "_");
            }

            final Class buffer_type = Utils.getNIOBufferType(param.asType());
            if (buffer_type == null) {
              writer.print(param.getSimpleName());
            } else {
              writer.print("MemoryUtil.getAddress");
              if (check_annotation != null && check_annotation.canBeNull()) {
                writer.print("Safe");
              }
              writer.print("(");
              writer.print(param.getSimpleName());
              writer.print(")");
            }
          }
        }
        if (type != long.class) {
          PointerWrapper pointer_annotation = param.getAnnotation(PointerWrapper.class);
          if (pointer_annotation != null) {
            if (pointer_annotation.canBeNull()) {
              writer.print(" == null ? 0 : " + param.getSimpleName());
            }
            writer.print(".getPointer()");
          }
        }
      }
    }
    return false;
  }