public NewGoFileAction() {
   super(
       GoBundle.message("new.go.file"),
       GoBundle.message("new.go.file.description"),
       GoIcons.GO_ICON_16x16,
       JavaModuleSourceRootTypes.SOURCES);
 }
  @Override
  public FileChooserDescriptor getHomeChooserDescriptor() {
    final FileChooserDescriptor descriptor =
        new FileChooserDescriptor(true, true, false, false, false, false) {
          public void validateSelectedFiles(VirtualFile[] files) throws Exception {
            if (files.length != 0) {
              final String selectedPath = files[0].getPath();
              boolean valid = isValidSdkHome(selectedPath);
              if (!valid) {
                valid = isValidSdkHome(adjustSelectedSdkHome(selectedPath));
                if (!valid) {
                  String message =
                      files[0].isDirectory()
                          ? ProjectBundle.message(
                              "sdk.configure.home.invalid.error", getPresentableName())
                          : ProjectBundle.message(
                              "sdk.configure.home.file.invalid.error", getPresentableName());
                  throw new Exception(message);
                }
              }
            }
          }
        };

    descriptor.setTitle(GoBundle.message("go.sdk.configure.title", getPresentableName()));
    return descriptor;
  }
  private static void checkNewCall(GoBuiltinCallExpression expression, InspectionResult result) {
    GoExpr[] arguments = expression.getArguments();
    GoPsiType type = expression.getTypeArgument();
    if (type == null) {
      if (arguments.length == 0) {
        result.addProblem(expression, GoBundle.message("error.missing.argument", "type", "new"));
      } else {
        result.addProblem(
            expression, GoBundle.message("error.expression.is.not.a.type", arguments[0].getText()));
      }
      return;
    }

    if (arguments.length != 0) {
      result.addProblem(expression, GoBundle.message("error.too.many.arguments.in.call", "new"));
    }
  }
  private static void checkMakeCall(GoBuiltinCallExpression expression, InspectionResult result) {
    GoExpr[] arguments = expression.getArguments();
    GoPsiType type = expression.getTypeArgument();
    if (type == null) {
      result.addProblem(expression, GoBundle.message("error.incorrect.make.type"));
      return;
    }

    GoPsiType finalType = resolveToFinalType(type);
    if (finalType instanceof GoPsiTypeSlice) {
      checkMakeSliceCall(expression, arguments, result);
    } else if (finalType instanceof GoPsiTypeChannel) {
      checkMakeChannelCall(arguments, result);
    } else if (finalType instanceof GoPsiTypeMap) {
      checkMakeMapCall(arguments, result);
    } else {
      result.addProblem(expression, GoBundle.message("error.cannot.make.type", type.getText()));
    }
  }
  public boolean validateConfiguration(CompileScope scope) {

    // Check for project sdk only if experimental make system is enabled (for now)
    Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
    if (projectSdk == null) {
      Messages.showErrorDialog(
          project,
          GoBundle.message("cannot.compile.no.go.project.sdk", project.getName()),
          GoBundle.message("cannot.compile"));
      return false;

    } else if (!(projectSdk.getSdkAdditionalData() instanceof GoSdkData)) {
      Messages.showErrorDialog(
          project,
          GoBundle.message("cannot.compile.invalid.project.sdk", project.getName()),
          GoBundle.message("cannot.compile"));
      return false;
    }

    return true;
  }
  protected void doCheckCreate(PsiDirectory dir, String parameterName, String typeName)
      throws IncorrectOperationException {
    // check to see if a file with the same name already exists

    String fileName = fileNameFromTypeName(typeName, parameterName);

    VirtualFile targetFile = dir.getVirtualFile().findFileByRelativePath(fileName);
    if (targetFile != null) {
      throw new IncorrectOperationException(
          GoBundle.message("target.file.exists", targetFile.getPath()));
    }
  }
  @Nullable
  @Override
  public ValidationInfo validate() {
    if (getSdkData() == null) {
      return new ValidationInfo(GoBundle.message("error.invalid.sdk.path", mySdkPath.getText()));
    }

    String goSdkPath = mySdkPath.getText();

    GoSdkType goSdk = new GoSdkType();
    if (!goSdk.isValidSdkHome(goSdkPath)) {
      return new ValidationInfo(GoBundle.message("error.invalid.sdk.path", mySdkPath.getText()));
    }

    GoSdkData goSdkData = GoSdkUtil.testGoogleGoSdk(goSdkPath);

    if (goSdkData == null) {
      return new ValidationInfo(GoBundle.message("error.invalid.sdk.path", mySdkPath.getText()));
    }

    goSdkData.GO_GOPATH_PATH = gopathPath.getText();

    labelSdkVersion.setText(goSdkData.VERSION_MAJOR);
    if (goSdkData.TARGET_OS != null && goSdkData.TARGET_ARCH != null) {
      labelSdkTarget.setText(
          String.format(
              "%s-%s (%s, %s)",
              goSdkData.TARGET_OS.getName(),
              goSdkData.TARGET_ARCH.getName(),
              GoSdkUtil.getCompilerName(goSdkData.TARGET_ARCH),
              GoSdkUtil.getLinkerName(goSdkData.TARGET_ARCH)));
    } else {
      labelSdkTarget.setText("Unknown target");
    }

    labelBinariesPath.setText(goSdkData.GO_BIN_PATH);
    return null;
  }
  public static void checkFunctionCallArguments(
      GoCallOrConvExpression call, InspectionResult result) {
    if (call == null) {
      return;
    }

    GoExpr[] arguments = call.getArguments();
    if (arguments == null) {
      return;
    }

    if (arguments.length > 1) {
      checkExpressionShouldReturnOneResult(arguments, result);
    }

    int argumentCount = arguments.length;
    if (argumentCount == 1) {
      argumentCount = getExpressionResultCount(arguments[0]);
    }

    int expectedCount = getFunctionParameterCount(call);
    if (argumentCount == UNKNOWN_COUNT || expectedCount == UNKNOWN_COUNT) {
      return;
    }

    String name = "";
    GoLiteralIdentifier id = getCallFunctionIdentifier(call);
    if (id != null) {
      name = id.getName();
    }

    if (argumentCount < expectedCount) {
      result.addProblem(call, GoBundle.message("error.not.enough.arguments.in.call", name));
    } else if (argumentCount > expectedCount) {
      result.addProblem(call, GoBundle.message("error.too.many.arguments.in.call", name));
    }
  }
  private static void checkMakeSliceCall(
      GoBuiltinCallExpression expression, GoExpr[] arguments, InspectionResult result) {
    if (arguments.length > 2) {
      result.addProblem(
          arguments[2],
          arguments[arguments.length - 1],
          GoBundle.message("error.too.many.arguments.in.call", "make"));
      return;
    } else if (arguments.length == 0) {
      String method = "make(" + expression.getTypeArgument().getText() + ")";
      result.addProblem(expression, GoBundle.message("error.missing.argument", "len", method));
      return;
    }

    // TODO: check len
    GoExpr len = arguments[0];

    if (arguments.length != 2) {
      return;
    }

    // TODO: check capacity
    GoExpr capacity = arguments[1];
  }
  private static void checkMakeChannelCall(GoExpr[] arguments, InspectionResult result) {
    if (arguments.length > 1) {
      result.addProblem(
          arguments[1],
          arguments[arguments.length - 1],
          GoBundle.message("error.too.many.arguments.in.call", "make"));
      return;
    }

    if (arguments.length != 1) {
      return;
    }

    // TODO: check bufferSize
    GoExpr bufferSize = arguments[0];
  }
  public static IElementType parse(PsiBuilder builder, GoParser parser) {

    if (!ParserUtils.lookAhead(builder, kIF)) return null;

    PsiBuilder.Marker marker = builder.mark();

    ParserUtils.getToken(builder, kIF);

    PsiBuilder.Marker mark = builder.mark();

    boolean allowComposite = parser.resetFlag(AllowCompositeLiteral, false);

    IElementType statementType = parser.parseStatementSimple(builder);
    if (statementType == EXPRESSION_STATEMENT && ParserUtils.lookAhead(builder, pLCURLY)) {
      mark.rollbackTo();
    } else {
      mark.drop();
      ParserUtils.endStatement(builder);
    }

    parser.parseExpression(builder);
    parser.resetFlag(AllowCompositeLiteral, allowComposite);

    parser.parseBody(builder);

    if (ParserUtils.lookAhead(builder, kELSE)) {
      if (builder.getTokenType() == kELSE) {
        ParserUtils.getToken(builder, kELSE);
        if (ParserUtils.lookAhead(builder, kIF)) IfStatement.parse(builder, parser);
        else if (ParserUtils.lookAhead(builder, pLCURLY)) BlockStatement.parse(builder, parser);
        else {
          builder.error(GoBundle.message("error.block.of.if.statement.expected"));
        }
      }
    }

    marker.done(IF_STATEMENT);
    return IF_STATEMENT;
  }
 @Override
 public String getDescription() {
   return GoBundle.message("go.module.type.description");
 }
 @Override
 public String getName() {
   return GoBundle.message("go.module.type.name");
 }
 @Override
 protected String getActionName(PsiDirectory directory, String newName, String templateName) {
   return GoBundle.message("new.go.lib.action.text");
 }
 @Override
 public String getReportActionText() {
   return GoBundle.message("go.error.report.action");
 }
 @Override
 public void buildUI(@NotNull SettingsStep settingsStep) {
   settingsStep.addSettingsField(GoBundle.message("go.sdk.configure.title"), mySdkPath);
 }