-
Notifications
You must be signed in to change notification settings - Fork 572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Additional statements for exporting individual Enum Values See #74 #81
Conversation
Why wouldn't we do this instead? public enum FooBarBazEnum {
FOO(1),
BAR(2),
BAZ(3);
private final int value;
private FooBarBazEnum(int value) {
this.value = value;
}
public int getValue() {
return value;
}
} Plus this eliminates the need to avoid reflection on the annotation when we serialize to the byte representation. |
@JakeWharton Yep this sounds better, the reflection part is definitely an advantage. Do we have a function in FOO(1),
BAR(2),
BAZ(3); ? |
Yes. writer.emitEnumValue("FOO(1)"); |
@JakeWharton Changed Enum code generation. However, still would require the ability to print the last enum with a semicolon publicly via JavaWriter (introduced in square/javapoet#42) . |
@@ -94,11 +94,28 @@ public void emitType(Type type, String currentType, Map<String, ?> optionsMap, b | |||
} else if (type instanceof EnumType) { | |||
EnumType enumType = (EnumType) type; | |||
writer.beginType(enumType.getName(), "enum", EnumSet.of(PUBLIC)); | |||
int index = 0; | |||
for (EnumType.Value value : enumType.getValues()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like we should just switch this to an indexed for loop since you're already having to do it manually.
List<Value> values = enumType.getValues();
for (int i = 0, count = values.size(); i < count; i++) {
Value value = values.get(i);
writer.emitEnumValue(value.getName() + "(" + value.getTag() + ")", i == count - 1);
}
We'll get a JavaWriter release out hopefully this week. |
MessageWriter.emitDocumentation(writer, value.getDocumentation()); | ||
writer.emitAnnotation(ProtoEnum.class, value.getTag()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still require the @ProtoEnum annotation in order to perform deserialization. We can probably adjust serialization to use getValue() instead of using reflection on the annotation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering about this. Which file is responsible for the serialization and deserialization, I can make the necessary changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See EnumAdapter in the wire-runtime module. If you can make @ProtoEnum go away and still pass tests, go for it!
Note that this will require change to the reference compiler output files in order to pass tests. |
JavaWriter 2.4.0 is out. Please update the root |
writer.emitEmptyLine(); | ||
|
||
// Private Constructor | ||
writer.beginMethod(null, enumType.getName(), EnumSet.of(PRIVATE), "int", "value"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
beginConstructor
So I open a new pull request for passing of the tests + removal of |
Just push to the same branch and it will update the PR. We can deal with
|
I have managed to remove Currently tests are failing due to extra indentation like this one:
Any ideas? Does the new version of JavaWriter change the way continuous indents are done? |
Yes. I'll bump and fix in a separate PR this morning and then you can rebase your changes on that. |
Nicely done. Be sure to delete ProtoEnum.java and fix up any references to it in comments. |
} catch (InvocationTargetException e) { | ||
throw new RuntimeException(e); | ||
} catch (NoSuchMethodException e) { | ||
throw new RuntimeException(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also advise if I should throw RuntimeException if the method is not found or should I wrap
int tag = (Integer) m.invoke(value);
fromInt.put(tag, value);
toInt.put(value, tag);
in another try-catch just to be safe because enumFromInt
function in Message.java
essentially targets Enums in general, so we can't be sure of when to throw a RuntimeException. We can choose to not throw the RuntimeException and keep returning null in case the method getValue
is not exposed in the code file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what you have is fine. Our generated code will always have the desired field and getValue() method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should switch ProtoEnum
to be an interface implemented by all enum
types.
public interface ProtoEnum {
int getValue()
}
So that we can simply cast and avoid reflection.
Tests are passing now. |
Squashed up my commits, I hope I did right? |
So the change looks good now, but something went wrong with the rebase. There should only be one commit and it looks like you've somehow pulled in multiple ones that aren't even yours. |
Yes I suppose that's because I pulled in changes, before doing the rebase. I will attempt to correct it, If I can't then will send a pull-request via a separate branch. |
Good to go Added overrides. |
*/ | ||
final class EnumAdapter<E extends Enum> { | ||
private final Map<Integer, E> fromInt = new LinkedHashMap<Integer, E>(); | ||
private final Map<E, Integer> toInt = new LinkedHashMap<E, Integer>(); | ||
|
||
EnumAdapter(Class<E> type) { | ||
// Record values for each constant annotated with '@ProtoEnum'. | ||
// Invoke getValue via Reflection to get the tag value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is no longer true either.
I have a few more really tiny comments. Sorry! After that I promise we'll get this in. It looks great. |
Modified the way how generated Enums look like, dropped annotation. Switch to an indexed for loop for Enum Generation. Update pom.xml to target javawriter 2.4.0 Use beginConstructor and endConstructor functions instead of method calls + Formatting issues. Change some test files Remove warning about var-args being ambigous for null type during method invoke Remove ProtoEnum annotation from AllTypes.java Update Reference Test Output Files for removal of ProtoEnum Clean up imports from code generation and EnumAdapter Clean up comments and finally ProtoEnum.java from the repository. Convert to interface ProtoEnum. Modify test files add implements ProtoEnum clause fix comment style. Clean up unused imports. Fix Checkstyle issues. Fix up ProtoEnum test output files for import issues. [All Tests passing] Add Override in code generated files Fix Comments and missing overrides in test. Fix up comments
Fixed the comments + missed an override in one of the test files. Tests pass 😄 |
Add Additional statements for exporting individual Enum Values See #74
Thanks for putting up with us. This change was worth it. |
My pleasure. Wire has been a lifesaver and easy to use. Count on me for more pull requests 👍 |
I'd love to start using this update in my projects. Do you know roughly when the next Wire release will be coming out with this enhancement in? |
After exposing last enum method in [https://github.com/square/javapoet/pull/42] I have added additional statements which allow individual Enum values to be exposed.
Now Enums look like this:
This change would require a SNAPSHOT version of JavaWriter and I am not quite sure which tests it's going to break and need fixing.
Comments? @danrice-square