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

[chore] Move go templates from pdatagen to separate files #11411

Merged
merged 1 commit into from
Oct 10, 2024
Merged
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
350 changes: 30 additions & 320 deletions pdata/internal/cmd/pdatagen/internal/base_slices.go

Large diffs are not rendered by default.

176 changes: 19 additions & 157 deletions pdata/internal/cmd/pdatagen/internal/base_structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,142 +5,13 @@ package internal // import "go.opentelemetry.io/collector/pdata/internal/cmd/pda

import (
"bytes"
"strings"
"text/template"
)

const messageValueTemplate = `{{ .description }}
//
// This is a reference type, if passed by value and callee modifies it the
// caller will see the modification.
//
// Must use New{{ .structName }} function to create new instances.
// Important: zero-initialized instance is not valid for use.
{{- if .isCommon }}
type {{ .structName }} internal.{{ .structName }}
{{- else }}
type {{ .structName }} struct {
orig *{{ .originName }}
state *internal.State
}
{{- end }}

func new{{ .structName }}(orig *{{ .originName }}, state *internal.State) {{ .structName }} {
{{- if .isCommon }}
return {{ .structName }}(internal.New{{ .structName }}(orig, state))
{{- else }}
return {{ .structName }}{orig: orig, state: state}
{{- end }}
}

// New{{ .structName }} creates a new empty {{ .structName }}.
//
// This must be used only in testing code. Users should use "AppendEmpty" when part of a Slice,
// OR directly access the member if this is embedded in another struct.
func New{{ .structName }}() {{ .structName }} {
state := internal.StateMutable
return new{{ .structName }}(&{{ .originName }}{}, &state)
}

// MoveTo moves all properties from the current struct overriding the destination and
// resetting the current instance to its zero value
func (ms {{ .structName }}) MoveTo(dest {{ .structName }}) {
ms.{{- if .isCommon }}getState(){{ else }}state{{ end }}.AssertMutable()
dest.{{- if .isCommon }}getState(){{ else }}state{{ end }}.AssertMutable()
*dest.{{ .origAccessor }} = *ms.{{ .origAccessor }}
*ms.{{ .origAccessor }} = {{ .originName }}{}
}

{{ if .isCommon -}}
func (ms {{ .structName }}) getOrig() *{{ .originName }} {
return internal.GetOrig{{ .structName }}(internal.{{ .structName }}(ms))
}

func (ms {{ .structName }}) getState() *internal.State {
return internal.Get{{ .structName }}State(internal.{{ .structName }}(ms))
}
{{- end }}

{{ range .fields -}}
{{ .GenerateAccessors $.messageStruct }}
{{ end }}

// CopyTo copies all properties from the current struct overriding the destination.
func (ms {{ .structName }}) CopyTo(dest {{ .structName }}) {
dest.{{- if .isCommon }}getState(){{ else }}state{{ end }}.AssertMutable()
{{- range .fields }}
{{ .GenerateCopyToValue $.messageStruct }}
{{- end }}
}`

const messageValueTestTemplate = `
func Test{{ .structName }}_MoveTo(t *testing.T) {
ms := {{ .generateTestData }}
dest := New{{ .structName }}()
ms.MoveTo(dest)
assert.Equal(t, New{{ .structName }}(), ms)
assert.Equal(t, {{ .generateTestData }}, dest)
sharedState := internal.StateReadOnly
assert.Panics(t, func() { ms.MoveTo(new{{ .structName }}(&{{ .originName }}{}, &sharedState)) })
assert.Panics(t, func() { new{{ .structName }}(&{{ .originName }}{}, &sharedState).MoveTo(dest) })
}

func Test{{ .structName }}_CopyTo(t *testing.T) {
ms := New{{ .structName }}()
orig := New{{ .structName }}()
orig.CopyTo(ms)
assert.Equal(t, orig, ms)
orig = {{ .generateTestData }}
orig.CopyTo(ms)
assert.Equal(t, orig, ms)
sharedState := internal.StateReadOnly
assert.Panics(t, func() { ms.CopyTo(new{{ .structName }}(&{{ .originName }}{}, &sharedState)) })
}

{{ range .fields }}
{{ .GenerateAccessorsTest $.messageStruct }}
{{ end }}`

const messageValueGenerateTestTemplate = `func {{ upperIfInternal "g" }}enerateTest{{ .structName }}() {{ .structName }} {
{{- if .isCommon }}
orig := {{ .originName }}{}
state := StateMutable
{{- end }}
tv := New{{ .structName }}({{ if .isCommon }}&orig, &state{{ end }})
{{ upperIfInternal "f" }}illTest{{ .structName }}(tv)
return tv
}

func {{ upperIfInternal "f" }}illTest{{ .structName }}(tv {{ .structName }}) {
{{- range .fields }}
{{ .GenerateSetWithTestValue $.messageStruct }}
{{- end }}
}`

