encoding/protobuf: implement time type conversions
Adheres to protobuf JSON mapping.
Also fixes a bug where a filed could mask the short
name of the import time packag.
Change-Id: Ib5e71023a4d68492e35da02e997c47f4e09e3dd5
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2722
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/encoding/protobuf/parse.go b/encoding/protobuf/parse.go
index 7f36f7f..8280f06 100644
--- a/encoding/protobuf/parse.go
+++ b/encoding/protobuf/parse.go
@@ -63,12 +63,12 @@
tfile.SetLinesForContent(b)
p = &protoConverter{
- id: filename,
- state: s,
- tfile: tfile,
- used: map[string]bool{},
- symbols: map[string]bool{},
- aliases: map[string]string{},
+ id: filename,
+ state: s,
+ tfile: tfile,
+ imported: map[string]bool{},
+ symbols: map[string]bool{},
+ aliases: map[string]string{},
}
defer func() {
@@ -133,14 +133,14 @@
p.topElement(e)
}
- used := []string{}
- for k := range p.used {
- used = append(used, k)
+ imported := []string{}
+ for k := range p.imported {
+ imported = append(imported, k)
}
- sort.Strings(used)
- p.sorted = used
+ sort.Strings(imported)
+ p.sorted = imported
- for _, v := range used {
+ for _, v := range imported {
spec := &ast.ImportSpec{
Path: &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(v)},
}
@@ -172,8 +172,8 @@
file *ast.File
inBody bool
- sorted []string
- used map[string]bool
+ sorted []string
+ imported map[string]bool
path []string
scope []map[string]mapping // for symbols resolution within package.
@@ -214,6 +214,15 @@
case *proto.Enum:
name = x.Name
pos = x.Position
+ case *proto.NormalField:
+ name = x.Name
+ pos = x.Position
+ case *proto.MapField:
+ name = x.Name
+ pos = x.Position
+ case *proto.Oneof:
+ name = x.Name
+ pos = x.Position
default:
continue
}
@@ -228,26 +237,25 @@
}
func (p *protoConverter) uniqueTop(name string) string {
- if len(p.path) == 0 {
- return name
- }
a := strings.SplitN(name, ".", 2)
- if p.path[len(p.path)-1] == a[0] {
- first := a[0]
- alias, ok := p.aliases[first]
- if !ok {
- // TODO: this is likely to be okay, but find something better.
- alias = "__" + first
- p.file.Decls = append(p.file.Decls, &ast.Alias{
- Ident: ast.NewIdent(alias),
- Expr: ast.NewIdent(first),
- })
- p.aliases[first] = alias
+ for i := len(p.scope) - 1; i > 0; i-- {
+ if _, ok := p.scope[i][a[0]]; ok {
+ first := a[0]
+ alias, ok := p.aliases[first]
+ if !ok {
+ // TODO: this is likely to be okay, but find something better.
+ alias = "__" + first
+ p.file.Decls = append(p.file.Decls, &ast.Alias{
+ Ident: ast.NewIdent(alias),
+ Expr: ast.NewIdent(first),
+ })
+ p.aliases[first] = alias
+ }
+ if len(a) > 1 {
+ alias += "." + a[1]
+ }
+ return alias
}
- if len(a) > 1 {
- alias += "." + a[1]
- }
- return alias
}
return name
}
@@ -265,6 +273,9 @@
}
func (p *protoConverter) resolve(pos scanner.Position, name string, options []*proto.Option) string {
+ if s, ok := protoToCUE(name, options); ok {
+ return s
+ }
if strings.HasPrefix(name, ".") {
return p.resolveTopScope(pos, name[1:], options)
}
@@ -286,16 +297,13 @@
}
if m, ok := p.scope[0][name[:i]]; ok {
if m.pkg != nil {
- p.used[m.pkg.goPkgPath] = true
+ p.imported[m.pkg.goPkgPath] = true
// TODO: do something more principled.
}
cueName := strings.Replace(name[i:], ".", "_", -1)
return p.uniqueTop(m.ref + cueName)
}
}
- if s, ok := protoToCUE(name, options); ok {
- return s
- }
failf(pos, "name %q not found", name)
return ""
}
diff --git a/encoding/protobuf/protobuf.go b/encoding/protobuf/protobuf.go
index 9ae5b64..a2a1413 100644
--- a/encoding/protobuf/protobuf.go
+++ b/encoding/protobuf/protobuf.go
@@ -21,29 +21,33 @@
//
// The following type mappings of defintions apply:
//
-// Proto type CUE type/def Comments
-// message struct Message fields become CUE fields, whereby
-// names are mapped to lowerCamelCase.
-// enum e1 | e2 | ... Where ex are strings. A separate mapping is
-// generated to obtain the numeric values.
-// map<K, V> { <>: V } All keys are converted to strings.
-// repeated V [...V] null is accepted as the empty list [].
+// Proto type CUE type/def Comments
+// message struct Message fields become CUE fields, whereby
+// names are mapped to lowerCamelCase.
+// enum e1 | e2 | ... Where ex are strings. A separate mapping is
+// generated to obtain the numeric values.
+// map<K, V> { <>: V } All keys are converted to strings.
+// repeated V [...V] null is accepted as the empty list [].
// bool bool
// string string
-// bytes bytes A base64-encoded string when converted to JSON.
-// int32, fixed32 int32 An integer with bounds as defined by int32.
-// uint32 uint32 An integer with bounds as defined by uint32.
-// int64, fixed64 int64 An integer with bounds as defined by int64.
-// uint64 uint64 An integer with bounds as defined by uint64.
-// float float32 A number with bounds as defined by float32.
-// double float64 A number with bounds as defined by float64.
-// Struct struct See struct.proto.
-// Value _ See struct.proto.
-// ListValue [...] See struct.proto.
-// BoolValue bool See struct.proto.
-// StringValue string See struct.proto.
-// NumberValue number See struct.proto.
-// StringValue string See struct.proto.
+// bytes bytes A base64-encoded string when converted to JSON.
+// int32, fixed32 int32 An integer with bounds as defined by int32.
+// uint32 uint32 An integer with bounds as defined by uint32.
+// int64, fixed64 int64 An integer with bounds as defined by int64.
+// uint64 uint64 An integer with bounds as defined by uint64.
+// float float32 A number with bounds as defined by float32.
+// double float64 A number with bounds as defined by float64.
+// Struct struct See struct.proto.
+// Value _ See struct.proto.
+// ListValue [...] See struct.proto.
+// NullValue null See struct.proto.
+// BoolValue bool See struct.proto.
+// StringValue string See struct.proto.
+// NumberValue number See struct.proto.
+// StringValue string See struct.proto.
+// Empty struct.MaxFields(0)
+// Timestamp time.Time See struct.proto.
+// Duration time.Duration See struct.proto.
//
// Protobuf definitions can be annotated with CUE constraints that are
// included in the generated CUE:
@@ -58,12 +62,12 @@
package protobuf
// TODO mappings:
-// Timestamp string "1972-01-01T10:00:20.021Z" Uses RFC 3339, where generated output will always be Z-normalized and uses 0, 3, 6 or 9 fractional digits. Offsets other than "Z" are also accepted.
-// Duration string "1.000340012s", "1s" Generated output always contains 0, 3, 6, or 9 fractional digits, depending on required precision, followed by the suffix "s". Accepted are any fractional digits (also none) as long as they fit into nano-seconds precision and the suffix "s" is required.
-// Empty object {}
//
// Wrapper types various types 2, "2", "foo", true, "true", null, 0, … Wrappers use the same representation in JSON as the wrapped primitive type, except that null is allowed and preserved during data conversion and transfer.
// FieldMask string "f.fooBar,h" See field_mask.proto.
+// Any {"@type":"url", See struct.proto.
+// f1: value,
+// ...}
import (
"os"
@@ -238,9 +242,7 @@
}
f, err = parser.ParseFile(f.Filename, buf, parser.ParseComments)
if err != nil {
- panic(err)
b.addErr(err)
- // return nil, err
continue
}
@@ -251,7 +253,7 @@
// return nil, err
// }
- for pkg := range r.p.used {
+ for pkg := range r.p.imported {
inst.ImportPaths = append(inst.ImportPaths, pkg)
}
}
diff --git a/encoding/protobuf/protobuf_test.go b/encoding/protobuf/protobuf_test.go
index d62951d..bd5a905 100644
--- a/encoding/protobuf/protobuf_test.go
+++ b/encoding/protobuf/protobuf_test.go
@@ -120,7 +120,7 @@
gotFiles[rel] = f
}
- filepath.Walk("testdata/istio.io/api", func(path string, fi os.FileInfo, err error) error {
+ _ = filepath.Walk("testdata/istio.io/api", func(path string, fi os.FileInfo, err error) error {
if err != nil || fi.IsDir() || !strings.HasSuffix(path, ".cue") {
return err
}
diff --git a/encoding/protobuf/testdata/attributes.proto.out.cue b/encoding/protobuf/testdata/attributes.proto.out.cue
index 055c6c8..73f2cd8 100644
--- a/encoding/protobuf/testdata/attributes.proto.out.cue
+++ b/encoding/protobuf/testdata/attributes.proto.out.cue
@@ -14,10 +14,7 @@
// limitations under the License.
package v1
-import (
- "github.com/golang/protobuf/ptypes/duration"
- "github.com/golang/protobuf/ptypes/timestamp"
-)
+import "time"
StructWrap: {
struct?: {} @protobuf(1,type=google.protobuf.Struct)
@@ -91,10 +88,10 @@
bytesValue?: bytes @protobuf(6,name=bytes_value)
} | {
// Used for values of type TIMESTAMP
- timestampValue?: timestamp.Timestamp @protobuf(7,type=google.protobuf.Timestamp,name=timestamp_value)
+ timestampValue?: time.Time @protobuf(7,type=google.protobuf.Timestamp,name=timestamp_value)
} | {
// Used for values of type DURATION
- durationValue?: duration.Duration @protobuf(8,type=google.protobuf.Duration,name=duration_value)
+ durationValue?: time.Duration @protobuf(8,type=google.protobuf.Duration,name=duration_value)
} | {
// Used for values of type STRING_MAP
stringMapValue?: Attributes_StringMap @protobuf(9,type=StringMap,name=string_map_value)
@@ -140,13 +137,13 @@
} @protobuf(5,type=map<sint32,bool>)
// Holds attributes of type TIMESTAMP
- timestamps: {
- <_>: timestamp.Timestamp
+ time: {
+ <_>: __time.Time
} @protobuf(6,type=map<sint32,google.protobuf.Timestamp>,"(gogoproto.nullable)=false","(gogoproto.stdtime)")
// Holds attributes of type DURATION
durations: {
- <_>: duration.Duration
+ <_>: __time.Duration
} @protobuf(7,type=map<sint32,google.protobuf.Duration>,"(gogoproto.nullable)=false","(gogoproto.stdduration)")
// Holds attributes of type BYTES
@@ -159,6 +156,7 @@
<_>: StringMap
} @protobuf(9,type=map<sint32,StringMap>,string_maps,"(gogoproto.nullable)=false")
}
+__time = time
// A map of string to string. The keys and values in this map are dictionary
// indices (see the [Attributes][istio.mixer.v1.CompressedAttributes] message for an explanation)
diff --git a/encoding/protobuf/testdata/client_config.proto.out.cue b/encoding/protobuf/testdata/client_config.proto.out.cue
index a3db5df..f8535a7 100644
--- a/encoding/protobuf/testdata/client_config.proto.out.cue
+++ b/encoding/protobuf/testdata/client_config.proto.out.cue
@@ -21,8 +21,8 @@
package client
import (
- "github.com/golang/protobuf/ptypes/duration"
"istio.io/api/mixer/v1"
+ "time"
)
// Specifies the behavior when the client is unable to connect to Mixer.
@@ -36,10 +36,10 @@
// Base time to wait between retries. Will be adjusted by exponential
// backoff and jitter.
- baseRetryWait?: duration.Duration @protobuf(3,type=google.protobuf.Duration,name=base_retry_wait)
+ baseRetryWait?: time.Duration @protobuf(3,type=google.protobuf.Duration,name=base_retry_wait)
// Max time to wait between retries.
- maxRetryWait?: duration.Duration @protobuf(4,type=google.protobuf.Duration,name=max_retry_wait)
+ maxRetryWait?: time.Duration @protobuf(4,type=google.protobuf.Duration,name=max_retry_wait)
}
// Example of single-value enum.
@@ -108,7 +108,7 @@
// Specify refresh interval to write Mixer client statistics to Envoy share
// memory. If not specified, the interval is 10 seconds.
- statsUpdateInterval?: duration.Duration @protobuf(5,type=google.protobuf.Duration,name=stats_update_interval)
+ statsUpdateInterval?: time.Duration @protobuf(5,type=google.protobuf.Duration,name=stats_update_interval)
// Name of the cluster that will forward check calls to a pool of mixer
// servers. Defaults to "mixer_server". By using different names for
@@ -185,5 +185,5 @@
// Specify report interval to send periodical reports for long TCP
// connections. If not specified, the interval is 10 seconds. This interval
// should not be less than 1 second, otherwise it will be reset to 1 second.
- reportInterval?: duration.Duration @protobuf(6,type=google.protobuf.Duration,name=report_interval)
+ reportInterval?: time.Duration @protobuf(6,type=google.protobuf.Duration,name=report_interval)
}
diff --git a/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes.proto b/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes.proto
index 780005c..ddc1b94 100644
--- a/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes.proto
+++ b/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes.proto
@@ -139,7 +139,7 @@
map<sint32, bool> bools = 5;
// Holds attributes of type TIMESTAMP
- map<sint32, google.protobuf.Timestamp> timestamps = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
+ map<sint32, google.protobuf.Timestamp> time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
// Holds attributes of type DURATION
map<sint32, google.protobuf.Duration> durations = 7 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];
diff --git a/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes_proto_gen.cue
index e5ee16d..085190a 100644
--- a/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes_proto_gen.cue
+++ b/encoding/protobuf/testdata/istio.io/api/mixer/v1/attributes_proto_gen.cue
@@ -14,10 +14,7 @@
// limitations under the License.
package v1
-import (
- "github.com/golang/protobuf/ptypes/duration"
- "github.com/golang/protobuf/ptypes/timestamp"
-)
+import "time"
StructWrap: {
struct?: {} @protobuf(1,type=google.protobuf.Struct)
@@ -91,10 +88,10 @@
bytesValue?: bytes @protobuf(6,name=bytes_value)
} | {
// Used for values of type TIMESTAMP
- timestampValue?: timestamp.Timestamp @protobuf(7,type=google.protobuf.Timestamp,name=timestamp_value)
+ timestampValue?: time.Time @protobuf(7,type=google.protobuf.Timestamp,name=timestamp_value)
} | {
// Used for values of type DURATION
- durationValue?: duration.Duration @protobuf(8,type=google.protobuf.Duration,name=duration_value)
+ durationValue?: time.Duration @protobuf(8,type=google.protobuf.Duration,name=duration_value)
} | {
// Used for values of type STRING_MAP
stringMapValue?: Attributes_StringMap @protobuf(9,type=StringMap,name=string_map_value)
@@ -140,13 +137,13 @@
} @protobuf(5,type=map<sint32,bool>)
// Holds attributes of type TIMESTAMP
- timestamps: {
- <_>: timestamp.Timestamp
+ time: {
+ <_>: __time.Time
} @protobuf(6,type=map<sint32,google.protobuf.Timestamp>,"(gogoproto.nullable)=false","(gogoproto.stdtime)")
// Holds attributes of type DURATION
durations: {
- <_>: duration.Duration
+ <_>: __time.Duration
} @protobuf(7,type=map<sint32,google.protobuf.Duration>,"(gogoproto.nullable)=false","(gogoproto.stdduration)")
// Holds attributes of type BYTES
@@ -159,6 +156,7 @@
<_>: StringMap
} @protobuf(9,type=map<sint32,StringMap>,string_maps,"(gogoproto.nullable)=false")
}
+__time = time
// A map of string to string. The keys and values in this map are dictionary
// indices (see the [Attributes][istio.mixer.v1.CompressedAttributes] message for an explanation)
diff --git a/encoding/protobuf/testdata/istio.io/api/mixer/v1/config/client/client_config_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/mixer/v1/config/client/client_config_proto_gen.cue
index 771cc01..dd44e5c 100644
--- a/encoding/protobuf/testdata/istio.io/api/mixer/v1/config/client/client_config_proto_gen.cue
+++ b/encoding/protobuf/testdata/istio.io/api/mixer/v1/config/client/client_config_proto_gen.cue
@@ -20,8 +20,8 @@
package client
import (
- "github.com/golang/protobuf/ptypes/duration"
"istio.io/api/mixer/v1"
+ "time"
)
// Specifies the behavior when the client is unable to connect to Mixer.
@@ -35,10 +35,10 @@
// Base time to wait between retries. Will be adjusted by exponential
// backoff and jitter.
- baseRetryWait?: duration.Duration @protobuf(3,type=google.protobuf.Duration,name=base_retry_wait)
+ baseRetryWait?: time.Duration @protobuf(3,type=google.protobuf.Duration,name=base_retry_wait)
// Max time to wait between retries.
- maxRetryWait?: duration.Duration @protobuf(4,type=google.protobuf.Duration,name=max_retry_wait)
+ maxRetryWait?: time.Duration @protobuf(4,type=google.protobuf.Duration,name=max_retry_wait)
}
// Example of single-value enum.
@@ -107,7 +107,7 @@
// Specify refresh interval to write Mixer client statistics to Envoy share
// memory. If not specified, the interval is 10 seconds.
- statsUpdateInterval?: duration.Duration @protobuf(5,type=google.protobuf.Duration,name=stats_update_interval)
+ statsUpdateInterval?: time.Duration @protobuf(5,type=google.protobuf.Duration,name=stats_update_interval)
// Name of the cluster that will forward check calls to a pool of mixer
// servers. Defaults to "mixer_server". By using different names for
@@ -184,5 +184,5 @@
// Specify report interval to send periodical reports for long TCP
// connections. If not specified, the interval is 10 seconds. This interval
// should not be less than 1 second, otherwise it will be reset to 1 second.
- reportInterval?: duration.Duration @protobuf(6,type=google.protobuf.Duration,name=report_interval)
+ reportInterval?: time.Duration @protobuf(6,type=google.protobuf.Duration,name=report_interval)
}
diff --git a/encoding/protobuf/testdata/istio.io/api/mixer/v1/mixer_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/mixer/v1/mixer_proto_gen.cue
index 44a4cad..c369365 100644
--- a/encoding/protobuf/testdata/istio.io/api/mixer/v1/mixer_proto_gen.cue
+++ b/encoding/protobuf/testdata/istio.io/api/mixer/v1/mixer_proto_gen.cue
@@ -17,8 +17,8 @@
package v1
import (
- "github.com/golang/protobuf/ptypes/duration"
"google.golang.org/genproto/googleapis/rpc/status"
+ "time"
)
// Used to get a thumbs-up/thumbs-down before performing an action.
@@ -74,7 +74,7 @@
status?: __status.Status @protobuf(1,type=google.rpc.Status,"(gogoproto.nullable)=false")
// The amount of time for which this result can be considered valid.
- validDuration?: duration.Duration @protobuf(2,type=google.protobuf.Duration,name=valid_duration,"(gogoproto.nullable)=false","(gogoproto.stdduration)")
+ validDuration?: time.Duration @protobuf(2,type=google.protobuf.Duration,name=valid_duration,"(gogoproto.nullable)=false","(gogoproto.stdduration)")
// The number of uses for which this result can be considered valid.
validUseCount?: int32 @protobuf(3,name=valid_use_count)
@@ -92,7 +92,7 @@
// Expresses the result of a quota allocation.
CheckResponse_QuotaResult: {
// The amount of time for which this result can be considered valid.
- validDuration?: duration.Duration @protobuf(1,type=google.protobuf.Duration,name=valid_duration,"(gogoproto.nullable)=false","(gogoproto.stdduration)")
+ validDuration?: time.Duration @protobuf(1,type=google.protobuf.Duration,name=valid_duration,"(gogoproto.nullable)=false","(gogoproto.stdduration)")
// The amount of granted quota. When `QuotaParams.best_effort` is true, this will be >= 0.
// If `QuotaParams.best_effort` is false, this will be either 0 or >= `QuotaParams.amount`.
diff --git a/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/duration/duration_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/duration/duration_proto_gen.cue
deleted file mode 100644
index bca02c4..0000000
--- a/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/duration/duration_proto_gen.cue
+++ /dev/null
@@ -1,106 +0,0 @@
-
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-package duration
-
-// A Duration represents a signed, fixed-length span of time represented
-// as a count of seconds and fractions of seconds at nanosecond
-// resolution. It is independent of any calendar and concepts like "day"
-// or "month". It is related to Timestamp in that the difference between
-// two Timestamp values is a Duration and it can be added or subtracted
-// from a Timestamp. Range is approximately +-10,000 years.
-//
-// # Examples
-//
-// Example 1: Compute Duration from two Timestamps in pseudo code.
-//
-// Timestamp start = ...;
-// Timestamp end = ...;
-// Duration duration = ...;
-//
-// duration.seconds = end.seconds - start.seconds;
-// duration.nanos = end.nanos - start.nanos;
-//
-// if (duration.seconds < 0 && duration.nanos > 0) {
-// duration.seconds += 1;
-// duration.nanos -= 1000000000;
-// } else if (durations.seconds > 0 && duration.nanos < 0) {
-// duration.seconds -= 1;
-// duration.nanos += 1000000000;
-// }
-//
-// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-//
-// Timestamp start = ...;
-// Duration duration = ...;
-// Timestamp end = ...;
-//
-// end.seconds = start.seconds + duration.seconds;
-// end.nanos = start.nanos + duration.nanos;
-//
-// if (end.nanos < 0) {
-// end.seconds -= 1;
-// end.nanos += 1000000000;
-// } else if (end.nanos >= 1000000000) {
-// end.seconds += 1;
-// end.nanos -= 1000000000;
-// }
-//
-// Example 3: Compute Duration from datetime.timedelta in Python.
-//
-// td = datetime.timedelta(days=3, minutes=10)
-// duration = Duration()
-// duration.FromTimedelta(td)
-//
-// # JSON Mapping
-//
-// In JSON format, the Duration type is encoded as a string rather than an
-// object, where the string ends in the suffix "s" (indicating seconds) and
-// is preceded by the number of seconds, with nanoseconds expressed as
-// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
-// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
-// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
-// microsecond should be expressed in JSON format as "3.000001s".
-//
-//
-Duration: {
- // Signed seconds of the span of time. Must be from -315,576,000,000
- // to +315,576,000,000 inclusive. Note: these bounds are computed from:
- // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
- seconds?: int64 @protobuf(1)
-
- // Signed fractions of a second at nanosecond resolution of the span
- // of time. Durations less than one second are represented with a 0
- // `seconds` field and a positive or negative `nanos` field. For durations
- // of one second or more, a non-zero value for the `nanos` field must be
- // of the same sign as the `seconds` field. Must be from -999,999,999
- // to +999,999,999 inclusive.
- nanos?: int32 @protobuf(2)
-}
diff --git a/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/timestamp/timestamp_proto_gen.cue b/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/timestamp/timestamp_proto_gen.cue
deleted file mode 100644
index f11f6e3..0000000
--- a/encoding/protobuf/testdata/istio.io/api/pkg/github.com/golang/protobuf/ptypes/timestamp/timestamp_proto_gen.cue
+++ /dev/null
@@ -1,128 +0,0 @@
-
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-package timestamp
-
-// A Timestamp represents a point in time independent of any time zone or local
-// calendar, encoded as a count of seconds and fractions of seconds at
-// nanosecond resolution. The count is relative to an epoch at UTC midnight on
-// January 1, 1970, in the proleptic Gregorian calendar which extends the
-// Gregorian calendar backwards to year one.
-//
-// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
-// second table is needed for interpretation, using a [24-hour linear
-// smear](https://developers.google.com/time/smear).
-//
-// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
-// restricting to that range, we ensure that we can convert to and from [RFC
-// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
-//
-// # Examples
-//
-// Example 1: Compute Timestamp from POSIX `time()`.
-//
-// Timestamp timestamp;
-// timestamp.set_seconds(time(NULL));
-// timestamp.set_nanos(0);
-//
-// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
-//
-// struct timeval tv;
-// gettimeofday(&tv, NULL);
-//
-// Timestamp timestamp;
-// timestamp.set_seconds(tv.tv_sec);
-// timestamp.set_nanos(tv.tv_usec * 1000);
-//
-// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
-//
-// FILETIME ft;
-// GetSystemTimeAsFileTime(&ft);
-// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
-//
-// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
-// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
-// Timestamp timestamp;
-// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
-// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
-//
-// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
-//
-// long millis = System.currentTimeMillis();
-//
-// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
-// .setNanos((int) ((millis % 1000) * 1000000)).build();
-//
-//
-// Example 5: Compute Timestamp from current time in Python.
-//
-// timestamp = Timestamp()
-// timestamp.GetCurrentTime()
-//
-// # JSON Mapping
-//
-// In JSON format, the Timestamp type is encoded as a string in the
-// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
-// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
-// where {year} is always expressed using four digits while {month}, {day},
-// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
-// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
-// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
-// is required. A proto3 JSON serializer should always use UTC (as indicated by
-// "Z") when printing the Timestamp type and a proto3 JSON parser should be
-// able to accept both UTC and other timezones (as indicated by an offset).
-//
-// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
-// 01:30 UTC on January 15, 2017.
-//
-// In JavaScript, one can convert a Date object to this format using the
-// standard
-// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
-// method. In Python, a standard `datetime.datetime` object can be converted
-// to this format using
-// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
-// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
-// the Joda Time's [`ISODateTimeFormat.dateTime()`](
-// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
-// ) to obtain a formatter capable of generating timestamps in this format.
-//
-//
-Timestamp: {
- // Represents seconds of UTC time since Unix epoch
- // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
- // 9999-12-31T23:59:59Z inclusive.
- seconds?: int64 @protobuf(1)
-
- // Non-negative fractions of a second at nanosecond resolution. Negative
- // second values with fractions must still have non-negative nanos values
- // that count forward in time. Must be from 0 to 999,999,999
- // inclusive.
- nanos?: int32 @protobuf(2)
-}
diff --git a/encoding/protobuf/types.go b/encoding/protobuf/types.go
index f54708e..5fff043 100644
--- a/encoding/protobuf/types.go
+++ b/encoding/protobuf/types.go
@@ -52,6 +52,11 @@
p.scope[0][from] = mapping{to, "", pkg}
}
+var (
+ pkgTime = &protoConverter{goPkgPath: "time"}
+ pkgStruct = &protoConverter{goPkgPath: "struct"}
+)
+
func (p *protoConverter) mapBuiltinPackage(pos scanner.Position, file string, required bool) (generate bool) {
// Map some builtin types to their JSON/CUE mappings.
switch file {
@@ -67,16 +72,22 @@
p.setBuiltin("google.protobuf.NumberValue", "number", nil)
return false
- // TODO: consider mapping the following:
+ case "google/protobuf/empty.proto":
+ p.setBuiltin("google.protobuf.Empty", "struct.MaxFields(0)", pkgStruct)
+ return false
- // case "google/protobuf/duration.proto":
- // p.setBuiltin("google.protobuf.Duration", "time.Duration", "time")
+ case "google/protobuf/duration.proto":
+ p.setBuiltin("google.protobuf.Duration", "time.Duration", pkgTime)
+ return false
- // case "google/protobuf/timestamp.proto":
- // p.setBuiltin("google.protobuf.Timestamp", "time.Time", "time")
+ case "google/protobuf/timestamp.proto":
+ p.setBuiltin("google.protobuf.Timestamp", "time.Time", pkgTime)
+ return false
- // case "google/protobuf/empty.proto":
- // p.setBuiltin("google.protobuf.Empty", "struct.MaxFields(0)", nil)
+ // case "google/protobuf/field_mask.proto":
+ // p.setBuiltin("google.protobuf.FieldMask", "protobuf.FieldMask", nil)
+
+ // protobuf.Any
default:
if required {