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

protoc-gen-ent: support timestamp and date #591

Open
wants to merge 1 commit 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
52 changes: 52 additions & 0 deletions entproto/cmd/protoc-gen-ent/google/type/date.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.type;

option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/type/date;date";
option java_multiple_files = true;
option java_outer_classname = "DateProto";
option java_package = "com.google.type";
option objc_class_prefix = "GTP";

// Represents a whole or partial calendar date, such as a birthday. The time of
// day and time zone are either specified elsewhere or are insignificant. The
// date is relative to the Gregorian Calendar. This can represent one of the
// following:
//
// * A full date, with non-zero year, month, and day values
// * A month and day value, with a zero year, such as an anniversary
// * A year on its own, with zero month and day values
// * A year and month value, with a zero day, such as a credit card expiration
// date
//
// Related types are [google.type.TimeOfDay][google.type.TimeOfDay] and
// `google.protobuf.Timestamp`.
message Date {
// Year of the date. Must be from 1 to 9999, or 0 to specify a date without
// a year.
int32 year = 1;

// Month of a year. Must be from 1 to 12, or 0 to specify a year without a
// month and day.
int32 month = 2;

// Day of a month. Must be from 1 to 31 and valid for the year and month, or 0
// to specify a year by itself or a year and month where the day isn't
// significant.
int32 day = 3;
}
20 changes: 19 additions & 1 deletion entproto/cmd/protoc-gen-ent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,16 @@ func toSchema(m *protogen.Message, opts *entopts.Schema) (*schemast.UpsertSchema
}

func isEdge(f *protogen.Field) bool {
return f.Desc.Kind() == protoreflect.MessageKind
isMessageKind := f.Desc.Kind() == protoreflect.MessageKind
if isMessageKind {
switch f.Desc.Message().FullName() {
case "google.protobuf.Timestamp":
return false
case "google.type.Date":
return false
}
}
return isMessageKind
}

func toEdge(f *protogen.Field) (ent.Edge, error) {
Expand Down Expand Up @@ -194,6 +203,15 @@ func toField(f *protogen.Field) (ent.Field, error) {
values = append(values, string(pbEnum.Get(i).Name()))
}
fld = field.Enum(name).Values(values...)
case protoreflect.MessageKind:
switch f.Desc.Message().FullName() {
case "google.protobuf.Timestamp":
fld = field.Time(name)
case "google.type.Date":
fld = field.Time(name)
default:
return nil, fmt.Errorf("protoc-gen-ent: unsupported kind %q", f.Desc.Kind())
}
default:
return nil, fmt.Errorf("protoc-gen-ent: unsupported kind %q", f.Desc.Kind())
}
Expand Down
14 changes: 13 additions & 1 deletion entproto/cmd/protoc-gen-ent/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ func TestBasic(t *testing.T) {
require.True(t, strings.HasPrefix(contents, "// File updated by protoc-gen-ent."))
}

func TestTimeTypes(t *testing.T) {
tt, err := newGenTest(t, "testdata/time_types.proto")
require.NoError(t, err)
contents, err := tt.fileContents("employee.go")
require.NoError(t, err)
require.Contains(t, contents, "type Employee struct")
require.Contains(t, contents, `field.String("name")`)
require.Contains(t, contents, `field.Time("date_of_birth")`)
require.Contains(t, contents, `field.Time("start_date")`)
require.True(t, strings.HasPrefix(contents, "// File updated by protoc-gen-ent."))
}

func TestCustomName(t *testing.T) {
tt, err := newGenTest(t, "testdata/custom_name.proto")
require.NoError(t, err)
Expand Down Expand Up @@ -106,7 +118,7 @@ func newGenTest(t *testing.T, files ...string) (*genTest, error) {
})
var parser protoparse.Parser
var descs []*descriptorpb.FileDescriptorProto
tgts := []string{"google/protobuf/descriptor.proto", "options/ent/opts.proto"}
tgts := []string{"google/protobuf/descriptor.proto", "google/protobuf/timestamp.proto", "google/type/date.proto", "options/ent/opts.proto"}
tgts = append(tgts, files...)
parsed, err := parser.ParseFiles(tgts...)
require.NoError(t, err)
Expand Down
16 changes: 16 additions & 0 deletions entproto/cmd/protoc-gen-ent/testdata/time_types.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto3";

package testdata;

import "options/ent/opts.proto";
import "google/protobuf/timestamp.proto";
import "google/type/date.proto";

option go_package = "ent/testdata";

message Employee {
option (ent.schema).gen = true;
string name = 1;
google.type.Date date_of_birth = 2;
google.protobuf.Timestamp start_date = 3;
}