ygot icon indicating copy to clipboard operation
ygot copied to clipboard

Go code generation from Yang files - reasons

Open adibrastegarnia opened this issue 6 years ago • 9 comments

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

adibrastegarnia avatar Apr 02 '19 16:04 adibrastegarnia

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.

robshakir avatar Apr 02 '19 16:04 robshakir

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).

adibrastegarnia avatar Apr 02 '19 21:04 adibrastegarnia

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 [email protected] 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 .

robshakir avatar Apr 02 '19 21:04 robshakir

That is great. Thanks. I will try.

adibrastegarnia avatar Apr 02 '19 21:04 adibrastegarnia

@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?

adibrastegarnia avatar Apr 05 '19 13:04 adibrastegarnia

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 [email protected] 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 .

robshakir avatar Apr 05 '19 13:04 robshakir

@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.

adibrastegarnia avatar Apr 05 '19 13:04 adibrastegarnia

Sure, no problems!

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

  • Population of relevant fields here
  • Generation template here

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

r.

robshakir avatar Apr 05 '19 13:04 robshakir

@robshakir

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

Thanks Adib

adibrastegarnia avatar Apr 08 '19 21:04 adibrastegarnia