Skip to content

Commit e607ea6

Browse files
authored
feat: Base messages in google_cloud_protobuf (#2660)
1. supports the move of `ProtoMessage` and `ProtoEnum` to `package:google_cloud_protobuf` 2. supports the move of `encodings.dart` to `package:google_cloud_protobuf` Fixes googleapis/google-cloud-dart#51
1 parent 09468fa commit e607ea6

File tree

7 files changed

+60
-34
lines changed

7 files changed

+60
-34
lines changed

internal/sidekick/internal/dart/annotate.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ type modelAnnotations struct {
6060
ApiKeyEnvironmentVariables []string
6161
// Dart `export` statements e.g.
6262
// ["export 'package:google_cloud_gax/gax.dart' show Any", "export 'package:google_cloud_gax/gax.dart' show Status"]
63-
Exports []string
63+
Exports []string
64+
ProtoPrefix string
6465
}
6566

6667
// HasServices returns true if the model has services.
@@ -97,6 +98,7 @@ type messageAnnotation struct {
9798
// A custom body for the message's constructor.
9899
ConstructorBody string
99100
ToStringLines []string
101+
Model *api.API
100102
}
101103

102104
// HasFields returns true if the message has fields.
@@ -167,6 +169,7 @@ type fieldAnnotation struct {
167169
type enumAnnotation struct {
168170
Name string
169171
DocLines []string
172+
Model *api.API
170173
}
171174

172175
type enumValueAnnotation struct {
@@ -234,6 +237,8 @@ func (annotate *annotateModel) annotateModel(options map[string]string) error {
234237
issueTrackerURL string
235238
apiKeyEnvironmentVariables = []string{}
236239
exports = []string{}
240+
protobufPrefix string
241+
pkgName string
237242
)
238243

239244
for key, definition := range options {
@@ -343,11 +348,18 @@ func (annotate *annotateModel) annotateModel(options map[string]string) error {
343348
devDependencies = append(devDependencies, "lints")
344349

345350
// Add the import for the google_cloud_gax package.
346-
annotate.imports[commonImport] = true
351+
if len(model.Services) > 0 {
352+
annotate.imports[gaxImport] = true
353+
}
347354

348-
packageDependencies, err := calculateDependencies(annotate.imports, annotate.dependencyConstraints)
349-
if err != nil {
350-
return err
355+
// `google.protobuf` defines `JsonEncodable`, which is needed by any package that defines a
356+
// `message` or `enum`, i.e., all of them.
357+
protobufPrefix = annotate.packagePrefixes["google.protobuf"]
358+
if protobufPrefix == "" {
359+
annotate.imports[protobufImport] = true
360+
} else {
361+
annotate.imports[protobufImport+" as "+protobufPrefix] = true
362+
protobufPrefix += "."
351363
}
352364

353365
if len(model.Services) > 0 && len(apiKeyEnvironmentVariables) == 0 {
@@ -358,9 +370,15 @@ func (annotate *annotateModel) annotateModel(options map[string]string) error {
358370
return errors.New("all packages must define 'issue-tracker-url'")
359371
}
360372

373+
pkgName = packageName(model, packageNameOverride)
374+
packageDependencies, err := calculateDependencies(annotate.imports, annotate.dependencyConstraints, pkgName)
375+
if err != nil {
376+
return err
377+
}
378+
361379
ann := &modelAnnotations{
362380
Parent: model,
363-
PackageName: packageName(model, packageNameOverride),
381+
PackageName: pkgName,
364382
PackageVersion: packageVersion,
365383
MainFileName: strcase.ToSnake(model.Name),
366384
CopyrightYear: generationYear,
@@ -385,6 +403,7 @@ func (annotate *annotateModel) annotateModel(options map[string]string) error {
385403
ReadMeQuickstartText: readMeQuickstartText,
386404
ApiKeyEnvironmentVariables: apiKeyEnvironmentVariables,
387405
Exports: exports,
406+
ProtoPrefix: protobufPrefix,
388407
}
389408

390409
model.Codec = ann
@@ -417,7 +436,7 @@ func calculateRequiredFields(model *api.API) map[string]*api.Field {
417436
}
418437

419438
// calculateDependencies calculates package dependencies based on `package:` imports.
420-
func calculateDependencies(imports map[string]bool, constraints map[string]string) ([]packageDependency, error) {
439+
func calculateDependencies(imports map[string]bool, constraints map[string]string, packageName string) ([]packageDependency, error) {
421440
deps := []packageDependency{}
422441

423442
for imp := range imports {
@@ -431,7 +450,10 @@ func calculateDependencies(imports map[string]bool, constraints map[string]strin
431450
if len(constraint) == 0 {
432451
return nil, fmt.Errorf("unknown version constraint for package %q (did you forget to add it to .sidekick.toml?)", name)
433452
}
434-
deps = append(deps, packageDependency{Name: name, Constraint: constraint})
453+
454+
if name != packageName {
455+
deps = append(deps, packageDependency{Name: name, Constraint: constraint})
456+
}
435457
}
436458
}
437459
}
@@ -501,7 +523,8 @@ func (annotate *annotateModel) annotateService(s *api.Service) {
501523

502524
func (annotate *annotateModel) annotateMessage(m *api.Message) {
503525
// Add the import for the common JSON helpers.
504-
annotate.imports[commonHelpersImport] = true
526+
527+
annotate.imports[encodingImport] = true
505528

506529
for _, f := range m.Fields {
507530
annotate.annotateField(f)
@@ -536,6 +559,7 @@ func (annotate *annotateModel) annotateMessage(m *api.Message) {
536559
OmitGeneration: omit || m.IsMap,
537560
ConstructorBody: constructorBody,
538561
ToStringLines: toStringLines,
562+
Model: annotate.model,
539563
}
540564
}
541565

@@ -869,6 +893,7 @@ func (annotate *annotateModel) annotateEnum(enum *api.Enum) {
869893
enum.Codec = &enumAnnotation{
870894
Name: enumName(enum),
871895
DocLines: formatDocComments(enum.Documentation, annotate.state),
896+
Model: annotate.model,
872897
}
873898
}
874899

internal/sidekick/internal/dart/annotate_test.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ var (
2929
"issue-tracker-url": "http://www.example.com/issues",
3030
"package:googleapis_auth": "^2.0.0",
3131
"package:google_cloud_gax": "^1.2.3",
32-
"package:http": "^4.5.6"}
32+
"package:http": "^4.5.6",
33+
"package:google_cloud_protobuf": "^7.8.9",
34+
}
3335
)
3436

3537
func TestAnnotateModel(t *testing.T) {
@@ -149,9 +151,10 @@ func TestAnnotateModel_Options(t *testing.T) {
149151
map[string]string{"google_cloud_gax": "^1.2.3", "package:http": "1.2.0"},
150152
func(t *testing.T, am *annotateModel) {
151153
if diff := cmp.Diff(map[string]string{
152-
"google_cloud_gax": "^1.2.3",
153-
"googleapis_auth": "^2.0.0",
154-
"http": "1.2.0"},
154+
"google_cloud_gax": "^1.2.3",
155+
"google_cloud_protobuf": "^7.8.9",
156+
"googleapis_auth": "^2.0.0",
157+
"http": "1.2.0"},
155158
am.dependencyConstraints); diff != "" {
156159
t.Errorf("mismatch in annotateModel.dependencyConstraints (-want, +got)\n:%s", diff)
157160
}
@@ -252,31 +255,33 @@ func TestAnnotateMethod(t *testing.T) {
252255

253256
func TestCalculateDependencies(t *testing.T) {
254257
for _, test := range []struct {
255-
name string
256-
imports []string
257-
want []packageDependency
258+
testName string
259+
pkgName string
260+
imports []string
261+
want []packageDependency
258262
}{
259-
{name: "empty", imports: []string{}, want: []packageDependency{}},
260-
{name: "dart import", imports: []string{typedDataImport}, want: []packageDependency{}},
261-
{name: "package import", imports: []string{httpImport}, want: []packageDependency{{Name: "http", Constraint: "^1.3.0"}}},
262-
{name: "dart and package imports", imports: []string{typedDataImport, httpImport}, want: []packageDependency{{Name: "http", Constraint: "^1.3.0"}}},
263-
{name: "package imports", imports: []string{
263+
{testName: "empty", pkgName: "google_cloud_bar", imports: []string{}, want: []packageDependency{}},
264+
{testName: "dart import", pkgName: "google_cloud_bar", imports: []string{typedDataImport}, want: []packageDependency{}},
265+
{testName: "package import", pkgName: "google_cloud_bar", imports: []string{httpImport}, want: []packageDependency{{Name: "http", Constraint: "^1.3.0"}}},
266+
{testName: "dart and package imports", pkgName: "google_cloud_bar", imports: []string{typedDataImport, httpImport}, want: []packageDependency{{Name: "http", Constraint: "^1.3.0"}}},
267+
{testName: "package imports", pkgName: "google_cloud_bar", imports: []string{
264268
httpImport,
265269
"package:google_cloud_foo/foo.dart",
266270
}, want: []packageDependency{{Name: "google_cloud_foo", Constraint: "^1.2.3"}, {Name: "http", Constraint: "^1.3.0"}}},
271+
{testName: "same package", pkgName: "google_cloud_bar", imports: []string{typedDataImport, httpImport, "google_cloud_bar"}, want: []packageDependency{{Name: "http", Constraint: "^1.3.0"}}},
267272
} {
268-
t.Run(test.name, func(t *testing.T) {
273+
t.Run(test.testName, func(t *testing.T) {
269274
deps := map[string]bool{}
270275
for _, imp := range test.imports {
271276
deps[imp] = true
272277
}
273-
got, err := calculateDependencies(deps, map[string]string{"google_cloud_foo": "^1.2.3", "http": "^1.3.0"})
278+
got, err := calculateDependencies(deps, map[string]string{"google_cloud_foo": "^1.2.3", "http": "^1.3.0"}, test.pkgName)
274279
if err != nil {
275280
t.Fatal(err)
276281
}
277282

278283
if diff := cmp.Diff(test.want, got); diff != "" {
279-
t.Errorf("mismatch in calculateDependencies (-want, +got)\n:%s", diff)
284+
t.Errorf("mismatch in %q in calculateDependencies (-want, +got)\n:%s", test.testName, diff)
280285
}
281286
})
282287
}

internal/sidekick/internal/dart/dart.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ import (
2828
var typedDataImport = "dart:typed_data"
2929
var authImport = "package:googleapis_auth/auth_io.dart as auth"
3030
var httpImport = "package:http/http.dart as http"
31-
var commonImport = "package:google_cloud_gax/gax.dart"
32-
var commonHelpersImport = "package:google_cloud_gax/src/encoding.dart"
31+
var gaxImport = "package:google_cloud_gax/gax.dart"
32+
var encodingImport = "package:google_cloud_protobuf/src/encoding.dart"
33+
var protobufImport = "package:google_cloud_protobuf/protobuf.dart"
3334

3435
var needsCtorValidation = map[string]string{
3536
".google.protobuf.Duration": "",

internal/sidekick/internal/dart/templates/analysis_options.yaml.mustache

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,4 @@ analyzer:
2525
camel_case_types: ignore
2626
implementation_imports: ignore
2727
unintended_html_in_doc_comment: ignore
28-
{{!
29-
`package:google_cloud_gax` protocol messages that are also found in
30-
other packages
31-
}}
32-
unnecessary_import: ignore
3328
unused_import: ignore

internal/sidekick/internal/dart/templates/lib/enum.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ limitations under the License.
1717
{{#Codec.DocLines}}
1818
{{{.}}}
1919
{{/Codec.DocLines}}
20-
final class {{Codec.Name}} extends ProtoEnum {
20+
final class {{Codec.Name}} extends {{Codec.Model.Codec.ProtoPrefix}}ProtoEnum {
2121
{{#Values}}
2222
{{#Codec.DocLines}}
2323
{{{.}}}

internal/sidekick/internal/dart/templates/lib/message.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ limitations under the License.
1818
{{#Codec.DocLines}}
1919
{{{.}}}
2020
{{/Codec.DocLines}}
21-
final class {{Codec.Name}} extends ProtoMessage {
21+
final class {{Codec.Name}} extends {{Codec.Model.Codec.ProtoPrefix}}ProtoMessage {
2222
static const String fullyQualifiedName = '{{Codec.QualifiedName}}';
2323
2424
{{#Fields}}

internal/sidekick/internal/dart/templates/lib/method.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Stream<{{Codec.ResponseType}}> {{Codec.Name}}({{Codec.RequestType}} request) {
4141
///
4242
/// This method can be used to get the current status of a long-running
4343
/// operation.
44-
Future<Operation<T, S>> getOperation<T extends ProtoMessage, S extends ProtoMessage>(Operation<T, S> request) async {
44+
Future<Operation<T, S>> getOperation<T extends {{Model.Codec.ProtoPrefix}}ProtoMessage, S extends {{Model.Codec.ProtoPrefix}}ProtoMessage>(Operation<T, S> request) async {
4545
final url = Uri.https(_host, '{{PathInfo.Codec.PathFmt}}');
4646
{{#Codec.ReturnsValue}}final response = {{/Codec.ReturnsValue}}await _client.{{Codec.RequestMethod}}(url{{#Codec.HasBody}}, body: {{Codec.BodyMessageName}}{{/Codec.HasBody}});
4747
return Operation.fromJson(response, request.operationHelper);

0 commit comments

Comments
 (0)