diff --git a/pkg/protodump/fixtures/edition.proto b/pkg/protodump/fixtures/edition.proto new file mode 100644 index 0000000..5f77d1a --- /dev/null +++ b/pkg/protodump/fixtures/edition.proto @@ -0,0 +1,12 @@ +edition = "2023"; + +package demo; + +option go_package = "./;editions"; + +message Sample { + int32 id = 1; + string name = 2; + repeated int32 values = 3; +} + diff --git a/pkg/protodump/proto.go b/pkg/protodump/proto.go index d70fa06..2d92e9f 100644 --- a/pkg/protodump/proto.go +++ b/pkg/protodump/proto.go @@ -23,23 +23,6 @@ type ProtoDefinition struct { filename string } -func (pd *ProtoDefinition) indent() { - pd.indendation += 1 -} - -func (pd *ProtoDefinition) dedent() { - pd.indendation -= 1 -} - -func (pd *ProtoDefinition) writeIndented(s string) { - pd.builder.WriteString(strings.Repeat(" ", pd.indendation)) - pd.write(s) -} - -func (pd *ProtoDefinition) write(s string) { - pd.builder.WriteString(s) -} - func escapeProtoString(s string) string { var b strings.Builder for i := 0; i < len(s); i++ { @@ -63,6 +46,34 @@ func escapeProtoString(s string) string { return b.String() } +func editionString(d protoreflect.FileDescriptor) (string, error) { + edition := protodesc.ToFileDescriptorProto(d).GetEdition().String() + if strings.HasPrefix(edition, "EDITION_") { + rest := strings.TrimPrefix(edition, "EDITION_") + if _, err := strconv.Atoi(rest); err == nil { + return rest, nil + } + } + return "unknown", fmt.Errorf("not a source edition: %v", edition) +} + +func (pd *ProtoDefinition) indent() { + pd.indendation += 1 +} + +func (pd *ProtoDefinition) dedent() { + pd.indendation -= 1 +} + +func (pd *ProtoDefinition) writeIndented(s string) { + pd.builder.WriteString(strings.Repeat(" ", pd.indendation)) + pd.write(s) +} + +func (pd *ProtoDefinition) write(s string) { + pd.builder.WriteString(s) +} + func (pd *ProtoDefinition) writeQuoted(s string) { pd.write("\"") pd.write(escapeProtoString(s)) @@ -334,9 +345,16 @@ func (pd *ProtoDefinition) writeFileOptions() { } func (pd *ProtoDefinition) writeFileDescriptor() { - pd.write("syntax = \"") - pd.write(pd.descriptor.Syntax().String()) - pd.write("\";\n\n") + if pd.descriptor.Syntax() == protoreflect.Editions { + pd.write("edition = \"") + edition, _ := editionString(pd.descriptor) + pd.write(edition) + pd.write("\";\n\n") + } else { + pd.write("syntax = \"") + pd.write(pd.descriptor.Syntax().String()) + pd.write("\";\n\n") + } packageName := pd.descriptor.FullName() if packageName != "" {