Skip to content

Conversation

@dmlloyd
Copy link
Contributor

@dmlloyd dmlloyd commented Oct 3, 2023

Update: there is now a basic (but incomplete) implementation.

This is a first draft of the builder API for constructing configuration instances. No implementation is included yet; this is just for API review.

Fixes #1001.

radcortez
radcortez previously approved these changes Oct 4, 2023
Copy link
Member

@radcortez radcortez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@dmlloyd dmlloyd changed the title [WIP] API for config instance builder [WIP] Config instance builder Oct 4, 2023
@radcortez
Copy link
Member

@dmlloyd

I've now started to look into this and pushed some initial implementation that includes:

  • Builder class generation
  • Simple leaf types and primitives
  • Simple optionals
  • @WithDefault

Of course, there is still a lot missing, and even the pieces I did are only for the most basic cases, so I need to start looking into all the edge cases, but it is a start.

In terms of the API, I think we could start with something smaller and drop withString and withDefaultFor variants. We could add them later if required.

On another note, with(F getter, int value) and with(F getter, long value) (as well as their Optional counterparts), are ambiguous when we try to call them:

interface Server {
    String host();
    int port();
}

Server server = forInterface(Server.class)
        .with(Server::host, "localhost")
        .with(Server::port, 8080)
        .build();

So, .with(Server::port, 8080) is reported as ambiguous by the compiler. Casting the value type doesn't seem to help, and it seems to be related to the Function type and method reference inferred type. Would you happen to have any idea?

@dmlloyd
Copy link
Contributor Author

dmlloyd commented Sep 5, 2025

@dmlloyd

I've now started to look into this and pushed some initial implementation that includes:

  • Builder class generation
  • Simple leaf types and primitives
  • Simple optionals
  • @WithDefault

Of course, there is still a lot missing, and even the pieces I did are only for the most basic cases, so I need to start looking into all the edge cases, but it is a start.

In terms of the API, I think we could start with something smaller and drop withString and withDefaultFor variants. We could add them later if required.

On another note, with(F getter, int value) and with(F getter, long value) (as well as their Optional counterparts), are ambiguous when we try to call them:

interface Server {
    String host();
    int port();
}

Server server = forInterface(Server.class)
        .with(Server::host, "localhost")
        .with(Server::port, 8080)
        .build();

So, .with(Server::port, 8080) is reported as ambiguous by the compiler. Casting the value type doesn't seem to help, and it seems to be related to the Function type and method reference inferred type. Would you happen to have any idea?

This is caused by using a type variable in the first argument, which I believe prevents inferencing due to some complexity aspect. I recommend creating a custom interface type for each type of property which also implements Serializable, like I did in Gizmo 2. That should remove the ambiguity from the type inference.

@radcortez radcortez changed the title [WIP] Config instance builder Config instance builder Sep 12, 2025
@radcortez radcortez marked this pull request as ready for review September 12, 2025 14:35
@radcortez
Copy link
Member

@dmlloyd I think this is ready for a first version:

  • Supports all types and combinations as @ConfigMapping
  • Support @WithDefault to automatically set values for all types
  • Support @WithConverter in combination with @WithDefault (values set via the builder are not subject to conversions)
  • Throws an exception if all required values are not set when calling build

I've removed the withString and withDefaultFor method variants to simplify this initial version. We can add them later.

Let me know what you think.

@dmlloyd
Copy link
Contributor Author

dmlloyd commented Sep 18, 2025

Seems OK. Don't forget to JavaDoc the rest of the API.

dmlloyd and others added 7 commits October 13, 2025 19:52
- Builder class generation
- Simple leaf types and primitives
- Simple optionals
- @WithDefault
- Builder class generation
- Leaf types and primitives
- Optionals
- Maps
- Collections
- @WithDefault
- Optional Group
- Map with Collections
- Default methods
- Remove unused methods from ConfigInstanceBuilder
- Share the same code between ConfigInstanceBuilder and ConfigMappingContext
- Simplify ConfigMappingGenerator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API for using mapped configurations in a standalone way

2 participants