openconfig / ygot

A YANG-centric Go toolkit - Go/Protobuf Code Generation; Validation; Marshaling/Unmarshaling
Apache License 2.0
286 stars 107 forks source link

Go code generation from Yang files - reasons #280

Open adibrastegarnia opened 5 years ago

adibrastegarnia commented 5 years ago

Hi,

I have a quick question. I would like to know if there is any reason that you generate Go code from Yang files instead of using protoc to generate go code from protobuf models? It looks like the Go code that we can generate using protoc is more comprehensive when compared with the Go code generated by ygot. Am I missing something?

Thanks, Adib

robshakir commented 5 years ago

Generating Go code gives us a number of options to provide helpers, and validation around the data structures. For example, we generate YANG-specific helpers like NewXXX, AppendXXX, ReplaceXXX methods on lists. We also have the ability to implement specific helpers that help with serialisation/deserialisation and validation against constraints that that are described in the model (see .Validate() for model elements.

Since protoc-gen-go is generically handling any proto, then it doesn't have these specific helpers, or validation that is aware of YANG. Whilst we could have translated to proto, and then subsequently built these helpers around proto messages, we didn't want to take this approach, since then we end up with a strong dependency on the way that protoc-gen-go presents an API to the user.

For Go users, I'd recommend using the generated Go to take advantage of the helpers, and get the benefits of serialisation to gNMI notifications, JSON according to rfc7951 etc.

adibrastegarnia commented 5 years ago

Thanks for your quick response and that makes sense but I think it still has lack of functions when compared with Go code that we can generate using protoc-gen-go. For example, I don't see any getter functions to access the fields of a data structure (perhaps those are not needed but I can see them in the code that I generate using protoc-gen-go).

robshakir commented 5 years ago

In general, additional functions being generated are controlled by flags - including get, append and delete functions. Please see the flags in https://github.com/openconfig/ygot/blob/master/generator/generator.go

These functions add both getters and get/create helpers.

Cheers, r.

On Tue, Apr 2, 2019, 2:17 PM Adib Rastegarnia notifications@github.com wrote:

Thanks for your quick response and that makes sense but I think it still has lack of functions when compared with Go code that we can generate using protoc-gen-go. For example, I don't see any getter functions to access the fields of a data structure (perhaps those are not needed but I can see them in the code that I generate using protoc-gen-go).

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/openconfig/ygot/issues/280#issuecomment-479206637, or mute the thread https://github.com/notifications/unsubscribe-auth/AEnN1T-o9h7O_j7NTgDkAQxwz5jTmI5nks5vc8jVgaJpZM4cYhRp .

adibrastegarnia commented 5 years ago

That is great. Thanks. I will try.

adibrastegarnia commented 5 years ago

@robshakir

If you have time take a look at this example:

Example

I generated go code for RFC 8345 yang files. I noticed that there is no helper function to update the end-points of a link. There is a function which creates a link (GetOrCreateLink) based on linkId and there is a function which creates an end point for a link (GetOrCreateSrc, GetOrCreateDestination) but there is no helper function to update the end points of a link. To do that we need to access the pointers of the its data structure. What do you think?

robshakir commented 5 years ago

It looks like you might want to check our the functions like ygot.String() for assignment to the struct's fields. These avoid some of the assignment/take address repetition you have in this example.

We don't currently generate leaf "setters" - but this could be added if there is demand for it. Contributions are welcome.

r.

On Fri, Apr 5, 2019, 6:21 AM Adib Rastegarnia notifications@github.com wrote:

@robshakir https://github.com/robshakir

If you have time take a look at this example:

[( https://github.com/adibrastegarnia/ygot-scripts/blob/master/src/demo/rfc8345_example/main.go )]

I generated go code for RFC 8345 yang files. I noticed that there is no helper function to update the end-points of a link. There is a function which creates a link (GetOrCreateLink) based on linkId and there is a function which creates an end point for a link (GetOrCreateSrc, GetOrCreateDestination) but there is no helper function to update the end points of a link. To do that we need to access the pointers of the its data structure. What do you think?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/openconfig/ygot/issues/280#issuecomment-480273004, or mute the thread https://github.com/notifications/unsubscribe-auth/AEnN1atVdHVRFwLn33hhiH6nV1DxCOYVks5vd03ogaJpZM4cYhRp .

adibrastegarnia commented 5 years ago

@robshakir I would like to add that feature. I will take a look and submit a PR If I can figure that out. I will let you know if I have any questions. Thanks for your quick reply.

robshakir commented 5 years ago

Sure, no problems!

A good place to start looking would be the code in ygen to generate leaf getters. Particularly:

Something similar in the generated code will be needed for leaf setters.

r.

adibrastegarnia commented 5 years ago

@robshakir

I sent a PR to add leaf "setters". Please take a look whenever you get a chance.

Thanks Adib