const messageValueAliasTemplate = `
type {{ .structName }} struct {
orig *{{ .originName }}
state *State
}

func GetOrig{{ .structName }}(ms {{ .structName }}) *{{ .originName }} {
return ms.orig
}

func Get{{ .structName }}State(ms {{ .structName }}) *State {
return ms.state
}

func New{{ .structName }}(orig *{{ .originName }}, state *State) {{ .structName }} {
return {{ .structName }}{orig: orig, state: state}
}`

type baseStruct interface {
getName() string
generateStruct(sb *bytes.Buffer)
generateTests(sb *bytes.Buffer)
generateTestValueHelpers(sb *bytes.Buffer)
generateInternal(sb *bytes.Buffer)
generate(packageInfo *PackageInfo) []byte
generateTests(packageInfo *PackageInfo) []byte
generateInternal(packageInfo *PackageInfo) []byte
}

// messageValueStruct generates a struct for a proto message. The struct can be generated both as a common struct
Expand All @@ -157,43 +28,31 @@ func (ms *messageValueStruct) getName() string {
return ms.structName
}

func (ms *messageValueStruct) generateStruct(sb *bytes.Buffer) {
t := template.Must(template.New("messageValueTemplate").Parse(messageValueTemplate))
if err := t.Execute(sb, ms.templateFields()); err != nil {
func (ms *messageValueStruct) generate(packageInfo *PackageInfo) []byte {
var sb bytes.Buffer
if err := messageTemplate.Execute(&sb, ms.templateFields(packageInfo)); err != nil {
panic(err)
}
return sb.Bytes()
}

func (ms *messageValueStruct) generateTests(sb *bytes.Buffer) {
t := template.Must(template.New("messageValueTestTemplate").Parse(messageValueTestTemplate))
if err := t.Execute(sb, ms.templateFields()); err != nil {
panic(err)
}
}

func (ms *messageValueStruct) generateTestValueHelpers(sb *bytes.Buffer) {
funcs := template.FuncMap{
"upperIfInternal": func(in string) string {
if usedByOtherDataTypes(ms.packageName) {
return strings.ToUpper(in)
}
return in
},
}
t := template.Must(template.New("messageValueGenerateTestTemplate").Funcs(funcs).Parse(messageValueGenerateTestTemplate))
if err := t.Execute(sb, ms.templateFields()); err != nil {
func (ms *messageValueStruct) generateTests(packageInfo *PackageInfo) []byte {
var sb bytes.Buffer
if err := messageTestTemplate.Execute(&sb, ms.templateFields(packageInfo)); err != nil {
panic(err)
}
return sb.Bytes()
}

func (ms *messageValueStruct) generateInternal(sb *bytes.Buffer) {
t := template.Must(template.New("messageValueAliasTemplate").Parse(messageValueAliasTemplate))
if err := t.Execute(sb, ms.templateFields()); err != nil {
func (ms *messageValueStruct) generateInternal(packageInfo *PackageInfo) []byte {
var sb bytes.Buffer
if err := messageInternalTemplate.Execute(&sb, ms.templateFields(packageInfo)); err != nil {
panic(err)
}
return sb.Bytes()
}

func (ms *messageValueStruct) templateFields() map[string]any {
func (ms *messageValueStruct) templateFields(packageInfo *PackageInfo) map[string]any {
return map[string]any{
"messageStruct": ms,
"fields": ms.fields,
Expand All @@ -208,6 +67,9 @@ func (ms *messageValueStruct) templateFields() map[string]any {
"description": ms.description,
"isCommon": usedByOtherDataTypes(ms.packageName),
"origAccessor": origAccessor(ms),
"packageName": packageInfo.name,
"imports": packageInfo.imports,
"testImports": packageInfo.testImports,
}
}

Expand Down
97 changes: 12 additions & 85 deletions pdata/internal/cmd/pdatagen/internal/packages.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 15 additions & 13 deletions pdata/internal/cmd/pdatagen/internal/pcommon_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@
package internal // import "go.opentelemetry.io/collector/pdata/internal/cmd/pdatagen/internal"

var pcommon = &Package{
name: "pcommon",
path: "pcommon",
imports: []string{
`"go.opentelemetry.io/collector/pdata/internal"`,
`otlpcommon "go.opentelemetry.io/collector/pdata/internal/data/protogen/common/v1"`,
`otlpresource "go.opentelemetry.io/collector/pdata/internal/data/protogen/resource/v1"`,
},
testImports: []string{
`"testing"`,
``,
`"github.com/stretchr/testify/assert"`,
``,
`"go.opentelemetry.io/collector/pdata/internal"`,
info: &PackageInfo{
name: "pcommon",
path: "pcommon",
imports: []string{
`"go.opentelemetry.io/collector/pdata/internal"`,
`otlpcommon "go.opentelemetry.io/collector/pdata/internal/data/protogen/common/v1"`,
`otlpresource "go.opentelemetry.io/collector/pdata/internal/data/protogen/resource/v1"`,
},
testImports: []string{
`"testing"`,
``,
`"github.com/stretchr/testify/assert"`,
``,
`"go.opentelemetry.io/collector/pdata/internal"`,
},
},
structs: []baseStruct{
scope,
Expand Down
Loading
Loading