瀏覽代碼

Refactor FilterXContentParser and DelegatingXContentParser (#83457)

We have two implementations of XContentParser that both delegate all of its methods to a delegate, either an inner parser provided at construction (FilterXContentParser) or a more dynamic variant that is returned by overriding the delegate method (DelegatingXContentParser).

Effectively the two classes do exactly the same, the only difference being how the delegate parser is provided. While these two are two separate implementations, they could inherit from each other.

With this change we make FilterXContentParser be the previous DelegatingXContentParser, that allows to override the delegate method, and we introduce a new FilterXContentParserWrapper that takes the fixed delegate as a constructor argument.

Additionally, XContentSubParser is rewritten to extend FilterXContentParserWrapper.
Luca Cavanna 3 年之前
父節點
當前提交
35c9258e46

+ 0 - 244
libs/x-content/src/main/java/org/elasticsearch/xcontent/DelegatingXContentParser.java

@@ -1,244 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.xcontent;
-
-import org.elasticsearch.core.CheckedFunction;
-import org.elasticsearch.core.RestApiVersion;
-
-import java.io.IOException;
-import java.nio.CharBuffer;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
-
-public abstract class DelegatingXContentParser implements XContentParser {
-
-    protected abstract XContentParser delegate();
-
-    @Override
-    public XContentType contentType() {
-        return delegate().contentType();
-    }
-
-    @Override
-    public void allowDuplicateKeys(boolean allowDuplicateKeys) {
-        delegate().allowDuplicateKeys(allowDuplicateKeys);
-    }
-
-    @Override
-    public Token nextToken() throws IOException {
-        return delegate().nextToken();
-    }
-
-    @Override
-    public void skipChildren() throws IOException {
-        delegate().skipChildren();
-    }
-
-    @Override
-    public Token currentToken() {
-        return delegate().currentToken();
-    }
-
-    @Override
-    public String currentName() throws IOException {
-        return delegate().currentName();
-    }
-
-    @Override
-    public Map<String, Object> map() throws IOException {
-        return delegate().map();
-    }
-
-    @Override
-    public Map<String, Object> mapOrdered() throws IOException {
-        return delegate().mapOrdered();
-    }
-
-    @Override
-    public Map<String, String> mapStrings() throws IOException {
-        return delegate().mapStrings();
-    }
-
-    @Override
-    public <T> Map<String, T> map(Supplier<Map<String, T>> mapFactory, CheckedFunction<XContentParser, T, IOException> mapValueParser)
-        throws IOException {
-        return delegate().map(mapFactory, mapValueParser);
-    }
-
-    @Override
-    public List<Object> list() throws IOException {
-        return delegate().list();
-    }
-
-    @Override
-    public List<Object> listOrderedMap() throws IOException {
-        return delegate().listOrderedMap();
-    }
-
-    @Override
-    public String text() throws IOException {
-        return delegate().text();
-    }
-
-    @Override
-    public String textOrNull() throws IOException {
-        return delegate().textOrNull();
-    }
-
-    @Override
-    public CharBuffer charBufferOrNull() throws IOException {
-        return delegate().charBufferOrNull();
-    }
-
-    @Override
-    public CharBuffer charBuffer() throws IOException {
-        return delegate().charBuffer();
-    }
-
-    @Override
-    public Object objectText() throws IOException {
-        return delegate().objectText();
-    }
-
-    @Override
-    public Object objectBytes() throws IOException {
-        return delegate().objectBytes();
-    }
-
-    @Override
-    public boolean hasTextCharacters() {
-        return delegate().hasTextCharacters();
-    }
-
-    @Override
-    public char[] textCharacters() throws IOException {
-        return delegate().textCharacters();
-    }
-
-    @Override
-    public int textLength() throws IOException {
-        return delegate().textLength();
-    }
-
-    @Override
-    public int textOffset() throws IOException {
-        return delegate().textOffset();
-    }
-
-    @Override
-    public Number numberValue() throws IOException {
-        return delegate().numberValue();
-    }
-
-    @Override
-    public NumberType numberType() throws IOException {
-        return delegate().numberType();
-    }
-
-    @Override
-    public short shortValue(boolean coerce) throws IOException {
-        return delegate().shortValue(coerce);
-    }
-
-    @Override
-    public int intValue(boolean coerce) throws IOException {
-        return delegate().intValue(coerce);
-    }
-
-    @Override
-    public long longValue(boolean coerce) throws IOException {
-        return delegate().longValue(coerce);
-    }
-
-    @Override
-    public float floatValue(boolean coerce) throws IOException {
-        return delegate().floatValue(coerce);
-    }
-
-    @Override
-    public double doubleValue(boolean coerce) throws IOException {
-        return delegate().doubleValue(coerce);
-    }
-
-    @Override
-    public short shortValue() throws IOException {
-        return delegate().shortValue();
-    }
-
-    @Override
-    public int intValue() throws IOException {
-        return delegate().intValue();
-    }
-
-    @Override
-    public long longValue() throws IOException {
-        return delegate().longValue();
-    }
-
-    @Override
-    public float floatValue() throws IOException {
-        return delegate().floatValue();
-    }
-
-    @Override
-    public double doubleValue() throws IOException {
-        return delegate().doubleValue();
-    }
-
-    @Override
-    public boolean isBooleanValue() throws IOException {
-        return delegate().isBooleanValue();
-    }
-
-    @Override
-    public boolean booleanValue() throws IOException {
-        return delegate().booleanValue();
-    }
-
-    @Override
-    public byte[] binaryValue() throws IOException {
-        return delegate().binaryValue();
-    }
-
-    @Override
-    public XContentLocation getTokenLocation() {
-        return delegate().getTokenLocation();
-    }
-
-    @Override
-    public <T> T namedObject(Class<T> categoryClass, String name, Object context) throws IOException {
-        return delegate().namedObject(categoryClass, name, context);
-    }
-
-    @Override
-    public NamedXContentRegistry getXContentRegistry() {
-        return delegate().getXContentRegistry();
-    }
-
-    @Override
-    public boolean isClosed() {
-        return delegate().isClosed();
-    }
-
-    @Override
-    public RestApiVersion getRestApiVersion() {
-        return delegate().getRestApiVersion();
-    }
-
-    @Override
-    public DeprecationHandler getDeprecationHandler() {
-        return delegate().getDeprecationHandler();
-    }
-
-    @Override
-    public void close() throws IOException {
-        delegate().close();
-    }
-}

+ 8 - 8
libs/x-content/src/main/java/org/elasticsearch/xcontent/DotExpandingXContentParser.java

@@ -17,9 +17,9 @@ import java.util.Deque;
  *
  * A fieldname named {@code "foo.bar.baz":...} will be parsed instead as {@code 'foo':{'bar':{'baz':...}}}
  */
-public class DotExpandingXContentParser extends FilterXContentParser {
+public class DotExpandingXContentParser extends FilterXContentParserWrapper {
 
-    private static class WrappingParser extends DelegatingXContentParser {
+    private static final class WrappingParser extends FilterXContentParser {
 
         final Deque<XContentParser> parsers = new ArrayDeque<>();
 
@@ -135,7 +135,7 @@ public class DotExpandingXContentParser extends FilterXContentParser {
             assert expandedTokens < subPaths.length * 2;
             if (expandedTokens == subPaths.length * 2 - 1) {
                 state = State.PARSING_ORIGINAL_CONTENT;
-                Token token = in.currentToken();
+                Token token = delegate().currentToken();
                 if (token == Token.START_OBJECT || token == Token.START_ARRAY) {
                     innerLevel++;
                 }
@@ -170,7 +170,7 @@ public class DotExpandingXContentParser extends FilterXContentParser {
         return switch (state) {
             case EXPANDING_START_OBJECT -> expandedTokens % 2 == 1 ? Token.START_OBJECT : Token.FIELD_NAME;
             case ENDING_EXPANDED_OBJECT -> Token.END_OBJECT;
-            case PARSING_ORIGINAL_CONTENT -> in.currentToken();
+            case PARSING_ORIGINAL_CONTENT -> delegate().currentToken();
         };
     }
 
@@ -181,14 +181,14 @@ public class DotExpandingXContentParser extends FilterXContentParser {
             // whenever we are parsing some inner object/array we can easily delegate to the inner parser
             // e.g. field.with.dots: { obj:{ parsing here } }
             if (innerLevel > 0) {
-                return in.currentName();
+                return delegate().currentName();
             }
             Token token = currentToken();
             // if we are parsing the outer object/array, only at the start object/array we need to return
             // e.g. dots instead of field.with.dots otherwise we can simply delegate to the inner parser
             // which will do the right thing
             if (innerLevel == 0 && token != Token.START_OBJECT && token != Token.START_ARRAY) {
-                return in.currentName();
+                return delegate().currentName();
             }
             // note that innerLevel can be -1 if there are no inner object/array e.g. field.with.dots: value
             // as well as while there is and we are parsing their END_OBJECT or END_ARRAY
@@ -199,7 +199,7 @@ public class DotExpandingXContentParser extends FilterXContentParser {
     @Override
     public void skipChildren() throws IOException {
         if (state == State.EXPANDING_START_OBJECT) {
-            in.skipChildren();
+            delegate().skipChildren();
             state = State.ENDING_EXPANDED_OBJECT;
         }
         if (state == State.PARSING_ORIGINAL_CONTENT) {
@@ -231,7 +231,7 @@ public class DotExpandingXContentParser extends FilterXContentParser {
         return super.booleanValue();
     }
 
-    private static class SingletonValueXContentParser extends FilterXContentParser {
+    private static class SingletonValueXContentParser extends FilterXContentParserWrapper {
 
         protected SingletonValueXContentParser(XContentParser in) {
             super(in);

+ 48 - 50
libs/x-content/src/main/java/org/elasticsearch/xcontent/FilterXContentParser.java

@@ -18,234 +18,232 @@ import java.util.Map;
 import java.util.function.Supplier;
 
 /**
- * Filters an existing XContentParser by using a delegate
+ * Delegates every method to the parser returned by the {@link #delegate()} method.
+ * To be used extended directly when the delegated parser may dynamically changed.
+ * Extend {@link FilterXContentParserWrapper} instead when the delegate is fixed and can be provided at construction time.
  */
 public abstract class FilterXContentParser implements XContentParser {
 
-    protected final XContentParser in;
-
-    protected FilterXContentParser(XContentParser in) {
-        this.in = in;
-    }
+    protected abstract XContentParser delegate();
 
     @Override
     public XContentType contentType() {
-        return in.contentType();
+        return delegate().contentType();
     }
 
     @Override
     public void allowDuplicateKeys(boolean allowDuplicateKeys) {
-        in.allowDuplicateKeys(allowDuplicateKeys);
+        delegate().allowDuplicateKeys(allowDuplicateKeys);
     }
 
     @Override
     public Token nextToken() throws IOException {
-        return in.nextToken();
+        return delegate().nextToken();
     }
 
     @Override
     public void skipChildren() throws IOException {
-        in.skipChildren();
+        delegate().skipChildren();
     }
 
     @Override
     public Token currentToken() {
-        return in.currentToken();
+        return delegate().currentToken();
     }
 
     @Override
     public String currentName() throws IOException {
-        return in.currentName();
+        return delegate().currentName();
     }
 
     @Override
     public Map<String, Object> map() throws IOException {
-        return in.map();
+        return delegate().map();
     }
 
     @Override
     public Map<String, Object> mapOrdered() throws IOException {
-        return in.mapOrdered();
+        return delegate().mapOrdered();
     }
 
     @Override
     public Map<String, String> mapStrings() throws IOException {
-        return in.mapStrings();
+        return delegate().mapStrings();
     }
 
     @Override
     public <T> Map<String, T> map(Supplier<Map<String, T>> mapFactory, CheckedFunction<XContentParser, T, IOException> mapValueParser)
         throws IOException {
-        return in.map(mapFactory, mapValueParser);
+        return delegate().map(mapFactory, mapValueParser);
     }
 
     @Override
     public List<Object> list() throws IOException {
-        return in.list();
+        return delegate().list();
     }
 
     @Override
     public List<Object> listOrderedMap() throws IOException {
-        return in.listOrderedMap();
+        return delegate().listOrderedMap();
     }
 
     @Override
     public String text() throws IOException {
-        return in.text();
+        return delegate().text();
     }
 
     @Override
     public String textOrNull() throws IOException {
-        return in.textOrNull();
+        return delegate().textOrNull();
     }
 
     @Override
     public CharBuffer charBufferOrNull() throws IOException {
-        return in.charBufferOrNull();
+        return delegate().charBufferOrNull();
     }
 
     @Override
     public CharBuffer charBuffer() throws IOException {
-        return in.charBuffer();
+        return delegate().charBuffer();
     }
 
     @Override
     public Object objectText() throws IOException {
-        return in.objectText();
+        return delegate().objectText();
     }
 
     @Override
     public Object objectBytes() throws IOException {
-        return in.objectBytes();
+        return delegate().objectBytes();
     }
 
     @Override
     public boolean hasTextCharacters() {
-        return in.hasTextCharacters();
+        return delegate().hasTextCharacters();
     }
 
     @Override
     public char[] textCharacters() throws IOException {
-        return in.textCharacters();
+        return delegate().textCharacters();
     }
 
     @Override
     public int textLength() throws IOException {
-        return in.textLength();
+        return delegate().textLength();
     }
 
     @Override
     public int textOffset() throws IOException {
-        return in.textOffset();
+        return delegate().textOffset();
     }
 
     @Override
     public Number numberValue() throws IOException {
-        return in.numberValue();
+        return delegate().numberValue();
     }
 
     @Override
     public NumberType numberType() throws IOException {
-        return in.numberType();
+        return delegate().numberType();
     }
 
     @Override
     public short shortValue(boolean coerce) throws IOException {
-        return in.shortValue(coerce);
+        return delegate().shortValue(coerce);
     }
 
     @Override
     public int intValue(boolean coerce) throws IOException {
-        return in.intValue(coerce);
+        return delegate().intValue(coerce);
     }
 
     @Override
     public long longValue(boolean coerce) throws IOException {
-        return in.longValue(coerce);
+        return delegate().longValue(coerce);
     }
 
     @Override
     public float floatValue(boolean coerce) throws IOException {
-        return in.floatValue(coerce);
+        return delegate().floatValue(coerce);
     }
 
     @Override
     public double doubleValue(boolean coerce) throws IOException {
-        return in.doubleValue(coerce);
+        return delegate().doubleValue(coerce);
     }
 
     @Override
     public short shortValue() throws IOException {
-        return in.shortValue();
+        return delegate().shortValue();
     }
 
     @Override
     public int intValue() throws IOException {
-        return in.intValue();
+        return delegate().intValue();
     }
 
     @Override
     public long longValue() throws IOException {
-        return in.longValue();
+        return delegate().longValue();
     }
 
     @Override
     public float floatValue() throws IOException {
-        return in.floatValue();
+        return delegate().floatValue();
     }
 
     @Override
     public double doubleValue() throws IOException {
-        return in.doubleValue();
+        return delegate().doubleValue();
     }
 
     @Override
     public boolean isBooleanValue() throws IOException {
-        return in.isBooleanValue();
+        return delegate().isBooleanValue();
     }
 
     @Override
     public boolean booleanValue() throws IOException {
-        return in.booleanValue();
+        return delegate().booleanValue();
     }
 
     @Override
     public byte[] binaryValue() throws IOException {
-        return in.binaryValue();
+        return delegate().binaryValue();
     }
 
     @Override
     public XContentLocation getTokenLocation() {
-        return in.getTokenLocation();
+        return delegate().getTokenLocation();
     }
 
     @Override
     public <T> T namedObject(Class<T> categoryClass, String name, Object context) throws IOException {
-        return in.namedObject(categoryClass, name, context);
+        return delegate().namedObject(categoryClass, name, context);
     }
 
     @Override
     public NamedXContentRegistry getXContentRegistry() {
-        return in.getXContentRegistry();
+        return delegate().getXContentRegistry();
     }
 
     @Override
     public boolean isClosed() {
-        return in.isClosed();
+        return delegate().isClosed();
     }
 
     @Override
     public void close() throws IOException {
-        in.close();
+        delegate().close();
     }
 
     @Override
     public RestApiVersion getRestApiVersion() {
-        return in.getRestApiVersion();
+        return delegate().getRestApiVersion();
     }
 
     @Override
     public DeprecationHandler getDeprecationHandler() {
-        return in.getDeprecationHandler();
+        return delegate().getDeprecationHandler();
     }
 }

+ 25 - 0
libs/x-content/src/main/java/org/elasticsearch/xcontent/FilterXContentParserWrapper.java

@@ -0,0 +1,25 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.xcontent;
+
+/**
+ * Wraps the provided {@link XContentParser} and delegates to it.
+ */
+public class FilterXContentParserWrapper extends FilterXContentParser {
+    private final XContentParser delegate;
+
+    public FilterXContentParserWrapper(XContentParser delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    protected final XContentParser delegate() {
+        return delegate;
+    }
+}

+ 4 - 213
libs/x-content/src/main/java/org/elasticsearch/xcontent/XContentSubParser.java

@@ -8,14 +8,7 @@
 
 package org.elasticsearch.xcontent;
 
-import org.elasticsearch.core.CheckedFunction;
-import org.elasticsearch.core.RestApiVersion;
-
 import java.io.IOException;
-import java.nio.CharBuffer;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
 
 /**
  * Wrapper for a XContentParser that makes a single object/array look like a complete document.
@@ -24,34 +17,23 @@ import java.util.function.Supplier;
  * as skipping to the end of the object in case of a parsing error. The wrapper is intended to be
  * used for parsing objects that should be ignored if they are malformed.
  */
-public class XContentSubParser implements XContentParser {
+public class XContentSubParser extends FilterXContentParserWrapper {
 
-    private final XContentParser parser;
     private int level;
     private boolean closed;
 
     public XContentSubParser(XContentParser parser) {
-        this.parser = parser;
+        super(parser);
         if (parser.currentToken() != Token.START_OBJECT && parser.currentToken() != Token.START_ARRAY) {
             throw new IllegalStateException("The sub parser has to be created on the start of an object or array");
         }
         level = 1;
     }
 
-    @Override
-    public XContentType contentType() {
-        return parser.contentType();
-    }
-
-    @Override
-    public void allowDuplicateKeys(boolean allowDuplicateKeys) {
-        parser.allowDuplicateKeys(allowDuplicateKeys);
-    }
-
     @Override
     public Token nextToken() throws IOException {
         if (level > 0) {
-            Token token = parser.nextToken();
+            Token token = super.nextToken();
             if (token == Token.START_OBJECT || token == Token.START_ARRAY) {
                 level++;
             } else if (token == Token.END_OBJECT || token == Token.END_ARRAY) {
@@ -65,7 +47,7 @@ public class XContentSubParser implements XContentParser {
 
     @Override
     public void skipChildren() throws IOException {
-        Token token = parser.currentToken();
+        Token token = currentToken();
         if (token != Token.START_OBJECT && token != Token.START_ARRAY) {
             // skip if not starting on an object or an array
             return;
@@ -78,202 +60,11 @@ public class XContentSubParser implements XContentParser {
         }
     }
 
-    @Override
-    public Token currentToken() {
-        return parser.currentToken();
-    }
-
-    @Override
-    public String currentName() throws IOException {
-        return parser.currentName();
-    }
-
-    @Override
-    public Map<String, Object> map() throws IOException {
-        return parser.map();
-    }
-
-    @Override
-    public Map<String, Object> mapOrdered() throws IOException {
-        return parser.mapOrdered();
-    }
-
-    @Override
-    public Map<String, String> mapStrings() throws IOException {
-        return parser.mapStrings();
-    }
-
-    @Override
-    public <T> Map<String, T> map(Supplier<Map<String, T>> mapFactory, CheckedFunction<XContentParser, T, IOException> mapValueParser)
-        throws IOException {
-        return parser.map(mapFactory, mapValueParser);
-    }
-
-    @Override
-    public List<Object> list() throws IOException {
-        return parser.list();
-    }
-
-    @Override
-    public List<Object> listOrderedMap() throws IOException {
-        return parser.listOrderedMap();
-    }
-
-    @Override
-    public String text() throws IOException {
-        return parser.text();
-    }
-
-    @Override
-    public String textOrNull() throws IOException {
-        return parser.textOrNull();
-    }
-
-    @Override
-    public CharBuffer charBufferOrNull() throws IOException {
-        return parser.charBufferOrNull();
-    }
-
-    @Override
-    public CharBuffer charBuffer() throws IOException {
-        return parser.charBuffer();
-    }
-
-    @Override
-    public Object objectText() throws IOException {
-        return parser.objectText();
-    }
-
-    @Override
-    public Object objectBytes() throws IOException {
-        return parser.objectBytes();
-    }
-
-    @Override
-    public boolean hasTextCharacters() {
-        return parser.hasTextCharacters();
-    }
-
-    @Override
-    public char[] textCharacters() throws IOException {
-        return parser.textCharacters();
-    }
-
-    @Override
-    public int textLength() throws IOException {
-        return parser.textLength();
-    }
-
-    @Override
-    public int textOffset() throws IOException {
-        return parser.textOffset();
-    }
-
-    @Override
-    public Number numberValue() throws IOException {
-        return parser.numberValue();
-    }
-
-    @Override
-    public NumberType numberType() throws IOException {
-        return parser.numberType();
-    }
-
-    @Override
-    public short shortValue(boolean coerce) throws IOException {
-        return parser.shortValue(coerce);
-    }
-
-    @Override
-    public int intValue(boolean coerce) throws IOException {
-        return parser.intValue(coerce);
-    }
-
-    @Override
-    public long longValue(boolean coerce) throws IOException {
-        return parser.longValue(coerce);
-    }
-
-    @Override
-    public float floatValue(boolean coerce) throws IOException {
-        return parser.floatValue(coerce);
-    }
-
-    @Override
-    public double doubleValue(boolean coerce) throws IOException {
-        return parser.doubleValue();
-    }
-
-    @Override
-    public short shortValue() throws IOException {
-        return parser.shortValue();
-    }
-
-    @Override
-    public int intValue() throws IOException {
-        return parser.intValue();
-    }
-
-    @Override
-    public long longValue() throws IOException {
-        return parser.longValue();
-    }
-
-    @Override
-    public float floatValue() throws IOException {
-        return parser.floatValue();
-    }
-
-    @Override
-    public double doubleValue() throws IOException {
-        return parser.doubleValue();
-    }
-
-    @Override
-    public boolean isBooleanValue() throws IOException {
-        return parser.isBooleanValue();
-    }
-
-    @Override
-    public boolean booleanValue() throws IOException {
-        return parser.booleanValue();
-    }
-
-    @Override
-    public byte[] binaryValue() throws IOException {
-        return parser.binaryValue();
-    }
-
-    @Override
-    public XContentLocation getTokenLocation() {
-        return parser.getTokenLocation();
-    }
-
-    @Override
-    public <T> T namedObject(Class<T> categoryClass, String name, Object context) throws IOException {
-        return parser.namedObject(categoryClass, name, context);
-    }
-
-    @Override
-    public NamedXContentRegistry getXContentRegistry() {
-        return parser.getXContentRegistry();
-    }
-
     @Override
     public boolean isClosed() {
         return closed;
     }
 
-    @Override
-    public RestApiVersion getRestApiVersion() {
-        return parser.getRestApiVersion();
-    }
-
-    @Override
-    public DeprecationHandler getDeprecationHandler() {
-        return parser.getDeprecationHandler();
-    }
-
     @Override
     public void close() throws IOException {
         if (closed == false) {

+ 3 - 3
server/src/main/java/org/elasticsearch/index/mapper/CompletionFieldMapper.java

@@ -30,8 +30,8 @@ import org.elasticsearch.index.query.SearchExecutionContext;
 import org.elasticsearch.search.suggest.completion.CompletionSuggester;
 import org.elasticsearch.search.suggest.completion.context.ContextMapping;
 import org.elasticsearch.search.suggest.completion.context.ContextMappings;
-import org.elasticsearch.xcontent.DelegatingXContentParser;
 import org.elasticsearch.xcontent.DeprecationHandler;
+import org.elasticsearch.xcontent.FilterXContentParser;
 import org.elasticsearch.xcontent.NamedXContentRegistry;
 import org.elasticsearch.xcontent.ToXContent;
 import org.elasticsearch.xcontent.XContentLocation;
@@ -610,8 +610,8 @@ public class CompletionFieldMapper extends FieldMapper {
      * consumer supports the object structure.
      */
     // This parser changes behaviour depending on which methods are called by consumers, which is extremely delicate. This kind of works for
-    // our internal mappers, but what about mappers from plugins
-    static class MultiFieldParser extends DelegatingXContentParser {
+    // our internal mappers, but what about mappers from plugins?
+    static class MultiFieldParser extends FilterXContentParser {
         private final String textValue;
         private final String fieldName;
         private final XContentLocation locationOffset;

+ 4 - 4
server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java

@@ -13,7 +13,7 @@ import org.elasticsearch.common.time.DateFormatter;
 import org.elasticsearch.index.IndexSettings;
 import org.elasticsearch.index.analysis.IndexAnalyzers;
 import org.elasticsearch.xcontent.DotExpandingXContentParser;
-import org.elasticsearch.xcontent.FilterXContentParser;
+import org.elasticsearch.xcontent.FilterXContentParserWrapper;
 import org.elasticsearch.xcontent.XContentParser;
 
 import java.io.IOException;
@@ -380,7 +380,7 @@ public abstract class DocumentParserContext {
 
     // XContentParser that wraps an existing parser positioned on a value,
     // and a field name, and returns a stream that looks like { 'field' : 'value' }
-    private static class CopyToParser extends FilterXContentParser {
+    private static class CopyToParser extends FilterXContentParserWrapper {
 
         enum State {
             FIELD,
@@ -400,7 +400,7 @@ public abstract class DocumentParserContext {
         public Token nextToken() throws IOException {
             if (state == State.FIELD) {
                 state = State.VALUE;
-                return in.currentToken();
+                return delegate().currentToken();
             }
             return Token.END_OBJECT;
         }
@@ -410,7 +410,7 @@ public abstract class DocumentParserContext {
             if (state == State.FIELD) {
                 return Token.FIELD_NAME;
             }
-            return in.currentToken();
+            return delegate().currentToken();
         }
 
         @Override

+ 2 - 2
server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java

@@ -42,7 +42,7 @@ import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
 import org.elasticsearch.search.lookup.FieldValues;
 import org.elasticsearch.search.lookup.SearchLookup;
 import org.elasticsearch.search.runtime.GeoPointScriptFieldDistanceFeatureQuery;
-import org.elasticsearch.xcontent.FilterXContentParser;
+import org.elasticsearch.xcontent.FilterXContentParserWrapper;
 import org.elasticsearch.xcontent.XContentBuilder;
 import org.elasticsearch.xcontent.XContentParser;
 
@@ -225,7 +225,7 @@ public class GeoPointFieldMapper extends AbstractPointGeometryFieldMapper<GeoPoi
      * in the incoming document. We rely on the fact that consumers are only ever call {@link XContentParser#textOrNull()} and never
      * advance tokens, which is explicitly disallowed by this parser.
      */
-    static class GeoHashMultiFieldParser extends FilterXContentParser {
+    static class GeoHashMultiFieldParser extends FilterXContentParserWrapper {
         private final String value;
 
         GeoHashMultiFieldParser(XContentParser innerParser, String value) {

+ 2 - 2
test/framework/src/main/java/org/elasticsearch/common/xcontent/support/AbstractFilteringTestCase.java

@@ -13,7 +13,7 @@ import org.elasticsearch.common.util.set.Sets;
 import org.elasticsearch.core.CheckedFunction;
 import org.elasticsearch.test.ESTestCase;
 import org.elasticsearch.xcontent.DeprecationHandler;
-import org.elasticsearch.xcontent.FilterXContentParser;
+import org.elasticsearch.xcontent.FilterXContentParserWrapper;
 import org.elasticsearch.xcontent.NamedXContentRegistry;
 import org.elasticsearch.xcontent.XContent;
 import org.elasticsearch.xcontent.XContentBuilder;
@@ -55,7 +55,7 @@ public abstract class AbstractFilteringTestCase extends ESTestCase {
                         .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, stream)
                 ) {
                     // copyCurrentStructure does not property handle filters when it is passed a json parser. So we hide it.
-                    return builder.copyCurrentStructure(new FilterXContentParser(parser) {
+                    return builder.copyCurrentStructure(new FilterXContentParserWrapper(parser) {
                     });
                 }
             }

+ 2 - 2
x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/support/xcontent/WatcherXContentParser.java

@@ -8,7 +8,7 @@ package org.elasticsearch.xpack.core.watcher.support.xcontent;
 
 import org.elasticsearch.ElasticsearchParseException;
 import org.elasticsearch.core.Nullable;
-import org.elasticsearch.xcontent.FilterXContentParser;
+import org.elasticsearch.xcontent.FilterXContentParserWrapper;
 import org.elasticsearch.xcontent.XContentParser;
 import org.elasticsearch.xpack.core.watcher.common.secret.Secret;
 import org.elasticsearch.xpack.core.watcher.crypto.CryptoService;
@@ -26,7 +26,7 @@ import java.time.ZonedDateTime;
  * {@link Secret}s are encrypted values that are stored in memory and are decrypted
  * on demand when needed.
  */
-public class WatcherXContentParser extends FilterXContentParser {
+public class WatcherXContentParser extends FilterXContentParserWrapper {
 
     public static final String REDACTED_PASSWORD = "::es_redacted::";