1717package com .networknt .schema ;
1818
1919import com .fasterxml .jackson .databind .JsonNode ;
20+ import com .networknt .schema .utils .SetView ;
2021
2122import org .slf4j .Logger ;
2223import org .slf4j .LoggerFactory ;
2324
2425import java .util .*;
25- import java .util .stream .Collectors ;
2626
2727/**
2828 * {@link JsonValidator} for anyOf.
@@ -64,7 +64,7 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
6464
6565 boolean initialHasMatchedNode = state .hasMatchedNode ();
6666
67- Set <ValidationMessage > allErrors = new LinkedHashSet <>() ;
67+ SetView <ValidationMessage > allErrors = null ;
6868
6969 int numberOfValidSubSchemas = 0 ;
7070 try {
@@ -82,7 +82,10 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
8282 // ignore it
8383 // For union type, it is a must to call TypeValidator
8484 if (typeValidator .getSchemaType () != JsonType .UNION && !typeValidator .equalsToSchemaType (node )) {
85- allErrors .addAll (typeValidator .validate (executionContext , node , rootNode , instanceLocation ));
85+ if (allErrors == null ) {
86+ allErrors = new SetView <>();
87+ }
88+ allErrors .union (typeValidator .validate (executionContext , node , rootNode , instanceLocation ));
8689 continue ;
8790 }
8891 }
@@ -105,63 +108,60 @@ public Set<ValidationMessage> validate(ExecutionContext executionContext, JsonNo
105108
106109 if (errors .isEmpty () && (!this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ())
107110 && canShortCircuit () && canShortCircuit (executionContext )) {
108- // Clear all errors.
109- allErrors . clear () ;
111+ // Clear all errors. Note that this is checked in finally.
112+ allErrors = null ;
110113 // return empty errors.
111114 return errors ;
112115 } else if (this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ()) {
113116 if (this .discriminatorContext .isDiscriminatorMatchFound ()) {
114117 if (!errors .isEmpty ()) {
115- allErrors .addAll (errors );
116- allErrors .add (message ().instanceNode (node ).instanceLocation (instanceLocation )
117- .locale (executionContext .getExecutionConfig ().getLocale ())
118- .failFast (executionContext .isFailFast ())
119- .arguments (DISCRIMINATOR_REMARK ).build ());
118+ // The following is to match the previous logic adding to all errors
119+ // which is generally discarded as it returns errors but the allErrors
120+ // is getting processed in finally
121+ if (allErrors == null ) {
122+ allErrors = new SetView <>();
123+ }
124+ allErrors .union (Collections
125+ .singleton (message ().instanceNode (node ).instanceLocation (instanceLocation )
126+ .locale (executionContext .getExecutionConfig ().getLocale ())
127+ .failFast (executionContext .isFailFast ()).arguments (DISCRIMINATOR_REMARK )
128+ .build ()));
120129 } else {
121- // Clear all errors.
122- allErrors . clear () ;
130+ // Clear all errors. Note that this is checked in finally.
131+ allErrors = null ;
123132 }
124133 return errors ;
125134 }
126135 }
127- allErrors .addAll (errors );
136+ if (allErrors == null ) {
137+ allErrors = new SetView <>();
138+ }
139+ allErrors .union (errors );
128140 }
129141 } finally {
130142 // Restore flag
131143 executionContext .setFailFast (failFast );
132144 }
133145
134- // determine only those errors which are NOT of type "required" property missing
135- Set <ValidationMessage > childNotRequiredErrors = allErrors .stream ()
136- .filter (error -> !ValidatorTypeCode .REQUIRED .getValue ().equals (error .getType ()))
137- .collect (Collectors .toCollection (LinkedHashSet ::new ));
138-
139- // in case we had at least one (anyOf, i.e. any number >= 1 of) valid subschemas, we can remove all other errors about "required" properties
140- if (numberOfValidSubSchemas >= 1 && childNotRequiredErrors .isEmpty ()) {
141- allErrors = childNotRequiredErrors ;
142- }
143-
144146 if (this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators () && this .discriminatorContext .isActive ()) {
145- final Set <ValidationMessage > errors = new LinkedHashSet <>();
146- errors .add (message ().instanceNode (node ).instanceLocation (instanceLocation )
147+ return Collections .singleton (message ().instanceNode (node ).instanceLocation (instanceLocation )
147148 .locale (executionContext .getExecutionConfig ().getLocale ())
148149 .arguments (
149150 "based on the provided discriminator. No alternative could be chosen based on the discriminator property" )
150151 .build ());
151- return Collections .unmodifiableSet (errors );
152152 }
153153 } finally {
154154 if (this .validationContext .getConfig ().isOpenAPI3StyleDiscriminators ()) {
155155 executionContext .leaveDiscriminatorContextImmediately (instanceLocation );
156156 }
157- if (allErrors .isEmpty ()) {
157+ if (allErrors == null || allErrors .isEmpty ()) {
158158 state .setMatchedNode (true );
159159 }
160160 }
161161 if (numberOfValidSubSchemas >= 1 ) {
162162 return Collections .emptySet ();
163163 }
164- return Collections .unmodifiableSet ( allErrors );
164+ return allErrors != null ? allErrors : Collections .emptySet ( );
165165 }
166166
167167 @ Override
0 commit comments