Code review comment: assuming the discriminator is the first, can we avoid buffering? It can be done later, for now it would be great to understand how the current API would evolve to allow it.

Code under review:
public static AnimalWithTypeIdContainingDot fromJson(JsonReader jsonReader) {
        return JsonUtils.readObject(jsonReader, reader -> {
            
            String json = JsonUtils.bufferedJsonObject(jsonReader);

            
            JsonReader replayReader = DefaultJsonReader.fromString(json);

            String discriminatorValue = null;

            
            while (replayReader.nextToken() != JsonToken.END_OBJECT) {
                if ("@odata.type".equals(replayReader.getFieldName())) {
                    replayReader.nextToken();
                    discriminatorValue = replayReader.getStringValue();
                    break;
                }
            }

            
            if ("
                return DogWithTypeIdContainingDot.fromJson(DefaultJsonReader.fromString(json));
            } else if ("
                return CatWithTypeIdContainingDot.fromJson(DefaultJsonReader.fromString(json));
            } else if ("
                return RabbitWithTypeIdContainingDot.fromJson(DefaultJsonReader.fromString(json));
            } else {
                throw new IllegalStateException("Discriminator field '@odata.type' was either missing or didn't match "
                    + "one of the expected values '
                    + "'
                    + "'
            }
        });
    }

Line commented on: String json = JsonUtils.bufferedJsonObject(jsonReader);

Revised code:
public static AnimalWithTypeIdContainingDot fromJson(JsonReader jsonReader) {
        return JsonUtils.readObject(jsonReader, reader -> {
            String discriminatorValue = null;
            JsonReader readerToUse = null;

            
            jsonReader.nextToken();
            if ("@odata.type".equals(jsonReader.getFieldName())) {
                jsonReader.nextToken();
                discriminatorValue = jsonReader.getStringValue();
                readerToUse = jsonReader;
            } else {
                
                
                String json = JsonUtils.bufferJsonObject(jsonReader);
                JsonReader replayReader = DefaultJsonReader.fromString(json);
                while (replayReader.nextToken() != JsonToken.END_OBJECT) {
                    String fieldName = replayReader.getFieldName();
                    replayReader.nextToken();

                    if ("@odata.type".equals(fieldName)) {
                        discriminatorValue = replayReader.getStringValue();
                        break;
                    } else {
                        replayReader.skipChildren();
                    }
                }

                if (discriminatorValue != null) {
                    readerToUse = DefaultJsonReader.fromString(json);
                }
            }

            
            if ("
                return DogWithTypeIdContainingDot.fromJson(readerToUse);
            } else if ("
                return CatWithTypeIdContainingDot.fromJson(readerToUse);
            } else if ("
                return RabbitWithTypeIdContainingDot.fromJson(readerToUse);
            } else {
                throw new IllegalStateException("Discriminator field '@odata.type' was either missing or didn't match "
                    + "one of the expected values '
                    + "'
                    + "'
            }
        });
    }