private void checkArgValueMatchesAllowedInputType()

in src/main/com/intellij/lang/jsgraphql/types/schema/idl/ArgValueOfAllowedTypeChecker.java [129:184]


  private void checkArgValueMatchesAllowedInputType(List<GraphQLError> errors,
                                                    @Nullable Value<?> instanceValue,
                                                    InputObjectTypeDefinition allowedTypeDefinition) {
    if (!(instanceValue instanceof ObjectValue objectValue)) {
      if (instanceValue != null) {
        addValidationError(errors, EXPECTED_OBJECT_MESSAGE, instanceValue.getClass().getSimpleName());
      }
      return;
    }

    // duck typing validation, if it looks like the definition
    // then it must be the same type as the definition

    List<ObjectField> fields = objectValue.getObjectFields();
    List<InputObjectTypeExtensionDefinition> inputObjExt =
      typeRegistry.inputObjectTypeExtensions().getOrDefault(allowedTypeDefinition.getName(), emptyList());
    Stream<InputValueDefinition> inputObjExtValues = inputObjExt.stream().flatMap(inputObj -> inputObj.getInputValueDefinitions().stream());
    List<InputValueDefinition> inputValueDefinitions =
      Stream.concat(allowedTypeDefinition.getInputValueDefinitions().stream(), inputObjExtValues).toList();

    // check for duplicated fields
    Map<String, Long> fieldsToOccurrenceMap = fields.stream().map(ObjectField::getName)
      .collect(groupingBy(Function.identity(), counting()));

    if (ContainerUtil.exists(fieldsToOccurrenceMap.values(), count -> count > 1)) {
      addValidationError(errors, DUPLICATED_KEYS_MESSAGE, fieldsToOccurrenceMap.entrySet().stream()
        .filter(entry -> entry.getValue() > 1)
        .map(Map.Entry::getKey)
        .collect(joining(",")));
      return;
    }

    // check for unknown fields
    Map<String, InputValueDefinition> nameToInputValueDefMap = inputValueDefinitions.stream()
      .collect(toMap(InputValueDefinition::getName, inputValueDef -> inputValueDef));

    List<ObjectField> unknownFields = ContainerUtil.filter(fields, field -> !nameToInputValueDefMap.containsKey(field.getName()));

    if (!unknownFields.isEmpty()) {
      addValidationError(errors, UNKNOWN_FIELDS_MESSAGE,
                         unknownFields.stream()
                           .map(ObjectField::getName)
                           .collect(joining(",")),
                         allowedTypeDefinition.getName());
      return;
    }

    // fields to map for easy access
    Map<String, ObjectField> nameToFieldsMap = fields.stream()
      .collect(toMap(ObjectField::getName, objectField -> objectField));
    // check each single field with its definition
    inputValueDefinitions.forEach(allowedValueDef -> {
      ObjectField objectField = nameToFieldsMap.get(allowedValueDef.getName());
      checkArgInputObjectValueFieldMatchesAllowedDefinition(errors, objectField, allowedValueDef);
    });
  }