// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This proto verifies that we keep the name mangling algorithm (which is
// position dependent) intact in the protoc_gen_go generator. The field names
// and the getter names have to be kept intact over time, both in the OPEN and
// in the HYBRID API. How fields are "mangled" is described in a comment per
// field.

// The order of "evaluation" of fields is important. Fields are evaluated in
// order of appearance, except the oneof union names, that are evaluated after
// their first member. For each field, check if there is a previous field name
// or getter name that clashes with this field or it's getter. In case there is
// a clash, add an _ to the field name and repeat. In the case of oneof's, the
// union will be renamed if it clashes with it's first member, but not if it
// clashes with it's second.

// This scheme is here for backwards compatibility.
// The type of clashes that can be are the following:
// 1 - My field name clashes with their getter name
// 2 - My getter name clashes with their field name

syntax = "proto3";

package net.proto2.go.testdata.nameclashopen3;

import "google/protobuf/go_features.proto";

option go_package = "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/nameclash/test_name_clash_open3";

message M0 {
  int32 i1 = 1;
}

message M1 {
  // initial name in Go     | Clashes with field | type | final name
  // Foo                    | -                  | -    | Foo
  // GetFoo                 | foo                | 1    | GetFoo_
  // GetGetFoo              | -                  | -    | GetGetFoo
  M0 foo = 1;
  M0 get_foo = 2;
  M0 get_get_foo = 3;
}

message M2 {
  // initial name in Go     | Clashes with field | type | final name
  // GetGetFoo              | -                  | -    | GetGetFoo
  // GetFoo                 | get_get_foo        | 2    | GetFoo_
  // Foo                    | -                  | -    | Foo
  M0 get_get_foo = 3;
  M0 get_foo = 2;
  M0 foo = 1;
}

message M3 {
  // initial name in Go     | Clashes with field | type | final name
  // GetFoo                 | -                  | -    | GetFoo
  // GetGetFoo              | get_foo            | 1    | GetGetFoo_
  // Foo                    | get_foo            | 2    | Foo_
  M0 get_foo = 2;
  M0 get_get_foo = 3;
  M0 foo = 1;
}

message M4 {
  // initial name in Go     | Clashes with field | type | final name
  // GetFoo                 | -                  | -    | GetFoo
  // GetGetFoo              | get_foo            | 1    | GetGetFoo_
  //  GetGetGetFoo          | -                  | -    | GetGetGetFoo
  //                        |                    |      |
  // Foo                    | get_foo            | 2    | Foo_
  M0 get_foo = 2;

  oneof get_get_foo {
    int32 get_get_get_foo = 3;
  }

  M0 foo = 1;
}

message M5 {
  // Note evaluation order - get_get_foo before get_get_get_foo
  // initial name in Go     | Clashes with field | type | final name
  // GetFoo                 | -                  | -    | GetFoo
  // GetGetGetFoo           | -                  | -    | GetGetGetFoo
  //  GetGetFoo             | get_foo            | 1    | GetGetFoo_
  //                        |                    |      |
  // Foo                    | get_foo            | 2    | Foo_
  M0 get_foo = 2;

  oneof get_get_get_foo {
    int32 get_get_foo = 3;
  }

  M0 foo = 1;
}

message M6 {
  // Note evaluation order - get_get_get_foo before get_get_foo
  // initial name in Go     | Clashes with field | type | final name
  // GetGetFoo              | -                  | -    | GetGetFoo
  //  GetGetGetFoo          | -                  | -    | GetGetGetFoo
  //                        |                    |      |
  // GetFoo                 | get_get_foo        | 2    | GetFoo_
  // Foo                    | -                  | -    | Foo
  oneof get_get_foo {
    int32 get_get_get_foo = 3;
  }

  M0 get_foo = 2;
  M0 foo = 1;
}

message M7 {
  // Note evaluation order - bar before get_get_foo, then get_get_get_foo
  // initial name in Go     | Clashes with field | type | final name
  // GetGetFoo              | -                  | -    | GetGetFoo
  //  Bar                   | -                  | -    | Bar
  //  GetFoo                | foo                | 1    | GetFoo_
  //                        |                    |      |
  // Foo                    | -                  | -    | Foo
  oneof get_get_foo {
    bool bar = 4;
    int32 get_foo = 3;
  }

  M0 foo = 1;
}

message M8 {
  // Note evaluation order - get_get_foo before get_get_get_foo
  // initial name in Go     | Clashes with field | type | final name
  // GetGetGetFoo           | get_get_foo        | 1    | GetGetGetFoo_
  //  GetGetFoo             | -                  | -    | GetGetFoo
  //                        |                    |      |
  // GetFoo                 | get_get_foo        | 2    | GetFoo_
  // Foo                    | -                  | -    | Foo
  oneof get_get_get_foo {
    int32 get_get_foo = 3;
  }

  M0 get_foo = 2;
  M0 foo = 1;
}

message M9 {
  // Note evaluation order - get_get_foo before get_get_get_foo, then get_foo
  // initial name in Go     | Clashes with field | type | final name
  // GetGetGetFoo           | get_get_foo        | 1    | GetGetGetFoo_
  //  GetGetFoo             | -                  | -    | GetGetFoo
  //  GetFoo                | get_get_foo        | 2    | GetFoo_
  //                        |                    |      |
  // Foo                    | -                  | -    | Foo
  oneof get_get_get_foo {
    int32 get_get_foo = 3;
    int32 get_foo = 2;
  }

  M0 foo = 1;
}


message M21 {
  string _foo = 1;
  string X_foo = 2;
  string get_x_foo = 3;
}
