-
-
Notifications
You must be signed in to change notification settings - Fork 75
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
Default values are not set. #107
Comments
Hmm. this looks like has something to do with generated getters. for proto3 we are supposed to call here: protoc-gen-ts/src/descriptor.js Line 889 in b47d74a
would like to fix it and send a PR with tests included? |
for anyone who wants to fix this: https://developers.google.com/protocol-buffers/docs/proto3#default |
Hey, I'm looking into this problem. The thing is proto3 seems to remove So both (.net and javascript) introduces functions /**
* Clears the field making it undefined.
* @return {!proto.MessageVerThree} returns this
*/
proto.MessageVerThree.prototype.clearNullableInt = function() {
return jspb.Message.setField(this, 4, undefined);
};
/**
* Returns whether this field is set.
* @return {boolean}
*/
proto.MessageVerThree.prototype.hasNullableInt = function() {
return jspb.Message.getField(this, 4) != null;
}; Meaning there are 2? options how to solve this:
The first one preserves usage between (I hope) all implementations. The second one is prettier to use for me. 😄 |
I believe a simple trick in this function here: protoc-gen-ts/src/descriptor.js Line 889 in b47d74a
the logic is already there you just have to add a branch to say something like |
this is not written anywhere but we never do work at runtime if it can be done in compile time so the second option is not an ideal solution. |
I'd like to have presence getters in here if you are willing to send a separate PR for it. |
Yea but then there is a problem when you can't distinguish between not set and default value. I'm already working on the presence getter.
That's pretty much my first purposed solution and I'm already working on it. That means I'll try to mimic the result from the javascript plugin. 😄 |
this is exactly what getFieldWithDefault does. If the field is present it gives you the value of it but if not it will return you whatever you passed to it as the third argument. |
they are basically guarding against serializing default values. it is a small optimization that I didn't bother implementing. |
@thesayyn is it possible to contact you on any other platform? I'm having issues with compilation. Otherwise AST should be done. |
grpc has no slack channel. I am on bazel slack channel. you can reach me there. |
in order to close this issue, protoc-gen-ts should be fixed to not serialize default values and should return defaults when field has no presence |
but as far as I am concerned, there shouldn't be any interoperability issues between protoc-gen-ts and other language implementations. |
diff --git a/src/descriptor.ts b/src/descriptor.ts
index f1cb6da..2d1c68f 100644
--- a/src/descriptor.ts
+++ b/src/descriptor.ts
@@ -916,7 +916,13 @@ function createGetterCall(
ts.factory.createNumericLiteral(fieldDescriptor.number),
];
- if (fieldDescriptor.default_value) {
+ let default_val = fieldDescriptor.default_value
+
+ if (!default_val) {
+ // assign default values
+ }
+
+ if (default_val) {
getterMethod = "getFieldWithDefault";
let _default: ts.Expression;
diff --git a/src/type.ts b/src/type.ts
index 93422c0..d27feac 100644
--- a/src/type.ts
+++ b/src/type.ts
@@ -4,6 +4,7 @@ import * as ts from "typescript";
const symbolMap: Map<string, string> = new Map();
const dependencyMap: Map<string, ts.Identifier> = new Map();
const mapMap: Map<string, descriptor.DescriptorProto> = new Map();
+const enumLeadingMemberMap: Map<string, string> = new Map();
export function resetDependencyMap() {
dependencyMap.clear();
@@ -26,6 +27,13 @@ export function getMapDescriptor(
return mapMap.get(typeName);
}
+
+export function getLeadingEnumMember(
+ type_name: string,
+): string | undefined {
+ return enumLeadingMemberMap.get(type_name);
+}
+
export function getTypeReferenceExpr(
rootDescriptor: descriptor.FileDescriptorProto,
typeName: string,
@@ -83,7 +91,9 @@ export function preprocess(
prefix: string,
) {
for (const enumDescriptor of targetDescriptor.enum_type) {
- symbolMap.set(replaceDoubleDots(`${prefix}.${enumDescriptor.name}`), path);
+ const name = replaceDoubleDots(`${prefix}.${enumDescriptor.name}`)
+ symbolMap.set(name, path);
+ enumLeadingMemberMap.set(name, enumDescriptor.value[0].name);
}
const messages: descriptor.DescriptorProto[] =
@@ -98,7 +108,6 @@ export function preprocess(
if (isMapEntry(messageDescriptor)) {
mapMap.set(name, messageDescriptor);
messages.splice(index, 1);
-
continue;
}
|
@thesayyn Will you be adding this to the next release? |
sorry that there has been so little activity on this one from me. I'd love to help out as I really like this project. Unfortunately I'm so packed with work that I don't find the time to get into to topic enough to contribute (my biggest issue is not beeing familiar with the build and test frameworks). I hope I'll find some more time soon. Additionaly I just noticed that boolean values seem to have the same problem. false seems to dissapear as its beeing the default value. I can open up a separate issue for that just wanted to clarifiy hiere first |
+1 |
fixed at #146 and released in 0.8.5 |
Alot of implementations omit default values when serializing protobufs. So e.g. enums set to 0 will not be sent over the wire. When the message is deserialized this missing value should be set to the default value of 0. However default values will not be set by protoc-gen-ts. This causes problems with interoperability between e.g. C# and JavaScript/TypeScript as in our case. I investigated the generated code a bit and my suspect is this
src/compiler/descriptor.js
If I read this correct then the value is only set if it is there but according to the specification it should be set to the default value 0.
The text was updated successfully, but these errors were encountered: