Skip to content
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

Support explicitly setting field tags #339

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions ygen/codegen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1983,8 +1983,11 @@ func TestGenerateProto3(t *testing.T) {
wantOutputFiles map[string]string
wantErr bool
}{{
name: "simple protobuf test with compression",
inFiles: []string{filepath.Join(TestRoot, "testdata", "proto", "proto-test-a.yang")},
name: "simple protobuf test with compression",
inFiles: []string{
filepath.Join(TestRoot, "testdata", "proto", "proto-test-a.yang"),
filepath.Join(TestRoot, "testdata", "proto", "openconfig-codegen-extensions.yang"),
},
inConfig: GeneratorConfig{
TransformationOptions: TransformationOpts{
CompressBehaviour: genutil.PreferIntendedConfig,
Expand Down
46 changes: 45 additions & 1 deletion ygen/protogen.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"

"github.com/openconfig/goyang/pkg/yang"
Expand Down Expand Up @@ -95,6 +96,13 @@ const (
protoMatchingListNameKeySuffix = "key"
)

// Names from https://github.com/openconfig/public/blob/master/release/models/extensions/openconfig-codegen-extensions.yang
const (
codegenExtModuleName = "openconfig-codegen-extensions"
fieldNumExtName = "field-number"
offsetExtName = "field-number-offset"
)

// protoMsgField describes a field of a protobuf message.
// Note, throughout this package private structs that have public fields are used
// in text/template which cannot refer to unexported fields.
Expand Down Expand Up @@ -1090,8 +1098,44 @@ func safeProtoIdentifierName(name string) string {
}

// protoTagForEntry returns a protobuf tag value for the entry e.
// If the entry has user-specified field numberings, then use that instead:
// https://github.com/openconfig/ygot/blob/master/docs/yang-to-protobuf-transformations-spec.md#field-numbering
func protoTagForEntry(e *yang.Entry) (uint32, error) {
return fieldTag(e.Path())
var fieldNum uint32
exts, err := yang.MatchingEntryExtensions(e, codegenExtModuleName, fieldNumExtName)
if err != nil {
return 0, err
}
switch len(exts) {
case 0:
return fieldTag(e.Path())
case 1:
num, err := strconv.ParseUint(exts[0].Argument, 10, 32)
if err != nil || num == 0 {
return 0, fmt.Errorf("could not parse %s:%s %q as a non-zero integer: %s", codegenExtModuleName, fieldNumExtName, exts[0].Argument, err)
}
fieldNum = uint32(num)
default:
return 0, fmt.Errorf("more than one %s:%s defined", codegenExtModuleName, fieldNumExtName)
}

exts, err = yang.MatchingEntryExtensions(e, codegenExtModuleName, offsetExtName)
if err != nil {
return 0, err
}
for _, ext := range exts {
num, err := strconv.ParseUint(ext.Argument, 10, 32)
if err != nil {
return 0, fmt.Errorf("could not parse %s:%s %q as an uint: %s", codegenExtModuleName, offsetExtName, ext.Argument, err)
}
// Allow for multiple offsets to accumulate.
fieldNum += uint32(num)
}

if fieldNum > 1000 || fieldNum < 1 {
return 0, fmt.Errorf("%s: %d not in reserved range of 1-1000 for %s:%s", e.Path(), fieldNum, codegenExtModuleName, offsetExtName)
}
return fieldNum, nil
}

// fieldTag takes an input string and calculates a FNV hash for the value. If the
Expand Down
Loading