Refactor JavaValidationRenderer#185
Conversation
ae6d631 to
20dade9
Compare
armiol
left a comment
There was a problem hiding this comment.
@yevhenii-nadtochii very dense PR, good job! However, in some places I think you went too far. Please see my comments.
| // All the validation rules of a single message type. | ||
| message MessageValidation { | ||
| // A message compiled by the validation library with its constraints, if any. | ||
| message CompiledMessage { |
There was a problem hiding this comment.
As long as in Spine there is a "Model Compiler" (which in turn heavily uses the Validation codegen capabilities), we cannot use CompiledMessage, because it clashes with that domain. Until I saw the before-after in this changeset, I had no idea what a CompiledMessage was. My only guess was that it was something describing the work of the Model Compiler routines completed for some particular Message instance, more of an item in some audit log.
I agree that MessageValidation isn't the best name. But still, what this declaration represents is by no means a result of a compilation process in that sense which we assume in Model Compiler. That's why it cannot be "compiled" (a participle, meaning "it's done"), It's rather an intermediate view of a "to-do" list for the next stages.
There was a problem hiding this comment.
Let's think of a better name. I will, too.
There was a problem hiding this comment.
I thought about CompiledMessage as a message that is being compiled right now. It can also be CompilingMessage, CompilationMessage.
| messageTypes | ||
| .map { m -> m.message.javaFile(m.fileHeader) } | ||
| .mapNotNull { path -> find(path) } | ||
| .distinct() |
There was a problem hiding this comment.
Are you sure that the newly introduced distinct() (line 98) is semantically equal to this whole block? I suspect there might be a subtle difference.
There was a problem hiding this comment.
Now, ProtoData combines calls of javaFile(header), find(path) and unchecked cast to SourceFile<Java> in a single SourceFileSet.javaFileOf() method.
This new method throws when find(path) returns null (meaning no Java file). I have added if (!sources.hasJavaRoot) { return } in the beginning of the renderer to avoid this.
| * Creates a new instance with the generated validation constraints code. | ||
| */ | ||
| fun generate(r: JavaValidationRenderer, v: MessageValidation): ValidationConstraintsCode { | ||
| fun generate(r: JavaValidationRenderer, v: CompiledMessage): ValidationConstraintsCode { |
There was a problem hiding this comment.
As a general comment: when renaming something, please check the corresponding variable names, too.
|
|
||
| // `true` if the field is marked with `(required) = true`, `false` otherwise. | ||
| bool required = 3; | ||
| bool enabled = 3; |
There was a problem hiding this comment.
The field was called required because it's written like that in the consumer code.
"Enabled" is about something else. "Whether the validation is enabled or not?"
There was a problem hiding this comment.
It is a bit weird both ways.
I suggest not create RequiredField view for non-required fields at all. The same with the rest of such views. We do nothing when such a flag is false because RequiredField with required = false is NonRequiredField.
Having this bool something = false flag in SomethingField means this something field is not something.
|
|
||
| import "spine/protodata/ast.proto"; | ||
|
|
||
| // Uniquely identifies a message field. |
There was a problem hiding this comment.
I would say it uniquely identifies a declaration of a field in some Message.
It doesn't identify the field instance itself, as one might think reading this.
There was a problem hiding this comment.
It doesn't identify the field instance itself, as one might think reading this.
It does because it has both the parent type name and the field name.
| // Name of the containing type. | ||
| protodata.TypeName type = 1; | ||
|
|
||
| // Short name of the field. |
There was a problem hiding this comment.
I think it's enough that we call the field name "short" in the declaration of the FieldName itself.
|
|
||
| // Value of `set_once` boolean option. | ||
| // `true` if the field is marked with `(set_once) = true`, `false` otherwise. | ||
| bool enabled = 3; |
There was a problem hiding this comment.
Basically, I would have this named set_once for that same reason as above.
|
|
||
| // Validation rules. | ||
| // | ||
| // All these rules must be met in order for a message to be regarded as valid. |
There was a problem hiding this comment.
Why remove? The meaning is somewhat changed, don't you think?
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #185 +/- ##
============================================
+ Coverage 31.65% 32.16% +0.50%
Complexity 329 329
============================================
Files 142 141 -1
Lines 2818 2786 -32
Branches 229 227 -2
============================================
+ Hits 892 896 +4
+ Misses 1860 1824 -36
Partials 66 66 |
|
@armiol PTAL |
armiol
left a comment
There was a problem hiding this comment.
@yevhenii-nadtochii LGTM with the respect of the comment.
|
|
||
| import "spine/protodata/ast.proto"; | ||
|
|
||
| // Uniquely identifies a field declaration within the compilation messages. |
There was a problem hiding this comment.
I think this type addresses not only "compilation" messages. It's a part of AST, so I say we shouldn't be specific about "compilation" messages.
This PR refactors
JavaValidationRendererand suggests renaming ofMessageValidation→CompilationMessage. I need this change to proceed with the migration to PSI and simultaneous support of rules and standalone generators (as we complete the migration to the latter).Changes to
JavaValidationRenderer:render()method now. A significant part of this method is local comments, describing why all modifications of a message file cannot be done under a singleforEach. I describe this inconsistency, but leave it "as is" because I'm going to migrate to PSI in the upcoming PRs.protectedmodifier fromrender()because it is unnecessary withoverride, and makes the entry point a bit harder to locate.Other changes:
Validationscollection, we can easily go without this class. We already have many classes with "Validation" in their names. Takes time to differentiate their purposes.FieldIdup infield_views.protofile.MessageValidationtoCompilationMessage.3.1. This projection stores views for each message being compiled.
3.2. Having one or more constraints is optional. We always add
validate()to all messages (and related stuff), which go through the library no matter if they have constraints or not.3.3. When we complete migration from
Rule, this class will disappear completely. Each generator will query only a view of interest, likeRequiredFieldVieworDistinctFieldView.3.4. Its usages talked more about a
compilationMessage, and less as of aset of constraints.3.5. This eliminates another class with "Validation" in its name.
Unrelated changes:
SetOnceValidationRenderer. Both options are good enough, but the new one looks a bit better to me. AndJavaValidationRendereralso usesallCompilationMessages.