PsiElementVisitor (@NotNull JsonValue root, @Nullable JsonSchemaObject schema, @NotNull JsonSchemaService service, @NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) { boolean checkRefs = schema != null && service.isSchemaFile(schema); return new JsonElementVisitor() { @Override public void visitElement(@NotNull PsiElement element) { if (element == root) { if (element instanceof JsonObject) { final JsonProperty schemaProp = ((JsonObject)element).findProperty("$schema"); if (schemaProp != null) { doCheck(schemaProp.getValue()); } } } super.visitElement(element); } @Override public void visitProperty(@NotNull JsonProperty o) { if (!checkRefs) return; if ("$ref".equals(o.getName())) { doCheck(o.getValue()); } super.visitProperty(o); } private void doCheck(JsonValue value) { if (!(value instanceof JsonStringLiteral)) return; for (PsiReference reference : value.getReferences()) { if (reference instanceof WebReference) continue; final PsiElement resolved = reference.resolve(); if (resolved == null) { holder.registerProblem(reference, getReferenceErrorDesc(reference), ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } } private static @InspectionMessage String getReferenceErrorDesc(PsiReference reference) { final String text = reference.getCanonicalText(); if (reference instanceof FileReference) { final int hash = text.indexOf('#'); return JsonBundle.message("json.schema.ref.file.not.found", hash == -1 ? text : text.substring(0, hash)); } if (reference instanceof JsonPointerReferenceProvider.JsonSchemaIdReference) { return JsonBundle.message("json.schema.ref.cannot.resolve.id", text); } final int lastSlash = text.lastIndexOf('/'); if (lastSlash == -1) { return JsonBundle.message("json.schema.ref.cannot.resolve.path", text); } final String substring = text.substring(text.lastIndexOf('/') + 1); try { Integer.parseInt(substring); return JsonBundle.message("json.schema.ref.no.array.element", substring); } catch (Exception e) { return JsonBundle.message("json.schema.ref.no.property", substring); } } }; }