private static void ValidateObjectField(
            ICollection <ISchemaError> errors,
            ObjectType objectType,
            InterfaceField first)
        {
            if (objectType.Fields.TryGetField(first.Name, out ObjectField field))
            {
                if (!field.Type.IsEqualTo(first.Type))
                {
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(string.Format(
                                               CultureInfo.InvariantCulture,
                                               TypeResources.InterfaceImplRule_ReturnTypeInvalid,
                                               first.Name,
                                               objectType.Name))
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .SetExtension("objectField", field)
                               .SetExtension("interfaceField", first)
                               .Build());
                }

                if (!ArgumentsAreEqual(field.Arguments, first.Arguments))
                {
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(string.Format(
                                               CultureInfo.InvariantCulture,
                                               TypeResources.InterfaceImplRule_ArgumentsNotImpl,
                                               objectType.Name,
                                               first.Name,
                                               first.DeclaringType.Name))
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .SetExtension("objectField", field)
                               .SetExtension("interfaceField", first)
                               .Build());
                }
            }
            else
            {
                errors.Add(SchemaErrorBuilder.New()
                           .SetMessage(string.Format(
                                           CultureInfo.InvariantCulture,
                                           TypeResources.InterfaceImplRule_FieldNotImpl,
                                           objectType.Name,
                                           first.Name,
                                           first.DeclaringType.Name))
                           .SetCode(ErrorCodes.Schema.MissingType)
                           .SetTypeSystemObject(objectType)
                           .AddSyntaxNode(objectType.SyntaxNode)
                           .AddSyntaxNode(first.SyntaxNode)
                           .Build());
            }
        }
        private static bool ValidateInterfaceFieldGroup(
            ICollection <ISchemaError> errors,
            ObjectType objectType,
            InterfaceField first,
            IGrouping <NameString, InterfaceField> interfaceField)
        {
            if (interfaceField.Count() == 1)
            {
                return(true);
            }

            foreach (InterfaceField field in interfaceField)
            {
                if (!field.Type.IsEqualTo(first.Type))
                {
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(string.Format(
                                               CultureInfo.InvariantCulture,
                                               TypeResources.InterfaceImplRule_FieldTypeInvalid,
                                               first.Name,
                                               first.DeclaringType.Name,
                                               field.DeclaringType.Name,
                                               objectType.Name))
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .SetExtension("objectField", field)
                               .SetExtension("interfaceField", first)
                               .Build());
                    return(false);
                }

                if (!ArgumentsAreEqual(field.Arguments, first.Arguments))
                {
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(string.Format(
                                               CultureInfo.InvariantCulture,
                                               TypeResources.InterfaceImplRule_ArgumentsDontMatch,
                                               first.Name,
                                               first.DeclaringType.Name,
                                               field.DeclaringType.Name,
                                               objectType.Name))
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .SetExtension("objectField", field)
                               .SetExtension("interfaceField", first)
                               .Build());
                    return(false);
                }
            }

            return(true);
        }
        private static void ValidateField(
            ICollection <ISchemaError> errors,
            ObjectType objectType,
            IGrouping <NameString, InterfaceField> interfaceField)
        {
            InterfaceField first = interfaceField.First();

            if (ValidateInterfaceFieldGroup(errors, objectType, first, interfaceField))
            {
                ValidateObjectField(errors, objectType, first);
            }
        }
        private static void ValidateObjectField(
            ICollection <ISchemaError> errors,
            ObjectType objectType,
            InterfaceField first)
        {
            if (objectType.Fields.TryGetField(first.Name, out ObjectField field))
            {
                if (!field.Type.IsEqualTo(first.Type))
                {
                    // TODO : RESOURCES
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(
                                   "The return type of the interface field " +
                                   $"{first.Name} does not match the field declared " +
                                   $"by object type {objectType.Name}.")
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .Build());
                }

                if (!ArgumentsAreEqual(field.Arguments, first.Arguments))
                {
                    // TODO : RESOURCES
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(
                                   $"Object type {objectType.Name} does not implement " +
                                   $"all arguments of field {first.Name} " +
                                   $"from interface {first.DeclaringType.Name}.")
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .Build());
                }
            }
            else
            {
                // TODO : RESOURCES
                errors.Add(SchemaErrorBuilder.New()
                           .SetMessage(
                               $"Object type {objectType.Name} does not implement the " +
                               $"field {first.Name} " +
                               $"from interface {first.DeclaringType.Name}.")
                           .SetCode(TypeErrorCodes.MissingType)
                           .SetTypeSystemObject(objectType)
                           .AddSyntaxNode(objectType.SyntaxNode)
                           .AddSyntaxNode(first.SyntaxNode)
                           .Build());
            }
        }
        private static bool ValidateInterfaceFieldGroup(
            ICollection <ISchemaError> errors,
            ObjectType objectType,
            InterfaceField first,
            IGrouping <NameString, InterfaceField> interfaceField)
        {
            if (interfaceField.Count() == 1)
            {
                return(true);
            }

            foreach (InterfaceField field in interfaceField)
            {
                if (!field.Type.IsEqualTo(first.Type))
                {
                    // TODO : RESOURCES
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(
                                   "The return type of the interface field " +
                                   $"{first.Name} from interface " +
                                   $"{first.DeclaringType.Name} and " +
                                   $"{field.DeclaringType.Name} do not match " +
                                   $"and are implemented by object type {objectType.Name}.")
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .Build());
                    return(false);
                }

                if (!ArgumentsAreEqual(field.Arguments, first.Arguments))
                {
                    // TODO : RESOURCES
                    errors.Add(SchemaErrorBuilder.New()
                               .SetMessage(
                                   $"The arguments of the interface field {first.Name} " +
                                   $"from interface {first.DeclaringType.Name} and " +
                                   $"{field.DeclaringType.Name} do not match " +
                                   $"and are implemented by object type {objectType.Name}.")
                               .SetTypeSystemObject(objectType)
                               .AddSyntaxNode(objectType.SyntaxNode)
                               .AddSyntaxNode(first.SyntaxNode)
                               .Build());
                    return(false);
                }
            }

            return(true);
        }