Skip to content

Commit 9ca1265

Browse files
committed
Use enums for union variant tags
1 parent 2a1c738 commit 9ca1265

31 files changed

+191
-958
lines changed

java-client/src/main/java/co/elastic/clients/json/AttributedJsonpMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class AttributedJsonpMapper implements JsonpMapper {
2929
private final String name;
3030
private final Object value;
3131

32-
public AttributedJsonpMapper(JsonpMapper mapper, String name, Object value) {
32+
AttributedJsonpMapper(JsonpMapper mapper, String name, Object value) {
3333
this.mapper = mapper;
3434
this.name = name;
3535
this.value = value;

java-client/src/main/java/co/elastic/clients/json/ExternallyTaggedUnion.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public interface ExternallyTaggedUnion {
4545
* A deserializer for externally-tagged unions. Since the union variant discriminant is provided externally, this cannot be a
4646
* regular {@link JsonpDeserializer} as the caller has to provide the discriminant value.
4747
*/
48-
class Deserializer<Union extends TaggedUnion<Member>, Member> {
48+
class Deserializer<Union extends TaggedUnion<?, Member>, Member> {
4949
private final Map<String, JsonpDeserializer<? extends Member>> deserializers;
5050
private final BiFunction<String, Member, Union> unionCtor;
5151

@@ -75,7 +75,7 @@ public TypedKeysDeserializer<Union> typedKeys() {
7575
}
7676
}
7777

78-
class TypedKeysDeserializer<Union extends TaggedUnion<?>> extends JsonpDeserializerBase<Map<String, Union>> {
78+
class TypedKeysDeserializer<Union extends TaggedUnion<?, ?>> extends JsonpDeserializerBase<Map<String, Union>> {
7979
Deserializer<Union, ?> deserializer;
8080
protected TypedKeysDeserializer(Deserializer<Union, ?> deser) {
8181
super(EnumSet.of(Event.START_OBJECT));
@@ -111,20 +111,20 @@ public void deserializeEntry(String key, JsonParser parser, JsonpMapper mapper,
111111
/**
112112
* Serialize an externally tagged union using the typed keys encoding.
113113
*/
114-
static <T extends JsonpSerializable & TaggedUnion<?>> void serializeTypedKeys(
114+
static <T extends JsonpSerializable & TaggedUnion<? extends JsonEnum, ?>> void serializeTypedKeys(
115115
Map<String, T> map, JsonGenerator generator, JsonpMapper mapper
116116
) {
117117
generator.writeStartObject();
118118
serializeTypedKeysInner(map, generator, mapper);
119119
generator.writeEnd();
120120
}
121121

122-
static <T extends JsonpSerializable & TaggedUnion<?>> void serializeTypedKeysInner(
122+
static <T extends JsonpSerializable & TaggedUnion<? extends JsonEnum, ?>> void serializeTypedKeysInner(
123123
Map<String, T> map, JsonGenerator generator, JsonpMapper mapper
124124
) {
125125
for (Map.Entry<String, T> entry: map.entrySet()) {
126126
T value = entry.getValue();
127-
generator.writeKey(value._type() + "#" + entry.getKey());
127+
generator.writeKey(value._kind().jsonValue() + "#" + entry.getKey());
128128
value.serialize(generator, mapper);
129129
}
130130
}

java-client/src/main/java/co/elastic/clients/util/StringEnum.java renamed to java-client/src/main/java/co/elastic/clients/json/JsonEnum.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,8 @@
1717
* under the License.
1818
*/
1919

20-
package co.elastic.clients.util;
20+
package co.elastic.clients.json;
2121

22-
import co.elastic.clients.json.JsonpDeserializerBase;
23-
import co.elastic.clients.json.JsonpMapper;
24-
import co.elastic.clients.json.JsonpSerializable;
2522
import jakarta.json.stream.JsonGenerator;
2623
import jakarta.json.stream.JsonParser;
2724
import jakarta.json.stream.JsonParsingException;
@@ -34,15 +31,15 @@
3431
/**
3532
* Base interface for enumerations.
3633
*/
37-
public interface StringEnum extends JsonpSerializable {
34+
public interface JsonEnum extends JsonpSerializable {
3835
String jsonValue();
3936

4037
@Override
4138
default void serialize(JsonGenerator generator, JsonpMapper params) {
4239
generator.write(jsonValue());
4340
}
4441

45-
class Deserializer<T extends Enum<T> & StringEnum> extends JsonpDeserializerBase<T> {
42+
class Deserializer<T extends JsonEnum> extends JsonpDeserializerBase<T> {
4643
private final Map<String, T> lookupTable;
4744

4845
public Deserializer(T[] values) {

java-client/src/main/java/co/elastic/clients/json/JsonpDeserializer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package co.elastic.clients.json;
2121

22-
import co.elastic.clients.util.StringEnum;
2322
import jakarta.json.JsonValue;
2423
import jakarta.json.stream.JsonParser;
2524
import jakarta.json.stream.JsonParser.Event;
@@ -187,7 +186,7 @@ static <T> JsonpDeserializer<Map<String, T>> stringMapDeserializer(JsonpDeserial
187186
return new JsonpDeserializerBase.StringMapDeserializer<T>(itemDeserializer);
188187
}
189188

190-
static <K extends StringEnum, V> JsonpDeserializer<Map<K, V>> enumMapDeserializer(
189+
static <K extends JsonEnum, V> JsonpDeserializer<Map<K, V>> enumMapDeserializer(
191190
JsonpDeserializer<K> keyDeserializer, JsonpDeserializer<V> valueDeserializer
192191
) {
193192
return new JsonpDeserializerBase.EnumMapDeserializer<K, V>(keyDeserializer, valueDeserializer);

java-client/src/main/java/co/elastic/clients/json/UnionDeserializer.java

Lines changed: 44 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,30 @@
3636
import java.util.Set;
3737
import java.util.function.BiFunction;
3838

39-
public class UnionDeserializer<T, M> implements JsonpDeserializer<T> {
39+
public class UnionDeserializer<Union, Kind, Member> implements JsonpDeserializer<Union> {
4040

4141
public static class AmbiguousUnionException extends RuntimeException {
4242
public AmbiguousUnionException(String message) {
4343
super(message);
4444
}
4545
}
4646

47-
private abstract static class EventHandler<T, M> {
48-
abstract T deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<String, M, T> buildFn);
47+
private abstract static class EventHandler<Union, Kind, Member> {
48+
abstract Union deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<Kind, Member, Union> buildFn);
4949
abstract EnumSet<Event> nativeEvents();
5050
}
5151

52-
private static class SingleMemberHandler<T, M> extends EventHandler<T, M> {
53-
private final JsonpDeserializer<? extends M> deserializer;
54-
private final String tag;
52+
private static class SingleMemberHandler<Union, Kind, Member> extends EventHandler<Union, Kind, Member> {
53+
private final JsonpDeserializer<? extends Member> deserializer;
54+
private final Kind tag;
5555
// ObjectDeserializers provide the list of fields they know about
5656
private final Set<String> fields;
5757

58-
SingleMemberHandler(String tag, JsonpDeserializer<? extends M> deserializer) {
58+
SingleMemberHandler(Kind tag, JsonpDeserializer<? extends Member> deserializer) {
5959
this(tag, deserializer, null);
6060
}
6161

62-
SingleMemberHandler(String tag, JsonpDeserializer<? extends M> deserializer, Set<String> fields) {
62+
SingleMemberHandler(Kind tag, JsonpDeserializer<? extends Member> deserializer, Set<String> fields) {
6363
this.deserializer = deserializer;
6464
this.tag = tag;
6565
this.fields = fields;
@@ -71,7 +71,7 @@ EnumSet<Event> nativeEvents() {
7171
}
7272

7373
@Override
74-
T deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<String, M, T> buildFn) {
74+
Union deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<Kind, Member, Union> buildFn) {
7575
return buildFn.apply(tag, deserializer.deserialize(parser, mapper, event));
7676
}
7777
}
@@ -80,22 +80,22 @@ T deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<Str
8080
* An event handler for value events (string, number, etc) that can try multiple handlers, which are ordered
8181
* from most specific (e.g. enum) to least specific (e.g. string)
8282
*/
83-
private static class MultiMemberHandler<T, M> extends EventHandler<T, M> {
84-
private List<SingleMemberHandler<T, M>> handlers;
83+
private static class MultiMemberHandler<Union, Kind, Member> extends EventHandler<Union, Kind, Member> {
84+
private List<SingleMemberHandler<Union, Kind, Member>> handlers;
8585

8686
@Override
8787
EnumSet<Event> nativeEvents() {
8888
EnumSet<Event> result = EnumSet.noneOf(Event.class);
89-
for (SingleMemberHandler<T, M> smh: handlers) {
89+
for (SingleMemberHandler<Union, Kind, Member> smh: handlers) {
9090
result.addAll(smh.deserializer.nativeEvents());
9191
}
9292
return result;
9393
}
9494

9595
@Override
96-
T deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<String, M, T> buildFn) {
96+
Union deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<Kind, Member, Union> buildFn) {
9797
RuntimeException exception = null;
98-
for (EventHandler<T, M> d: handlers) {
98+
for (EventHandler<Union, Kind, Member> d: handlers) {
9999
try {
100100
return d.deserialize(parser, mapper, event, buildFn);
101101
} catch(RuntimeException ex) {
@@ -106,37 +106,37 @@ T deserialize(JsonParser parser, JsonpMapper mapper, Event event, BiFunction<Str
106106
}
107107
}
108108

109-
public static class Builder<T, M> implements ObjectBuilder<JsonpDeserializer<T>> {
109+
public static class Builder<Union, Kind, Member> implements ObjectBuilder<JsonpDeserializer<Union>> {
110110

111-
private final BiFunction<String, M, T> buildFn;
111+
private final BiFunction<Kind, Member, Union> buildFn;
112112

113-
private final List<UnionDeserializer.SingleMemberHandler<T, M>> objectMembers = new ArrayList<>();
114-
private final Map<Event, EventHandler<T, M>> otherMembers = new HashMap<>();
113+
private final List<UnionDeserializer.SingleMemberHandler<Union, Kind, Member>> objectMembers = new ArrayList<>();
114+
private final Map<Event, EventHandler<Union, Kind, Member>> otherMembers = new HashMap<>();
115115
private final boolean allowAmbiguousPrimitive;
116116

117-
public Builder(BiFunction<String, M, T> buildFn, boolean allowAmbiguities) {
117+
public Builder(BiFunction<Kind, Member, Union> buildFn, boolean allowAmbiguities) {
118118
// If we allow ambiguities, multiple handlers for a given json value event will be allowed
119119
this.allowAmbiguousPrimitive = allowAmbiguities;
120120
this.buildFn = buildFn;
121121
}
122122

123-
private void addAmbiguousDeserializer(Event e, String tag, JsonpDeserializer<? extends M> deserializer) {
124-
EventHandler<T, M> m = otherMembers.get(e);
125-
MultiMemberHandler<T, M> mmh;
126-
if (m instanceof MultiMemberHandler<?, ?>) {
127-
mmh = (MultiMemberHandler<T, M>) m;
123+
private void addAmbiguousDeserializer(Event e, Kind tag, JsonpDeserializer<? extends Member> deserializer) {
124+
EventHandler<Union, Kind, Member> m = otherMembers.get(e);
125+
MultiMemberHandler<Union, Kind, Member> mmh;
126+
if (m instanceof MultiMemberHandler<?, ?, ?>) {
127+
mmh = (MultiMemberHandler<Union, Kind, Member>) m;
128128
} else {
129129
mmh = new MultiMemberHandler<>();
130130
mmh.handlers = new ArrayList<>(2);
131-
mmh.handlers.add((SingleMemberHandler<T, M>) m);
131+
mmh.handlers.add((SingleMemberHandler<Union, Kind, Member>) m);
132132
otherMembers.put(e, mmh);
133133
}
134134
mmh.handlers.add(new SingleMemberHandler<>(tag, deserializer));
135135
// Sort handlers by number of accepted events, which gives their specificity
136136
mmh.handlers.sort(Comparator.comparingInt(a -> a.deserializer.acceptedEvents().size()));
137137
}
138138

139-
private void addMember(Event e, String tag, UnionDeserializer.SingleMemberHandler<T, M> member) {
139+
private void addMember(Event e, Kind tag, UnionDeserializer.SingleMemberHandler<Union, Kind, Member> member) {
140140
if (otherMembers.containsKey(e)) {
141141
if (!allowAmbiguousPrimitive || e == Event.START_OBJECT || e == Event.START_ARRAY) {
142142
throw new AmbiguousUnionException("Union member '" + tag + "' conflicts with other members");
@@ -151,26 +151,26 @@ private void addMember(Event e, String tag, UnionDeserializer.SingleMemberHandle
151151
}
152152
}
153153

154-
public Builder<T, M> addMember(String tag, JsonpDeserializer<? extends M> deserializer) {
154+
public Builder<Union, Kind, Member> addMember(Kind tag, JsonpDeserializer<? extends Member> deserializer) {
155155

156156
JsonpDeserializer<?> unwrapped = DelegatingDeserializer.unwrap(deserializer);
157157
if (unwrapped instanceof ObjectDeserializer) {
158158
ObjectDeserializer<?> od = (ObjectDeserializer<?>) unwrapped;
159159
Set<String> allFields = od.fieldNames();
160160
Set<String> fields = new HashSet<>(allFields); // copy to update
161-
for (UnionDeserializer.SingleMemberHandler<T, M> member: objectMembers) {
161+
for (UnionDeserializer.SingleMemberHandler<Union, Kind, Member> member: objectMembers) {
162162
// Remove respective fields on both sides to keep specific ones
163163
fields.removeAll(member.fields);
164164
member.fields.removeAll(allFields);
165165
}
166-
UnionDeserializer.SingleMemberHandler<T, M> member = new SingleMemberHandler<>(tag, deserializer, fields);
166+
UnionDeserializer.SingleMemberHandler<Union, Kind, Member> member = new SingleMemberHandler<>(tag, deserializer, fields);
167167
objectMembers.add(member);
168168
if (od.shortcutProperty() != null) {
169169
// also add it as a string
170170
addMember(Event.VALUE_STRING, tag, member);
171171
}
172172
} else {
173-
UnionDeserializer.SingleMemberHandler<T, M> member = new SingleMemberHandler<>(tag, deserializer);
173+
UnionDeserializer.SingleMemberHandler<Union, Kind, Member> member = new SingleMemberHandler<>(tag, deserializer);
174174
for (Event e: deserializer.nativeEvents()) {
175175
addMember(e, tag, member);
176176
}
@@ -180,9 +180,9 @@ public Builder<T, M> addMember(String tag, JsonpDeserializer<? extends M> deseri
180180
}
181181

182182
@Override
183-
public JsonpDeserializer<T> build() {
183+
public JsonpDeserializer<Union> build() {
184184
// Check that no object member had all its fields removed
185-
for (UnionDeserializer.SingleMemberHandler<T, M> member: objectMembers) {
185+
for (UnionDeserializer.SingleMemberHandler<Union, Kind, Member> member: objectMembers) {
186186
if (member.fields.isEmpty()) {
187187
throw new AmbiguousUnionException("All properties of '" + member.tag + "' also exist in other object members");
188188
}
@@ -201,16 +201,16 @@ public JsonpDeserializer<T> build() {
201201
}
202202
}
203203

204-
private final BiFunction<String, M, T> buildFn;
204+
private final BiFunction<Kind, Member, Union> buildFn;
205205
private final EnumSet<Event> nativeEvents;
206-
private final Map<String, EventHandler<T, M>> objectMembers;
207-
private final Map<Event, EventHandler<T, M>> otherMembers;
208-
private final EventHandler<T, M> fallbackObjectMember;
206+
private final Map<String, EventHandler<Union, Kind, Member>> objectMembers;
207+
private final Map<Event, EventHandler<Union, Kind, Member>> otherMembers;
208+
private final EventHandler<Union, Kind, Member> fallbackObjectMember;
209209

210210
public UnionDeserializer(
211-
List<SingleMemberHandler<T, M>> objectMembers,
212-
Map<Event, EventHandler<T, M>> otherMembers,
213-
BiFunction<String, M, T> buildFn
211+
List<SingleMemberHandler<Union, Kind, Member>> objectMembers,
212+
Map<Event, EventHandler<Union, Kind, Member>> otherMembers,
213+
BiFunction<Kind, Member, Union> buildFn
214214
) {
215215
this.buildFn = buildFn;
216216

@@ -219,7 +219,7 @@ public UnionDeserializer(
219219
this.objectMembers = Collections.emptyMap();
220220
} else {
221221
this.objectMembers = new HashMap<>();
222-
for (SingleMemberHandler<T, M> member: objectMembers) {
222+
for (SingleMemberHandler<Union, Kind, Member> member: objectMembers) {
223223
for (String field: member.fields) {
224224
this.objectMembers.put(field, member);
225225
}
@@ -229,7 +229,7 @@ public UnionDeserializer(
229229
this.otherMembers = otherMembers;
230230

231231
this.nativeEvents = EnumSet.noneOf(Event.class);
232-
for (EventHandler<T, M> member: otherMembers.values()) {
232+
for (EventHandler<Union, Kind, Member> member: otherMembers.values()) {
233233
this.nativeEvents.addAll(member.nativeEvents());
234234
}
235235

@@ -253,15 +253,15 @@ public EnumSet<Event> acceptedEvents() {
253253
}
254254

255255
@Override
256-
public T deserialize(JsonParser parser, JsonpMapper mapper) {
256+
public Union deserialize(JsonParser parser, JsonpMapper mapper) {
257257
Event event = parser.next();
258258
JsonpUtils.ensureAccepts(this, parser, event);
259259
return deserialize(parser, mapper, event);
260260
}
261261

262262
@Override
263-
public T deserialize(JsonParser parser, JsonpMapper mapper, Event event) {
264-
EventHandler<T, M> member = otherMembers.get(event);
263+
public Union deserialize(JsonParser parser, JsonpMapper mapper, Event event) {
264+
EventHandler<Union, Kind, Member> member = otherMembers.get(event);
265265

266266
if (member == null && event == Event.START_OBJECT && !objectMembers.isEmpty()) {
267267
// Parse as an object to find matching field names

java-client/src/main/java/co/elastic/clients/util/MapBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ public MapBuilder(Supplier<B> builderCtor) {
3434
this.builderCtor = builderCtor;
3535
}
3636

37-
public MapBuilder<K, V, B> entry(K key, V value) {
37+
public MapBuilder<K, V, B> put(K key, V value) {
3838
map.put(key, value);
3939
return this;
4040
}
4141

42-
public MapBuilder<K, V, B> entry(K key, Function<B, ObjectBuilder<V>> fn) {
43-
return entry(key, fn.apply(builderCtor.get()).build());
42+
public MapBuilder<K, V, B> put(K key, Function<B, ObjectBuilder<V>> fn) {
43+
return put(key, fn.apply(builderCtor.get()).build());
4444
}
4545

4646
@Override

java-client/src/main/java/co/elastic/clients/util/TaggedUnion.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,14 @@
1919

2020
package co.elastic.clients.util;
2121

22-
public interface TaggedUnion<BaseType> {
22+
public interface TaggedUnion<Tag extends Enum<?>, BaseType> {
2323

2424
/**
25-
* Get the of the type of the variant held by this union object.
25+
* Get the of the kind of variant held by this object.
2626
*
27-
* @return the variant type
27+
* @return the variant kind
2828
*/
29-
String _type();
29+
Tag _kind();
3030

3131
BaseType _get();
32-
33-
/**
34-
* Checks if this object is of a given variant type.
35-
*/
36-
default boolean _is(String type) {
37-
return _type().equals(type);
38-
}
39-
4032
}

0 commit comments

Comments
 (0)