Azure / autorest.java

Extension for AutoRest (https://github.com/Azure/autorest) that generates Java code
MIT License
32 stars 80 forks source link

mgmt azure-json, in `fromJson`, sub class cannot call package-private setters on read-only properties of child class that's in a different package #2741

Open XiaofeiCao opened 2 months ago

XiaofeiCao commented 2 months ago
### Tasks
- [x] Identify properties to shadow: read-only properties from parent models that's not in constructor
- [x] Shadow these properties in child classes
- [x] Adjust `fromJson` in stream-style-serialization
- [x] getters implementation, return shadowing property

Parent class:

public class PirCommunityGalleryResource implements JsonSerializable<PirCommunityGalleryResource> {

  private String name;
  private String location;
  private String type;

  PirCommunityGalleryResource withName(String name) {
      this.name = name;
      return this;
  }

  PirCommunityGalleryResource withLocation(String location) {
      this.location = location;
      return this;
  }

  PirCommunityGalleryResource withType(String type) {
      this.type = type;
      return this;
  }
}

Child class(in different package):

public final class CommunityGalleryInner extends PirCommunityGalleryResource {

    public static CommunityGalleryInner fromJson(JsonReader jsonReader) throws IOException {
        return jsonReader.readObject(reader -> {
            CommunityGalleryInner deserializedCommunityGalleryInner = new CommunityGalleryInner();
            while (reader.nextToken() != JsonToken.END_OBJECT) {
                String fieldName = reader.getFieldName();
                reader.nextToken();

                if ("name".equals(fieldName)) {
                    // withName is package private in parent class, can't be accessed by child class in a different package
                    deserializedCommunityGalleryInner.withName(reader.getString());
                } else if ("location".equals(fieldName)) {
                    deserializedCommunityGalleryInner.withLocation(reader.getString());
                } else if ("type".equals(fieldName)) {
                    deserializedCommunityGalleryInner.withType(reader.getString());
                } else {
                    reader.skipChildren();
                }
            }

            return deserializedCommunityGalleryInner;
        });
    }
}

proposal child class

public final class CommunityGalleryInner extends PirCommunityGalleryResource {

    // shadow properties
    private String name;
    private String type;
    private String location;

    public static CommunityGalleryInner fromJson(JsonReader jsonReader) throws IOException {
        return jsonReader.readObject(reader -> {
            CommunityGalleryInner deserializedCommunityGalleryInner = new CommunityGalleryInner();
            while (reader.nextToken() != JsonToken.END_OBJECT) {
                String fieldName = reader.getFieldName();
                reader.nextToken();

                if ("name".equals(fieldName)) {
                    // access through shadow properties
                    deserializedCommunityGalleryInner.name = reader.getString();
                } else if ("location".equals(fieldName)) {
                    deserializedCommunityGalleryInner.location = reader.getString();
                } else if ("type".equals(fieldName)) {
                    deserializedCommunityGalleryInner.type = reader.getString();
                } else {
                    reader.skipChildren();
                }
            }

            return deserializedCommunityGalleryInner;
        });
    }

    // override getters
    @Override
    public String name() {
        return this.name;
    }

    @Override
    public String type() {
        return this.type;
    }

    @Override
    public String location() {
        return this.location;
    }
}