-
Notifications
You must be signed in to change notification settings - Fork 185
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
Introduce a class for field types #605
base: master
Are you sure you want to change the base?
Conversation
6f6631e
to
d8ad30b
Compare
This change should be backwards compatible and should not require any changes in
|
I'm working on fixing the issue described above. It seems like for the same buffer, at some point, we read a repeated
In this branch when compiling the same file:
I checked the changes in |
Ah, so by default assertions are not enabled and I was trying to run the plugin with assertions disabled. When I enable assertions with the patch below I get more helpful error messages. Should be easier to debug now. diff --git a/protoc_plugin/bin/protoc-gen-dart b/protoc_plugin/bin/protoc-gen-dart
index b1f8169..86b62aa 100755
--- a/protoc_plugin/bin/protoc-gen-dart
+++ b/protoc_plugin/bin/protoc-gen-dart
@@ -1,3 +1,3 @@
#!/bin/bash
BINDIR=$(dirname "$0")
-dart "$BINDIR/protoc_plugin.dart" -c "$@"
+dart --enable-asserts "$BINDIR/protoc_plugin.dart" -c "$@" |
e3bf4b5
to
08dd5be
Compare
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 like how the code becomes simpler to reason about, however I am somewhat concerned about performance implications. Have you tried running benchmarks for perf? It introduces additional memory reads where previously there were none.
isRepeated = false, | ||
isRequired = false; | ||
|
||
const FieldType.MAP() |
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.
It might be good to align names with Dart style guide, e.g. MAP
should probably be map
etc.
Even better pattern could be:
const FieldType._({
required this.baseType,
this.isGroup = false,
this.isPacked = false,
this.isRepeated = false,
this.isRequired = false,
});
static const map = FieldType._(FieldBaseType.map);
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.
It might be good to align names with Dart style guide
We should check this automatically somehow, but I don't know if it's possible, and if it is how. I'll figure it out.
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 would have expected that this is caught by https://dart-lang.github.io/linter/lints/non_constant_identifier_names.html ?
It part of core and recommended lint lists. I am surprised that this is not detected. /cc @pq
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.
🤔
const FieldType.MAP()
should definitely get flagged by non_constant_identifier_names
.
Lints are a little subtle in some IDEs so maybe it was just overlooked.
Here's how it should look in IntelliJ for example:
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 just realized that we disable this lint at the beginning of this file.
Most of the identifiers in the files are used by the generated code and have cryptic names and I guess we disable the lints for those. For now I will fix naming of the identifiers for user-written code manually.
This will definitely make things slower, but I'm hoping that it will either be negligible amount or we will find something else to improve perf back to the original numbers. Having view types (aka. I will learn how to run internal benchmarks this week and update. This API will be used externally to implement new serialization formats, for example the protobuf text format (#125). I'm currently working on implementing #125 using this change as a PoC. |
Finally had time to benchmark these changes using the benchmarks in VM:
AOT:
JS:
It seems like One way to improve representation of final FieldBaseType baseType;
final bool isGroup;
final bool isPacked;
final bool isRepeated;
final bool isRequired; Then we provide getters to map the bits to |
I tried this in another branch: 04a5110. Unfortunately it made things slower. I suspect this is because // Before
const FieldType.REQUIRED_MESSAGE()
: baseType = FieldBaseType.message,
isGroup = false,
isPacked = false,
isRepeated = false,
isRequired = true;
// After
FieldType.required_message()
: _fieldTypePacked = FieldBaseType.message.index | _REQUIRED_BIT; |
Next thing to try here is to keep using an |
I just realized today that the "view types" (renamed as "inline classes") proposal was merged a while ago: https://github.com/dart-lang/language/blob/master/accepted/future-releases/inline-classes/feature-specification.md Currently none of the backends implement it, but they soon will, and we will be able to use an inline class for the field type type. |
This replaces the old
int
-based field type values with aFieldType
class.FieldType
holds the base type (int32, string, enum, etc.) and the propertiesrepeated
,optional
,packed
, andgroup
.The new classes
FieldType
andFieldBaseType
are made public to allowimplementing new serialization formats as libraries.
FieldBaseType
enum provides much better interface for both externalserializers and also within the
protobuf.dart
library:Case analyses on field types are now checked by the compiler for
exhaustiveness. As a result, all of the
default
branches ofswitch
statements on field types are now gone.
We no longer need to manually mask the bits for
optional
,repeated
etc.properties.
A lot of invalid states made unrepresentable: we don't need assertions about
multiple base type bits being set. (e.g. 9da84ae)
Note that previously for map fields we would set both the map and message
bits. The code is refactored to treat maps the same as messages when needed.
This PR should does not change interface to the generated code so
protoc_plugin
does not need any changes. We also do not remove any of theexisting public symbols, only add new ones (
FieldType
andFieldBaseType
).So this PR should be backwards compatible with both
protoc_plugin
-generatedcode and the user-written code.